Post by unknownThe C equivalent of (SHOULDNT) is abort(). Not, by the way, assert(0).
If that's the case, SHOULDNT shouldn't be in the language.
After all, forcing the execution of the program to a halt is unmodular:
the caller might want to run the code and try an alternate strategy.
(Heck, that's what Erlang is all about: surviving faulty code that does
thing's that shouldn't happen.)
Post by unknownIs it clear to everyone that
"This code must raise an exception at run time"
and
"This code is in error"
are different?
This classification isn't complete, and I think the ongoing discussion
is at least partially senseless because wrong distinctions of this kind
are constantly being made.
Actually, Erlang has more failure modes (and this list may not even be
complete):
1. Erroneous code that's rejected by the compiler. This includes stuff
like "1 = 2 3".
2. Code that will raise an exception. Example: "1 = 2".
3. Code that will terminate the process. Essentially, that's code that
doesn't catch all exceptions that may occur.
4. Code that will terminate the Erlang node.
5. Code that will terminate all communicating Erlang nodes.
Category 2 is what most confusion comes from: depending personal
definitions, one may consider it erroneous or not (and either definition
makes sense, depending on the point of view).
There's another source of confusion: Some people here argue that a
compiler shouldn't change the semantics of the language, but is that
indeed the case? Both syntax and semantics of Erlang have changed over
the years, in in an upwards-compatible fashion.
Post by unknownIs it also clear that
"This code is obviously silly"
and
"This code must raise an exception at run time"
are different? Lint warns about things that are clearly silly,
yet perfectly legal, and perfectly harmless. For example,
x == y;
as a C statement is perfectly well defined, and quite harmless,
yet lint warns about it because you probably didn't mean it.
A C compiler which refused to compile such a program would not
be helpful, it would be buggy.
A C compiler would emit a warning and be compliant.
If I were to decide, I'd adopt a similar policy: issue warnings about
constructs like 1=2.
However, I dislike somethine entirely different about them. There's
clearly a need to make a computation fail, and different people use
different idioms to express is. Some say 1=2, others say a+0, and I saw
mentions a handful others.
While that's neat, it's also an unnecessary maintenance obstacle.
Whenever a maintainer sees such code, he has to (a) find out what this
code does (which will take more time than usual because he'll have to
revisit the usual assumption that code isn't written for raising
exception), (b) figure out whether the code is raising the exception
intentionally or not.
There are two additional disadvantages: (c) it's impossible to do a grep
to see whether any temporary exception-raisers were accidentally left in
some code that's considered ready for production release, and (d) if the
code does raise an exception, it will give the maintainer wrong
information: the true error is that the system is trying to execute
unwritten code, but the system will give a different error message.
I'm quite mystified why there isn't a "niy" (not implemented yet) or
"tbd" (to be determined) routine, that explicitly raises an exception
saying "fatal error: trying to execute code that has not yet been
written" (or something similar).
Once such a routine is in place, the question whether changing the
semantics of obviously silly constructs is a no-brainer: if there's no
useful purpose for them, their semantics is irrelevant and can be
changed. One may adopt a more conservative approach and maintain
compatibility with legacy code, so a warning would probably be more
appropriate. An even better option would be if that warning could be
turned into an error for those shops who want strict discipline (not all
shops need that, but sometimes there are good reasons to turn on the
equivalent of -Wall --warnings-as-errors).
Post by unknownIt is possible to make (=)-for-(==) and (==)-for-(=) errors in
Erlang, and lint checking for Erlang might warn about them even
though they are legal.
Whether a particular piece of apparent silliness is worth warning
about is an empirical question: how often do programmers make the
kind of mistake that results in an instance of that pattern, and
how often do they intend it?
And, more importantly: how easy is it to make the compiler detect that
pattern, and how likely is it that the compiler will make errors when
identifying such patterns?
Post by unknownI've worked on a couple of compilers for languages that supported
exception handling. (I _think_ mine was the first paper on doing this
for Prolog, except that Quintus insisted on yanking it from the conference
after it was accepted.) Exception handling can be very tricky to get
right. (There's a debate raging in the Clean mailing list at this moment.)
ANSI Smalltalk exception handling is a case in point; to me it seems
insanely complicated, and it's not clear that Squeak has got it 100% right
yet. This means that especially when you are maintaining compilers, you
_need_ simple test cases which are certain to cause exceptions because
that's what you're testing.
There's always the explicit exception raising statement. Any language
that has exceptions should have such a statement, and Erlang does it right.
Actually, I don't think that generating a test case should be a problem,
ever. There's always the possibility to do unit testing. You'll have to
structure the compiler so that it has units to be tested, but this
restructuring will clean up the compiler considerably, making is more
stable and reliable, so this is a good idea anyway. Loss of test cases
due to changes in language syntax or semantics is just an indicator that
the compiler is badly structured IMNSHO.
Regards,
Jo