Skip to content

Latest commit

 

History

History
114 lines (96 loc) · 2.94 KB

demo.rst

File metadata and controls

114 lines (96 loc) · 2.94 KB

Demo

;; A few examples. Click 'Load source' to load them. ; Closures (let (count 0) (define (counter) (set! count (+ 1 count)))) ; You can also define variables (define x 2) (set! x 3) ; Let (let (x 2 y 3) (+ x y)) ; Lambda (set! x (lambda () 'bla)) (x) ; Factorial example (define (fact n) (if (= n 0) 1 (* n (fact (- n 1))))) (fact 5) ; Length example (define (length list) (if (empty? list) 0 (+ 1 (length (cdr list))))) (length '(1 2 3)) ; Map example (define (map func list) (if (empty? list) nil (cons (func (car list)) (map func (cdr list))))) (map (lambda (x) (+ x 1)) '(1 2 3)) ; And macro example (defmacro (and x . xs) (if (empty? xs) x `(when ,x (and . ,xs)))) (expand-code '(and a b c d)) ; and to demonstrate the short-circuit mechanism: ; ((unknown) should crash when run) (and (= 2 2) (= 2 3) (unknown)) ;; Hygiene in macros ; Consider a simple macro: (defmacro (bad-swap a b) `(let (tmp ,a) (set! ,a ,b) (set! ,b tmp))) ; Usage example: (let (x 1 y 2) (bad-swap x y) (list x y)) ; (2 1) ; Unfortunately, this fails if we have a variable called tmp! (let (x 1 tmp 2) (bad-swap x tmp) (list x tmp)) ; (1 2) ; We solve that by using the gensym function to generate a new name ; that will not conflict with anything else: (defmacro (swap a b) (let (tmp (gensym 'tmp)) `(let (,tmp ,a) (set! ,a ,b) (set! ,b ,tmp)))) ; Now try: (expand-code '(swap x tmp)) ; (let (#tmp-0 x) (set! x tmp) (set! tmp #tmp-0))