Discussion:
Program abortion in Oberon-07
(too old to reply)
August Karlstrom
2010-06-07 15:48:42 UTC
Permalink
Hi,

In Oberon-07 the procedure HALT was removed. According to the author of
the language the call HALT(n) should now be written as ASSERT(FALSE, n)
instead. I find this a bit strange as the common usage of assertions is
to let the compiler disable them when the program is ready for
production. If we disable assertions we therefore also rule out program
abortion. Is the intention here that the compiler should always generate
instructions for the calls to ASSERT? For me HALT and ASSERT are
somewhat different concepts.

Can anyone shed some light on this?


Regards

August
Pascal J. Bourguignon
2010-06-07 16:01:15 UTC
Permalink
Post by August Karlstrom
In Oberon-07 the procedure HALT was removed. According to the author
of the language the call HALT(n) should now be written as
ASSERT(FALSE, n) instead. I find this a bit strange as the common
usage of assertions is to let the compiler disable them when the
program is ready for production. If we disable assertions we therefore
also rule out program abortion. Is the intention here that the
compiler should always generate instructions for the calls to ASSERT?
For me HALT and ASSERT are somewhat different concepts.
Can anyone shed some light on this?
Disabling assertions in production is like using a seat belt while
you're driving your pedal car as a child, and not using it when you're
adult in a real car.

It's really when you're in production that you want to be sure that
the data produced is good!
--
__Pascal Bourguignon__ http://www.informatimago.com/
Chris Burrows
2010-06-08 00:14:23 UTC
Permalink
Post by Pascal J. Bourguignon
Post by August Karlstrom
In Oberon-07 the procedure HALT was removed. According to the author
of the language the call HALT(n) should now be written as
ASSERT(FALSE, n) instead. I find this a bit strange as the common
usage of assertions is to let the compiler disable them when the
program is ready for production. If we disable assertions we therefore
also rule out program abortion. Is the intention here that the
compiler should always generate instructions for the calls to ASSERT?
For me HALT and ASSERT are somewhat different concepts.
Can anyone shed some light on this?
Disabling assertions in production is like using a seat belt while
you're driving your pedal car as a child, and not using it when you're
adult in a real car.
It's really when you're in production that you want to be sure that
the data produced is good!
That's a good analogy - I agree 100%. The compiler should always generate
instructions for the calls to ASSERT. It is up to the implementor of the
assertion handler to decide what should happen next.

--
Chris Burrows
CFB Software
Astrobe: ARM Oberon-07 Development System
http://www.astrobe.com
August Karlstrom
2010-06-08 15:56:59 UTC
Permalink
Post by Pascal J. Bourguignon
Disabling assertions in production is like using a seat belt while
you're driving your pedal car as a child, and not using it when you're
adult in a real car.
It's really when you're in production that you want to be sure that
the data produced is good!
OK, I agree with that. My only doubt is that assertions are sometimes
quite costly to perform; e.g. post conditions like asserting that a
sequence is sorted at the end of a sort procedure or making sure an
element has bee inserted at the end of an insert procedure.


August
Chris Burrows
2010-06-09 04:07:35 UTC
Permalink
Post by August Karlstrom
Post by Pascal J. Bourguignon
Disabling assertions in production is like using a seat belt while
you're driving your pedal car as a child, and not using it when you're
adult in a real car.
It's really when you're in production that you want to be sure that
the data produced is good!
OK, I agree with that. My only doubt is that assertions are sometimes
quite costly to perform; e.g. post conditions like asserting that a
sequence is sorted at the end of a sort procedure or making sure an
element has bee inserted at the end of an insert procedure.
Typically I would perform that level of post-condition checking at the unit
testing stage of development only. However, it all depends on the
requirements of the application. e.g. if the assertion that the sequence is
sorted is a life-or-death question then you have no choice but to perform it
in the actual code rather than just in the unit-testing framework.

The following article by G. Sawitzki explores various aspects of the use of
assertions to handle pre- and post-conditions :

http://statlab.uni-heidelberg.de/projects/oberon/kurs/www/Kap12.html

--
Chris Burrows
CFB Software
Astrobe: ARM Oberon-07 Development System
http://www.astrobe.com
August Karlstrom
2010-06-09 14:17:44 UTC
Permalink
Post by Chris Burrows
Typically I would perform that level of post-condition checking at the unit
testing stage of development only. However, it all depends on the
requirements of the application. e.g. if the assertion that the sequence is
sorted is a life-or-death question then you have no choice but to perform it
in the actual code rather than just in the unit-testing framework.
The following article by G. Sawitzki explores various aspects of the use of
http://statlab.uni-heidelberg.de/projects/oberon/kurs/www/Kap12.html
Thanks for the link.

Still, since Oberon pre Oberon-07 had a HALT procedure, Wirth must have
reasoned that it was needed.


August
Chris Burrows
2010-06-10 00:26:03 UTC
Permalink
Post by August Karlstrom
Still, since Oberon pre Oberon-07 had a HALT procedure, Wirth must have
reasoned that it was needed.
Well, yes - but that was before there was an ASSERT statement in Oberon. My
observation is that Wirth takes great pains to:

a) avoid redundancy and

b) keep the number of reserved words to a minimum wherever possible.

Why go to all the effort to implement a separate HALT statement (which has
very limited application anyway) when it is just a special case of ASSERT?

In my early days with Pascal I was puzzled why there was an 'Odd' function
but no complementary 'Even' function. I now have a better understanding why.

Regards,
Chris Burrows
CFB Software

Astrobe: ARM Oberon-07 Development System
http://www.astrobe.com
Bill Leary
2010-06-13 23:52:37 UTC
Permalink
Post by Pascal J. Bourguignon
Post by August Karlstrom
In Oberon-07 the procedure HALT was removed. According to the author
of the language the call HALT(n) should now be written as
ASSERT(FALSE, n) instead. I find this a bit strange as the common
usage of assertions is to let the compiler disable them when the
program is ready for production. If we disable assertions we therefore
also rule out program abortion. Is the intention here that the
compiler should always generate instructions for the calls to ASSERT?
For me HALT and ASSERT are somewhat different concepts.
Can anyone shed some light on this?
Disabling assertions in production is like using a seat belt while
you're driving your pedal car as a child, and not using it when you're
adult in a real car.
Disagree.

For many places and most languages, the idea is to use assertions during
development, accepting the performance hit and the cryptic assert failure
messages, then compile them out for production code. If you have a need to
always validate something, then there should be live (not assertion) code in
there to do it, clean up, and to give a non-cryptic indication to the user
about what happened. In my own first encounters with assert (in Eiffel) you
were expected (at least then, not sure about now) to liberally apply
assertions to the program during devleopment to ensure that the
design-by-contract was satisfied. The performance hit was dramatic. It was
assumed that you would compile out the pre- and post-conditions and the
assertions for production code. Later, when we started having ASSERT
availalbe in C the same expectations existed. I've only recently
encountered cases where the code was clearly dangerous if the assertions
were removed. On the hand, in this code, I also noticed that the assertions
were now used as if they were "if (some error) exit(n);" and they'd given up
using them for design verification altogether.

Does Oberon-7 still support the comple-out option?

If they're proposing that ASSERT(FALSE, n) is the replacment for HALT(n).
I'd expect not.

On the other hand, it could be argued that HALT(n) (and exit(n) in C and so
on) is a bad idea anyway as there are other, though often tedious, ways to
handle fatal cases.
Post by Pascal J. Bourguignon
It's really when you're in production that you want to be sure that
the data produced is good!
By using real code that handles the precise failure, not something that
basically just dumps the machine. If you're going to use HALT(n) should be
the last thing in a code series that handles the fatal case.

- Bill
Chris Burrows
2010-06-14 02:36:56 UTC
Permalink
Post by Bill Leary
Does Oberon-7 still support the comple-out option?
When talking about Oberon-07 be careful to distinguish between 'Oberon-07
the language' and a particular 'implementation of Oberon-07' Compile-time
options are completely absent from the language report - it is intended to
be as platform-agnostic as is possible. AFAIR the same applied to the
design of Pascal and Modula-2. Compile-time options are
implementation-specific details. It is the responsibility of whoever is
implementing an Oberon-07 system to determine whether the specific
requirements of whichever particular system (which may exist now or even
sometime in the future) they are targeting . They are not a prescriptive
part of the Oberon-07 language itself.

Note that a compile-time option is not the *only* possible solution to
satisfy those who prefer to have the option of switching assertions on / off
. There are other possible implementation-specific mechanisms that don't
need compile-time options or need to be spelt out as additional features in
the design of the *language*.

For example I can imagine (but not necessarily encourage) a scheme that
could allow multiple-levels of enabling / disabling assertions all under
programmer control without a runtime performance hit, as follows:

a) It is feasible that an optimising compiler could statically determine
that it was unnecessary to generate ANY code for an assert statement of the
form:

ASSERT(TRUE, n)

b) If so, a programmer using that system could define a global constant e.g.

CONST
AssertLevel = 5;

c) Then throughout his code, for optional assertions he would write
something like:

ASSERT((AssertLevel > 3) & (param > 0), 100);

d) Then if he changed the constant to:

CONST
AssertLevel = 3;

and recompiled his program the previous ASSERT statement woul dbe optimised
away to nothing. However, any ASSERT statements with AssertLevels <= 3 would
still be activated.
Post by Bill Leary
If they're proposing that ASSERT(FALSE, n) is the replacment for HALT(n).
I'd expect not.
The substitute for HALT is ASSERT(FALSE) without the additional parameter
which, depending on the actual system in question, presumably would lead to
some sort of unconditional program termination.

The additional parameter on the general form of the ASSERT statement
indicates that the assertion handler can take alternative actions depending
on the value of the parameter. Depending on what the system was designed to
do, this could conceivably include an action where just a warning is
produced and processing then resumes from where the assertion failed. It all
depends on how the implementor chooses to interpret the word 'abort'.

--
Chris Burrows
CFB Software
Astrobe: ARM Oberon-07 Development System
http://www.astrobe.com
Bill Leary
2010-06-14 05:42:30 UTC
Permalink
((..trimmed for brevity..))
Post by Chris Burrows
Post by Bill Leary
Does Oberon-7 still support the comple-out option?
When talking about Oberon-07 be careful to distinguish between 'Oberon-07
the language' and a particular 'implementation of Oberon-07'
Right, good catch. I was sloppy in my phrasing. I meant "current
implementations of..." or something similar.
Post by Chris Burrows
Note that a compile-time option is not the *only* possible solution to
satisfy those who prefer to have the option of switching assertions on /
off . There are other possible implementation-specific mechanisms that
don't need compile-time options or need to be spelt out as additional
features in the design of the *language*.
No, it's just very common. Java, I've been told, always carries the
assertion code but the run-time, by default, doesn't execute it.
Post by Chris Burrows
For example I can imagine (but not necessarily encourage) a scheme that
could allow multiple-levels of enabling / disabling assertions all under
a) It is feasible that an optimising compiler could statically determine
that it was unnecessary to generate ANY code for an assert statement of
ASSERT(TRUE, n)
b) If so, a programmer using that system could define a global constant e.g.
CONST
AssertLevel = 5;
c) Then throughout his code, for optional assertions he would write
ASSERT((AssertLevel > 3) & (param > 0), 100);
CONST
AssertLevel = 3;
and recompiled his program the previous ASSERT statement woul dbe
optimised away to nothing. However, any ASSERT statements with
AssertLevels <= 3 would still be activated.
I've seen similar used for DEBUG(...), laid out pretty much as you've
outlined.
Post by Chris Burrows
Post by Bill Leary
If they're proposing that ASSERT(FALSE, n) is the replacment for HALT(n).
I'd expect not.
The substitute for HALT is ASSERT(FALSE) without the additional parameter
which, depending on the actual system in question, presumably would lead
to some sort of unconditional program termination.
I was quoting from the August Karlstrom message "In Oberon-07 the procedure
HALT was removed. According to the author of the language the call HALT(n)
should now be written as ASSERT(FALSE, n) instead." Perhaps he meant author
of the implementation he's using? I haven't looked at the '-07 language
report myself.

- Bill
Chris Burrows
2010-06-14 12:52:46 UTC
Permalink
Post by Bill Leary
Post by Chris Burrows
The substitute for HALT is ASSERT(FALSE) without the additional parameter
which, depending on the actual system in question, presumably would lead
to some sort of unconditional program termination.
I was quoting from the August Karlstrom message "In Oberon-07 the
procedure HALT was removed. According to the author of the language the
call HALT(n) should now be written as ASSERT(FALSE, n) instead." Perhaps
he meant author of the implementation he's using? I haven't looked at the
'-07 language report myself.
Understood. If you are interested in looking at the Oberon-07 Language
Report it is only 16 pages long (every word counts though!):

"The Programming Language Oberon-07 (Revised Oberon)"

http://www.inf.ethz.ch/personal/wirth/Articles/Oberon.html

HALT is not defined in the Oberon-07 Language Report but Wirth notes its
absence in two of the support documents on the same website:

"HALT(n) replaced by ASSERT(FALSE, n)" (ref: "Oberon at a Glance")

"... and HALT is replaced by ASSERT(FALSE)" (ref: "Differences between
Oberon-07 and Oberon")

The latter was the one I was referring to. However as the only form of HALT
defined in the 1990 Oberon Report on the same website was HALT(x), the
former, that August presumably was referring to, appears to be more
accurate.

Regards,
Chris
Bill Leary
2010-06-17 03:17:20 UTC
Permalink
Post by Chris Burrows
Post by Bill Leary
Post by Chris Burrows
The substitute for HALT is ASSERT(FALSE) without the additional
parameter which, depending on the actual system in question, presumably
would lead to some sort of unconditional program termination.
I was quoting from the August Karlstrom message "In Oberon-07 the
procedure HALT was removed. According to the author of the language the
call HALT(n) should now be written as ASSERT(FALSE, n) instead." Perhaps
he meant author of the implementation he's using? I haven't looked at
the '-07 language report myself.
Understood. If you are interested in looking at the Oberon-07 Language
"The Programming Language Oberon-07 (Revised Oberon)"
http://www.inf.ethz.ch/personal/wirth/Articles/Oberon.html
Thanks. I've book marked it and will read it when I have a chance.
Post by Chris Burrows
HALT is not defined in the Oberon-07 Language Report but Wirth notes its
"HALT(n) replaced by ASSERT(FALSE, n)" (ref: "Oberon at a Glance")
"... and HALT is replaced by ASSERT(FALSE)" (ref: "Differences between
Oberon-07 and Oberon")
The latter was the one I was referring to. However as the only form of
HALT defined in the 1990 Oberon Report on the same website was HALT(x),
the former, that August presumably was referring to, appears to be more
accurate.
That makes sense.

- Bill
August Karlstrom
2010-06-14 13:23:16 UTC
Permalink
Post by Bill Leary
I was quoting from the August Karlstrom message "In Oberon-07 the
procedure HALT was removed. According to the author of the language the
call HALT(n) should now be written as ASSERT(FALSE, n) instead." Perhaps
he meant author of the implementation he's using? I haven't looked at
the '-07 language report myself.
I did not refer to any particular implementation; my source was the
document "Oberon at a glance" (section "Changes"):

http://www.inf.ethz.ch/personal/wirth/Articles/Oberon/OberonSummary.pdf

With this new convention you would typically use ASSERT(FALSE) to abort
a program with a standard "exit failure" code.


August
Chris Burrows
2010-06-15 00:49:35 UTC
Permalink
Post by Bill Leary
((..trimmed for brevity..))
Post by Chris Burrows
Note that a compile-time option is not the *only* possible solution to
satisfy those who prefer to have the option of switching assertions on /
off . There are other possible implementation-specific mechanisms that
don't need compile-time options or need to be spelt out as additional
features in the design of the *language*.
No, it's just very common. Java, I've been told, always carries the
assertion code but the run-time, by default, doesn't execute it.
I can see how that might work for Java if it is the execution machine
(interpreter) that is deciding *at runtime* whether or not to ignore the
assertions.

It is a different question when asking a compiler to selectively suppress
the generation of code at compile-time. If as little as one byte in an
executable code file changes the behaviour of the program can change -
sometimes drastically.

If all of the extensive testing that was performed *before* assertions are
switched off is duplicated after assertions are switched off (in addition to
any other pre-shipping final testing) then I would not be so concerned.
However, being cynical, I suspect the sequence more often goes like this:

1. Perform unit testing
2. Perform integration testing
3. Switch off assertions, range checking, bounds checking etc.
4. Rebuild
5. Ship

I hope my pessimism is unjustified,

Regards,
Chris
Bill Leary
2010-06-17 03:27:05 UTC
Permalink
Post by Chris Burrows
Post by Bill Leary
((..trimmed for brevity..))
Post by Chris Burrows
Note that a compile-time option is not the *only* possible solution to
satisfy those who prefer to have the option of switching assertions on /
off . There are other possible implementation-specific mechanisms that
don't need compile-time options or need to be spelt out as additional
features in the design of the *language*.
No, it's just very common. Java, I've been told, always carries the
assertion code but the run-time, by default, doesn't execute it.
I can see how that might work for Java if it is the execution machine
(interpreter) that is deciding *at runtime* whether or not to ignore the
assertions.
It is a different question when asking a compiler to selectively suppress
the generation of code at compile-time. If as little as one byte in an
executable code file changes the behaviour of the program can change -
sometimes drastically.
If all of the extensive testing that was performed *before* assertions are
switched off is duplicated after assertions are switched off (in addition
to any other pre-shipping final testing) then I would not be so concerned.
1. Perform unit testing
2. Perform integration testing
3. Switch off assertions, range checking, bounds checking etc.
4. Rebuild
5. Ship
I hope my pessimism is unjustified,
No, it's quite justified. In the OO shop I worked at, using Eiffel in it's
early days, the process was pretty much as you note except that between 2
and 5 was regression testing and between 4 and 5 there was a testing step,
but it was by no means as extensive as the testing done with all the
protective stuff turned on. And we got burned by it once. Once was enough
to change the process for us. The process after we got burned (crashed
rather spectacularly at a customer site) became (using your outline):

1. Perform unit testing
2. Perform integration testing
3. Switch off assertions, range checking, bounds checking etc.
4. Rebuild
5. Perform full regression testing
6. Perform full new feature testing
7. Ship.

We changed the process and put the heavy testing into AFTER the protective
stuff was switched off. That meant that when a bug was found, we had to
turn it back on and rebuild, an all day process as I recall, to find the
bug, but we had no more customer crashes. And we usually found that the
problem was that someone had used a precondition or assert, which got
compiled out, rather than live code to test for in cases where you might
actually, on a live system, get an out of range input. The fix was almost
always to put in that live code to handle the situation explicitly.

- Bill
August Karlstrom
2010-06-14 14:41:21 UTC
Permalink
Post by Chris Burrows
b) If so, a programmer using that system could define a global constant e.g.
CONST
AssertLevel = 5;
c) Then throughout his code, for optional assertions he would write
ASSERT((AssertLevel> 3)& (param> 0), 100);
CONST
AssertLevel = 3;
and recompiled his program the previous ASSERT statement woul dbe optimised
away to nothing. However, any ASSERT statements with AssertLevels<= 3 would
still be activated.
I reason that this would not work since it is in conflict with the
language semantics - if AssertLevel is 3 then the statement

ASSERT((AssertLevel > 3) & (param > 0), 100)

should be treated the same as

ASSERT(FALSE, 100)

You would need some kind of meta identifiers (a language extension) to
achieve selective inclusion/exclusion of assertions.


August
Chris Burrows
2010-06-15 00:32:42 UTC
Permalink
Post by August Karlstrom
and recompiled his program the previous ASSERT statement would be
optimised
away to nothing.
Oops! No it wouldn't. TRUE & (possibly) FALSE # TRUE

Go to the back of the class Burrows!
Post by August Karlstrom
I reason that this would not work since it is in conflict with the
language semantics - if AssertLevel is 3 then the statement
ASSERT((AssertLevel > 3) & (param > 0), 100)
should be treated the same as
ASSERT(FALSE, 100)
Thank you for pointing out my error.
Post by August Karlstrom
You would need some kind of meta identifiers (a language extension) to
achieve selective inclusion/exclusion of assertions.
I have previously considered how I could implement the #IFDEF type of
mechanism for selective compilation without the use of meta-identifiers or
language extensions. As this is a general solution it could also be used for
selective inclusion/exclusion of assertions. See what you think about this:

a) It would be feasible (and correct?) for a compiler to generate zero code
for statements that could be statically evaluated to:

IF FALSE THEN .... END;

b) Then you could write:

IF (assertLevel > 3) THEN ASSERT(param > 0, 100) END;

That would work wouldn't it?

Regards,
Chris
August Karlstrom
2010-06-15 08:09:08 UTC
Permalink
Post by Chris Burrows
Post by August Karlstrom
You would need some kind of meta identifiers (a language extension) to
achieve selective inclusion/exclusion of assertions.
Seems like I was wrong.

[...]
Post by Chris Burrows
a) It would be feasible (and correct?) for a compiler to generate zero code
IF FALSE THEN .... END;
IF (assertLevel> 3) THEN ASSERT(param> 0, 100) END;
That would work wouldn't it?
Looks OK to me.


August
Chris Burrows
2010-06-17 07:01:42 UTC
Permalink
Post by August Karlstrom
You would need some kind of meta identifiers (a language extension) to
achieve selective inclusion/exclusion of assertions.
Having thought about it some more, my original proposal without using IF ...
THEN would also have been OK if I hadn't made the silly logic errors. Here
is another attempt:

a) It is feasible that an optimising compiler could statically determine
that it was unnecessary to generate ANY code for an assert statement
equivalent to:

ASSERT(TRUE, n)

b) If so, a programmer using that system could define a global constant e.g.

CONST
DisableAssert = FALSE;

c) Then throughout his code, for optional assertions he would write
something like:

ASSERT(DisableAssert OR (param > 0), 100);

d) Then if he changed the constant to:

CONST
DisableAssert = TRUE;

and recompiled his program the previous ASSERT statement would be optimised
away to nothing. However, any ASSERT statements without the DisableAssert
test would still be activated.

Fingers crossed ;-)

Regards,
Chris.

Loading...