4 ms·
I agree, but lambdas do not really have a canonical syntax in the same way that braces have become synonymous with delimiters for statement blocks. This particu
by ulrikrasmussen 5y ago
I agree, but lambdas do not really have a canonical syntax in the same way that braces have become synonymous with delimiters for statement blocks. This particular syntax comes from Haskell, where e.g.
\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.
- chrismorgan 5y ago> function(x) { f(x); } Slight correction (presuming JavaScript): that’d be `function(x) { return f(x); }`.
- ulrikrasmussen 5y agoThank you, fixed!
- marcle 5y agoThis could also be R, which allows for `function(x) {f(x)}` and (since version 4.1) `\(x) {f(x)}`.
- boondaburrah 5y agofor clojure there's #(f %) or (fn [x] (f x))
- kennywinker 5y agoExamples 3 and 4 are cursed, to my eye. Curly braces denote a block, so why is there some magic syntax inside the block that denotes that this block happens to be a lambda? surely the block is the closure itself. The syntax to say what the block is goes outside. 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.
- ulrikrasmussen 5y agoI wholeheartedly agree. Whether {} denotes a block or a lambda is context-dependent in the language I took these examples from (Kotlin). I think they adopted the syntax from Groovy. It is "useful" for creating DSLs because you can implement constructs like `.forEach` so they look like imperative constructs, e.g. list.forEach { x -> ... } But it becomes harder to read code outside an IDE, especially if the implicit `it` construct is used.
- zorr 5y agoThat's the thing that annoys me most about Kotlin (even though aside from that it is my personal 10X language). In a large project that uses DSL's, coroutines and flow it quickly becomes a curly brace mess and it gets hard to see what code runs where, when and in which context.
- ulrikrasmussen 5y agoSame, I use Kotlin daily, and I would choose it over Java any day as it really solves a lot of its quirks very nicely. There are however some parts of the syntax that keep confusing me on a daily basis, curly braces being one of them. The other is the weird unintuitive asymmetry that is going on between function types and lambdas. For example, a lambda of type (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.
- RedNifre 5y agoNo, the idea is that {} denotes executable blocks, which lamdas are. In Kotlin, if the last parameter of a function is a lambda, you can close the parenthesis before the lambda: 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.
- thewakalix 5y agoI can’t believe the canonical anonymous function notation is omitted: (lambda (x) (f x)) On the other hand, this is a discussion about syntax, and Lisp is the “syntaxless” language…
- bidirectional 5y agoHow is that canonical? λ x . f x is the original syntax of Church, Lisp came around decades later.
- amw-zero 5y agoCanonical from a programming languages perspective.