On assertion naming (is VS check VS assert VS ...) Andrew Tropin (17 Apr 2026 12:57 UTC)
Re: On assertion naming (is VS check VS assert VS ...) Jakub T. Jankiewicz (17 Apr 2026 13:42 UTC)
Re: On assertion naming (is VS check VS assert VS ...) Marc Nieper-Wißkirchen (17 Apr 2026 13:55 UTC)
Re: On assertion naming (is VS check VS assert VS ...) Andrew Tropin (17 Apr 2026 14:20 UTC)
Re: On assertion naming (is VS check VS assert VS ...) Sudarshan S Chawathe (19 Apr 2026 20:13 UTC)

On assertion naming (is VS check VS assert VS ...) Andrew Tropin 17 Apr 2026 12:56 UTC
The most heated discussion so far was regarding assertion naming, `is`
syntax in particular.

I decided to spend a bit more time on this topic to come up with a
clearer naming.  And there are actually two parts: the user facing
syntax and underlying object sent to the test runner important for test
runners implementers. The syntax and entity respectively.

How it works at the moment:

(is (equal? a b))

send the following message to a test-runner:

`((type . runner/run-assert)
  (assert . ((assert/body-thunk . ,(lambda () (equal? a b)))
             (assert/args-thunk . ,(lambda () (list a b)))
             (assert/body . (equal? a b))
             (assert/location . location))))

So the syntax `is` creates an assert entity and sends it to the test
runner.  Test runner decides how to proceed further with it (usually run
body thunk within exception/contiunation guards).

1. Internal entity.

is defines an invariant, so when the test executed this invariant is
checked.  This invariant is represented in assert entity at the
moment. And assert is a pretty common name for this type of entity in
context of testing framework. However, assert is not a noun, it's a
verb, so the proper name would be assertion. There are a few other
options, the word invariant itself would work here or a check.

The message type to test runner would look like:
runner/run-assert
runner/run-assertion
runner/check-invariant
runner/run-check

So we have 4 options:

- assert (current) - is not a exactly is noun + has overloaded meaning
  (e.g. general purpose `assert` form that usually throws an exception
  and present in many languages and Scheme dialects), so should be
  avoided to reduce confusion.

- assertion - is ok, but a bit long and also a bit overloaded.  From
  practical experience runners and reporters will need to work with a
  lot of assertion-related functions and having assertion in the name of
  such functions make them too verbose assertion-runs->test-run-outcome,
  assertion-run->assertion-outcome, etc

- invariant - seems semantically good, but a bit harder with naming
  (usual word like run, outcome don't play well with it). So naming
  become even more verbose and inconsistent.
  invariant-checks->test-run-outcome, invariant-check->invariant-status ?

- check - compact, a bit too generic, but fits the fit the purpose.
  check-runs->test-run-outcome, check-run->check-outcome

So, my opinion here is that we need to change assert to either assertion
or check.  I gravitate more towards check, because it more compact and less
overloaded.  Interested in your thoughts, please share.

2. The syntax.

The goal of the syntax is to encourage people to define many
invariants/asserts/checks and at the same time keep tests look clean,
uncluttered, readable.

Keep in mind, no matter what the syntax is, the underlying code is
preserved and will be used by test runner/reporter to construct
meaningful error/failure message.  It can show the diff for
strings/sets, it can show evaluated predicate arguments and so on.
The reporting is extensible on runner/reporter side and doesn't depend
on the syntax name.  So it's enough to have only one good name for
"assertion" syntax.

## First obvious candidate is `is`.

+ Extremely compact, have very few competitors in this field (`ok`,
  `so`).  From my personal experience, it makes skimming the tests
  really comfortable and convinient.

+ From Clojure ecosystems we know that is works well and adopted in
  large scale. The clojure.test test definition syntax used almost
  exclusevly. It has multiple runners, from simple ones like cognitec's
  to full blown like kaocha, with all bells, wistles and reporters.

+ It easily learnable. (is (equal? a b)) reads as "is it right?" "Does
  equality holds?".

- not hundred percent intuitive at first glance. Need at least a couple
  glanes to comprehend.

- There could be some expectations from other languages like (is? a b) =>
  "Does a of a type b?" or something similiar.

## Second one is `assert`.

Straight no-no, as it too overloaded, used in other langugages and
various Scheme in different context.  It's a blocker, no need for
further discussion.

Third one is `run-assertion`.
(`capture-assertion-thunk-and-send-to-the-test-runner`, etc):

While such names can be semantically correct, they are extremely verbose
and it will make people less likely to use them.  Another no go, I guess.

## Forth one is `check`.

+ Clear, understandable, semantically correct.

+ Producing check alist entity, same way as test and suite macros
producing test and suite alist entities.

+ Read well (check (eq? a b)): "Check equality of a and b" or "Equality
check for a and b".

- Slightly longer than is, a bit more verbose.

- Harder to skim the code as it mixes in same length functions.

(is (eq? 'a b)) ; <- much more distinct
(format #t "hi")
(check (eq? 'a b))

## Fifth option is ok/so.

so similiar to is. "Check so a equal to b". But probably have no history
of usage experince like is in whole Clojure ecosystem.

ok is ok. but doesn't reads well.

Not much point to prefer either of them over is.

# Conclusion

For internal representation the primary options are: assertion and
check.  With slightly preference to check as less overloaded and more
compact.

For syntax: `is` or `check`.  With a preference to `is` as it is more
visually distinct from usual functions and macros names.

Would be really glad to hear your thought, please let me know what you
think! :)

--
Best regards,
Andrew Tropin