Skip to content

procedure

TurtleKitty edited this page May 18, 2019 · 5 revisions

lambda

The simplest form of procedure is lambda. They are first-class closures.

(def foo (lambda (x) (* x x)))

(lambda? foo)  ; true
(foo 7)        ; 49

; creating lambdas is common enough that capital-L is aliased to lambda

(def xs '(2 3 5))
(def ys '(7 11 13))

(map (L (x y) (+ x y)) xs ys) ; (9 14 18)

proc

A proc is a lambda with a little extra machinery: they are variadic (rest), can accept optional keyword parameters (opt), and can abort computation early with the return keyword.

The proc operator can take a name before its formals. This is syntactic sugar for (def name (proc (args) ...).

(def square
   (proc (x)
      (* x x)))

(proc? square) ; true
(square 3)     ; 9

; opt and rest arguments

(proc snazzer (x y)
   (if opt.snazz
      (list x y opt.snazz opt.snarf rest)
      (list x y rest)))

(snazzer 1 2)                                   ; (1 2 ())
(snazzer 1 2 3)                                 ; (1 2 (3))
(snazzer 1 2 3 4 5)                             ; (1 2 (3 4 5))
(snazzer 1 2 3 4 5 snazz: true)                 ; (1 2 true null (3 4 5))
(snazzer 1 2 3 4 5 snazz: true snarf: "SNARF!") ; (1 2 true "SNARF!" (3 4 5))

; early return

(proc foo (x)
   (when (< x 10)
      return 'no-worries)
   'some-long-and-painful-computation)

The _ operator can be used as a short way of generating one-argument procedures.

(def nums (list 1 2 3)) 
(map (_ (* _ _)) nums)   ; (1 4 9)
(map (_ _.to-text) nums) ; ("1" "2" "3")

Vaquero has tail call optimization; tail-recursive functions can recurse forever without blowing the stack.

(proc factorial (n)
   (proc fact (n acc)
      (if (= n 1)
         acc
         (fact (- n 1) (* n acc))))
   (fact n 1))

(factorial 99999) ; 28242294079603478742934... (456546 more digits)

There are also generic procedures that allow multiple dispatch on all argument types.

predicate

(lambda? x) (proc? x)

(lambda? +) ; true
(proc? +)   ; false
(lambda? 1) ; false

messages

(def add-7 (lambda (x) (+ x 7)))

(proc add-11 (x y)
   (+ x y 11))

add-7.type  ; (lambda)
add-11.type ; (proc lambda)

add-7.to-bool  ; true
add-11.to-bool ; true

add-7.arity    ; 1
add-11.arity   ; 2

add-7.formals  ; (x)
add-11.formals ; (x y)

add-7.code  ; (lambda (x) (+ x 7))
add-7.env   ; #(env add-7 (lambda (x) ...))
add-11.code ; (proc (x y) (+ x y 11))
add-11.env  ; #(env add-11 (proc (x y) ...))

Clone this wiki locally