Native Assertions

# Michael Haufe (5 years ago)

Seven years ago there was discussion around standardizing "assert". Has there been any movement on this since then?

esdiscuss.org/topic/native

# Cyril Auburtin (5 years ago)

There's console.assert

also check michaelficarra/proposal-first-class-protocols#27

# T.J. Crowder (5 years ago)

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:

  1. Have the asserts active in production (throwing assertion errors).

  2. 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.)

  3. 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

# Michael Haufe (5 years ago)

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:

  1. AssertionError <: Error
  2. assert(x === 12); // throws an AssertionError with a default error message
  3. 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.

# Michał Wadas (5 years ago)

How about extending debugger statement?

Eg. debugger.assert.

# felix (5 years ago)

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.

# Michael Haufe (5 years ago)

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

# Sebastian Zartner (5 years ago)

console.assert is standardized by the WHATWG at console.spec.whatwg.org/#assert.

Sebastian

# Michael Haufe (5 years ago)

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