#lang racket ;; The first line above is important. It tells DrRacket which ;; language to use. We almost always use Racket. Unless an ;; assignment or example says otherwise, use '#lang racket'. ;; This is a comment that continues to the end of the line. ; One semi-colon is enough. ;; A common convention in Racket is to use two semi-colons for ;; multiple lines of comments, and a single semi-colon when ;; adding a comment on the same line as code. #| This is a block comment, which starts with #| and ends with a |#. Block comments can be nested. The internal pair make a nested comment. |# ;; #; comments out a single form. I use #; below to comment ;; out an entire expression, even though it spans two lines. #;(/ (+ 1 1) 0) ;; ----------------------------------------------------------- ;; Built-in atomic data ;; Booleans #t ; the value for true, and the way it prints #f ; ditto for false true ; another name for true, if you prefer the word false ; ditto for false ;; Numbers 1 0.5 1/2 ; this is a literal fraction, not a division operation 1+2i ; complex number ;; Strings "apple" "banana cream pie" ;; Symbols 'apple 'banana-cream-pie 'a->b '#%$^@*&?! ;; Characters (we don't use these much) #\a #\b #\A #\space ; same as #\ (with a space after \) ;; ----------------------------------------------------------- ;; Built-in functions on atomic data (not true) ; => #f (not false) ; => #t (+ 1 2) ; => 3 (- 1 2) ; => -1 (* 1 2) ; => 2 ;; etc. (< 1 2) ; => #t (> 1 2) ; => #f (= 1 2) ; => #f (<= 1 2) ; => #t (>= 1 2) ; => #f (string-append "a" "b") ; => "ab" (string=? "a" "b") ; => false (string-ref "a" 0) ; => #\a (char=? #\a #\b) ; => #f (equal? "apple" "apple") ; => #t (string=? "apple" "apple") ; => #t (equal? "apple" (string-append "a" "pple")) ; => #t (eq? 'apple 'apple) ; => #t (eq? 'apple 'orange) ; => #f (eq? "apple" "apple") ; => #t (eq? "apple" (string-append "a" "pple")) ; => #f ;; ----------------------------------------------------------- ;; Basic expression forms ;; Procedure application ;; ( ...) (not true) ; => #f (+ 1 2) ; => 3 (string-append "a" "b") ; => "ab" ;; If expression ;; (if ) (if (< 3 1) ; simpler form for single test "apple" ; "banana") ; => "banana" ;; Conditionals ;; (cond ;; [ ] ...) ;; (cond ;; [ ] ... ;; [else ]) (cond ; [(< 2 1) 17] ; [(> 2 1) 18]) ; => 18 (cond ; second expression not evaluated [true 8] ; [false (/ 1 0)]) ; => 8 (cond ; in fact, second test not evaluated [true 9] ; [(zero? (/ 1 0)) 0]) ; => 9 (cond ; any number of cond-lines allowed [(< 3 1) 0] ; [(< 3 2) 1] ; [(< 3 3) 2] ; [(< 3 4) 3]) ; => 3 (cond ; else allowed as last case [(eq? 'a 'b) 0] ; [(eq? 'a 'c) 1] ; [else 2]) ; => 2 ;; and and Or ;; (and ...) ;; (or ...) (and true true) ; => #t (and true false) ; => #f (and (< 2 1) true) ; => #f (and (< 2 1) (zero? (/ 1 0))) ; => #f (second expression is not evaluated) (or false true) ; #t (or false false) ; #f (or (< 1 2) (zero? (/ 1 0))) ; => #t (second expression is not evaluated) (and true true true true) ; => #t (or false false false) ; => #f ;; ----------------------------------------------------------- ;; Built-in compound data ;; Lists empty ; => '() null ; => '() (list 1 2 3) ; => '(1 2 3) (cons 0 (list 1 2 3)) ; => '(0 1 2 3) (list 'a 'b) ; => '(a b), because ' also distributes to elements (list 1 'a) ; we can mix types in a list (list "a" "b") ; => '("a" "b") (list (list 1 2) (list 3)) ; '((1 2) (3)) (cons 1 empty) ; => '(1) (cons 'a (cons 'b empty)) ; => '(a b) (list (list 1) empty) ; => '((1) ()) (cons (list 1) empty) ; => '((1)) (append (list 1 2) empty) ; => '(1 2) (append (list 1 2) (list 3 4)) ; => '(1 2 3 4) (first (list 1 2 3)) ; => 1 (rest (list 1 2 3)) ; => '(2 3) (first (rest (list 1 2))) ; => 2 (list-ref (list 1 2 3) 2) ; => 3 ;; Vectors (we don't use these much, if at all) (vector 1 2 3 4) ; => '#(1 2 3 4) (vector-ref (vector 1 2) 0) ; => 1 ;; Boxes (we don't use these much, if at all) (box 1) ; => '#&1 (unbox (box 1)) ; => 1 ;; Tuples (we don't use these much, if at all) (values 1 2) ; 1 and 2 as separate value (values 1 "a") ; likewise 1 "a" ;; ----------------------------------------------------------- ;; Definitions ;; Defining constants ;; (define ) (define PI 3.14159) (* PI 10) ; => 31.4159 ;; Defining functions ;; (define ( ...) ) (define (circle-area r) (* PI (* r r))) ; also (* PI r r) (circle-area 10) ; => 314.159 (define (circle-perimeter r) (* 2 (* PI r))) (circle-perimeter 10) ; => 62.8318 (define (is-odd? x) (if (zero? x) false (is-even? (- x 1)))) (define (is-even? x) (if (zero? x) true (is-odd? (- x 1)))) (is-odd? 12) ; => #f ;; Definition matching a tuple (define-values (size color) (values 10 'red)) size ; => 10 color ; => 'red ;; ----------------------------------------------------------- ;; Local binding forms ;; Let ;; (let ([ ] ...) ) (let ([x 10] [y 11]) (+ x y)) ; => 21 (let ([x 0]) (let ([x 10] [y (+ x 1)]) (+ x y))) ; => 11 (let ([x 0]) (let* ([x 10] [y (+ x 1)]) (+ x y))) ; => 21 ;; ----------------------------------------------------------- ;; First-class functions ;; Anonymous function: ;; (lambda ( ...) ) (lambda (x) (+ x 1)) ; => # ((lambda (x) (+ x 1)) 10) ; => 11 (define add-one (lambda (x) (+ x 1))) (add-one 10) ; => 11 (define add-two (lambda (x) (+ x 2))) (add-two 10) ; => 12 (define (make-adder n) (lambda (m) (+ m n))) (make-adder 8) ; => # (define add-five (make-adder 5)) (add-five 12) ; => 17 ((make-adder 5) 12) ; => 17 (map (lambda (x) (* x x)) (list 1 2 3)) ; => (list 1 4 9) ;; ----------------------------------------------------------- ;; Polymorphic functions identity ; => # (identity "a") ; => "a" (identity 1) ; => 1 ;; identity is a priimitive. We could define it as: (define identity (lambda (x) x)) ;; ----------------------------------------------------------- ;; Testing (require rackunit) ;; simple unit testing (check-equal? (+ 5 5) 10) ; => test passes; displays nothing (check-equal? (+ 5 4) 10) ; => test fails; displays error message (check-= (+ 5 5) 10 0.01) ; => test passes; displays nothing (check-= (+ 5 5) 10.005 0.01) ; => test passes; displays nothing (check-= (+ 5 5) 10.015 0.01) ; => test fails; displays error message (check-true (< 1 2)) ; => test passes; displays nothing (check-false (< 1 2)) ; => test fails; displays error message (check-exn exn:fail? ; => test causes an error, as expected (lambda () ; displays nothing (/ 1 0))) ; (check-exn exn:fail? ; => test does not cause an error (lambda () ; displays an error message (/ 1 2))) ; ;; ----------------------------------------------------------- ;; Side effects ;; IMPORTANT: ;; In this course, using a side effect is almost always ;; wrong. Do *not* use side effects unless the problem ;; explicitly says to. ;; set! and begin ;; (set! ) ;; (begin *) (define count 0) (set! count (+ count 1)) ; => no value printed count ; => 1 (begin (set! count (+ count 1)) count) ; => 2 ;; set-box! is a function: (define B (box 10)) (set-box! B 12) ; => B ; => (box 12) (unbox B) ; => 12 ;; ----------------------------------------------------------- ;; More information ;; Use the "Help Desk" item in DrRacket's "Help" menu ;; -----------------------------------------------------------