;; The first three lines of this file were inserted by DrRacket. They record metadata ;; about the language level of this file in a form that our tools can easily process. #reader(lib "htdp-advanced-reader.ss" "lang")((modname start-design-recipe-before) (read-case-sensitive #t) (teachpacks ()) (htdp-settings #(#t constructor repeating-decimal #t #t none #f () #f))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; A hello-world program: "Hello World" ; Racket is an industrial-strength scheme ; Scheme is an elegant, minimal version of Lisp ; Lisp is the 2nd-oldest high-level language still in use (after Fortran) ; (Lisp ~ 1965) ; When calling 'substring', we pass it 3 inputs (string, natural-number, natural-number), ; and we get a string back. ; In Ada, python: substring("Mississippi", 2, 5) (substring "Mississippi" 2 5) ; When calling '+', we pass it 2 [or more] inputs (number, number) ; and we get a number back ;; In Ada, python: 2 + 3 ;; "operators" are just functions that are called with a different syntax. (+ 2 3) ; IN racket: "(" means 'call a function'. ; Syntax for calling a function: ; ( ... ) ; Give the racket version of the math-expression: (1+√5)/2 (/ (+ 1 (sqrt -5)) 2) #| Examples of provided data types: number (real, rational, integer) 2.3 -47 #i3.14 boolean #false #true char #\A #\right string "Mississippi" symbol 'MS 'VA 'TX 'NY 'bart-simpson (...and regexp #rx"[0-9]*", images, ports, etc) |# #| Some built-in functions and their signatures (types): Signature Example substring : string, natnum, natnum -> string (substring "hello" 1 4) = "ell" string-ref : string, natnum -> char (string-ref "hello" 1) = #\e string-length : string -> natnum (string-length "hello") = 5 string-append : string, string -> string (string-append "hel" "lo") = "hello" = : number, number -> boolean (= 4 (+ 2 3)) = #false string=? : string, string -> boolean (string=? "ell" (substring "hello" 1 4)) = #true string? : ANY -> boolean (string? 43) = #false number->string : number -> string (number->string (* 7 6)) = "42" char-downcase : char -> char (char-downcase #\A) = #\a |# #| `define`: a keyword to bind an identifier to a value: |# (define n 37) (define m (* n 99)) (define fname "Ian") (define lname "B-meister") ; Syntax for define-a-variable: ; (define ...) #| The Design Recipe (take 1 -- primitive types only) ------- per function: 4. tests 5. stub : signature, purpose statement, header, stub 7. complete the body-expression 8. watch your tests pass |# ;;;;;;;;;;;; Example, of design recipe ;;;;;;;;;;;;;;;;;;;;; (check-expect (pizza-area 0) 0) (check-within (pizza-area 2) pi 0.000000001) (check-within (pizza-area 20) (* 100 pi) 0.000000001) (check-within (pizza-area 2.5) 4.91 0.01) ; pizza-area : non-negative real -> non-negative real ; The area (in sq.in.) of a pizza, whose diameter is `diam` (in inches) ; (define (pizza-area diam) (* pi (expt (/ diam 2) 2))) ; New syntax: `define` for functions. ; Note how it mirrors how the function is called (but params instead of argument-expressions). ; Syntax for define-a-function: ; (define ( ...) ; ) ;;; EXAMPLE: Together, we'll write: `monogram`: ; Given a first name and last name, return a monogram with initials: (check-expect (monogram "Ian" "Barland") "i.b.") (check-expect (monogram "Jay" "Z") "j.z.") (check-expect (monogram "H" "S") "h.s.") (check-expect (monogram "Ke$ha" "Sebert") "k.s.") ; monogram : non-empty-string, non-empty-string -> string ; Given a first name and last name, return a monogram with initials: (define (monogram first last) (string-append (string (char-downcase (string-ref first 0))) "." (string (char-downcase (string-ref last 0))) ".")) ; Note -- you're NOT expected to know about `string-ref`, `char-downcase`, `string` -- ; those are things you'd learn, when you need them, reading through the documentation. ; ; One approach to searching documentation, in racket (besides googling): ; In DrRacket, press "F1" when the caret is on a *related* word/function. ; For example: Write `substring`, hit F1, and it'll lead you to the documentation ; for `substring` (because luckily that was a real name in the docs), ; and then that page also has mentions the other string-functions like `string-ref`. ;;; EXAMPLE: Okay, now YOU write: `initialize`: ; Return the first letter of a word downcase'd, followed by ".". (check-expect (initialize "Ke$ha") "k.") (check-expect (initialize "z") "z.") ; initalize: non-empty-string -> string ; Return the first letter of a word downcased, following by ".". (define (initialize wrd) (string-append (string (char-downcase (string-ref wrd 0))) ".")) ;; Let's re-factor `monogram`! #| (define (monogram first last) (string-append (initialize first) (initialize last))) |# #| One reaction to factoring out `initialize` above is: "Gee Barland, you did a bunch of extra work, for a fairly small amount of duplicate-code-elimination." (a) All duplicate code smells bad; (b) Smaller functions leads to better testing-via-unit-tests; it reduces the need for printf-debugging or stepping with a debugger. (c) The helper-function might even be useful in its own right. |# ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; Bonus full-racket code-teaser ;;;;;;;;;;;;;;;;;;;;;;;;; #| As an example of (c) above, AND a preview of the higher-order function `map` that we'll discuss later, here's another function. (You are NOT expected to be able to sit down and write this ...yet!) The following code uses the full-racket language; copy/paste the contents of the #|...|# below into a new DrRacket window, and select: Languages > Choose Language... > The Racket Language ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |# #| #lang racket (require rackunit) ; initalize: non-empty-string -> string ; Return the first letter of a word downcased, followed by ".". (define (initialize wrd) (string-append (string (char-downcase (string-ref wrd 0))) ".")) (check-equal? (initialize "Ke$ha") "k.") (check-equal? (initialize "z") "z.") ; acronymize : string -> string ; Given a multi-word phrase, return its acronym. ; (define (acronymize phrase) (apply string-append (map initialize (regexp-split #px"( |-)+" phrase)))) (check-equal? (acronymize "Self contained underwater breathing apparatus") "s.c.u.b.a.") (check-equal? (acronymize "Light-amplified stimulated emission of radiation") "l.a.s.e.r.") ;;; Again, to be clear: ;;; In this class we will NOT use full-racket, nor worry about regexp's etc. ;;; (We will, though, use `map` in intermediate-student, in a few weeks.) |# ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; ADDITIONAL Bonus full-racket code-teaser ;;;;;;;;;;;;;; #| As the bonus sample code above, except this passes the "l.a.s.e.r." example by ignoring any common-words in the input-phrase. The following code uses the full-racket language; copy/paste the contents of the #|...|# below into a new DrRacket window, and select: Languages > Choose Language... > The Racket Language ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |# #| #lang racket (require rackunit) ; initalize: non-empty-string -> string ; Return the first letter of a word downcased, following by ".". (define (initialize wrd) (string-append (string (char-downcase (string-ref wrd 0))) ".")) (check-equal? (initialize "Ke$ha") "k.") (check-equal? (initialize "z") "z.") (define COMMON-WORDS (map symbol->string '(the of and or))) ; acronymize : string -> string ; Given a multi-word phrase, return its acronym. ; Ignore any COMMON-WORDS ; (define (acronymize phrase) (apply string-append (map initialize (filter (λ(wrd) (not (member wrd COMMON-WORDS))) (regexp-split #px" |-" (string-downcase phrase)))))) (check-equal? (acronymize "Self contained underwater breathing apparatus") "s.c.u.b.a.") (check-equal? (acronymize "Light-amplified stimulated emission of radiation") "l.a.s.e.r.") ;;; Again, to be clear: ;;; In this class we will NOT use full-racket, nor worry about regexp's etc. ;;; (We will, though, use `map` in intermediate-student, in a few weeks.) |#