Skip to content

Latest commit

 

History

13 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

FUN - Lexical Scope

FUN extends LET with first-class functions.

Functions are first-class citizens of the language since they are values that can be bound to names:

let
  identity =
    fun (x) x
in
(identity -(456, 123))

passed as arguments:

let
  applytwice =
    fun (f) (f (f 5))
in
let
  double =
    fun (x) -(x, -(0, x))
in
(applytwice double)

and returned as results:

let
  select =
    fun (n)
      if zero?(n) then
        fun (x) x

      else
        fun (x) -(x, 1)
in
((select 1) 8)

In this version of FUN, functions are lexically scoped (for the dynamically scoped version check out the dynamic-scope branch). The runtime value that represents a function definition now saves the environment in which the function was created. This value is called a closure. When the function is called, the closure associated with that function provides the environment in which that function's free variables can be accessed.

So the following example:

let
  add =
    fun (a)
      fun (b)
        -(a, -(0, b))
in
let
  a = 11
in
((add 3) 5)

evaluates to 8 and not 16.

For a closer look at how closures enable lexically scoped functions, read FUN: Making Curried Functions Work in the Presence of Free Variables.

Explore

To explore this language on your own machine, you'll need Nix with flakes enabled.

nix develop
elm repl

Then:

import FUN.Interpreter as I

I.run """
  let
    add =
      fun (a)
        fun (b)
          -(a, -(0, b))
  in
  let
    a = 11
  in
  ((add 3) 5)
"""
-- Ok (VNumber 8)

About

FUN extends LET with first-class functions. Both dynamically and lexically scoped functions are explored.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages