Skip to content
This repository has been archived by the owner on Feb 6, 2022. It is now read-only.
/ Calcula Public archive

Swift lambda calculus functions supporting intensional equality

License

Notifications You must be signed in to change notification settings

JadenGeller/Calcula

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

21 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Calcula

Calcula provides a Lambda type for defining, comparing, and printing lambda calculus functions.

In lambda calculus, values are represented by functions. Here's an example defining two function values, one representing true and one representing false. It's too hard to tell if two functions actually do the same thing, so we define equality based on shape. A function with the exact same shape as our truth function is what we call intensionally equal to our truth function. Thus, we can represent the values true and false with functions of a particular shape.

let truth   = Lambda { t in Lambda { f in t } }
let falsity = Lambda { t in Lambda { f in f } }

We didn't just arbitrarily choose these definitions though! Note that truth is a function that takes two arguments and always returns the first, and that falsity is a function that takes two arguments and always returns the second.

Also, notice that the arguments are curried, that is, every function actually only takes a single argument, but we can simulate multi-argument functions by writing a function that takes an argument, and returns a function that takes the second argument (which is exactly what we did).

We can easily write a function not that will return falsity given truth and will return truth given falsity.

let not = Lambda { condition in condition[falsity][truth] }

See how, when condition == truth, it will return the first argument passed to it, falsity, and when condition == falsity, it will return the second argument passed to it, truth. (Note that we use brackets to represent function invocation as parenthesis are reserved by Swift.)

We can also easily write and and or. When condition1 is true, and will take on the value of condition2; otherwise, and will take on the value falsity. Similiarly, when condition1 is false, or will take on the value of condition2' otherwise, or will take on the value truth.

let and = Lambda { condition1 in Lambda { condition2 in condition1[condition2][falsity] } }
let or  = Lambda { condition1 in Lambda { condition2 in condition1[truth][condition2] } }

We can easily check whether our functions work since Calcula supports checking intensional equality with the == operator.

print(and[truth][falsity] == falsity) // -> true
print(or[truth][falsity] == truth)    // -> true

Here's another example:

let makePair  = Lambda { first in Lambda { second in Lambda { selector in selector[first][second] } } }
let getFirst  = Lambda { pair in pair[truth] }
let getSecond = Lambda { pair in pair[falsity] }

print(getFirst[makePair[truth][falsity]] == truth)    // -> true
print(getSecond[makePair[truth][falsity]] == falsity) // -> true

In the definition of pair, we apply some unknown selector function to first and second so we can later retrieve the desired argument by choice of a selector function. Recall that truth and falsity both expect two arguments, but truth returns the first argument it receives while falsity returns the second argument it receives. Thus, if we pass the selector truth, we can retrive the first element of our pair and if we pass the selector falsity, we can retrive the second element of our pair.

If you're like me and think this is all super cool, a great next step would be try to encode numbers using Church numerals, and then write functions to add, subtract, and multiply them! Let me know if you have any questions! :)

About

Swift lambda calculus functions supporting intensional equality

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages