Building Blocks
We’ve already come up with a number of cool functions I’ve been using in the examples. One of these is our fun
function that allows us to declare functions in a neater way. We should definitely include this in our standard library.
; Function Definitions
(def {fun} (\ {f b} {
def (head f) (\ (tail f) b)
}))
We also had our unpack
and pack
functions. These too are going to be essential for users. We should include these along with their curry
and uncurry
aliases.
; Unpack List for Function
(fun {unpack f l} {
eval (join (list f) l)
})
; Pack List for Function
(fun {pack f & xs} {f xs})
; Curried and Uncurried calling
(def {curry} unpack)
(def {uncurry} pack)
Say we want to do several things in order. One way we can do this is to put each thing to do as an argument to some function. We know that arguments are evaluated in order from left to right, which is essentially sequencing events. For functions such as print
and load
we don’t care much about what it evaluates to, but do care about the order in which it happens.
Therefore we can create a do
function which evaluates a number of expressions in order and returns the last one. This relies on the last
function, which returns the final element of a list. We’ll define this later.
; Perform Several things in Sequence
(fun {do & l} {
if (== l nil)
{nil}
{last l}
})
Sometimes we want to save results to local variables using the =
operator. When we’re inside a function this will implicitly only save results locally, but sometimes we want to open up an even more local scope. For this we can create a function let
which creates an empty function for code to take place in, and evaluates it.
; Open new scope
(fun {let b} {
((\ {_} b) ())
})
We can use this in conjunction with do
to ensure that variables do not leak out of their scope.
lispy> let {do (= {x} 100) (x)}
100
lispy> x
Error: Unbound Symbol 'x'
lispy>