numbat icon indicating copy to clipboard operation
numbat copied to clipboard

Add anonymous functions/lambdas

Open Goju-Ryu opened this issue 1 year ago • 2 comments

Following discussion in #261, it was decided to move discussion about lambdas to a separate issue. There are a few unknowns still in regards to the implementation and syntax. The syntax is mostly a preference issue with many proposed syntax's. Here are most or all of the discussed variations:

(a, b) => a + b

|a, b| = a + b 
|a, b| => a + b

\(a, b) = a + b
\(a, b) => a + b

fn (a, b) = a + b
fn (a, b) a + b

The implementation aspect relates to closures and their handling which is not as straightforward a problem to solve. See #347 for more on this.

Other questions about the implementation were discussed in this comment but is copied below with the syntax updated to current numbat syntax for ease of access.

  • Do we want partial function application "by default"? Or would users have to curry/uncurry manually, i.e. write scale as fn scale(a) = |x| a * x and then use it with expr -> scale(10).

  • Do we need anonymous functions if we have closures and lambdas?

  • Do we want to keep both expr |> fn and expr -> fn? Right now, they are not 100% equivalent, expr |> fn can only be used for "proper" functions, while expr -> fn can also be used for other callables (function pointers), like in now() -> tz("Europe/Berlin")

Goju-Ryu avatar Dec 27 '24 20:12 Goju-Ryu

What is the difference between an anonymous function, a closure, and a lambda?

rben01 avatar May 20 '25 15:05 rben01

What is the difference between an anonymous function, a closure, and a lambda?

An anonymous function and a lambda are often interchangeable and unless we talk about the implementation details of specific languages it is often used as such. In some languages there are differences though, where syntax for an anonymous function often is the same as for normal functions except without providing a name and lambdas often has an arrow syntax like some of the examples above. Beyond that it is language dependent as far as I know. I think javascript has some rather important differences in scoping between the two, but that is a js thing not a general rule.

A closure however is the context of the lambda. For example, if we define a lambda function inside another function we may use variables existing in that functions scope inside the body of the lambda. To make sure the lambda remembers the value of this variable when it is later applied in a different scope we have to save the relevant variables from the original context. This package of variables and their values is called a closure. Baeldung has an explanation that may make more sense than this description, so take a look for an introduction to the concept with a bit more detail.

Goju-Ryu avatar Jun 20 '25 13:06 Goju-Ryu