Merging with let*-values? Marc Nieper-Wißkirchen (24 Aug 2020 15:10 UTC)
Re: Merging with let*-values? Adam Nelson (31 Aug 2020 17:12 UTC)
Re: Merging with let*-values? Marc Nieper-Wißkirchen (31 Aug 2020 17:29 UTC)
Fwd: Merging with let*-values? Marc Nieper-Wißkirchen (31 Aug 2020 17:29 UTC)

Re: Merging with let*-values? Adam Nelson 31 Aug 2020 17:11 UTC

This is sufficiently different that it should be its own SRFI; feel free
to write that SRFI if you want to. My opinion is that merging `chain`
and any form of `let*` is unclear. It's somewhat obvious what a macro
called `chain` does. But it's completely non-obvious that Scheme's
`let*` assigns special meaning to _ when no other Lisp's `let*` does
that, and even less obvious that this is a feature that only certain
Schemes support (it can't be added without language-level support, since
some Schemes don't allow shadowing of core special forms). Core special
forms shared with other Lisps shouldn't do unpredictable magic things.

On 8/24/20 10:28 AM, Marc Nieper-Wißkirchen wrote:
> In replying to Arne's comment about allowing "_0", "_1", ... as
> placeholders, the following just came to my mind:
>
> Can't we merge "chain" with let*-values?
>
> In let*-values, every binding is a list of two entries (the bound
> formals on the left and the initialization expression on the right).
> This leaves room for extension, namely when bindings just consist of
> 1-element lists (see also and-let* of SRFI 2, which extends let*'s
> syntax likewise).
>
> Every 1-element list can mean that the results are bound anonymously.
> They can be referenced in the next step using the placeholders "_" and
> "_ ...".
>
> To get the full power of "chain" as well, the body of the extended
> let*-values forms is allowed to be empty. In that case, the last
> binding must be anonymous and the result of the expression is the
> result of the last binding.
>
> For example,
>
> (chain bowl
>         (add flour _)
>         (add sugar _)
>         (add eggs _)
>         (mix _)
>         (pour _)
>         (bake _ (fahrenheit 350)))
>
> becomes
>
> (let*-values
>    (bowl)
>    ((add flour _))
>    ((add sugar _))
>    ((add eggs _))
>    ((mix _))
>    ((pour _))
>    ((bake _ (fahrenheit 350)))
>
> But we can also do the following:
>
> (let*-values
>    ((alpha))
>    ((x y) (beta _))
>    ((gamma y x))
>    ((delta x _ ...))
>
> I think such an extension of let*-values unifying both let*-values and
> chain carries on more than adding positional anonymous parameters.
>
> Rewriting SRFI 197 to use this idea is a bit late in the process, but
> this could go into its own SRFI, the unifying one.
>
> One has to think a bit about the semantics of "_", though. In "chain"
> every expression occurring is just a procedure call. In the case of
> let*-values, on the other hand, the right-hand sides are arbitrary
> expressions. Therefore, we either have to bind "_" unhygienically or
> with syntax parameters for the right-hand sides (both ways are not
> equivalent; the unhygienic binding is more what we want).
>
> Another problem that has to be solved is the meaning of "_ ...". In
> arbitrary expressions, this can only expand into a list. For this,
> would have to turn "(delta x _ ...)" into "(apply delta x _ ...)"
> though. In this case, "_ ..." is not a good mnemonic anymore.