Introspection
Wolfgang Corcoran-Mathe
(10 May 2020 23:41 UTC)
|
Re: Introspection Marc Nieper-Wißkirchen (11 May 2020 07:11 UTC)
|
Multiple-values SRFI
Lassi Kortela
(11 May 2020 09:09 UTC)
|
Re: Multiple-values SRFI
Marc Nieper-Wißkirchen
(11 May 2020 09:41 UTC)
|
Re: Multiple-values SRFI
Lassi Kortela
(11 May 2020 10:52 UTC)
|
Re: Multiple-values SRFI
Lassi Kortela
(11 May 2020 11:04 UTC)
|
Re: Introspection
John Cowan
(11 May 2020 18:02 UTC)
|
Re: Introspection
Marc Nieper-Wißkirchen
(11 May 2020 18:26 UTC)
|
Re: Introspection
Marc Feeley
(11 May 2020 18:34 UTC)
|
Re: Introspection
Marc Nieper-Wißkirchen
(11 May 2020 19:29 UTC)
|
Re: Introspection
Marc Feeley
(12 May 2020 04:15 UTC)
|
Re: Introspection
John Cowan
(12 May 2020 15:36 UTC)
|
Re: Introspection
Lassi Kortela
(12 May 2020 16:07 UTC)
|
Re: Introspection
John Cowan
(12 May 2020 18:19 UTC)
|
Re: Introspection
Lassi Kortela
(12 May 2020 18:46 UTC)
|
Re: Introspection
Marc Nieper-Wißkirchen
(04 Jun 2020 16:39 UTC)
|
Re: Introspection
Marc Nieper-Wißkirchen
(09 Jun 2020 08:38 UTC)
|
Re: Introspection
John Cowan
(09 Jun 2020 17:53 UTC)
|
Re: Introspection
Marc Nieper-Wißkirchen
(09 Jun 2020 19:39 UTC)
|
Re: Introspection
John Cowan
(10 Jun 2020 21:46 UTC)
|
Re: Introspection
Marc Nieper-Wißkirchen
(11 Jun 2020 11:55 UTC)
|
Re: Introspection
Marc Nieper-Wißkirchen
(04 Jun 2020 16:36 UTC)
|
Thanks for chiming in, Wolfgang! I will then submit a general multiple values SRFI before SRFI 195 is finalized (and maybe also before SRFI 189 is). This SRFI will include syntax like [...] > > (values->vector <expr>) > > (values-length <expr>) > > (values->list <expr>) > > (values-ref <expr> <index>) I am not so sure about the naming; in view of SRFI 8, it could make sense to use names like `receive-list`, `receive-vector`. I am open to suggestions! Such a SRFI will also include procedures that go the other way, like (list->values <list>) which is equivalent to (apply values <list>), an often-used idiom, but may be implemented more efficiently. Again, there may be better names, like `unpack-list` or `explode-vector`. Racket has `set!-values` (https://docs.racket-lang.org/reference/set_.html#%28form._%28%28lib._racket%2Fprivate%2Fmore-scheme..rkt%29._set%21-values%29%29), which can slightly be generalized to also take formals with a rest argument, and which also should go into such a multiple-values SRFI. Moreover, we have case-lambda that dispatches on the number of arguments an ordinary procedure receives; we don't have a similar construct for the number a continuation receives (and which could be useful to implement some of SRFI 189's conversion procedures whose protocol depends on the number of values). Therefore, I would also propose (case-receive <expr> (<formals> <body>) ...) which can be rewritten into (with-values <expr> (case-lambda ((<formals> <body>) ...) Here, `with-values` is of course (define-syntax with-values (syntax-rules () ((with-values expr receiver) (call-with-values (lambda () expr) receiver)))) (If I remember correctly, Kent Dybvig once made a point that `with-values` should have been standardized, not `call-with-values` because both are equivalent in expressiveness but it easier to work with an optimize `with-values`.) Another part of the language, where everyone could benefit from a better support of multiple values, are various higher-order procedures. For example, SRFI 1 defines `fold` and `fold-right`. `fold` is the fundamental list iteration operator and `fold-right` is the fundamental list recursion operator. Code that uses them is conceptionally clearer than code using hand-written loops with named-let. The problem is, however, when more than one value has to be threaded through the iteration or recursion. Most of the time, the user will have to go back to hand-written loops but will then have to deal with `values` and `let-values` explicitly. However, there is no obvious generalization of `fold` and friends to multiple values (which implies multiple seeds). The problem is the calling convention of the procedure that is being called in each step. Currently, it takes the accumulator and an arbitrary number of values corresponding to the number of lists (vectors, generators, gadgets, ...) being iterated or recursed over. A multiple-value version `fold*` would have to apply an arbitrary number of accumulator values and an arbitrary number of values corresponding to the number of lists present but there is only one rest argument. One solution would be to make `fold*` into syntax, say: (fold* (<list-formals> <seed-formals> <body>) (<seed> ...) (<list> ...)), which would work unless anyone would want to use `fold*` itself in any higher-order context (are there any use cases for that?). Alternatively, `fold*` is an ordinary higher-order procedure receiving a procedure that evaluates into another procedure first, e.g. like the following or similarly: (fold* (lambda <list-formals> (lambda <seed-formals> body)) (lambda () (values <seed> ...)) <list> ...) Or we could restrict `fold*` to a single list, but this would restrict its usefulness. I would love to hear your suggestions, especially about further procedures and syntax that should be included. Marc P.S.: Some SRFI should also describe `(delay <expr>)` when <expr> evaluates to an arbitrary number of values and the corresponding `(force <expr>)` and `(make-promise <expr> ...)`. This extension is necessary for programs that want to employ both lazy semantics and multiple values that are present in Scheme's evaluation model. (SRFI 45 describes a recipe to convert an algorithm with lazy semantics to Scheme with explicit use of the lazy primitives. As soon as multiple values are present, this conversion won't work anymore. When I wrote SRFI 155, I should have already noted it but I didn't, so I will have to revise it.)