-
Notifications
You must be signed in to change notification settings - Fork 2
procedure
TurtleKitty edited this page May 18, 2019
·
5 revisions
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)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.
(lambda? x) (proc? x)
(lambda? +) ; true
(proc? +) ; false
(lambda? 1) ; false(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) ...))