Initial comments on SRFI 269 Wolfgang Corcoran-Mathe (14 Jun 2026 01:43 UTC)
Re: Initial comments on SRFI 269 Andrew Tropin (19 Jun 2026 11:29 UTC)
Re: Initial comments on SRFI 269 Wolfgang Corcoran-Mathe (19 Jun 2026 18:16 UTC)
Re: Initial comments on SRFI 269 Wolfgang Corcoran-Mathe (19 Jun 2026 18:29 UTC)

Re: Initial comments on SRFI 269 Wolfgang Corcoran-Mathe 19 Jun 2026 18:16 UTC

Andrew,

Thanks for your reply.

On 2026-06-19 18:29 +0700, Andrew Tropin wrote:
> > 1. Why is the parameter called 'test-runner*' and not 'test-runner'?
>
> No particular reason, it's just a naming convention in guile-ares-rs
> project (where reference implementation of the suitbl testing library is
> developed) to make dynamically scoped variables stand out.  I derived it
> from clojure's style of `*dynamic-var*`, but without prefix asterisk.  I
> know it conflicts with let* and alike.  Also, somebody already mentioned
> and suggest current-test-runner.

Yes, I heartily endorse 'current-test-runner'.  The "current-" prefix
is standard for several parameters.  SRFI 64 also uses
'current-test-runner' for the equivalent feature.

> > 2. There is currently no assertion support for multiple values.
>
> [snip]
>
> I gave it a brief thought and it still seems general enough (I will
> address issue with predicate form replying to the #3).  The design of
> SRFI-269 is heavily relies on shifting as much as possible to test
> runner and focusing only on definition semantics, not execusion.  So,
> it's the responsibility of test runner to decide what asserting means.
>
> As for test runner in suitbl, we just inherit semantics of `if`.  For
> Guile it's following (I just checked it a few minutes ago): If
> there are 0 values, it's exception, if more than zero the first value is
> checked for truethness.

(This is intertwined with the predicate-argument form issue.)

I think this is a bit too subtle, especially when the default test
runner may silently discard extra values!  There should be a way to
test multiple values explicitly, rather than leaving it to the runner
to decide what a "pass" is in the multiple-values case (all values
truthy?).

Here's a rough sketch of a reworked assertion form which supports
multi-valued test expressions *and* some degree of rich-mode error
reporting.  It is based vaguely on SRFI 61's generalized 'cond'
clause.

== Begin spec ==

(is <generator> <consumer>)

<generator> and <consumer> are expressions, and <consumer> must
evaluate to a procedure.  Asserts that

    (call-with-values (lambda () <generator>)
                      <consumer>)

evaluates to a single true value.  The entity constructed from this
form has (at least) the following keys:

assertion/generator-thunk

  Equivalent to (lambda () <generator>).

assertion/generator-source

  A datum representation of <generator>.

assertion/consumer-proc

  The value of <consumer>.

assertion/consumer-source

  A datum representation of <consumer>.

assertion/location

  An assertion source code location

(is <generator> <consumer> <description>)

As above, with a human-readable description.  (Keys as above, plus
'assertion/description'.)

(is <expression>)

Special case. Equivalent to

    (is <expression> values).

== End spec ==

This subsumes the current assertion model.  The special-case
'assertion/args-thunk' can be eliminated, since this model decouples
test-expression evaluation and consumer application.  <generator>, its
values, and <consumer> can all be reported separately, without the need
for subterm analysis.  (Instead of writing (is (integer? (+ 2 2))) to
get rich-mode reporting, you would write (is (+ 2 2) integer?).)

A minor drawback is losing (is <expression> <description>) due to
syntactic ambiguity.  That needs some work.  One solution is to "tag"
the <description> argument, e.g.

(is (integer? 4) (desc "4 is an integer")).

While not exactly beautiful, this trick has the advantage of allowing
descriptions to appear anywhere, since they can be unambiguously
identified:

(is (desc "4 is an integer") 4 integer?)

I'm not sure the additional syntax is worth it, but it's an idea.  SRFI
64, chibi-test, and CHICKEN test users are probably used to writing
their descriptions first, which becomes possible with a tagged
<description> argument.

Let me know what you think.

--
Wolfgang Corcoran-Mathe  <xxxxxx@sigwinch.xyz>