gosh> ((lambda (x) (* x x)) 3)
9
gosh> (let ( (a 3)
(b 4)
(square (lambda(x) (* x x)))
(plus +))
(sqrt (plus (square a) (square b))))
5
gosh> b
*** ERROR: unbound variable: b
Stack Trace:
_______________________________________
gosh> (car '(1 2 3 4 5))
1
gosh> (cdr '(1 2 3 4 5))
(2 3 4 5)
gosh> (cons 1 '(2 3 4 5))
(1 2 3 4 5)
gosh> (null? () )
#t
gosh> (null? '(2))
#f
gosh> (memq 'a '(a b c d))
(a b c d)
gosh> (memq 'b '(a b c d))
(b c d)
gosh> (memq 'c '(a b c d))
(c d)
gosh> (member '(a) '((a) b c d))
((a) b c d)
gosh> (member '(b) '((a) b c d))
#f
gosh> (member '(b) '((a) (b) c d))
((b) c d)
gosh> (if (< 2 3) 4 5)
4
gosh> (cond
((< 3 2) 1)
((< 4 3) 2)
(else 3))
3
gosh> (define iter-fib (lambda (n)
(do ((i 0 (+ i 1))
(a 0 b)
(b 1 (+ a b)))
((= i n) b)
(display b)
(display " "))))
gosh> (iter-fib 10)
1 1 2 3 5 8 13 21 34 55 89
Lisp is self-representing; a program is a list, and lists are what programs manipulate.
quote and eval: the opposite of a quote '(something) is an eval '(something)
gosh> (eval '(+ 3 4) (interaction-environment))
7
gosh> (eval (quote (+ 3 4)) (interaction-environment))
7
gosh> (+ 3 4 5)
12
gosh> (apply + '(3 4 5))
12
gosh> (map + '(3 4 5))
(3 4 5)
gosh> (apply + '(3 4 5) '(8 9 10))
*** ERROR: operation + is not defined between (3 4 5) and 8
gosh> (map + '(3 4 5) '(8 9 10))
(11 13 15)
A language is strict iff if all function calls are strict; a function call is strict iff it is undefined when any of its arguments is undefined. Scheme is strict; Haskell is nonstrict.
So, how do you achieve this nonstrict behavior? Laziness! You get normal-order evaluation, and acceptable speed, also. The trick is via "memoization", which tags an argument with a value when it becomes known (viz., dynamic programming.)
Laziness is really useful also for infinite data structures, such as the Haskell infinite list [1..]
The fly in the ointment, of course, are side-effects; however, the usual solution to that dilemma is to just forbid side-effects (hey, what about I/O? Isn't that just a bunch of side effects!?)
How about viewing I/O as a stream, an unbounded list of whose elements are generated lazily.
But, while useful, streams are not quite enough.
Prelude> let plus a b = a + b
Prelude> let x = plus 3
Prelude> x 7
10
Prelude> x 100
103
Prelude> let y = plus 21
Prelude> y 200
221
Prelude> y 300
321
Prelude> foldl plus 0 [1..10]
55