Is it just me or is the "\" in front of parenthesis (func params) is just off-putting. I wonder, what purpose does it solve?
Familiar syntax makes it much easier to adopt and easily convince devs in your team to try it for real.
Is it just me or is the "\" in front of parenthesis (func params) is just off-putting. I wonder, what purpose does it solve?
Familiar syntax makes it much easier to adopt and easily convince devs in your team to try it for real.
\x -> f x
denotes an anonymous function that applies its first argument to `f`.But I have seen at least these forms in other languages of varying popularity:
[x] f x
|x| f x
{ f(it) }
{ x -> f(x) }
fn x => f x
function(x) { return f(x); }
x -> f(x)
(x: A) => f(x)
In other words, I think it is really hard to pick a syntax for this construct that every programmer is going to feel familiar with, especially if your language is supposed to cater both to programmers coming from FP and more traditional languages.Edit: Fixed error in JS example; added Java and Scala.
Imagine if i wrote a conditional like that:
if x > y { return x; } else { return y; }
as { if x > y; return x; } { else; return y; }
It completely erases the usefulness of {}, and is cursed, cursed I say! And I’m looking at you, rust, swift, ruby, etc. list.forEach { x -> ... }
But it becomes harder to read code outside an IDE, especially if the implicit `it` construct is used. (Int, Float) -> Boolean
is written as { i, f -> ... body ... }
but a lambda of type (Pair<Int, Float>) -> Boolean
is written as { (i, f) -> ... body ... }
because `(x, y)` is a destructuring pattern that projects the first and second components into `x` and `y`, respectively. The pattern in the lambda has to use tuple syntax exactly when the type doesn't, and vice versa. Gets me on a weekly basis even though I completely understand what's going on, it's just not very ergonomic. f(5, { square(it) }
can be written as f(5) { square(it) }
which makes constructs like if(condition) { foo() }
Look like if(condition, { foo() } )
as in a function that takes a boolean and a lambda and only executes the lambda if the boolean is true.It's a neat reinterpretation of what {} means.
f(5) { square(it) }
My preference would be to tag the fn signature on the outside of the braces, something like: f(5) [(x)->int]{ square(x) }
I’d also accept ||, (), or nothing as the delimiters around the fn signature. Key point is that it’s OUTSIDE the executable block.I’m not opposed to using some smarts to infer/simplify the expression when possible. I.e. if it’s a closure with inferable parameter and return types the “it” construct could be used (in swift they use $0, $1, $2 etc for unnamed parameters). Just the only thing inside an executable block {} should be code that gets executed - not type information about that block
(lambda (x) (f x))
On the other hand, this is a discussion about syntax, and Lisp is the “syntaxless” language…Slight correction (presuming JavaScript): that’d be `function(x) { return f(x); }`.
#(f %)
or (fn [x] (f x)) x => f x
Or x -> f x \x -> x + 1