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.