Re: [RFC] alist-let: let-like alist destructuring syntax
siiky 04 Jun 2022 11:25 UTC
Hi Marc,
Thanks for your inputs!
> This, and any macro expanding in such a piece of code is not very
> efficient, i.e. O(n²) instead of the optimal O(n).
Yup, I know the current implementation isn't optimal, I just needed it
work. But for now I want to focus on the syntax itself, not on
implementation details (unless they relate to the syntax), because
that's the most difficult part and also what's going to stick with us
for eternity. :)
> That said, a general problem with an alist-let macro like the one you
> propose is that it confuses identifiers and symbols. The keys of your
> alist are symbols while the variables are represented by identifiers
that,
> for example, can be renamed ones through invocations of hygienic macros.
Yeah, I also agree this is a problem, that's why I put it as a con of
the current implementation, and it is something I intend to change.
The (: foo) idea is a neat one! But it looks to me to lead to cluttered
code in the body. One could use a `let` in it but then... what is even
the point?
Because of that, and in order not to restrict keys to symbols, I think
it might not be a bad idea to mandate both key and variable name. Even
if it means the bindings list is a bit more verbose.
(alist-let al ((foo 'foo) (bar 'bar) (x 'zaz) BINDING ...) BODY ...)
(I'm tending to make the syntax not alist-specific so that, even if the
end result is alist-specific, others may improve on it to support other
dictionary structures)
> PS: It makes sense to separate binding from unpacking. The primitive
> unpacking macro would be invoked as in
>
> (alist-values <alist-expression> <key-or-key/default> ...)
Oh I like this idea too! Is something like `alist-values` feasible for
other dictionary structures?
> PPS: I just notice that I probably mistook your (x zaz) form for zaz being
> a default binding for x.
`zaz` is the corresponding key for the variable `x`
(let ((x (alist-ref 'zaz x)) ...) ...)
Like I said above, it may make more sense to make both key and variable
mandatory, and then this confusion shouldn't be a problem.
And something that just came to mind, you could then use dynamic values
as keys:
(let ((some-key "foo"))
(alist-let al ((foo some-key) ...) ...))
siiky