I am trying to learn a bit of type theory. This is being taught using a dialect of lisp the author wrote called pie.
Let's say we have defined some function f that takes a single argument of type A and produces an output of type B and I have some a that is of type A.
If I try to type the expression:
(f a)
I can't decide between two possible outcomes:
When is a list a list, and when is it an application? What if i wanted lists of functions, how would this work, what's to stop the list being interpreted as an application?
The expression (f a)
is a form with f
as the first identifier and a
as the second. This can never be a list unless f
is syntax* (macro).
Thus f
gets evaluated to some object which is applied with the evaluated a
as argument. If f
evaluates to anything else than a function object you'll get an error since it cannot be applied.
You can create literal lists with quote
. eg. (quote (f a))
or the syntax abbreviation '(f a)
applies the syntax quote
which evaluates it's argument as data. eg. a list with two symbols, f
and a
.
You can create lists dynamically with cons
. eg. (cons 'f (cons 'a '()))
creates a new list (f a)
and (list 'f 'a)
is a function that makes a chain of cons
with the arguments as elements.
If you wanted to create a list of two functions you can do (cons + (cons - '()))
or (list + -)
and they are not getting applied because they have no parentheses around them. If you were to do (list (+) (-))
they both get applied with zero arguments and the list results in being (0 0)
. Note that +
and -
are just variables here that get evaluated to function objects. You can create new function objects with lambda eg. (lambda (arg) (* arg arg))
is an implementaion of square. They need to be evaluated to become functions so you cannot put them in literals. Eg. '((lambda (arg) (* arg arg)) +)
will become a list with the first element being a list with symbol lambda
and the second the symbol +
. None have anything to do with functions.