-
Notifications
You must be signed in to change notification settings - Fork 6
Description
Candidates for tail lambda / hi-order function syntax
Syntax for inline lambdas (tail lambdas) and hi-order function variables in NFun-Lang.
Constraints
fun x:conflicts with type annotation syntax → typed form must befun(x:int):int- Lambda boundary must be explicit (no bracketless forms)
- Must support: anonym (
it), named params, typed params, single-line, multi-line, chaining, hi-order variables
Candidates
1. (fun ...)
| Form | Example |
|---|---|
| single line anonym | data.map(fun it * 2) |
| multiline anonym | data.map(fun val = it * 2 val + 1) |
| single line named | data.map(fun x: x * 2) |
| multiline named | data.map(fun x: val = x * 2 val + 1) |
| single line typed | data.map(fun(x:int):int x * 2) |
| multiline typed | data.map(fun(x:int):int val = x * 2 val + 1) |
| hi-order variable | transform = fun x: x * 2 |
Full example:
result = data
.filter(fun x: x > 0)
.map(fun(x:int):int
val = x * 100
val + 1
)
.fold(0, fun acc, x: acc + x)
Pros: fun is a well-known keyword (JS, Kotlin, OCaml). Reads naturally.
Cons: Closing ) belongs to (fun, may visually merge with function call parens.
2. [fun ...]
| Form | Example |
|---|---|
| single line anonym | data.map[fun it * 2] |
| multiline anonym | data.map[fun val = it * 2 val + 1] |
| single line named | data.map[fun x: x * 2] |
| multiline named | data.map[fun x: val = x * 2 val + 1] |
| single line typed | data.map[fun(x:int):int x * 2] |
| multiline typed | data.map[fun(x:int):int val = x * 2 val + 1] |
| hi-order variable | transform = [fun x: x * 2] |
Full example:
result = data
.filter[fun x: x > 0]
.map[fun(x:int):int
val = x * 100
val + 1
]
.fold(0, [fun acc, x: acc + x])
Pros: [] visually distinct from function call (). Clear lambda boundary. fun keyword is self-documenting.
Cons: [] conventionally means arrays — potential cognitive conflict. [fun] inside () for non-tail args looks heavy: fold(0, [fun acc, x: acc + x]).
3. (:: ...)
| Form | Example |
|---|---|
| single line anonym | data.map(:: it * 2) |
| multiline anonym | data.map(:: val = it * 2 val + 1) |
| single line named | data.map(:: x: x * 2) |
| multiline named | data.map(:: x: val = x * 2 val + 1) |
| single line typed | data.map(::(x:int):int x * 2) |
| multiline typed | data.map(::(x:int):int val = x * 2 val + 1) |
| hi-order variable | transform = (:: x: x * 2) |
Full example:
result = data
.filter(:: x: x > 0)
.map(::(x:int):int
val = x * 100
val + 1
)
.fold(0, :: acc, x: acc + x)
Pros: Very concise. :: is visually distinct — easy to spot lambdas in code.
Cons: :: is unfamiliar as lambda marker. :: x: has double-colon visual noise. Not self-documenting.
4. [:: ...]
| Form | Example |
|---|---|
| single line anonym | data.map[:: it * 2] |
| multiline anonym | data.map[:: val = it * 2 val + 1] |
| single line named | data.map[:: x: x * 2] |
| multiline named | data.map[:: x: val = x * 2 val + 1] |
| single line typed | data.map[::(x:int):int x * 2] |
| multiline typed | data.map[::(x:int):int val = x * 2 val + 1] |
| hi-order variable | transform = [:: x: x * 2] |
Full example:
result = data
.filter[:: x: x > 0]
.map[::(x:int):int
val = x * 100
val + 1
]
.fold(0, [:: acc, x: acc + x])
Pros: [] visually distinct from (). :: is concise.
Cons: [] = arrays conflict. [::] looks like Python slice [::]. Double unfamiliarity ([] + ::).
Existing NFun syntax (for reference)
Current rule syntax:
data.map(rule it * 2) # anonym
data.filter(rule it > 0) # chaining works
transform = rule it * 2 # hi-order variable
rule limitations: no named parameters, no typed parameters, no multi-line blocks.
Comparison matrix
| Criteria | (fun) |
[fun] |
(::) |
[::] |
|---|---|---|---|---|
| Readability | ⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐ | ⭐⭐ |
| Familiarity | ⭐⭐⭐ | ⭐⭐ | ⭐ | ⭐ |
| Conciseness | ⭐⭐ | ⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ |
| No conflicts | ⭐⭐ | ⭐⭐ | ⭐⭐ | ⭐ |
| Typed form | clean | clean | ok | ok |
| Variable form | natural | ok | ok | odd |
| Multi-line | good | good | good | good |
Distinct from call () |
no | yes | no | yes |
Array [] conflict |
no | yes | no | yes |