Native Assertions
There's console.assert
On Sun, Jan 13, 2019 at 6:49 PM Cyril Auburtin <cyril.auburtin at gmail.com> wrote:
There's
console.assert
The problem with that and other userland solutions is that for something like this:
assert(a !== b, `a (${a}) !== b (${b})`);
you have only three choices for production builds:
-
Have the asserts active in production (throwing assertion errors).
-
Have the asserts do the relevant check and process the template literal, but not raise an error when it fails. (So
a !== b
still gets executed, but no error is raised if it's false.) -
Pre-process your scripts to remove the assertions
Whereas with a language-level assert, in production that entire
pseudo-function-call would be parsed but then completely ignored, including
the a !== b
and evaluating the template. And ideally, with a
language-level feature, even when assertions are enabled, the template
would only be evaluated if the assertion failed, as though you'd written:
if (a !== b) {
throw new AssertionError(`a (${a}) !== b (${b})`);
}
-- T.J. Crowder
console.assert is not standardized at this point, nor is it part of the language. Additionally, the semantics are inappropriate for the required use cases.
To requote the relevant part from the linked thread:
- AssertionError <: Error
- assert(x === 12); // throws an AssertionError with a default error message
- assert(x === 12, "twelve, supposedly") // throws an AssertionError with the given error message
console.assert does not throw and its intent is not the same. The assert I'm referring to is related to Code Contracts. Therefore your reference is seemingly orthogonal.
How about extending debugger statement?
Eg. debugger.assert.
mild abuse of tagged templates:
const ENABLE_ASSERT = true;
let a = 3;
let b = 4;
assert `a !== b` `${a} !== ${b}`;
assert `a === b` `${a} === ${b}`;
function assert(strings, ...keys) {
if (!ENABLE_ASSERT) { return function ignore() {}; }
let result = eval(String.raw(strings, ...keys))
if (result) {
return function pass() {};
} else {
return function fail(strings, ...keys) {
throw new Error("assert fail: " + String.raw(strings, ...keys));
};
}
}
In theory, the assert code can be completely eliminated if ENABLE_ASSERT is false. But Google Closure Compiler only partially eliminates it for some reason.
If the intent of assert is only about sanity checks, then this would not be unreasonable. C# has done similar < docs.microsoft.com/en-us/dotnet/api/system.diagnostics.debug.assert?view=netframework-4.7.2
.
If this is treated as a foot in the door for Code Contracts, then extending debugger is inappropriate as the intentions are different.
The latter subsumes the former, but is probably a bridge too far for ECMAScript at this stage. I would practically look for:
import {assert} from ''std:contracts"
along with comparable behavior to: < docs.microsoft.com/en-us/dotnet/framework/debug-trace-profile/code
console.assert is standardized by the WHATWG at console.spec.whatwg.org/#assert.
Sebastian
Good to know that has moved forward, but it is still minimally relevant due to the other points raised.
Also as an FYI the following paper from OOPSLA 2018:
Collapsible Contracts: Fixing a Pathology of Gradual Typing
www.eecs.northwestern.edu/~robby/pubs/papers/oopsla2018-fgsfs.pdf
Seven years ago there was discussion around standardizing "assert". Has there been any movement on this since then?
esdiscuss.org/topic/native