Closed amano-kenji closed 3 months ago
Thanks for elaborating. Perhaps the text could expand on things a bit more. May be a PR would be accepted toward that end.
Note though that currently the following text exists at the bottom of the destructuring page:
Destructuring works in many places in Janet, including let expressions, function parameters, and var.
I didn't recognize that there was struct destructuring after &keys
....
I thought it was a special syntax...
I thought the same thing!
I saw your original issue over in janet-lang/janet (agree that this is a better place for it). Before that I didn't realize that [&keys foo]
was valid syntax.
This is a useful thing to know, because sometimes I need to pass the whole struct received after &keys
to another function. But if I've destructured it in the main function's params, then there's no symbol bound to the whole struct and I have to manually reconstruct it in the arguments of the sub function:
(defn foo [&keys {:a apples :b bananas}]
(print apples)
(print bananas)
(count-calories {:a apples :b bananas}))
This small example is already annoying, but it's much worse the more keys are in the struct.
That kinda turned me off from using &keys
at all almost ever:
(defn foo [fruitmap]
(print (fruitmap :a))
(print (fruitmap :b))
(count-calories fruitmap))
But it turns out, this is valid:
(defn foo [&keys fruitmap]
(print (fruitmap :a))
(print (fruitmap :b))
(count-calories fruitmap))
So &keys
might get more use in my Janet code moving forward.
What would be really nice is if I could have the best of both worlds:
(defn foo [&keys {:a apples :b bananas} :as fruitmap]
(print apples)
(print bananas)
(count-calories fruitmap))
But I don't think Janet's defn
/approach to destructuring in general currently supports this.
Yeah an :as
sort of thing could be nice.
Not sure of the specifics though.
For reference, the fennel folks seem to do this sort of thing (inspired by Clojure perhaps?):
{:expr expr#
:res result#
:debugger-id ,(tostring debugger-id)
:id id#
&as data#}
Ignore the #
and ,
stuff -- it's from within a macro definition (^^;
I see :as
as Clojurism :-), as it brings another layer of magic into the restructuring. All the puns intended :-D.
I'm sure if there was anything really bothering me I could find a way to fix it with macros, at least to my own satisfaction. 🙂 No need to change the language, unless more people than just me would find something of that kind useful.
More on the topic of this issue, I do think it would be helpful to clarify the docs around &keys
syntax.
Not sure there is really a nice solution, but IIUC ATM there is a trade-off one must make between:
I think you can't have your cake and eat it too...though may be this cake is not tasty enough (^^;
Back to the topic (as CFiggers mentioned), perhaps an additional example in the docs (plus some text) that demonstrates the point would be worthwhile.
Haskell provides an enhanced destructuring syntax.
For example, in haskell, something like this is possible
(defn
[arg1 &keys attrs@{:abc abc :bcd bcd}]
(pp attrs)
(pp abc)
...)
Regarding possible changes to the documentation, perhaps an additional example can be added to the end of the keyword-style arguments section along with some explanatory text.
Here's a first draft:
Note that what follows `&keys` does not have to be a
struct and can instead be a single symbol. The
symbol can then be used as a name within the function
body for a struct containing the passed keys and values:
(defn feline-counter
[&keys animals]
(if-let [n-furries (get animals :cat)]
(printf "Awww, there are %d cats!" n-furries)
(print "Shucks, where are my friends?")))
(feline-counter :ant 1 :bee 2 :cat 3)
That's what I meant.
Thanks for clarifying.
I submitted PR #214.
Looks like this issue may have been address by the merging of #214. Perhaps it can be closed.
Until recently, I didn't recognize the example for
&keys
on https://janet-lang.org/docs/functions.html was using destructuring. I thought the destructured struct was the only allowed syntax for&keys
.I didn't think it was a destructured struct. I thought it was just the only syntax for
&keys
.For years, I didn't know something like this was possible.
https://janet-lang.org/docs/functions.html should mention that what follows after
&keys
is actually a destructured struct.