ES4 draft: assert expression

# Lars Hansen (17 years ago)

We talked about debugging information and an assertion form on es4-discuss a while ago, in a thread about the Error object. As a result of that discussion, I'm sending out a draft for an "assert" expression form. In addition, the Error object draft will be updated to accomodate a new subclass AssertionExpression, and a simple standard for debugging information will be added to the description of the Error classes.

The last detail from that discussion, about providing a way for programs to set the source origin and line numbers -- aiding translators -- is still open, but I am aware of how desirable this is for certain applications.

Anyhow, here's the first draft spec for the assert expression.

# P T Withington (17 years ago)

Is there any way the value thrown in the 1-arg case could be the
'text' of arg1? It's so painful to get an assertion and not know what
it is...

# Lars Hansen (17 years ago)

Ah! Of course.

The natural thing to spec would be that the text of the expression would be part of (all of?) the "message" of the exception object in the 1-arg case.

# T. Michael Keesey (17 years ago)

On Fri, Apr 11, 2008 at 12:48 PM, Lars Hansen <lhansen at adobe.com> wrote:

Ah! Of course.

The natural thing to spec would be that the text of the expression would be part of (all of?) the "message" of the exception object in the 1-arg case.

Or would it be better for AssertionError to have another field (say, "expression") storing that, and then optionally use that in the default value of "message", which could be slightly more informative (e.g., "Assertion failed: <expression>")?

Maybe that's unnecessary, but I thought I'd throw it out there.

# Mark S. Miller (17 years ago)

2008/4/11 Lars Hansen <lhansen at adobe.com>:

We talked about debugging information and an assertion form on es4-discuss a while ago, in a thread about the Error object. As a result of that discussion, I'm sending out a draft for an "assert" expression form.

Hi Lars,

I missed the earlier discussion. From the draft spec you attached, it seems like the first argument to assert is always evaluated, its value is always checked, and if false, an error always thrown. While I like this better than the behavior normally associated with the name "assert", it is different, so I'm wondering if a different name is called for?

In C, C++, Java, and IIRC Eiffel, the assert expressions (and in Eiffel, the pre and post conditions as well) are not supposed to be part of the meaning of the program. If P is a correct program in any of these languages, then erasing P's assert statements (or turning them off through other means) should be correctness preserving. E and Caja have similar but mandatory checking functions, named "require" and "enforce" respectively. A correct program can validly depend on their arguments being executed, and can depend on these function throwing when the argument evaluates to false.

Can a correct ES4 program depend of the assert expression to do its thing? If so, then we should consider these expressions to be part of the meaning of the program, not just descriptions of what the program's meaning should be. If so, "assert" is a confusing name.

# Lars Hansen (17 years ago)

-----Original Message----- From: Mark S. Miller [mailto:erights at google.com] Sent: 14. april 2008 18:11 To: Lars Hansen Cc: es4-discuss at mozilla.org Subject: Re: ES4 draft: assert expression

2008/4/11 Lars Hansen <lhansen at adobe.com>:

We talked about debugging information and an assertion form on
es4-discuss a while ago, in a thread about the Error object. As a
result of that discussion, I'm sending out a draft for an "assert" expression form.

Hi Lars,

I missed the earlier discussion. From the draft spec you attached, it seems like the first argument to assert is always evaluated, its value is always checked, and if false, an error always thrown. While I like this better than the behavior normally associated with the name "assert", it is different, so I'm wondering if a different name is called for?

In C, C++, Java, and IIRC Eiffel, the assert expressions (and in Eiffel, the pre and post conditions as well) are not supposed to be part of the meaning of the program. If P is a correct program in any of these languages, then erasing P's assert statements (or turning them off through other means) should be correctness preserving. E and Caja have similar but mandatory checking functions, named "require" and "enforce" respectively. A correct program can validly depend on their arguments being executed, and can depend on these function throwing when the argument evaluates to false.

Can a correct ES4 program depend of the assert expression to do its thing? If so, then we should consider these expressions to be part of the meaning of the program, not just descriptions of what the program's meaning should be. If so, "assert" is a confusing name.

Since there is no way to turn off asserts the program can (correctly) come to depend on the evaluation of the assertion. And I think your point is therefore a good one, though I don't know if it outweighs the benefits of (re)using a common name for this functionality.

Of course, in C and C++ programs and I assume Java there is no guarantee that the program does not depend on the evaluation of the assert expression; I see bugs like that from time to time.

(The inability to turn off asserts may in itself be a weakness, so maybe that's where the problem lies. But it is unclear how we would handle that problem in practice.)

# David Flanagan (17 years ago)

Lars Hansen wrote:

Since there is no way to turn off asserts the program can (correctly) come to depend on the evaluation of the assertion. And I think your point is therefore a good one, though I don't know if it outweighs the benefits of (re)using a common name for this functionality.

Hi everyone. I've been lurking in the archives, but this is the first time I've felt compelled (and able) to reply...

If there is no way to turn assertions off, and since the spec requires the parentheses around the assertion, I don't see what is gained by making this a expression instead of a global function. If all this spec offers is standardization of the error reporting information in the exception objects, I'm not sure that's worth it.

It doesn't look like this proposal has made it to the spreadsheet, and I haven't read whatever previous discussion spurred it, but it doesn't seem to me that it is worth doing as it stands.

(The inability to turn off asserts may in itself be a weakness, so maybe that's where the problem lies. But it is unclear how we would handle that problem in practice.)

I assume that the ideal way to turn assertions on and off must be outside the language as part of the embedding. But wouldn't a pragma like 'use assertions' be better than nothing? That way developers transitioning their code from development to production wouldn't have to go through and comment their assertions out, they'd just have to go and remove a pragma.

While on the topic of assertions and pragmas, if 'use strict' ends up checking for and warning about statements with no side effects, I imagine it could also check for and warn about assertions that obviously do have side effects... Not foolproof, but it could catch the case where someone writes = instead of ==, for example.

Of course, I get the impression that the true es4 approach (and this is a joke, I think) is to allow blocks of code to be placed in namespaces, and to allow the execution of those blocks to be turned on with 'use'. Kind of like #ifdef. With that in place, then the assert expression would be syntax sugar for placing the assertion in the the assertions namespace, and 'use assertions' would turn on the execution of assertions :-)

 David Flanagan
# Jeff Dyer (17 years ago)

On 4/15/08 11:05 AM, David Flanagan wrote:

Of course, I get the impression that the true es4 approach (and this is a joke, I think)

Careful what you ask for (or joke about :))

is to allow blocks of code to be placed in namespaces, and to allow the execution of those blocks to be turned on with 'use'. Kind of like #ifdef. With that in place, then the assert expression would be syntax sugar for placing the assertion in the the assertions namespace, and 'use assertions' would turn on the execution of assertions :-)

AS3 has just that. It was written up here:

proposals:program_configuration

We (Adobe) wanted to give it a "once around the block" before proposing for ES. Perhaps it will be ready for ES5.

# David Flanagan (17 years ago)

David Flanagan wrote:

If there is no way to turn assertions off, and since the spec requires the parentheses around the assertion, I don't see what is gained by making this a expression instead of a global function. If all this spec offers is standardization of the error reporting information in the exception objects, I'm not sure that's worth it.

Replying to myself here... Is the reason for an assert expression instead of an assert function that not having a method invocation makes a difference for performance?

Instead of adding 'assert' to the language, have you considered adding an 'assertion' keyword instead?

assertion x > 0, 'x must be positive'

This would be syntax sugar to create an invokeable object with an associated message or exception. The expression doesn't get evaluated unless the assertion is actually invoked or asserted or tested... A global assert() method could then accept assertion objects and either invoke them or ignore them. I'm not sure how the performance of this would compare to just having regular assertion always on, though. Treating assertions as objects does allow programmers to do things like start attaching arrays of preconditions and postconditions to methods.

I suspect this is all too complicated, though. My feeling is that if assertions can't be done right (and that includes turning them off) they shouldn't be done at all.

# Garrett Smith (17 years ago)

Sometimes errors might happen outside of an assert.

Then the developer would have to try to rely on other things, like Spidermonkey's error.lineNumber and error.stack, or even window.onerror, even though it is buggy.

It would be useful to get more error detail for free (w/o having to predefine an assert()).

Is it a security problem to have a lineNumber and/or stack by default on Error? If so, could it be addressed in some other way?

I don't have any problems with assert(), however, I would probably use it mostly during debugging, to try and track down an error. In this way, adding assert() would be a replacement for inserting console.log(). I would not put in too many assert()'s in by default because testing should be thorough and it should be done in another layer.

I would still want to know about other runtime exceptions that weren't wrapped in assert().

As for removing assertions, I would do that in my build process, if I needed to.

Garrett

# Mike Shaver (17 years ago)

On Wed, Apr 16, 2008 at 1:08 PM, David Flanagan <david at davidflanagan.com> wrote:

David Flanagan wrote:

If there is no way to turn assertions off, and since the spec requires the parentheses around the assertion, I don't see what is gained by making this a expression instead of a global function. If all this spec offers is standardization of the error reporting information in the exception objects, I'm not sure that's worth it.

Replying to myself here... Is the reason for an assert expression instead of an assert function that not having a method invocation makes a difference for performance?

Also, with an expression you don't have to evaluate the arguments when they're disabled.

assert (checkIntegrityOfObjectGraph())

Mike

# David Flanagan (17 years ago)

Mike Shaver wrote:

On Wed, Apr 16, 2008 at 1:08 PM, David Flanagan <david at davidflanagan.com> wrote:

David Flanagan wrote:

Also, with an expression you don't have to evaluate the arguments when they're disabled.

assert (checkIntegrityOfObjectGraph())

Mike

Right, but as the draft spec stands now, there is no way to disable assertions. Which is why I don't really see the point.

# Waldemar Horwat (17 years ago)

My comments:

I'm agnostic at this point as to whether there should be a way to disable assertions. Different languages do it different ways, and some provide both, with no clear winner.

The |assert| expression is a new /PrimaryExpression/. The identifier |assert| is contextually reserved.

How big is "assert"'s reservation context -- is it like "let" and other such things? I assume that this means that "assert" cannot be used as an identifier in an expression (except after a dot field name operator or similar such places).

Waldemar