> (local [a b & rest &as t] [1 2 3 4 5])
Compile error in unknown:12
expected rest argument before last parameter
* Try moving & to right before the final identifier when destructuring.
It would be great if this case could be handled somehow, as it would allow for eliminating a let-block and a nesting level in many places.
Can you give an example of when you would want both of these constructs in the same binding?
Sure, here's a real-life example from a Neovim plugin - a rare, but valid use case, when the head (
first
), the tail (rest
), and the whole table (positions
) are all referenced later. (This occurs at maybe one or two other places in that script.)
Yeah, makes sense. I imagined it would take longer before this came up, but I knew it would eventually.
I think it's still a good idea to require
& rest
to be the last thing in the arglist, but allowing it to be preceded by&as all
is reasonable. I can take a patch for this.
I'm not so sure about that...
&as
preceding& rest
would be very confusing and counter-intuitive IMO. (One might think that&as
refers to the preceding arguments only.) At the very first position -[&as all x y z & rest]
- it might make a bit more sense, but still hard to read. (Definitely better than in the middle though.)
Well, I guess you can see why we don't currently allow them to be combined--because it's easier to make them mutually exclusive than it is to come to an agreement upon what the best way to combine them would be.
If there is no way to combine them that doesn't sacrifice clarity then we should just leave them as mutually exclusive. Better for the code to be slightly more verbose than to make it unclear.
I'm editing this comment, as I've changed my mind, and I think that
&
should come right after elements, and&as
and others should be only allowed after&
meaning that thsese are only valid variants:[x y & ys &as whole] [x y &as whole] [x y & ys]
further down if we ever to add other
&thing
things, their order should not matter, as long as they're after&
or at the end of the binding list.
Makes perfect sense to me too (after all, this was my initial intuition).
Looks like this has landed now in 566a9b6; thanks Xero!
FYI, this doesn't work in
(fn [x & xs &as xx] [x xs xx])
I'd expect it to compile to
function (x, ...) local xs = {...} local xx = {x, ...} end
It also does not work in case/match/case-try/case-match.
;; per tests, working (let [[a b & c &as t] [1 2 3 4 5]] [a b c t]) (case [1 2 3 4 5] ;; expected & rest argument before last parameter [a b & c &as t] [a b c t])
there was a patch and the discussion on the mailing list regarding the support (of now deprecated)
__fennelrest
metamethod, that altered how&
works. The reason for this behavior is outlined in #171, and I believe this is the same case here.
~technomancy, should this be reopened?