Closed jaawerth closed 4 years ago
Since ...
isn't lexically scoped, it seems to me that another possible way forward is to allow the use of ...
itself in hashfns, since any current use of that would be met with an "unexpected vararg" error.
That's a good point. My one concern there is that normally when ...
is used, you can see on the screen where it's being bound in the args, and implicitly binding it under the hood could lead to confusion, even if it isn't actually semantically ambiguous.
Worth adding to the list, though!
since any current use of that would be met with an "unexpected vararg" error.
I actually think the fact that this signals an error is valuable, because the lack of proper scoping makes it so easy to screw up.
I'd be inclined to use $...
as I feel it communicates the intent most clearly.
Agreed. In regular functions, where ...
came from is explicit, since you have to put it in the function signature to use it. From a readability standpoint, making an explicit version for hashfn like $...
prevents ambiguity from creeping in.
Upon further reflection, introducing $...
can lead to some hard-to-read code because contents of $...
would be determined by the highest $n
used, so
(local pp #(print (view $)))
(pp (#[$5 $1 $...] :a :b :c :d :e))
(pp (#[$4 $1 $...] :a :b :c :d :e))
(pp (#[$3 $1 $...] :a :b :c :d :e))
(pp (#[$2 $1 $...] :a :b :c :d :e))
would result in
["e" "a"]
["d" "a" "e"]
["c" "a" "d" "e"]
["b" "a" "c" "d" "e"]
@jaawerth I don't believe the contents of $...
would need to be determined by the highest used $n. Maybe I didn't read carefully enough at first, but the way I initially interpreted this issue was that $...
would contain all arguments passed in, not just the trailing arguments. ie
(fn generated [...]
(local ($1 $2 $3 $4 $5 $6 $7 $8 $9) ...)
,body)
I feel like this would be simpler to implement, and would resolve your hard-to-read code examples, but may not be what you were looking for initially.
Hmm, that could definitely work. It would be less confusing than my example, for sure. The question is whether those semantics would be confusing if we used the symbol $...
, since in regular functions the length of ...
gets smaller the more named arguments there are.
On the other hand, adding some other magic symbol like $&
may just confuse things even more...
Made an initial pass yesterday in hashfn-varargs. It works, with $...
and $1, $2, $3...
mutually exclusive for the time being (we can always open up that restriction later and just require positional args to be contiguous); before I make a PR it just needs an update to the reference, plus a little cleanup and commenting.
I'll also see if I can further generalize walk
/walkAST
into something that can be used on more than just ASTs.
There's currently no way to refer to
...
in hashfn's. Initially this made sense to me, as they're really just meant as shorthand sugar for very simple functions, but there are a few instances where it would really come in handy, as well as some powerful usecases I think we're missing out on.A couple usecases
Function composition
While we could introduce a
comp
macro, we wouldn't really need it if we had this. Assuming, for the case of argument, hashfn varargs take the form of$&
, left-right composition is as simple asThere's still an issue with multiple returns making this harder, but if we introduced
as->
(separate issue forthcoming) or another means to concisely limit and manipulate function args, that too cleans up nicely.Wrapping other functions
One of the primary usecases for hashfn is to wrap other functions or operators, and it obviates the need for some kind of placeholder special for doing positional partial application. This is somewhat limited by the lack of
...
.What should it be?
$...
would make the most sense but is somewhat awkward.$&
would be in line with clojure's use of%&
, but it isn't quite as obvious since fennel sticks with...
instead of using&
in normal functions.$$
is easy to remember....
. Works because...
isn't lexically scoped, but may make the syntax more confusing to someone picking up the language?