provide &pack destructuring for function arglists and multi-value destructuring

It would be very nice to have a way to quickly store the ... part in functions, and the rest of multiple value return into a packed table like this:

(fn foo [x y &pack zs] zs)
(foo :a :b :c :d :e) ;=> {1 "c" 2 "d" 3 "e" :n 3}

Such function can expand to the following code:

(fn foo [x y ...]
  (let [zs (doto [...] (tset :n (select "#" ...)))]

Multivalue destructuring can also benefit from this:

(fn bar [] (values :a :b :c :d))
(let [(a b &pack cs) (bar)]
  cs) ;=> {1 "c" 2 "d" :n 2}

Though this is a bit trickier to pull off, as it reqires storing multivalues somewhere in the first place, as we can't introduce a multivalue literal outside of the function's arglist. But it can be done if a function is generated:

local function bar() return "a", "b", "c", "d" end
local a, b, cs = (function (a, b, ...) return a, b, {n = select("#", ...), ...} end)(bar())
Assigned to
1 year, 3 months ago
5 months ago
No labels applied.

~jaawerth 5 months ago

Rather than adding an entire new inline form, couldn't we just try to get & in arglists to work the same way they do when destructuring a table? It's effectively rest parameters as a sequence anyway, and that should lower cognitive debt. Plus, people are already used to rest params coming at the end, which this will also require.

(fn cut2 [a b & zs] zs)
(cut2 1 2 3 4 5) ; => [3 4 5]
Register here or Log in to comment, or comment via email.