Skip to content

Support nested function definitions#5668

Open
OceanOak wants to merge 2 commits into
darklang:mainfrom
OceanOak:nested-fns
Open

Support nested function definitions#5668
OceanOak wants to merge 2 commits into
darklang:mainfrom
OceanOak:nested-fns

Conversation

@OceanOak
Copy link
Copy Markdown
Collaborator

@OceanOak OceanOak commented Jun 2, 2026

This PR adds support for nested function definitions.
You can now define a helper function inside a function body, instead of only at the package top level:

let reverse (list: List<'a>) : List<'a> =
  let reverseHelper (list: List<'a>) (acc: List<'a>) : List<'a> =
    match list with
    | [] -> acc
    | head :: tail -> reverseHelper tail (push acc head)

  reverseHelper list []

The let f (x: T) : R = ... form is now a variant of the regular let expression, so it works anywhere a let can appear (function bodies, match arms, lambda bodies, etc.).

How it works

  • Desugars to a let-bound lambda; type annotations are parsed but dropped at runtime (lambdas are untyped)
  • Self-recursion is supported - a nested fn can call itself by name

Limitations

  • A nested fn whose name collides with a fn/value already in scope is rejected
  • Mutual recursion between nested fns isn't supported - calling a nested fn defined later gives a "forward calls between nested functions aren't supported" error

@OceanOak OceanOak marked this pull request as ready for review June 3, 2026 14:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant