Skip to content

Candidates for tail lambda / hi-order function syntax #95

@tmteam

Description

@tmteam

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 be fun(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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions