In this post I’ll describe the basics of functions in Marco. They behave mostly like Racket functions, except without any syntactic sugar or variadic functions for now.
Definition and Application
In Marco, there is only one way to define functions: using the macro
function. This macro takes two parameters, the list of formal arguments and the function body:
This binds the defined function to the symbol
inc. Note how the function is anonymous. I could change its “name” by binding it to another symbol:
Calling functions, also called “application” consists of evaluating a list which has the function in its head and the arguments in its tail (like common lisp):
Functions have lexical scope, which means that they have access to the environment where they are defined, even during the application.
What about later bindings? What should happen in this case?
It returns 9. Access to to the environment is not restricted by order (much like letrec in Racket). This is one of the mechanisms that allow recursion.
Higher order functions
Functions are first class values. Referencing a symbol just returns the function, which can be passed to other functions:
Perform takes a function
f and a value
x and calls
Or they can returned from functions:
Which looks a lot like how one could implement currying.
Functions parameters are immutable, so this is an error (unlike in Racket):
Cannot mutate symbol: x
Let me know what you think so far!