1 Evaluation
Evaluation is the process of running a bit of code to it's result. eg. (+ 1 2) ;==> 3
. In this particular example +
is free variable that needs to be in the environment. It might evaluate to the global prcedure +
or it might be that it's a lexical variable from code run before this.
2 Environment
Environment is the variables accessable at a certain point. eg.
(define x 10)
(define f1 (lambda (y) (+ x y))
(define f2 (let ((x 5))
(lamdba (y) (+ x y))))
The lambda forms that cerate f1
and f2
are equal in the sense they do the exact same thing. The difference in the environment.
(f1 3) ; ==> 13
(f2 3) ; ==> 8
The scope of f2
's x
is no more but it's referenced in the procedure
and accessible when running it but not from any other place. An evaluated lambda
form (ie. a procedure) is also known as a closure since the variables accessable at the point of evaluation is accessible when applying the result of that lambda form (the procedure).
3 Initial value
When starting up a Scheme program you have an initial global environment. variables like +
and cons
are defined. I'm not sure this is what you were after. Perhaps you should give an example of what you were thinking?
4 let
, let*
, letrec
, and lambda
You have these in all examples:
(define x 10)
(define f (lambda (x) x)
Everyone of them turns into anonymous lambda
function calls. I'll just do one level, but since you can transform let*
into let
and let
into lambda
you can transform everyone of these to lots of lambda
forms. Here's how:
(let ((a 1) (b 2) ...) body ...)
is the same as ((lambda (a b ..) body ...) 1 2 ...)
thus this is true:
(let ((x 5) (y (+ x 1)) (f (lambda (x) (if (< 5 x) (f (- x 1)) x))))
(list x y (f 10))) ; ==> (5 11 9)
(let ((a 1) (b 2)) body ...)
is the same as (let ((a 1)) (let ((b 2)) body ...)
thus this is true:
(let* ((x 5) (y (+ x 1)) (f (lambda (x) (if (< 5 x) (f (- x 1)) x))))
(list x y (f 10))) ; ==> (5 6 9)
(letrec ((a 1) (b 2)) body ...)
is the same as (let ((a 'undef) (b 'undef)) (let ((tmpa 1) (tmpb 2)) (set! a tmpa) (set! b tmpb)) body ...)
thus this is true:
(letrec ((x 5) (y (list x 1)) (f (lambda (x) (if (< 5 x) (f (- x 1)) x))))
(list x y (f 10))) ; ==> (5 (undef 1) 5)
Note i changed +
to list
since (+ 'undef 1)
won't work. Your Scheme implementation might use any value in place of undef
. When to use what? Use ``letrecand named
letfor procedures that you need to recurse, use
let*for variables where you rely on a previous calculation (it keeps you from writing nested
letforms and use
let` as much as you can.
So imagine you have a procedure that is not recursive, a variable and a variable you derive you can use let*
:
(let* ((sq (lambda (x) (* x x))) ; given this is a top level it will have global environment
(x (sq 5))
(y (sq 10))
(res (+ x y)) ; here I'm using both x and y
(do-something res))
5 declarations
There is. If I want to make global variables I do it like this:
(define test 55)
(define fun (lambda (x) (+ test x))