Andy Balaam, OpenMarket artificialworlds.net/blog
Scheme is
Scheme is simple by design.
$ sudo apt install racket
$ mzscheme
>
Scheme has:
Both are actually the same.
(operator operand1 operand2 ...)
> (+ 3 4)
> (+ 3 4)
7
> (+ 3 4)
7
> (* 3 4)
> (+ 3 4)
7
> (* 3 4)
12
> (+ 3 4)
7
> (* 3 4)
12
> (+ 5 (* 2 2))
> (+ 3 4)
7
> (* 3 4)
12
> (+ 5 (* 2 2))
9
> (define foo 3)
> (define foo 3)
> foo
> (define foo 3)
> foo
3
> (define foo 3)
> foo
3
> (* foo 4)
> (define foo 3)
> foo
3
> (* foo 4)
12
> (define (square x) (* x x))
> (define (square x) (* x x))
> (square 4)
> (define (square x) (* x x))
> (square 4)
16
> (define (square x) (* x x))
> (square 4)
16
> (+ (square 2) (square 3))
> (define (square x) (* x x))
> (square 4)
16
> (+ (square 2) (square 3))
13
(define (abs x)
(if (< x 0)
(- x)
x))
(define (abs x)
(if (< x 0)
(- x)
x))
> (abs -3)
(define (abs x)
(if (< x 0)
(- x)
x))
> (abs -3)
3
(define (abs x)
(if (< x 0)
(- x)
x))
> (abs -3)
3
> (abs 3)
(define (abs x)
(if (< x 0)
(- x)
x))
> (abs -3)
3
> (abs 3)
3
> (list 9 3 5)
> (list 9 3 5)
(9 3 5)
> (list 9 3 5)
(9 3 5)
> (sort (list 9 3 5) <)
> (list 9 3 5)
(9 3 5)
> (sort (list 9 3 5) <)
(3 5 9)
> (list 9 3 5)
(9 3 5)
> (sort (list 9 3 5) <)
(3 5 9)
> (length (list 3 2))
> (list 9 3 5)
(9 3 5)
> (sort (list 9 3 5) <)
(3 5 9)
> (length (list 3 2))
2
Scheme is weird.
> (define x (list 1 2 3))
> (define x (list 1 2 3))
> (car x)
> (define x (list 1 2 3))
> (car x)
1
> (define x (list 1 2 3))
> (car x)
1
> (cdr x)
> (define x (list 1 2 3))
> (car x)
1
> (cdr x)
(2 3)
> (cons "a" "b")
> (cons "a" "b")
("a" . "b")
> (cons "a" "b")
("a" . "b")
> (cons (cons 5 6) 7)
> (cons "a" "b")
("a" . "b")
> (cons (cons 5 6) 7)
((5 . 6) . 7)
> (cons "a" "b")
("a" . "b")
> (cons (cons 5 6) 7)
((5 . 6) . 7)
> (define p (cons 1 2))
> (cons "a" "b")
("a" . "b")
> (cons (cons 5 6) 7)
((5 . 6) . 7)
> (define p (cons 1 2))
> (car p)
> (cons "a" "b")
("a" . "b")
> (cons (cons 5 6) 7)
((5 . 6) . 7)
> (define p (cons 1 2))
> (car p)
1
> (cons "a" "b")
("a" . "b")
> (cons (cons 5 6) 7)
((5 . 6) . 7)
> (define p (cons 1 2))
> (car p)
1
> (cdr p)
> (cons "a" "b")
("a" . "b")
> (cons (cons 5 6) 7)
((5 . 6) . 7)
> (define p (cons 1 2))
> (car p)
1
> (cdr p)
2
> null
> null
()
> null
()
> (cons 2 null)
> null
()
> (cons 2 null)
(2)
> null
()
> (cons 2 null)
(2)
> (cons 1 (cons 2 null))
> null
()
> (cons 2 null)
(2)
> (cons 1 (cons 2 null))
(1 2)
> null
()
> (cons 2 null)
(2)
> (cons 1 (cons 2 null))
(1 2)
> (list 1 2)
> null
()
> (cons 2 null)
(2)
> (cons 1 (cons 2 null))
(1 2)
> (list 1 2)
(1 2)
Â
(list 1 2 3)
cons
sticks things togethercar
gives you the first thingcdr
gives you the second thingcons
sticks things togethercar
gives you the "head"cdr
gives you the "tail"cadddr
's meaning should be obviouscadddr
's meaning should be obvious(cadddr v)
Returns (car (cdr (cdr (cdr v))))
(define (sum vs)
(if (= 1 (length vs))
(car vs)
(+ (car vs)
(sum (cdr vs)))))
(define (sum vs)
(if (= 1 (length vs))
(car vs)
(+ (car vs)
(sum (cdr vs)))))
> (sum (list 5 6 7))
(define (sum vs)
(if (= 1 (length vs))
(car vs)
(+ (car vs)
(sum (cdr vs)))))
> (sum (list 5 6 7))
18
(define (sum vs)
(if (= 1 (length vs))
(car vs)
(+ (car vs)
(sum (cdr vs)))))
(define (sum vs)
(if (= 1 (length vs))
(car vs)
(+ (car vs)
(sum (cdr vs)))))
(define (double value)
(* 2 value))
(define (apply-twice fn value)
(fn (fn value)))
> (apply-twice double 2)
(define (double value)
(* 2 value))
(define (apply-twice fn value)
(fn (fn value)))
> (apply-twice double 2)
8
(define (apply-twice fn value)
(fn (fn value)))
> (map double (list 3 4 5))
> (map double (list 3 4 5))
(6 8 10)
> (define s (list '+ 4 7))
> (define s (list '+ 4 7))
> s
> (define s (list '+ 4 7))
> s
(+ 4 7)
> (define s (list '+ 4 7))
> s
(+ 4 7)
> (eval s)
> (define s (list '+ 4 7))
> s
(+ 4 7)
> (eval s)
11
> (define (switchop a) (cons '* (cdr a)))
> (define (switchop a) (cons '* (cdr a)))
> (define s2 (switchop s))
> (define (switchop a) (cons '* (cdr a)))
> (define s2 (switchop s))
> s2
> (define (switchop a) (cons '* (cdr a)))
> (define s2 (switchop s))
> s2
(* 4 7)
> (define (switchop a) (cons '* (cdr a)))
> (define s2 (switchop s))
> s2
(* 4 7)
> (eval s2)
> (define (switchop a) (cons '* (cdr a)))
> (define s2 (switchop s))
> s2
(* 4 7)
> (eval s2)
28
> '(* 3 6)
> '(* 3 6)
(* 3 6)
> '(* 3 6)
(* 3 6)
> '(foo (bar "a" 3))
> '(* 3 6)
(* 3 6)
> '(foo (bar "a" 3))
(foo (bar "a" 3))
equal?
boom!
a*b
co-ordinates
<10
+
This is cool.
> (define (+ x y) 5)
> (+ 2 2)
5
This is cool.
> (sort (list 5 4 3 2 1) <)
(1 2 3 4 5)
> (sort (list "abc" "a" "ab") string<?)
("a" "ab" "abc")
This is somewhat uncool, but useful.
> (map
(lambda (x) (+ x 1))
(list 1 2 3))
(2 3 4)
(define (counter)
(define c 0)
(lambda ()
(set! c (+ c 1))
c))
(define (counter)
(define c 0)
(lambda ()
(set! c (+ c 1))
c))
> (define a (counter))
> (a)
> (define a (counter))
> (a)
1
> (define a (counter))
> (a)
1
> (a)
> (define a (counter))
> (a)
1
> (a)
2
> (define a (counter))
> (a)
1
> (a)
2
> (a)
> (define a (counter))
> (a)
1
> (a)
2
> (a)
3
> (define b (counter))
> (b)
> (define b (counter))
> (b)
1
> (define b (counter))
> (b)
1
> (a)
> (define b (counter))
> (b)
1
> (a)
4
Metaprogramming is just programming.
> (define (times-n n) (lambda (x) (* n x)))
Metaprogramming is just programming.
> (define (times-n n) (lambda (x) (* n x)))
> (define times3 (times-n 3))
Metaprogramming is just programming.
> (define (times-n n) (lambda (x) (* n x)))
> (define times3 (times-n 3))
> (define (trpl lst) (map times3 lst))
Metaprogramming is just programming.
> (define (times-n n) (lambda (x) (* n x)))
> (define times3 (times-n 3))
> (define (trpl lst) (map times3 lst))
> (trpl (list 1 2 3))
Metaprogramming is just programming.
> (define (times-n n) (lambda (x) (* n x)))
> (define times3 (times-n 3))
> (define (trpl lst) (map times3 lst))
> (trpl (list 1 2 3))
(3 6 9)
This presentation is available under cc by-sa at github.com/andybalaam/videos-scheme-accu2018.
(define (mcons a b)
(lambda (cmd)
(if (equal? cmd "car")
a
b)))
(define (mcar pair) (pair "car"))
(define (mcdr pair) (pair "cdr"))
> (define foo (mcons 1 2))
> (mcar foo)
1
> (mcdr foo)
2
(define n0 (lambda () null))
(define (minc x) (lambda () x))
(define (mdec x) (x))
(define n1 (minc n0))
(define n2 (minc n1))
(define n3 (minc n2))
(define n4 (minc n3))
(define n5 (minc n4))
(define (mzero? x) (null? (x)))
(define (mequal? x y)
(cond
((mzero? x) (mzero? y))
((mzero? y) (mzero? x))
(else (mequal? (mdec x) (mdec y)))))
> (mequal? n1 n0)
#f
> (mequal? n1 n1)
#t
(define (m+ x y)
(if (mzero? y)
x
(m+ (minc x) (mdec y))))
> (mequal? (m+ n0 n2) n2)
#t
> (mequal? (m+ n0 n2) n3)
#f
> (mequal? (m+ n0 n2) (m+ n1 n2))
#f
> (mequal? (m+ n2 n3) n5)
#t