(49)% mzscheme Welcome to MzScheme version 299.100, Copyright (c) 2004-2005 PLT Scheme, Inc. > (define (append L1 L2) (cond ((null? L1) L2) (else (cons (car L1) (append (cdr L1) L2))))) > (append '(1 2 3) '(a b c)) (1 2 3 a b c) > (reverse '(1 2 3 4)) (4 3 2 1) > (reverse '(1 (2 3) 4)) (4 (2 3) 1) > ;;; define our own reverse (define (reverse L) (cond ((null? L) '()) (else (append (reverse (cdr L)) (list (car L)))))) > (reverse '(3 4 (5 6) 7)) (7 (5 6) 4 3) > (define (rev L new) (cond ((null? L) new) (else (rev (cdr L) (cons (car L) new))))) > (rev '(3 4 5 6) '()) (6 5 4 3) > (define (reverse L) (rev L '())) > (reverse '(2 3 (4 5) 6)) (6 (4 5) 3 2) > ;;; one of the most useful functions: (map f L) applies f to every element ;;; of L, returning a list of the results (define (add1 x) (+ x 1)) > (map add1 '(2 4 6 8)) (3 5 7 9) > ;;; let's write map: (define (map f L) (cond ((null? L) '()) (else (cons (f (car L)) (map f (cdr L)))))) > (map car '((3 4) (a b) (hello goodbye))) (3 a hello) > ;;; suppose I wanted to add 2 to every element of a list: (define (add2 x) (+ x 2)) > (map add2 '(10 11 12)) (12 13 14) > ;;; instead, use a "lambda expression" to define a function ;;; without having to give it a name ;;; (lambda (param1...paramN) body) (lambda (x) (+ x 2)) # > (map (lambda (x) (+ x 2)) '(10 11 12)) (12 13 14) > ((lambda (y) (+ y 3)) 7) 10 > ;;; In fact ;;; (define (f x) (+ x 1)) ;;; is just syntactic sugar for ;;; (define f (lambda (x) (+ x 1))) (define f (lambda (n) (if (= n 0) 1 (* n (f (- n 1)))))) > (f 4) 24 > ;;; returning a function as a value (define (f x) (lambda (y) (+ x y))) > (f 3) # > (define g (f 3)) > (g 6) 9 > ((f 3) 6) 9 > (define M (list car cdr (lambda (L) (cadr L)))) > M (# # #) > ((caddr M) '(1 2 3 4)) 2 > ((cadr M) '(1 2 3 4)) (2 3 4) > ;;; defining local variables (let ((var1 exp1)...(varN expN)) body) (let ((x 1) (y 2)) (+ x y)) 3 > (define (f x) (let ((y 3)) (* x y))) > (f 6) 18 > ;;; exp1...expN cannot refer to any of the new var1 ... varN (let ((x (lambda (y) (* y 5))) (z 26)) (x z)) 130 > ;;; (let* ((var1 exp1) ... (varN expN)) body) ;;;; allows each expi to refer to the new variables var1..vari-1 defined ;;;; before (let ((x 7) (y (+ x 1))) (* y 2)) reference to undefined identifier: x > (let* ((x 7) (y (+ x 1))) (* y 2)) 16 > ;;; letrec allows each exp to refer to ANY of var1...varN (define (reverse L) (letrec ((rev (lambda (L new) (if (null? L) new (rev (cdr L) (cons (car L) new)))))) (rev L '()))) > (reverse '( 1 2 3 4)) (4 3 2 1) > (define (f x) (define (g y) (+ x y)) g) > (f 3) # > ((f 3) 7) 10 > (define (f z) (lambda (w) (* z w))) > (define h (f 10)) > z reference to undefined identifier: z > (h 23) 230 > ;;; Scheme does have assigment - BUT TO BE USED ONLY IF ABSOLUTELY NECESSARY 0 0 > (define x 3) > x 3 > (set! x 27) > x 27 > (define (new-counter) (let ((x 0)) (lambda () (set! x (+ x 1)) x))) > (new-counter) # > (define my-counter (new-counter)) > (my-counter) 1 > (my-counter) 2 > (define your-counter (new-counter)) > (your-counter) 1 > ;;; assignments to the car and cdr of a list: (set-car! L exp) (set-cdr! L exp) 0 0 > (define L '(1 2 3 4)) > > 0 0 > (set-car! L 15) > > L (15 2 3 4) > > (set-cdr! L '(16 17 18)) > L (15 16 17 18) > L (15 16 17 18) > (set-car! L L) > L #0=(#0# 16 17 18) >