Re: Returning records instead of multiple values Artyom Bologov 19 Sep 2026 20:12 UTC

Hi Peter, hi Arne,

>> The `procedure-check-of` currently returns two values. However, it
>> might be better to have it return a record type that one can then call
>> procedure-argument-checks and procedure-return-checks on.
>>
>> My reason for this is that an implementation can then add more fields
>> to that record for their own extensions. For example, it could add a
>> field to the record type that documents checks for keyword arguments.
>
> I prefer multiple values, because they avoid the added indirection and
> imported symbols of records (they’d also need procedure-checks? and
> make-procedure-checks, and those could conflict from different
> implementations of procedures that support procedure-check-of), and
> multiple values avoid having to know implementation details to retrieve
> additional information.

Technically, make-procedure-checks is unnecessary, as it’d be an opaque
structure only having exported predicate and accessors. But that’s
irrelevant.

Peter, I actually like your suggestion (and a parallel thread suggestion
of vector-of-arities.) This fixes the problem with multi-arity
procedures—if we return a list / vector of check records, then this is a
much more machine-processable structure than coming up with lists inside
lists inside lists I initially dreaded on Arne’s suggestion of
multi-arity checks.

> Practical problem: if you use both define-checked (SRFI-253) and
> define-typed (SRFI-284), then the record types from both might have
> different fields, but multiple-value returns should be compatible and
> allow introspection of both with the same mechanism.

Multiple-value returns are inflexible and require careful handling
though, as you, Arne, mention.

> Both problems could be avoided by returning an alist, where
> implementations can add arbitrary keys without creating conflicts.

This is an option that’s also friendlier to plaintext introspection, but
it lacks structure. It also suffers from the problem that you have to
know the names of implementation-specific fields. This is much less of a
problem than knowing and using accessor procedures, but much less
structured.

Besides, portable code would only need and have argument checks and
return checks in either of scenarios—multiple values, alist, or records.

I’m inclined to go down the sequence-of-records route, as it’s the most
structured and strict option with clearly named accessors for
everything.

Best of luck,
--
Artyom Bologov
https://aartaka.me