-
Notifications
You must be signed in to change notification settings - Fork 448
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Nicer syntax for higher level functions #1002
Comments
We probably want to use the backslash syntax for this because it's easy to parse but it's worth checking what other languages do and trying to be consistent with those if possible. |
Both backslash and -> syntax is not compatible with default arguments and deconstruction (Which is proposed here: #307, yet not implemented in neither Golang nor C++ implementations) std.filter((thing) => thing.isActive, things) It is easy to parse too (The only grammar conflict i see is parened identifier) As for currying, what about doing it on a call-site? I.e local multiply(x, y) = x * y;
local multiply_2 = multiply(2, ...);
multiply(2) == 4
For calls it should look like this: local curried = fn(1, 2, named1 = 1, named2 = 2);
curried(3, 4, named3 = 6, named4 = 7)
// should work same as
fn(1, 2, 3, 4, named1 = 1, named2 = 2, named3 = 6, named4 = 7) |
Why would it not be compatible? Optional parentheses could still be used when necessary, e.g.
Yup, that could also be a valid syntax. I don't think I understand the grammar conflict – if the arrow has the right precedence, then the semantics should be clear cut, right? The parse tree in your example would be:
That looks very different from what I've personally seen elsewhere – higher level functions is pretty well established as a concept. |
I think it should be treated not as optional parentheses, but as optional parenthesis omission JS allows it too in case of single identifier, i.e ([arr1, arr2]) => value
({field1, field2}) => value
(arg1, arg2) => value Because it will make parsing much harder, and will require backtracing |
@CertainLach yup, that makes sense. Again, my ML thinking leads me to think of "multiple arguments" as just a single value – a tuple. Indeed, one possible input to the deconstruction discussion would be to introduce the notion of tuples, with pattern matching allowing for setting defaults, e.g. local (a, b, c=42) = someFunc(x, y, z);
// Symmetrical with
local f = (a, b, c=42) -> ...;
f someFunc(); That last part would perhaps be a breaking change, though – not sure if we can clearly distinguish between the |
Unfortunately, parameters in jsonnet isn't just a tuple deconstruction They have non-trivial semantics regarding to named arguments (Jsonnet supports pythonic keyword arguments, |
I love the pure functional nature of Jsonnet! However, when trying to do things in a functional style, the syntax gets in the way a bit (not a lot, but a bit).
For example, defining higher level functions is a bit clumsy:
I think such functions would be more natural to use, and therefore get used more often, with more succinct syntax – and there's no need to invent anything fancy, since lots of other languages already use either a "fat" or a "thin" arrow,
=>
or->
.So the above snippet would become:
local f = x -> y -> z -> z*y*z;
This would also be nice and eligible for inline uses, e.g.
std.filter(thing -> thing.isActive, things)
.Hoping y'all think it makes sense! 🤞
The text was updated successfully, but these errors were encountered: