The documentation for htdp-lang now uses the new vocabulary.
This commit is contained in:
parent
6eea5b1793
commit
01b9bde7fa
|
@ -1,10 +1,8 @@
|
|||
#lang racket
|
||||
|
||||
|
||||
|
||||
(define-syntax (test stx) #'(begin)) ;; TODO: convert my test into DrRacket's test framework
|
||||
(require #;gmarceau/test
|
||||
parser-tools/lex
|
||||
(require ; gmarceau/test
|
||||
parser-tools/lex
|
||||
(prefix-in : parser-tools/lex-sre)
|
||||
(rename-in srfi/26 [cut //])
|
||||
(only-in srfi/1 break)
|
||||
|
@ -38,6 +36,7 @@
|
|||
|
||||
;; additional-highligts can specify their color
|
||||
(define additional-highlights/c (listof (or/c srcloc-syntax/c (list/c srcloc-syntax/c symbol?))))
|
||||
(define color/c (or/c #f symbol?))
|
||||
|
||||
;; colored-error-message : Exceptions that support highlighting contain a colored-error-message
|
||||
;; in addition to a string. The string message is automatically generated from
|
||||
|
@ -54,10 +53,11 @@
|
|||
[struct colored-msg-fragment ([locs srcloc-syntax/c]
|
||||
[frags (listof (or/c msg-fragment:str? msg-fragment:v?))]
|
||||
[important boolean?]
|
||||
[color (or/c #f symbol?)])])
|
||||
[color color/c])])
|
||||
|
||||
;; prop:exn:colored-message : The property of exceptions that contain colored-message information.
|
||||
;; The property's value is a function that when given an exception, returns the colored-error-message.
|
||||
(provide prop:exn:colored-message exn:colored-message? exn:colored-message-accessor)
|
||||
(define-values (prop:exn:colored-message
|
||||
exn:colored-message?
|
||||
exn:colored-message-accessor)
|
||||
|
@ -70,8 +70,8 @@
|
|||
;; get-error-message/color : When given an exception, if that exception contains coloring information,
|
||||
;; returns it, otherwise, returns a colored-error-message that capture the information provided by
|
||||
;; by field message and the srclocs property (if any) of the exception.
|
||||
(provide/contract [get-error-messages/color (exn? . -> . colored-error-message?)])
|
||||
(define (get-error-messages/color exn)
|
||||
(provide/contract [get-error-message/color (exn? . -> . colored-error-message?)])
|
||||
(define (get-error-message/color exn)
|
||||
(cond [(exn:colored-message? exn) ((exn:colored-message-accessor exn) exn)]
|
||||
[(exn:srclocs? exn)
|
||||
(colored-error-message (list (msg-fragment:str (exn-message exn)))
|
||||
|
@ -79,6 +79,17 @@
|
|||
[else
|
||||
(colored-error-message (list (msg-fragment:str (exn-message exn))) empty)]))
|
||||
|
||||
(provide/contract [get-error-colored-srclocs (exn? . -> . (listof (list/c srcloc-syntax/c color/c)))])
|
||||
(define (get-error-colored-srclocs exn)
|
||||
(define (promote srcloc) (if (list? srcloc) srcloc (list srcloc #f)))
|
||||
(define msg (get-error-message/color exn))
|
||||
(map promote
|
||||
(append
|
||||
(append*
|
||||
(filter-map (// match <> [(colored-msg-fragment locs _ _ c)
|
||||
(map (// list <> c) (if (list? locs) locs (list locs)))] [_ #f])
|
||||
(colored-error-message-fragments msg)))
|
||||
(colored-error-message-additional-highlights msg))))
|
||||
|
||||
(define lex (lexer
|
||||
[(eof) empty]
|
||||
|
@ -263,21 +274,23 @@
|
|||
;; in the fmt. additional-highlights specifies srclocs that should be highlighted, in addition
|
||||
;; to the highlights used to explicate the correspondance between the text and the piece of codes.
|
||||
(define (raise-colored-syntax-error fmt #:additional-highlights [additional-highlights empty] . args)
|
||||
(define formatted (apply colored-format fmt #:additional-highlights empty args))
|
||||
(define formatted (apply colored-format fmt #:additional-highlights additional-highlights args))
|
||||
(raise (exn:fail:colored:syntax (uncolor-message formatted)
|
||||
(current-continuation-marks)
|
||||
(important-srclocs formatted)
|
||||
formatted)))
|
||||
|
||||
(define (catch-the-error thunk) (with-handlers ([void (lambda (e) e)]) (thunk)))
|
||||
|
||||
(test 'raise-colored-syntax-error
|
||||
(check-exn-msg exn:fail:colored:syntax? #rx"only one part"
|
||||
(lambda () (raise-colored-syntax-error "~|cond|~: expected a clause with a question and answer, but found a clause with only ~|one part|~"
|
||||
#'stx #'question)))
|
||||
(check-match (with-handlers ([void (lambda (e) (get-error-messages/color e))])
|
||||
(raise-colored-syntax-error "~|cond|~: expected a clause with a question and answer, but found a clause with only ~|one part|~"
|
||||
#'stx #'question))
|
||||
|
||||
(check-match (get-error-message/color (catch-the-error (lambda () (raise-colored-syntax-error "~|cond|~: expected a clause with a question and answer, but found a clause with only ~|one part|~"
|
||||
#'stx #'question))))
|
||||
(colored-error-message (list (colored-msg-fragment
|
||||
(? syntax?)
|
||||
(? syntax?)
|
||||
(list (msg-fragment:str "cond")) #f #f)
|
||||
(msg-fragment:str ": expected a clause with a question and answer, but found a clause with only ")
|
||||
(colored-msg-fragment (? syntax?) (list (msg-fragment:str "one part")) #f #f))
|
||||
|
@ -285,5 +298,35 @@
|
|||
|
||||
|
||||
(test 'get-error-messages/color
|
||||
(check-equal? (get-error-messages/color (exn:fail:colored:syntax "ah!" (current-continuation-marks) (list #'here) (colored-error-message 1 2)))
|
||||
(colored-error-message 1 2)))
|
||||
(check-equal? (get-error-message/color (exn:fail:colored:syntax "ah!" (current-continuation-marks) (list #'here) (colored-error-message 1 2)))
|
||||
(colored-error-message 1 2))
|
||||
|
||||
(check-match (important-srclocs (colored-format "~|1|~" (list #'first #t) #:additional-highlights '(a b)))
|
||||
(list (app syntax-e 'first) a b))
|
||||
(check-match (get-error-colored-srclocs (catch-the-error (lambda () (raise-colored-syntax-error "~|1|~ ~||~" (list #'first #t) (list #'second 'red) #:additional-highlights (list #'a #'b)))))
|
||||
(list (list (app syntax-e 'first) #f) (list (app syntax-e 'second) 'red) (list (app syntax-e 'a) #f) (list (app syntax-e 'b) #f))))
|
||||
|
||||
#|
|
||||
(provide insert-colored-message)
|
||||
(define (insert-colored-message msg repl clickback)
|
||||
(send repl begin-edit-sequence)
|
||||
(define port (send repl get-err-port))
|
||||
(let loop ([fragments (colored-error-message-fragments msg)])
|
||||
(for ([f fragments])
|
||||
(match f
|
||||
[(msg-fragment:str str) (display str port)]
|
||||
[(msg-fragment:v v) (write v port)]
|
||||
[(colored-msg-fragment locs frags imp col)
|
||||
(define start (send repl get-insertion-point))
|
||||
(for-each loop frags)
|
||||
(define end (send repl get-insertion-point))
|
||||
(send repl higlight-range start end col #t)
|
||||
(send repl set-clickback start end (lambda () (clickback f)))])))
|
||||
(send repl highlight-errors (get-message-colored-srclocs msg))
|
||||
|
||||
;; need to flush here so that error annotations inserted in next line
|
||||
;; don't get erased if this output were to happen after the insertion
|
||||
(flush-output (send repl get-err-port))
|
||||
|
||||
(send repl end-edit-sequence))
|
||||
|#
|
||||
|
|
|
@ -1034,7 +1034,6 @@
|
|||
;; (string (union TST exn) -> void) -> string exn -> void
|
||||
;; adds in the bug icon, if there are contexts to display
|
||||
(define (teaching-languages-error-display-handler msg exn)
|
||||
|
||||
(if (exn? exn)
|
||||
(display (exn-message exn) (current-error-port))
|
||||
(fprintf (current-error-port) "uncaught exception: ~e" exn))
|
||||
|
|
|
@ -21,166 +21,166 @@
|
|||
(random (case->
|
||||
(integer -> integer)
|
||||
(-> (and/c real inexact? (>/c 0) (</c 1))))
|
||||
"to generate a random natural number less than some given integer, or to generate a random inexact number between 0.0 and 1.0 exclusive"))
|
||||
"Generates a random natural number less than some given integer, or to generate a random inexact number between 0.0 and 1.0 exclusive"))
|
||||
|
||||
("Reading and Printing"
|
||||
(with-input-from-file (string (-> any) -> any)
|
||||
"to open the named input file and to extract all input from there")
|
||||
"Opens the named input file and to extract all input from there")
|
||||
(with-output-to-file (string (-> any) -> any)
|
||||
"to open the named output file and to put all output there")
|
||||
"Opens the named output file and to put all output there")
|
||||
(with-input-from-string (string (-> any) -> any)
|
||||
"to turn the given string into input for read* operations")
|
||||
"Turns the given string into input for read* operations")
|
||||
(with-output-to-string (string (-> any) -> any)
|
||||
"to produce a string from all write/display/print operations")
|
||||
"Produces a string from all write/display/print operations")
|
||||
|
||||
|
||||
(print (any -> void)
|
||||
"to print the argument as a value to stdout")
|
||||
"Prints the argument as a value to stdout")
|
||||
(display (any -> void)
|
||||
"to print the argument to stdout (without quotes on symbols and strings, etc.)")
|
||||
"Prints the argument to stdout (without quotes on symbols and strings, etc.)")
|
||||
(write (any -> void)
|
||||
"to print the argument to stdout (in a traditional style that is somewhere between print and display)")
|
||||
"Prints the argument to stdout (in a traditional style that is somewhere between print and display)")
|
||||
((pp pretty-print) (any -> void)
|
||||
"like write, but with standard newlines and indentation")
|
||||
(printf (string any ... -> void)
|
||||
"to format the rest of the arguments according to the first argument and print it to stdout")
|
||||
"Formats the rest of the arguments according to the first argument and print it to stdout")
|
||||
(newline (-> void)
|
||||
"to print a newline to stdout")
|
||||
(read (-> sexp) "to read input from the user"))
|
||||
"Prints a newline to stdout")
|
||||
(read (-> sexp) "Reads input from the user"))
|
||||
|
||||
("Lists"
|
||||
(list? (any -> boolean)
|
||||
"to determine whether some value is a list")
|
||||
"Determines whether some value is a list")
|
||||
|
||||
((advanced-list* list*) (any ... (listof any) -> (listof any))
|
||||
"to construct a list by adding multiple items to a list")
|
||||
"Constructs a list by adding multiple items to a list")
|
||||
|
||||
((advanced-cons cons) (X (listof X) -> (listof X))
|
||||
"to construct a list")
|
||||
"Constructs a list")
|
||||
|
||||
((advanced-append append) ((listof any) ... -> (listof any))
|
||||
"to create a single list from several")
|
||||
"Creates a single list from several")
|
||||
|
||||
(assoc
|
||||
(any (listof any) -> (listof any) or false)
|
||||
"to produce the first element on the list whose first is equal? to v; otherwise it produces false"))
|
||||
"Produces the first element on the list whose first is equal? to v; otherwise it produces false"))
|
||||
|
||||
("Misc"
|
||||
(gensym (-> symbol?)
|
||||
"to generate a new symbol, different from all symbols in the program")
|
||||
"Generates a new symbol, different from all symbols in the program")
|
||||
(sleep (-> positive-number void)
|
||||
"to cause the program to sleep for the given number of seconds")
|
||||
"Causes the program to sleep for the given number of seconds")
|
||||
(current-milliseconds (-> exact-integer)
|
||||
"to return the current “time” in fixnum milliseconds (possibly negative)")
|
||||
"Returns the current “time” in fixnum milliseconds (possibly negative)")
|
||||
|
||||
(force (delay -> any) "to find the delayed value; see also delay")
|
||||
(promise? (any -> boolean) "to determine if a value is delayed")
|
||||
(void (-> void) "produces a void value")
|
||||
(void? (any -> boolean) "to determine if a value is void"))
|
||||
(force (delay -> any) "Finds the delayed value; see also delay")
|
||||
(promise? (any -> boolean) "Determines if a value is delayed")
|
||||
(void (-> void) "Produces a void value")
|
||||
(void? (any -> boolean) "Determines if a value is void"))
|
||||
|
||||
("Posns"
|
||||
(set-posn-x! (posn number -> void) "to update the x component of a posn")
|
||||
(set-posn-y! (posn number -> void) "to update the x component of a posn"))
|
||||
(set-posn-x! (posn number -> void) "Updates the x component of a posn")
|
||||
(set-posn-y! (posn number -> void) "Updates the x component of a posn"))
|
||||
|
||||
("Vectors"
|
||||
(vector (X ... -> (vector X ...))
|
||||
"to construct a vector")
|
||||
"Constructs a vector")
|
||||
(make-vector (number X -> (vectorof X))
|
||||
"to construct a vector")
|
||||
"Constructs a vector")
|
||||
(build-vector (nat (nat -> X) -> (vectorof X))
|
||||
"to construct a vector")
|
||||
"Constructs a vector")
|
||||
(vector-ref ((vector X) nat -> X)
|
||||
"to extract an element from a vector")
|
||||
"Extracts an element from a vector")
|
||||
(vector-length ((vector X) -> nat)
|
||||
"to determine the length of a vector")
|
||||
"Determines the length of a vector")
|
||||
(vector-set! ((vectorof X) nat X -> void)
|
||||
"to update a vector")
|
||||
"Updates a vector")
|
||||
(vector? (any -> boolean)
|
||||
"to determine if a value is a vector"))
|
||||
"Determines if a value is a vector"))
|
||||
|
||||
("Boxes"
|
||||
(box (any -> box)
|
||||
"to construct a box")
|
||||
"Constructs a box")
|
||||
(unbox (box -> any)
|
||||
"to extract the boxed value")
|
||||
"Extracts the boxed value")
|
||||
(set-box! (box any -> void)
|
||||
"to update a box")
|
||||
"Updates a box")
|
||||
(box? (any -> boolean)
|
||||
"to determine if a value is a box"))
|
||||
"Determines if a value is a box"))
|
||||
|
||||
("Hash Tables"
|
||||
((advanced-make-hash make-hash)
|
||||
(case->
|
||||
(-> (hash X Y))
|
||||
((listof (list X Y)) -> (hash X Y)))
|
||||
"to construct a mutable hash table from an optional list of mappings that uses equal? for comparisions")
|
||||
"Constructs a mutable hash table from an optional list of mappings that uses equal? for comparisions")
|
||||
((advanced-make-hasheq make-hasheq)
|
||||
(case->
|
||||
(-> (hash X Y))
|
||||
((listof (list X Y)) -> (hash X Y)))
|
||||
"to construct a mutable hash table from an optional list of mappings that uses eq? for comparisions")
|
||||
"Constructs a mutable hash table from an optional list of mappings that uses eq? for comparisions")
|
||||
((advanced-make-hasheqv make-hasheqv)
|
||||
(case->
|
||||
(-> (hash X Y))
|
||||
((listof (list X Y)) -> (hash X Y)))
|
||||
"to construct a mutable hash table from an optional list of mappings that uses eqv? for comparisions")
|
||||
"Constructs a mutable hash table from an optional list of mappings that uses eqv? for comparisions")
|
||||
((advanced-make-immutable-hash make-immutable-hash)
|
||||
(case->
|
||||
(-> (hash X Y))
|
||||
((listof (list X Y)) -> (hash X Y)))
|
||||
"to construct an immutable hash table from an optional list of mappings that uses equal? for comparisions")
|
||||
"Constructs an immutable hash table from an optional list of mappings that uses equal? for comparisions")
|
||||
((advanced-make-immutable-hasheq make-immutable-hasheq)
|
||||
(case->
|
||||
(-> (hash X Y))
|
||||
((listof (list X Y)) -> (hash X Y)))
|
||||
"to construct an immutable hash table from an optional list of mappings that uses eq? for comparisions")
|
||||
"Constructs an immutable hash table from an optional list of mappings that uses eq? for comparisions")
|
||||
((advanced-make-immutable-hasheqv make-immutable-hasheqv)
|
||||
(case->
|
||||
(-> (hash X Y))
|
||||
((listof (list X Y)) -> (hash X Y)))
|
||||
"to construct an immutable hash table from an optional list of mappings that uses eqv? for comparisions")
|
||||
"Constructs an immutable hash table from an optional list of mappings that uses eqv? for comparisions")
|
||||
(hash-set! ((hash X Y) X Y -> void)
|
||||
"to update a mutable hash table with a new mapping")
|
||||
"Updates a mutable hash table with a new mapping")
|
||||
(hash-set ((hash X Y) X Y -> (hash X Y))
|
||||
"to construct an immutable hash table with one new mapping from an existing immutable hash table")
|
||||
"Constructs an immutable hash table with one new mapping from an existing immutable hash table")
|
||||
(hash-ref (case->
|
||||
((hash X Y) X -> Y)
|
||||
((hash X Y) X Y -> Y)
|
||||
((hash X Y) X (-> Y) -> Y))
|
||||
"to extract the value associated with a key from a hash table; the three argument case allows a default value or default value computation")
|
||||
"Extracts the value associated with a key from a hash table; the three argument case allows a default value or default value computation")
|
||||
(hash-ref! (case->
|
||||
((hash X Y) X Y -> Y)
|
||||
((hash X Y) X (-> Y) -> Y))
|
||||
"to extract the value associated with a key from a mutable hash table; if the key does not have an mapping, the third argument is used as the value (or used to compute the value) and is added to the hash table associated with the key")
|
||||
"Extracts the value associated with a key from a mutable hash table; if the key does not have an mapping, the third argument is used as the value (or used to compute the value) and is added to the hash table associated with the key")
|
||||
(hash-update! (case->
|
||||
((hash X Y) X (Y -> Y) -> void)
|
||||
((hash X Y) X (Y -> Y) Y -> void)
|
||||
((hash X Y) X (Y -> Y) (-> Y) -> void))
|
||||
"to compose hash-ref and hash-set! to update an existing mapping; the third argument is used to compute the new mapping value; the fourth argument is used as the third argument to hash-ref")
|
||||
"Composes hash-ref and hash-set! to update an existing mapping; the third argument is used to compute the new mapping value; the fourth argument is used as the third argument to hash-ref")
|
||||
(hash-update (case->
|
||||
((hash X Y) X (Y -> Y) -> (hash X Y))
|
||||
((hash X Y) X (Y -> Y) Y -> (hash X Y))
|
||||
((hash X Y) X (Y -> Y) (-> Y) -> (hash X Y)))
|
||||
"to compose hash-ref and hash-set to update an existing mapping; the third argument is used to compute the new mapping value; the fourth argument is used as the third argument to hash-ref")
|
||||
"Composes hash-ref and hash-set to update an existing mapping; the third argument is used to compute the new mapping value; the fourth argument is used as the third argument to hash-ref")
|
||||
(hash-has-key? ((hash X Y) X -> boolean)
|
||||
"to determine if a key is associated with a value in a hash table")
|
||||
"Determines if a key is associated with a value in a hash table")
|
||||
(hash-remove! ((hash X Y) X -> void)
|
||||
"to remove an mapping from a mutable hash table")
|
||||
"Removes an mapping from a mutable hash table")
|
||||
(hash-remove ((hash X Y) X -> (hash X Y))
|
||||
"to construct an immutable hash table with one less mapping than an existing immutable hash table")
|
||||
"Constructs an immutable hash table with one less mapping than an existing immutable hash table")
|
||||
(hash-map ((hash X Y) (X Y -> A) -> (listof A))
|
||||
"to construct a new list by applying a function to each mapping of a hash table")
|
||||
"Constructs a new list by applying a function to each mapping of a hash table")
|
||||
(hash-for-each ((hash X Y) (X Y -> any) -> void)
|
||||
"to apply a function to each mapping of a hash table for effect only")
|
||||
"Applies a function to each mapping of a hash table for effect only")
|
||||
(hash-count (hash -> integer)
|
||||
"to determine the number of keys mapped by a hash table")
|
||||
"Determines the number of keys mapped by a hash table")
|
||||
(hash-copy (hash -> hash)
|
||||
"to copy a hash table")
|
||||
"Copies a hash table")
|
||||
(hash? (any -> boolean)
|
||||
"to determine if a value is a hash table")
|
||||
"Determines if a value is a hash table")
|
||||
(hash-equal? (hash -> boolean)
|
||||
"to determine if a hash table uses equal? for comparisions")
|
||||
"Determines if a hash table uses equal? for comparisions")
|
||||
(hash-eq? (hash -> boolean)
|
||||
"to determine if a hash table uses eq? for comparisions")
|
||||
"Determines if a hash table uses eq? for comparisions")
|
||||
(hash-eqv? (hash -> boolean)
|
||||
"to determine if a hash table uses eqv? for comparisions"))))
|
||||
"Determines if a hash table uses eqv? for comparisions"))))
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
(require mzlib/etc mzlib/list mzlib/math syntax/docprovide)
|
||||
|
||||
;; Implements the procedures:
|
||||
(require "teachprims.rkt"
|
||||
"../posn.rkt"
|
||||
"../imageeq.rkt")
|
||||
(require "teachprims.ss"
|
||||
"../posn.ss"
|
||||
"../imageeq.ss")
|
||||
|
||||
;; procedures with documentation:
|
||||
(provide-and-document
|
||||
|
@ -12,485 +12,485 @@
|
|||
|
||||
("Numbers: Integers, Rationals, Reals, Complex, Exacts, Inexacts"
|
||||
(number? (any -> boolean)
|
||||
"to determine whether some value is a number")
|
||||
"Determines whether some value is a number")
|
||||
(= (number number number ... -> boolean)
|
||||
"to compare numbers for equality")
|
||||
"Compares numbers for equality")
|
||||
(< (real real real ... -> boolean)
|
||||
"to compare real numbers for less-than")
|
||||
"Compares real numbers for less-than")
|
||||
(> (real real real ... -> boolean)
|
||||
"to compare real numbers for greater-than")
|
||||
"Compares real numbers for greater-than")
|
||||
(<= (real real real ... -> boolean)
|
||||
"to compare real numbers for less-than or equality")
|
||||
"Compares real numbers for less-than or equality")
|
||||
(>= (real real ... -> boolean)
|
||||
"to compare real numbers for greater-than or equality")
|
||||
"Compares real numbers for greater-than or equality")
|
||||
|
||||
((beginner-+ +) (number number number ... -> number)
|
||||
"to compute the sum of the input numbers")
|
||||
"Evaluates the sum of the input numbers")
|
||||
(- (number number ... -> number)
|
||||
"to subtract the second (and following) number(s) from the first; negate the number if there is only one argument")
|
||||
"subtracts the second (and following) number(s) from the first; negate the number if there is only one argument")
|
||||
((beginner-* *) (number number number ... -> number)
|
||||
"to compute the product of all of the input numbers")
|
||||
"Evaluates the product of all of the input numbers")
|
||||
((beginner-/ /) (number number number ... -> number)
|
||||
"to divide the first by the second (and all following) number(s); try (/ 3 4) and (/ 3 2 2)"
|
||||
"Divides the first by the second (and all following) number(s); try (/ 3 4) and (/ 3 2 2)"
|
||||
" only the first number can be zero.")
|
||||
(max (real real ... -> real)
|
||||
"to determine the largest number")
|
||||
"Determines the largest number")
|
||||
(min (real real ... -> real)
|
||||
"to determine the smallest number")
|
||||
"Determines the smallest number")
|
||||
(quotient (integer integer -> integer)
|
||||
"to divide the first integer (exact or inexact) into the second; try (quotient 3 4) and (quotient 4 3)")
|
||||
"Divides the first integer (exact or inexact) into the second; try (quotient 3 4) and (quotient 4 3)")
|
||||
(remainder (integer integer -> integer)
|
||||
"to determine the remainder of dividing the first by the second integer (exact or inexact)")
|
||||
"Determines the remainder of dividing the first by the second integer (exact or inexact)")
|
||||
(modulo (integer integer -> integer)
|
||||
"to find the remainder of the division of the first number by the second; try (modulo 4 3) (modulo 4 -3)")
|
||||
"Finds the remainder of the division of the first number by the second; try (modulo 4 3) (modulo 4 -3)")
|
||||
((beginner-sqr sqr) (number -> number)
|
||||
"to compute the square of a number")
|
||||
"Evaluates the square of a number")
|
||||
(sqrt (number -> number)
|
||||
"to compute the square root of a number")
|
||||
"Evaluates the square root of a number")
|
||||
(integer-sqrt (number -> integer)
|
||||
"to compute the integer (exact or inexact) square root of a number")
|
||||
"Evaluates the integer (exact or inexact) square root of a number")
|
||||
(expt (number number -> number)
|
||||
"to compute the power of the first to the second number")
|
||||
"Evaluates the power of the first to the second number")
|
||||
(abs (real -> real)
|
||||
"to compute the absolute value of a real number")
|
||||
"Evaluates the absolute value of a real number")
|
||||
(sgn (real -> (union 1 #i1.0 0 #i0.0 -1 #i-1.0))
|
||||
"to compute the sign of a real number")
|
||||
"Evaluates the sign of a real number")
|
||||
|
||||
;; fancy numeric
|
||||
(exp (number -> number)
|
||||
"to compute e raised to a number")
|
||||
"Evaluates e raised to a number")
|
||||
(log (number -> number)
|
||||
"to compute the base-e logarithm of a number")
|
||||
"Evaluates the base-e logarithm of a number")
|
||||
|
||||
;; trigonometry
|
||||
(sin (number -> number)
|
||||
"to compute the sine of a number (radians)")
|
||||
"Evaluates the sine of a number (radians)")
|
||||
(cos (number -> number)
|
||||
"to compute the cosine of a number (radians)")
|
||||
"Evaluates the cosine of a number (radians)")
|
||||
(tan (number -> number)
|
||||
"to compute the tangent of a number (radians)")
|
||||
"Evaluates the tangent of a number (radians)")
|
||||
(asin (number -> number)
|
||||
"to compute the arcsine (inverse of sin) of a number")
|
||||
"Evaluates the arcsine (inverse of sin) of a number")
|
||||
(acos (number -> number)
|
||||
"to compute the arccosine (inverse of cos) of a number")
|
||||
"Evaluates the arccosine (inverse of cos) of a number")
|
||||
(atan (number -> number)
|
||||
"to compute the arctan (inverse of tan) of a number")
|
||||
"Evaluates the arctan (inverse of tan) of a number")
|
||||
|
||||
(sinh (number -> number)
|
||||
"to compute the hyperbolic sine of a number")
|
||||
"Evaluates the hyperbolic sine of a number")
|
||||
(cosh (number -> number)
|
||||
"to compute the hyperbolic cosine of a number")
|
||||
"Evaluates the hyperbolic cosine of a number")
|
||||
|
||||
(exact? (number -> boolean)
|
||||
"to determine whether some number is exact")
|
||||
"Determines whether some number is exact")
|
||||
|
||||
(integer? (any -> boolean)
|
||||
"to determine whether some value is an integer (exact or inexact)")
|
||||
"Determines whether some value is an integer (exact or inexact)")
|
||||
|
||||
(zero? (number -> boolean)
|
||||
"to determine if some value is zero or not")
|
||||
"Determines if some value is zero or not")
|
||||
(positive? (number -> boolean)
|
||||
"to determine if some value is strictly larger than zero")
|
||||
"Determines if some value is strictly larger than zero")
|
||||
(negative? (number -> boolean)
|
||||
"to determine if some value is strictly smaller than zero")
|
||||
"Determines if some value is strictly smaller than zero")
|
||||
(odd? (integer -> boolean)
|
||||
"to determine if some integer (exact or inexact) is odd or not")
|
||||
"Determines if some integer (exact or inexact) is odd or not")
|
||||
(even? (integer -> boolean)
|
||||
"to determine if some integer (exact or inexact) is even or not")
|
||||
"Determines if some integer (exact or inexact) is even or not")
|
||||
|
||||
(add1 (number -> number)
|
||||
"to compute a number one larger than a given number")
|
||||
"Evaluates a number one larger than a given number")
|
||||
(sub1 (number -> number)
|
||||
"to compute a number one smaller than a given number")
|
||||
"Evaluates a number one smaller than a given number")
|
||||
|
||||
(lcm (integer integer ... -> integer)
|
||||
"to compute the least common multiple of two integers (exact or inexact)")
|
||||
"Evaluates the least common multiple of two integers (exact or inexact)")
|
||||
|
||||
(gcd (integer integer ... -> integer)
|
||||
"to compute the greatest common divisior of two integers (exact or inexact)")
|
||||
"Evaluates the greatest common divisior of two integers (exact or inexact)")
|
||||
|
||||
(rational? (any -> boolean)
|
||||
"to determine whether some value is a rational number")
|
||||
"Determines whether some value is a rational number")
|
||||
|
||||
(numerator (rat -> integer)
|
||||
"to compute the numerator of a rational")
|
||||
"Evaluates the numerator of a rational")
|
||||
|
||||
(denominator (rat -> integer)
|
||||
"to compute the denominator of a rational")
|
||||
"Evaluates the denominator of a rational")
|
||||
|
||||
(inexact? (number -> boolean)
|
||||
"to determine whether some number is inexact")
|
||||
"Determines whether some number is inexact")
|
||||
|
||||
(real? (any -> boolean)
|
||||
"to determine whether some value is a real number")
|
||||
"Determines whether some value is a real number")
|
||||
|
||||
(floor (real -> integer)
|
||||
"to determine the closest integer (exact or inexact) below a real number")
|
||||
"Determines the closest integer (exact or inexact) below a real number")
|
||||
|
||||
(ceiling (real -> integer)
|
||||
"to determine the closest integer (exact or inexact) above a real number")
|
||||
"Determines the closest integer (exact or inexact) above a real number")
|
||||
|
||||
(round (real -> integer)
|
||||
"to round a real number to an integer (rounds to even to break ties)")
|
||||
"Rounds a real number to an integer (rounds to even to break ties)")
|
||||
|
||||
(complex? (any -> boolean)
|
||||
"to determine whether some value is complex")
|
||||
"Determines whether some value is complex")
|
||||
|
||||
(make-polar (real real -> number)
|
||||
"to create a complex from a magnitude and angle")
|
||||
"Creates a complex from a magnitude and angle")
|
||||
|
||||
(make-rectangular (real real -> number)
|
||||
"to create a complex from a real and an imaginary part")
|
||||
"Creates a complex from a real and an imaginary part")
|
||||
|
||||
(real-part (number -> real)
|
||||
"to extract the real part from a complex number")
|
||||
"Extracts the real part from a complex number")
|
||||
|
||||
(imag-part (number -> real)
|
||||
"to extract the imaginary part from a complex number")
|
||||
"Extracts the imaginary part from a complex number")
|
||||
|
||||
(magnitude (number -> real)
|
||||
"to determine the magnitude of a complex number")
|
||||
"Determines the magnitude of a complex number")
|
||||
|
||||
(angle (number -> real)
|
||||
"to extract the angle from a complex number")
|
||||
"Extracts the angle from a complex number")
|
||||
|
||||
(conjugate (number -> number)
|
||||
"to compute the conjugate of a complex number")
|
||||
"Evaluates the conjugate of a complex number")
|
||||
|
||||
(exact->inexact (number -> number)
|
||||
"to convert an exact number to an inexact one")
|
||||
"Converts an exact number to an inexact one")
|
||||
|
||||
(inexact->exact (number -> number)
|
||||
"to approximate an inexact number by an exact one")
|
||||
"Approximates an inexact number by an exact one")
|
||||
|
||||
; "Odds and ends"
|
||||
; "Odds and ends"
|
||||
|
||||
(number->string (number -> string)
|
||||
"to convert a number to a string")
|
||||
"Converts a number to a string")
|
||||
|
||||
(integer->char (integer -> char)
|
||||
"to lookup the character that corresponds to the given integer (exact only!) in the ASCII table (if any)")
|
||||
"Lookups the character that corresponds to the given integer (exact only!) in the ASCII table (if any)")
|
||||
|
||||
((beginner-random random) (integer -> integer)
|
||||
"to generate a random natural number less than some given integer (exact only!)")
|
||||
"Generates a random natural number less than some given integer (exact only!)")
|
||||
|
||||
(current-seconds (-> integer)
|
||||
"to compute the current time in seconds elapsed"
|
||||
" (since a platform-specific starting date)")
|
||||
"Evaluates the current time in seconds elapsed"
|
||||
" (since a platform-specific starting date)")
|
||||
|
||||
(e real
|
||||
"Euler's number")
|
||||
"Euler's number")
|
||||
(pi real
|
||||
"the ratio of a circle's circumference to its diameter"))
|
||||
"The ratio of a circle's circumference to its diameter"))
|
||||
|
||||
("Booleans"
|
||||
(boolean? (any -> boolean)
|
||||
"to determine whether some value is a boolean")
|
||||
"Determines whether some value is a boolean")
|
||||
|
||||
(boolean=? (boolean boolean -> boolean)
|
||||
"to determine whether two booleans are equal")
|
||||
"Determines whether two booleans are equal")
|
||||
|
||||
(false? (any -> boolean)
|
||||
"to determine whether a value is false")
|
||||
"Determines whether a value is false")
|
||||
|
||||
((beginner-not not) (boolean -> boolean)
|
||||
"to compute the negation of a boolean value"))
|
||||
"Evaluates the negation of a boolean value"))
|
||||
|
||||
("Symbols"
|
||||
(symbol? (any -> boolean)
|
||||
"to determine whether some value is a symbol")
|
||||
"Determines whether some value is a symbol")
|
||||
|
||||
(symbol=? (symbol symbol -> boolean)
|
||||
"to determine whether two symbols are equal")
|
||||
"Determines whether two symbols are equal")
|
||||
|
||||
(symbol->string (symbol -> string)
|
||||
"to convert a symbol to a string") )
|
||||
"Converts a symbol to a string") )
|
||||
|
||||
("Lists"
|
||||
(cons? (any -> boolean)
|
||||
"to determine whether some value is a constructed list")
|
||||
"Determines whether some value is a constructed list")
|
||||
#;
|
||||
(pair? (any -> boolean)
|
||||
"to determine whether some value is a constructed list")
|
||||
"Determines whether some value is a constructed list")
|
||||
(empty? (any -> boolean)
|
||||
"to determine whether some value is the empty list")
|
||||
"Determines whether some value is the empty list")
|
||||
(null? (any -> boolean)
|
||||
"to determine whether some value is the empty list")
|
||||
"Determines whether some value is the empty list")
|
||||
|
||||
((beginner-cons cons) (X (listof X) -> (listof X))
|
||||
"to construct a list")
|
||||
"Constructs a list")
|
||||
|
||||
(null empty
|
||||
"the empty list")
|
||||
"The empty list")
|
||||
|
||||
((beginner-first first) ( (cons Y (listof X)) -> Y )
|
||||
"to select the first item of a non-empty list")
|
||||
"Selects the first item of a non-empty list")
|
||||
((beginner-car car) ( (cons Y (listof X)) -> Y )
|
||||
"to select the first item of a non-empty list")
|
||||
"Selects the first item of a non-empty list")
|
||||
((beginner-rest rest) ((cons Y (listof X)) -> (listof X))
|
||||
"to select the rest of a non-empty list")
|
||||
"Selects the rest of a non-empty list")
|
||||
((beginner-cdr cdr) ((cons Y (listof X)) -> (listof X))
|
||||
"to select the rest of a non-empty list")
|
||||
"Selects the rest of a non-empty list")
|
||||
|
||||
(second ( (cons Z (cons Y (listof X))) -> Y )
|
||||
"to select the second item of a non-empty list")
|
||||
"Selects the second item of a non-empty list")
|
||||
(cadr ( (cons Z (cons Y (listof X))) -> Y )
|
||||
"to select the second item of a non-empty list")
|
||||
"Selects the second item of a non-empty list")
|
||||
(cdar ( (cons (cons Z (listof Y)) (listof X)) -> (listof Y) )
|
||||
"to select the rest of a non-empty list in a list")
|
||||
"Selects the rest of a non-empty list in a list")
|
||||
(caar ( (cons (cons Z (listof Y)) (listof X)) -> Z )
|
||||
"to select the first item of the first list in a list")
|
||||
"Selects the first item of the first list in a list")
|
||||
(cddr ( (cons Z (cons Y (listof X))) -> (listof X) )
|
||||
"to select the rest of the rest of a list")
|
||||
"Selects the rest of the rest of a list")
|
||||
(third ( (cons W (cons Z (cons Y (listof X)))) -> Y )
|
||||
"to select the third item of a non-empty list")
|
||||
"Selects the third item of a non-empty list")
|
||||
(caddr ( (cons W (cons Z (cons Y (listof X)))) -> Y )
|
||||
"to select the third item of a non-empty list")
|
||||
"Selects the third item of a non-empty list")
|
||||
(caadr ( (cons (cons (cons W (listof Z)) (listof Y)) (listof X)) -> (listof Z) )
|
||||
"to select the rest of the first list in the first list of a list")
|
||||
"Selects the rest of the first list in the first list of a list")
|
||||
(caaar ( (cons (cons (cons W (listof Z)) (listof Y)) (listof X)) -> W )
|
||||
"to select the first item of the first list in the first list of a list")
|
||||
"Selects the first item of the first list in the first list of a list")
|
||||
(cdaar ( (cons (cons (cons W (listof Z)) (listof Y)) (listof X)) -> (listof Z) )
|
||||
"to select the rest of the first list in the first list of a list")
|
||||
"Selects the rest of the first list in the first list of a list")
|
||||
(cdadr ( (cons W (cons (cons Z (listof Y)) (listof X))) -> (listof Y) )
|
||||
"to select the rest of the first list in the rest of a list")
|
||||
"Selects the rest of the first list in the rest of a list")
|
||||
(cadar ( (cons (cons W (cons Z (listof Y))) (listof X)) -> Z )
|
||||
"to select the second item of the first list of a list")
|
||||
"Selects the second item of the first list of a list")
|
||||
(cddar ( (cons (cons W (cons Z (listof Y))) (listof X)) -> (listof Y) )
|
||||
"to select the rest of the rest of the first list of a list")
|
||||
"Selects the rest of the rest of the first list of a list")
|
||||
(cdddr ( (cons W (cons Z (cons Y (listof X)))) -> (listof X) )
|
||||
"to select the rest of the rest of the rest of a list")
|
||||
"Selects the rest of the rest of the rest of a list")
|
||||
(fourth ( (listof Y) -> Y ) ; domain: (cons V (cons W (cons Z (cons Y (listof X)))))
|
||||
"to select the fourth item of a non-empty list")
|
||||
"Selects the fourth item of a non-empty list")
|
||||
(cadddr ( (listof Y) -> Y ) ; domain: (cons V (cons W (cons Z (cons Y (listof X)))))
|
||||
"to select the fourth item of a non-empty list")
|
||||
"Selects the fourth item of a non-empty list")
|
||||
(fifth ( (listof Y) -> Y ) ; domain: (cons U (cons V (cons W (cons Z (cons Y (listof X))))))
|
||||
"to select the fifth item of a non-empty list")
|
||||
"Selects the fifth item of a non-empty list")
|
||||
(sixth ( (listof Y) -> Y ) ; domain: (cons T (cons U (cons V (cons W (cons Z (cons Y (listof X)))))))
|
||||
"to select the sixth item of a non-empty list")
|
||||
"Selects the sixth item of a non-empty list")
|
||||
(seventh ( (listof Y) -> Y ) ; domain: (cons S (cons T (cons U (cons V (cons W (cons Z (cons Y (listof X))))))))
|
||||
"to select the seventh item of a non-empty list")
|
||||
"Selects the seventh item of a non-empty list")
|
||||
(eighth ( (listof Y) -> Y ) ; domain: (cons R (cons S (cons T (cons U (cons V (cons W (cons Z (cons Y (listof X)))))))))
|
||||
"to select the eighth item of a non-empty list")
|
||||
"Selects the eighth item of a non-empty list")
|
||||
|
||||
(list-ref ((listof X) natural-number -> X )
|
||||
"to extract the indexed item from the list")
|
||||
"Extracts the indexed item from the list")
|
||||
|
||||
(list (any ... -> (listof any)) "to construct a list of its arguments")
|
||||
(list (any ... -> (listof any)) "constructs a list of its arguments")
|
||||
|
||||
(make-list (natural-number any -> (listof any)) "(make-list k x) constructs a list of k copies of x")
|
||||
|
||||
((beginner-list* list*) (any ... (listof any) -> (listof any))
|
||||
"to construct a list by adding multiple items to a list")
|
||||
"Constructs a list by adding multiple items to a list")
|
||||
|
||||
((beginner-append append) ((listof any) (listof any) (listof any) ... -> (listof any))
|
||||
"to create a single list from several, by juxtaposition of the items")
|
||||
"Creates a single list from several, by juxtaposition of the items")
|
||||
(length ((listof any) -> number)
|
||||
"to compute the number of items on a list")
|
||||
"Evaluates the number of items on a list")
|
||||
(memq (any (listof any) -> (union false list))
|
||||
"to determine whether some value is on some list"
|
||||
"Determines whether some value is on some list"
|
||||
" if so, it produces the suffix of the list that starts with x"
|
||||
" if not, it produces false."
|
||||
" (It compares values with the eq? predicate.)")
|
||||
(memv (any (listof any) -> (union false list))
|
||||
"to determine whether some value is on the list"
|
||||
"Determines whether some value is on the list"
|
||||
" if so, it produces the suffix of the list that starts with x"
|
||||
" if not, it produces false."
|
||||
" (it compares values with the eqv? predicate.)")
|
||||
((beginner-member? member?) (any (listof any) -> boolean)
|
||||
"to determine whether some value is on the list"
|
||||
"Determines whether some value is on the list"
|
||||
" (comparing values with equal?)")
|
||||
((beginner-member member) (any (listof any) -> boolean)
|
||||
"to determine whether some value is on the list"
|
||||
"Determines whether some value is on the list"
|
||||
" (comparing values with equal?)")
|
||||
((beginner-remove remove) (any (listof any) -> (listof any))
|
||||
"to construct a list like the given one with the first occurrence of the given item removed"
|
||||
"Constructs a list like the given one with the first occurrence of the given item removed"
|
||||
" (comparing values with equal?)")
|
||||
(reverse ((listof any) -> list)
|
||||
"to create a reversed version of a list")
|
||||
"Creates a reversed version of a list")
|
||||
(assq (X (listof (cons X Y)) -> (union false (cons X Y)))
|
||||
"to determine whether some item is the first item of a pair"
|
||||
"Determines whether some item is the first item of a pair"
|
||||
" in a list of pairs"))
|
||||
|
||||
("Posns"
|
||||
(posn signature "signature for posns")
|
||||
(make-posn (number number -> posn) "to construct a posn")
|
||||
(posn? (anything -> boolean) "to determine if its input is a posn")
|
||||
(posn-x (posn -> number) "to extract the x component of a posn")
|
||||
(posn-y (posn -> number) "to extract the y component of a posn"))
|
||||
(make-posn (number number -> posn) "constructs a posn")
|
||||
(posn? (anything -> boolean) "determines if its input is a posn")
|
||||
(posn-x (posn -> number) "extracts the x component of a posn")
|
||||
(posn-y (posn -> number) "extracts the y component of a posn"))
|
||||
|
||||
("Characters"
|
||||
(char? (any -> boolean)
|
||||
"to determine whether a value is a character")
|
||||
"Determines whether a value is a character")
|
||||
(char=? (char char char ... -> boolean)
|
||||
"to determine whether two characters are equal")
|
||||
"Determines whether two characters are equal")
|
||||
(char<? (char char char ... -> boolean)
|
||||
"to determine whether a character precedes another")
|
||||
"Determines whether a character precedes another")
|
||||
(char>? (char char char ... -> boolean)
|
||||
"to determine whether a character succeeds another")
|
||||
"Determines whether a character succeeds another")
|
||||
(char<=? (char char char ... -> boolean)
|
||||
"to determine whether a character precedes another"
|
||||
"Determines whether a character precedes another"
|
||||
" (or is equal to it)")
|
||||
(char>=? (char char char ... -> boolean)
|
||||
"to determine whether a character succeeds another"
|
||||
"Determines whether a character succeeds another"
|
||||
" (or is equal to it)")
|
||||
|
||||
(char-ci=? (char char char ... -> boolean)
|
||||
"to determine whether two characters are equal"
|
||||
"Determines whether two characters are equal"
|
||||
" in a case-insensitive manner")
|
||||
(char-ci<? (char char char ... -> boolean)
|
||||
"to determine whether a character precedes another"
|
||||
"Determines whether a character precedes another"
|
||||
" in a case-insensitive manner")
|
||||
(char-ci>? (char char char ... -> boolean)
|
||||
"to determine whether a character succeeds another"
|
||||
"Determines whether a character succeeds another"
|
||||
" in a case-insensitive manner")
|
||||
(char-ci<=? (char char char ... -> boolean)
|
||||
"to determine whether a character precedes another"
|
||||
"Determines whether a character precedes another"
|
||||
" (or is equal to it) in a case-insensitive manner")
|
||||
(char-ci>=? (char char char ... -> boolean)
|
||||
"to determine whether a character succeeds another"
|
||||
"Determines whether a character succeeds another"
|
||||
" (or is equal to it) in a case-insensitive manner")
|
||||
|
||||
(char-numeric? (char -> boolean)
|
||||
"to determine whether a character represents a digit")
|
||||
"Determines whether a character represents a digit")
|
||||
(char-alphabetic? (char -> boolean)
|
||||
"to determine whether a character represents"
|
||||
"Determines whether a character represents"
|
||||
" an alphabetic character")
|
||||
(char-whitespace? (char -> boolean)
|
||||
"to determine whether a character represents space")
|
||||
"Determines whether a character represents space")
|
||||
(char-upper-case? (char -> boolean)
|
||||
"to determine whether a character is an"
|
||||
"Determines whether a character is an"
|
||||
" upper-case character")
|
||||
(char-lower-case? (char -> boolean)
|
||||
"to determine whether a character is a"
|
||||
"Determines whether a character is a"
|
||||
" lower-case character")
|
||||
(char-upcase (char -> char)
|
||||
"to determine the equivalent upper-case character")
|
||||
"Determines the equivalent upper-case character")
|
||||
(char-downcase (char -> char)
|
||||
"to determine the equivalent lower-case character")
|
||||
"Determines the equivalent lower-case character")
|
||||
(char->integer (char -> integer)
|
||||
"to lookup the number that corresponds to the"
|
||||
"Lookups the number that corresponds to the"
|
||||
" given character in the ASCII table (if any)"))
|
||||
|
||||
("Strings"
|
||||
(string? (any -> boolean)
|
||||
"to determine whether a value is a string")
|
||||
"Determines whether a value is a string")
|
||||
(string-length (string -> nat)
|
||||
"to determine the length of a string")
|
||||
"Determines the length of a string")
|
||||
|
||||
((beginner-string-ith string-ith) (string nat -> string)
|
||||
"to extract the ith 1-letter substring from the given one")
|
||||
"Extracts the ith 1-letter substring from the given one")
|
||||
((beginner-replicate replicate) (nat string -> string)
|
||||
"to replicate the given string")
|
||||
"Replicates the given string")
|
||||
((beginner-int->string int->string) (integer -> string)
|
||||
"to convert an integer in [0,55295] or [57344 1114111] to a 1-letter string")
|
||||
"Converts an integer in [0,55295] or [57344 1114111] to a 1-letter string")
|
||||
((beginner-string->int string->int) (string -> integer)
|
||||
"to convert a 1-letter string to an integer in [0,55295] or [57344, 1114111]")
|
||||
"Converts a 1-letter string to an integer in [0,55295] or [57344, 1114111]")
|
||||
((beginner-explode explode) (string -> (listof string))
|
||||
"to translate a string into a list of 1-letter strings")
|
||||
"Translates a string into a list of 1-letter strings")
|
||||
((beginner-implode implode) ((listof string) -> string)
|
||||
"to concatenate the list of 1-letter strings into one string")
|
||||
"Concatenates the list of 1-letter strings into one string")
|
||||
((beginner-string-numeric? string-numeric?) (string -> boolean)
|
||||
"to determine whether all 'letters' in the string are numeric")
|
||||
"Determines whether all 'letters' in the string are numeric")
|
||||
((beginner-string-alphabetic? string-alphabetic?) (string -> boolean)
|
||||
"to determine whether all 'letters' in the string are alphabetic")
|
||||
"Determines whether all 'letters' in the string are alphabetic")
|
||||
((beginner-string-whitespace? string-whitespace?) (string -> boolean)
|
||||
"to determine whether all 'letters' in the string are white space")
|
||||
"Determines whether all 'letters' in the string are white space")
|
||||
((beginner-string-upper-case? string-upper-case?) (string -> boolean)
|
||||
"to determine whether all 'letters' in the string are upper case")
|
||||
"Determines whether all 'letters' in the string are upper case")
|
||||
((beginner-string-lower-case? string-lower-case?) (string -> boolean)
|
||||
"to determine whether all 'letters' in the string are lower case")
|
||||
"Determines whether all 'letters' in the string are lower case")
|
||||
|
||||
(string (char ... -> string)
|
||||
"(string c1 c2 ...) builds a string")
|
||||
(make-string (nat char -> string)
|
||||
"to produce a string of given length"
|
||||
"Produces a string of given length"
|
||||
" from a single given character")
|
||||
(string-ref (string nat -> char)
|
||||
"to extract the i-the character from a string")
|
||||
"Extracts the i-the character from a string")
|
||||
|
||||
(substring (string nat nat -> string)
|
||||
"to extract the substring starting at a 0-based index"
|
||||
"Extracts the substring starting at a 0-based index"
|
||||
" up to the second 0-based index (exclusive)")
|
||||
(string-copy (string -> string)
|
||||
"to copy a string")
|
||||
"Copies a string")
|
||||
(string-append (string ... -> string)
|
||||
"to juxtapose the characters of several strings")
|
||||
"Juxtaposes the characters of several strings")
|
||||
|
||||
(string=? (string string string ... -> boolean)
|
||||
"to compare two strings character-wise")
|
||||
"Compares two strings character-wise")
|
||||
(string<? (string string string ... -> boolean)
|
||||
"to determine whether one string alphabetically"
|
||||
"Determines whether one string alphabetically"
|
||||
" precedes another")
|
||||
(string>? (string string string ... -> boolean)
|
||||
"to determine whether one string alphabetically"
|
||||
"Determines whether one string alphabetically"
|
||||
" succeeds another")
|
||||
(string<=? (string string string ... -> boolean)
|
||||
"to determine whether one string alphabetically"
|
||||
"Determines whether one string alphabetically"
|
||||
" precedes another (or is equal to it)")
|
||||
(string>=? (string string string ... -> boolean)
|
||||
"to determine whether one string alphabetically"
|
||||
"Determines whether one string alphabetically"
|
||||
" succeeds another (or is equal to it)")
|
||||
|
||||
(string-ci=? (string string string ... -> boolean)
|
||||
"to compare two strings character-wise"
|
||||
"Compares two strings character-wise"
|
||||
" in a case-insensitive manner")
|
||||
(string-ci<? (string string string ... -> boolean)
|
||||
"to determine whether one string alphabetically"
|
||||
"Determines whether one string alphabetically"
|
||||
" precedes another in a case-insensitive manner")
|
||||
(string-ci>? (string string string ... -> boolean)
|
||||
"to determine whether one string alphabetically"
|
||||
"Determines whether one string alphabetically"
|
||||
" succeeds another in a case-insensitive manner")
|
||||
(string-ci<=? (string string string ... -> boolean)
|
||||
"to determine whether one string alphabetically"
|
||||
"Determines whether one string alphabetically"
|
||||
" precedes another (or is equal to it)"
|
||||
" in a case-insensitive manner")
|
||||
(string-ci>=? (string string string ... -> boolean)
|
||||
"to determine whether one string alphabetically"
|
||||
"Determines whether one string alphabetically"
|
||||
" succeeds another (or is equal to it)"
|
||||
" in a case-insensitive manner")
|
||||
|
||||
(string->symbol (string -> symbol)
|
||||
"to convert a string into a symbol")
|
||||
"Converts a string into a symbol")
|
||||
(string->number (string -> (union number false))
|
||||
"to convert a string into a number,"
|
||||
"Converts a string into a number,"
|
||||
" produce false if impossible")
|
||||
(string->list (string -> (listof char))
|
||||
"to convert a string into a list of characters")
|
||||
"Converts a string into a list of characters")
|
||||
(list->string ((listof char) -> string)
|
||||
"to convert a s list of characters into a string")
|
||||
"Converts a s list of characters into a string")
|
||||
|
||||
(format (string any ... -> string)
|
||||
"to format a string, possibly embedding values"))
|
||||
"Formats a string, possibly embedding values"))
|
||||
|
||||
("Images"
|
||||
(image? (any -> boolean)
|
||||
"to determine whether a value is an image")
|
||||
"Determines whether a value is an image")
|
||||
(image=? (image image -> boolean)
|
||||
"to determine whether two images are equal"))
|
||||
"Determines whether two images are equal"))
|
||||
|
||||
("Misc"
|
||||
(identity (any -> any)
|
||||
"to return the argument unchanged")
|
||||
((beginner-error error) (any ... -> void) "to signal an error, combining the given values into an error message.\n\nIf any of the values' printed representations is too long, it is truncated and ``...'' is put into the string. If the first value is a symbol, it is treated specially; it is suffixed with a colon and a space (the intention is that the symbol is the name of the function signalling the error).")
|
||||
"Returns the argument unchanged")
|
||||
((beginner-error error) (any ... -> void) "signals an error, combining the given values into an error message.\n\nIf any of the values' printed representations is too long, it is truncated and ``...'' is put into the string. If the first value is a symbol, it is treated specially; it is suffixed with a colon and a space (the intention is that the symbol is the name of the function signalling the error).")
|
||||
((beginner-struct? struct?) (any -> boolean)
|
||||
"to determine whether some value is a structure")
|
||||
"Determines whether some value is a structure")
|
||||
((beginner-equal? equal?) (any any -> boolean)
|
||||
"to determine whether two values are structurally equal"
|
||||
"Determines whether two values are structurally equal"
|
||||
" where basic values are compared with the eqv? predicate")
|
||||
(eq? (any any -> boolean)
|
||||
"to determine whether two values are equivalent from the"
|
||||
"Determines whether two values are equivalent from the"
|
||||
" computer's perspective (intensional)")
|
||||
(eqv? (any any -> boolean)
|
||||
"to determine whether two values are equivalent from the"
|
||||
"Determines whether two values are equivalent from the"
|
||||
" perspective of all functions that can be applied to it (extensional)")
|
||||
((beginner-=~ =~) (number number non-negative-real -> boolean)
|
||||
"to check whether two numbers are within some amount (the third argument) of either other")
|
||||
"Checks whether two numbers are within some amount (the third argument) of either other")
|
||||
((beginner-equal~? equal~?) (any any non-negative-real -> boolean)
|
||||
"to compare like equal? on the first two arguments, except using =~ in the case of numbers")
|
||||
"Compares like equal? on the first two arguments, except using =~ in the case of numbers")
|
||||
(eof eof
|
||||
"the end-of-file value")
|
||||
"The end-of-file value")
|
||||
(eof-object? (any -> boolean)
|
||||
"to determine whether some value is the end-of-file value")
|
||||
"Determines whether some value is the end-of-file value")
|
||||
((beginner-exit exit) ( -> void)
|
||||
"to exit the running program"))))
|
||||
"Exits the running program"))))
|
||||
|
|
|
@ -11,23 +11,23 @@
|
|||
|
||||
("Numbers (relaxed conditions)"
|
||||
|
||||
(+ (number ... -> number) "to add all given numbers")
|
||||
(* (number ... -> number) "to multiply all given numbers")
|
||||
(- (number ... -> number) "to subtract from the first all remaining numbers")
|
||||
(/ (number ... -> number) "to divide the first by all remaining numbers")
|
||||
(+ (number ... -> number) "Adds all given numbers")
|
||||
(* (number ... -> number) "Multiplys all given numbers")
|
||||
(- (number ... -> number) "Subtracts from the first all remaining numbers")
|
||||
(/ (number ... -> number) "Divides the first by all remaining numbers")
|
||||
)
|
||||
|
||||
("Lists"
|
||||
((intermediate-append append) ((listof any) ... -> (listof any))
|
||||
"to create a single list from several, by juxtaposition of the items"))
|
||||
"Creates a single list from several, by juxtaposition of the items"))
|
||||
|
||||
("Higher-Order Functions"
|
||||
(map ((X ... -> Z) (listof X) ... -> (listof Z))
|
||||
"to construct a new list by applying a function to each item on one or more existing lists")
|
||||
"Constructs a new list by applying a function to each item on one or more existing lists")
|
||||
(for-each ((any ... -> any) (listof any) ... -> void)
|
||||
"to apply a function to each item on one or more lists for effect only")
|
||||
"Applies a function to each item on one or more lists for effect only")
|
||||
((intermediate-filter filter) ((X -> boolean) (listof X) -> (listof X))
|
||||
"to construct a list from all those items on a list for which the predicate holds")
|
||||
"Constructs a list from all those items on a list for which the predicate holds")
|
||||
((intermediate-foldr foldr) ((X Y -> Y) Y (listof X) -> Y)
|
||||
"(foldr f base (list x-1 ... x-n)) = (f x-1 ... (f x-n base))")
|
||||
((intermediate-foldl foldl) ((X Y -> Y) Y (listof X) -> Y)
|
||||
|
@ -37,25 +37,25 @@
|
|||
((intermediate-build-string build-string) (nat (nat -> char) -> string)
|
||||
"(build-string n f) = (string (f 0) ... (f (- n 1)))")
|
||||
((intermediate-quicksort quicksort) ((listof X) (X X -> boolean) -> (listof X))
|
||||
"to construct a list from all items on a list in an order according to a predicate")
|
||||
"Constructs a list from all items on a list in an order according to a predicate")
|
||||
((intermediate-sort sort) ((listof X) (X X -> boolean) -> (listof X))
|
||||
"to construct a list from all items on a list in an order according to a predicate")
|
||||
"Constructs a list from all items on a list in an order according to a predicate")
|
||||
((intermediate-andmap andmap) ((X -> boolean) (listof X) -> boolean)
|
||||
"(andmap p (list x-1 ... x-n)) = (and (p x-1) ... (p x-n))")
|
||||
((intermediate-ormap ormap) ((X -> boolean) (listof X) -> boolean)
|
||||
"(ormap p (list x-1 ... x-n)) = (or (p x-1) ... (p x-n))")
|
||||
|
||||
(argmin ((X -> real) (listof X) -> X)
|
||||
"to find the (first) element of the list that minimizes the output of the function")
|
||||
"Finds the (first) element of the list that minimizes the output of the function")
|
||||
|
||||
(argmax ((X -> real) (listof X) -> X)
|
||||
"to find the (first) element of the list that maximizes the output of the function")
|
||||
"Finds the (first) element of the list that maximizes the output of the function")
|
||||
|
||||
(memf ((X -> any) (listof X) -> (union false (listof X)))
|
||||
"to determine whether the first argument produces a non-false value for any item in the second argument")
|
||||
"Determines whether the first argument produces a non-false value for any item in the second argument")
|
||||
(apply ((X-1 ... X-N -> Y) X-1 ... X-i (list X-i+1 ... X-N) -> Y)
|
||||
"to apply a function using items from a list as the arguments")
|
||||
"Applies a function using items from a list as the arguments")
|
||||
(compose ((Y-1 -> Z) ... (Y-N -> Y-N-1) (X-1 ... X-N -> Y-N) -> (X-1 ... X-N -> Z))
|
||||
"to compose a sequence of procedures into a single procedure")
|
||||
"Composes a sequence of procedures into a single procedure")
|
||||
(procedure? (any -> boolean)
|
||||
"to determine if a value is a procedure"))))
|
||||
"Determines if a value is a procedure"))))
|
||||
|
|
|
@ -2,102 +2,63 @@
|
|||
@(require "common.rkt" "std-grammar.rkt" "prim-ops.rkt"
|
||||
(for-label lang/htdp-advanced))
|
||||
|
||||
@(define-syntax-rule (bdl intm-define intm-lambda)
|
||||
(begin
|
||||
(require (for-label lang/htdp-intermediate-lambda))
|
||||
(define intm-define @racket[define])
|
||||
(define intm-lambda @racket[lambda])))
|
||||
@(bdl intm-define intm-lambda)
|
||||
|
||||
@(define-syntax-rule (bd intm-define-struct intm-local intm-letrec intm-let intm-let* intm-time)
|
||||
(begin
|
||||
(require (for-label lang/htdp-intermediate))
|
||||
(define intm-define @racket[define])
|
||||
(define intm-define-struct @racket[define-struct])
|
||||
(define intm-local @racket[local])
|
||||
(define intm-letrec @racket[letrec])
|
||||
(define intm-let @racket[let])
|
||||
(define intm-let* @racket[let*])
|
||||
(define intm-time @racket[time])))
|
||||
@(bd intm-define-struct intm-local intm-letrec intm-let intm-let* intm-time)
|
||||
|
||||
@(define-syntax-rule (bbd beg-define beg-define-struct beg-cond beg-if beg-and beg-or beg-check-expect beg-require)
|
||||
(begin
|
||||
(require (for-label lang/htdp-beginner))
|
||||
(define beg-define @racket[define])
|
||||
(define beg-define-struct @racket[define-struct])
|
||||
(define beg-cond @racket[cond])
|
||||
(define beg-if @racket[if])
|
||||
(define beg-and @racket[and])
|
||||
(define beg-or @racket[or])
|
||||
(define beg-check-expect @racket[check-expect])
|
||||
(define beg-require @racket[require])))
|
||||
@(bbd beg-define beg-define-struct beg-cond beg-if beg-and beg-or beg-check-expect beg-require)
|
||||
|
||||
|
||||
@title[#:style 'toc #:tag "advanced"]{Advanced Student}
|
||||
|
||||
@declare-exporting[lang/htdp-advanced]
|
||||
|
||||
@racketgrammar*+qq[
|
||||
#:literals (define define-struct define-datatype lambda λ cond else if and or empty true false require lib planet
|
||||
#:literals (define define-struct define-datatype lambda λ cond else if and or require lib planet
|
||||
local let let* letrec time begin begin0 set! delay shared recur when case match unless
|
||||
; match
|
||||
_ cons list list* struct vector box
|
||||
check-expect check-within check-error)
|
||||
(check-expect check-within check-error require)
|
||||
check-expect check-within check-member-of check-range check-error)
|
||||
(check-expect check-within check-error check-member-of check-range require)
|
||||
[program (code:line def-or-expr ...)]
|
||||
[def-or-expr definition
|
||||
expr
|
||||
expression
|
||||
test-case
|
||||
library-require]
|
||||
[definition (define (id id id ...) expr)
|
||||
(define id expr)
|
||||
(define-struct id (id ...))
|
||||
(define-datatype id (id id ...) ...)]
|
||||
[expr (begin expr expr ...)
|
||||
(begin0 expr expr ...)
|
||||
(set! id expr)
|
||||
(delay expr)
|
||||
(lambda (id ...) expr)
|
||||
(λ (id ...) expr)
|
||||
(local [definition ...] expr)
|
||||
(letrec ([id expr] ...) expr)
|
||||
(shared ([id expr] ...) expr)
|
||||
(let ([id expr] ...) expr)
|
||||
(let id ([id expr] ...) expr)
|
||||
(let* ([id expr] ...) expr)
|
||||
(recur id ([id expr] ...) expr)
|
||||
(code:line (expr expr ...) (code:comment @#,seclink["advanced-call"]{function call}))
|
||||
(cond [expr expr] ... [expr expr])
|
||||
(cond [expr expr] ... [else expr])
|
||||
(case expr [(choice choice ...) expr] ...
|
||||
[(choice choice ...) expr])
|
||||
(case expr [(choice choice ...) expr] ...
|
||||
[else expr])
|
||||
(match expr [pattern expr] ...)
|
||||
(if expr expr expr)
|
||||
(when expr expr)
|
||||
(unless expr expr)
|
||||
(and expr expr expr ...)
|
||||
(or expr expr expr ...)
|
||||
(time expr)
|
||||
empty
|
||||
(code:line id (code:comment @#,seclink["intermediate-id"]{identifier}))
|
||||
(code:line prim-op (code:comment @#,seclink["advanced-prim-ops"]{primitive operation}))
|
||||
(code:line @#,elem{@racketvalfont{'}@racket[_quoted]} (code:comment @#,seclink["beginner-abbr-quote"]{quoted value}))
|
||||
(code:line @#,elem{@racketvalfont{`}@racket[_quasiquoted]} (code:comment @#,seclink["beginner-abbr-quasiquote"]{quasiquote}))
|
||||
[definition (define (name variable ...) expression)
|
||||
(define name expression)
|
||||
(define-struct name (name ...))
|
||||
(define-datatype name (name name ...) ...)]
|
||||
[expression (begin expression expression ...)
|
||||
(begin0 expression expression ...)
|
||||
(set! variable expression)
|
||||
(delay expression)
|
||||
(lambda (variable ...) expression)
|
||||
(λ (variable ...) expression)
|
||||
(local [definition ...] expression)
|
||||
(letrec ([name expression] ...) expression)
|
||||
(shared ([name expression] ...) expression)
|
||||
(let ([name expression] ...) expression)
|
||||
(let name ([name expression] ...) expression)
|
||||
(let* ([name expression] ...) expression)
|
||||
(recur name ([name expression] ...) expression)
|
||||
(code:line (expression expression ...))
|
||||
(cond [expression expression] ... [expression expression])
|
||||
(cond [expression expression] ... [else expression])
|
||||
(case expression [(choice choice ...) expression] ...
|
||||
[(choice choice ...) expression])
|
||||
(case expression [(choice choice ...) expression] ...
|
||||
[else expression])
|
||||
(match expression [pattern expression] ...)
|
||||
(if expression expression expression)
|
||||
(when expression expression)
|
||||
(unless expression expression)
|
||||
(and expression expression expression ...)
|
||||
(or expression expression expression ...)
|
||||
(time expression)
|
||||
(code:line name)
|
||||
(code:line @#,elem{@racketvalfont{'}@racket[_quoted]})
|
||||
(code:line @#,elem{@racketvalfont{`}@racket[_quasiquoted]})
|
||||
number
|
||||
true
|
||||
|
||||
false
|
||||
string
|
||||
character]
|
||||
[choice (code:line id (code:comment @#,t{treated as a symbol}))
|
||||
[choice (code:line name)
|
||||
number]
|
||||
[pattern _
|
||||
empty
|
||||
id
|
||||
name
|
||||
number
|
||||
true
|
||||
false
|
||||
|
@ -111,7 +72,7 @@
|
|||
(struct id (pattern ...))
|
||||
(vector pattern ...)
|
||||
(box pattern)]
|
||||
[quasiquoted-pattern id
|
||||
[quasiquoted-pattern name
|
||||
number
|
||||
string
|
||||
character
|
||||
|
@ -122,310 +83,239 @@
|
|||
@#,elem{@racketfont[",@"]@racket[_pattern]}]
|
||||
]
|
||||
|
||||
@|prim-nonterms|
|
||||
|
||||
@prim-ops['(lib "htdp-advanced.rkt" "lang") #'here]
|
||||
@prim-nonterms[("advanced") define define-struct]
|
||||
|
||||
@prim-variables[("advanced") empty true false]
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
@section[#:tag "advanced-syntax"]{Syntax for Advanced}
|
||||
|
||||
@section[#:tag "advanced-define"]{@racket[define]}
|
||||
In Advanced, @racket[define] and @racket[lambda] can define functions of zero
|
||||
arguments, and (naturally) function calls can invoke functions of zero arguments.
|
||||
|
||||
@deftogether[(
|
||||
@defform[(define (id id ...) expr)]
|
||||
@defform/none[#:literals (define)
|
||||
(define id expr)]
|
||||
)]{
|
||||
|
||||
The same as Intermediate with Lambda's @|intm-define|, except that a
|
||||
function is allowed to accept zero arguments.}
|
||||
@defform[(lambda (variable ...) expression)]{
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
Creates a function that takes as many arguments as given @racket[variables]s,
|
||||
and whose body is @racket[expression].}
|
||||
|
||||
@section[#:tag "advanced-define-struct"]{@racket[define-struct]}
|
||||
@defform[(λ (variable ...) expression)]{
|
||||
|
||||
@defform[(define-struct structid (fieldid ...))]{
|
||||
The Greek letter @racket[λ] is a synonym for @racket[lambda].}
|
||||
|
||||
The same as Intermediate's @|intm-define-struct|, but defines an
|
||||
additional set of operations:
|
||||
|
||||
|
||||
@defform/none[(expression expression ...)]{
|
||||
|
||||
Calls the function that results from evaluating the first
|
||||
@racket[expression]. The value of the call is the value of function's body when
|
||||
every instance of @racket[name]'s variables are replaced by the values of the
|
||||
corresponding @racket[expression]s.
|
||||
|
||||
The function being called must come from either a definition appearing before the
|
||||
function call, or from a @racket[lambda] expression. The number of argument
|
||||
@racket[expression]s must be the same as the number of arguments expected by
|
||||
the function.}
|
||||
|
||||
|
||||
|
||||
In Advanced, @racket[define-struct] introduces one additional function:
|
||||
|
||||
@itemize[
|
||||
|
||||
@item{@racketidfont{set-}@racket[structid]@racketidfont{-}@racket[fieldid]@racketidfont{!}
|
||||
@item{@racketidfont{set-}@racket[structure-name]@racketidfont{-}@racket[field-name]@racketidfont{!}
|
||||
: takes an instance of the structure and a value, and changes
|
||||
the instance's field to the given value.}
|
||||
|
||||
]}
|
||||
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
@section[#:tag "advanced-define-datatype"]{@racket[define-datatype]}
|
||||
|
||||
@defform[(define-datatype datatypeid [variantid fieldid ...] ...)]{
|
||||
@defform[(define-datatype dataype-name [variant-name field-name ...] ...)]{
|
||||
|
||||
A short-hand for defining a group of related structures. The following @racket[define-datatype]:
|
||||
|
||||
A short-hand for defining a group of related structures. A @racket[define-datatype] form
|
||||
@racketblock[
|
||||
(define-datatype datatypeid
|
||||
[variantid fieldid (unsyntax @racketidfont{...})]
|
||||
(define-datatype datatype-name
|
||||
[variant-name field-name (unsyntax @racketidfont{...})]
|
||||
(unsyntax @racketidfont{...}))
|
||||
]
|
||||
is equivalent to
|
||||
is equivalent to:
|
||||
@racketblock[
|
||||
(define ((unsyntax @racket[datatypeid])? x)
|
||||
(or ((unsyntax @racket[variantid])? x) (unsyntax @racketidfont{...})))
|
||||
(define-struct variantid (fieldid (unsyntax @racketidfont{...})))
|
||||
(define ((unsyntax @racket[datatype-name])? x)
|
||||
(or ((unsyntax @racket[variant-name])? x) (unsyntax @racketidfont{...})))
|
||||
(define-struct variant-name (field-name (unsyntax @racketidfont{...})))
|
||||
(unsyntax @racketidfont{...})
|
||||
]}
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
@section[#:tag "advanced-lambda"]{@racket[lambda]}
|
||||
|
||||
@deftogether[(
|
||||
@defform[(lambda (id ...) expr)]
|
||||
@defform[(λ (id ...) expr)]
|
||||
)]{
|
||||
@defform[(begin expression expression ...)]{
|
||||
|
||||
The same as Intermediate with Lambda's @|intm-lambda|, except that a
|
||||
function is allowed to accept zero arguments.}
|
||||
Evaluates the @racket[expression]s in order from left to right. The value of
|
||||
the @racket[begin] expression is the value of the last @racket[expression].}
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
@section[#:tag "advanced-call"]{Function Calls}
|
||||
|
||||
@defform/none[(expr expr ...)]{
|
||||
@defform[(begin0 expression expression ...)]{
|
||||
|
||||
A function call in Advanced is the same as an Intermediate with Lambda
|
||||
@seclink["intermediate-lambda-call"]{function call}, except that zero
|
||||
arguments are allowed.}
|
||||
Evaluates the @racket[expression]s in order from left to right. The value of
|
||||
the @racket[begin] expression is the value of the first @racket[expression].}
|
||||
|
||||
@defform[(#%app expr expr ...)]{
|
||||
|
||||
A function call can be written with @racket[#%app], though it's
|
||||
practically never written that way.}
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
@defform[(set! variable expression)]{
|
||||
|
||||
@section{@racket[begin]}
|
||||
Evaluates @racket[expression], and then changes the definition @racket[variable]
|
||||
to have @racket[expression]'s value. The @racket[variable] must be defined or
|
||||
bound by @racket[define], @racket[letrec], @racket[let*], or @racket[let].}
|
||||
|
||||
@defform[(begin expr expr ...)]{
|
||||
|
||||
Evaluates the @racket[expr]s in order from left to right. The value of
|
||||
the @racket[begin] expression is the value of the last @racket[expr].}
|
||||
@defform[(delay expression)]{
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
Produces a ``promise'' to evaluate @racket[expression]. The @racket[expression]
|
||||
is not evaluated until the promise is forced with @racket[force]; when
|
||||
the promise is forced, the result is recorded, so that any further
|
||||
@racket[force] of the promise immediately produces the remembered value.}
|
||||
|
||||
@section{@racket[begin0]}
|
||||
|
||||
@defform[(begin0 expr expr ...)]{
|
||||
|
||||
Evaluates the @racket[expr]s in order from left to right. The value of
|
||||
the @racket[begin] expression is the value of the first @racket[expr].}
|
||||
@defform[(shared ([name expression] ...) expression)]{
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
@section{@racket[set!]}
|
||||
|
||||
@defform[(set! id expr)]{
|
||||
|
||||
Evaluates @racket[expr], and then changes the definition @racket[id]
|
||||
to have @racket[expr]'s value. The @racket[id] must be defined or
|
||||
bound by @racket[letrec], @racket[let], or @racket[let*].}
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
@section{@racket[delay]}
|
||||
|
||||
@defform[(delay expr)]{
|
||||
|
||||
Produces a ``promise'' to evaluate @racket[expr]. The @racket[expr] is
|
||||
not evaluated until the promise is forced through the @racket[force]
|
||||
operator; when the promise is forced, the result is recorded, so that
|
||||
any further @racket[force] of the promise always produces the
|
||||
remembered value.}
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
@section{@racket[shared]}
|
||||
|
||||
@defform[(shared ([id expr] ...) expr)]{
|
||||
|
||||
Like @racket[letrec], but when an @racket[expr] next to an @racket[id]
|
||||
Like @racket[letrec], but when an @racket[expression] next to an @racket[id]
|
||||
is a @racket[cons], @racket[list], @racket[vector], quasiquoted
|
||||
expression, or @racketidfont{make-}@racket[_structid] from a
|
||||
@racket[define-struct], the @racket[expr] can refer directly to any
|
||||
@racket[id], not just @racket[id]s defined earlier. Thus,
|
||||
expression, or @racketidfont{make-}@racket[_struct-name] from a
|
||||
@racket[define-struct], the @racket[expression] can refer directly to any
|
||||
@racket[name], not just @racket[name]s defined earlier. Thus,
|
||||
@racket[shared] can be used to create cyclic data structures.}
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
@section[#:tag "advanced-let"]{@racket[let]}
|
||||
|
||||
@defform*[[(let ([id expr] ...) expr)
|
||||
(let id ([id expr] ...) expr)]]{
|
||||
|
||||
The first form of @racket[let] is the same as Intermediate's
|
||||
@|intm-let|.
|
||||
|
||||
The second form is equivalent to a @racket[recur] form.}
|
||||
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
@section{@racket[recur]}
|
||||
|
||||
@defform[(recur id ([id expr] ...) expr)]{
|
||||
@defform[(recur name ([name expression] ...) expression)]{
|
||||
|
||||
A short-hand recursion construct. The first @racket[id] corresponds to
|
||||
the name of the recursive function. The parenthesized @racket[id]s are
|
||||
the function's arguments, and each corresponding @racket[expr] is a
|
||||
A short-hand syntax for recursive loops. The first @racket[name] corresponds to
|
||||
the name of the recursive function. The @racket[name]s in the parenthesis are
|
||||
the function's arguments, and each corresponding @racket[expression] is a
|
||||
value supplied for that argument in an initial starting call of the
|
||||
function. The last @racket[expr] is the body of the function.
|
||||
function. The last @racket[expression] is the body of the function.
|
||||
|
||||
More precisely, a @racket[recur] form
|
||||
More precisely, the following @racket[recur]:
|
||||
|
||||
@racketblock[
|
||||
(recur func-id ([arg-id arg-expr] (unsyntax @racketidfont{...}))
|
||||
body-expr)
|
||||
(recur func-name ([arg-name arg-expression] (unsyntax @racketidfont{...}))
|
||||
body-expression)
|
||||
]
|
||||
|
||||
is equivalent to
|
||||
is equivalent to:
|
||||
|
||||
@racketblock[
|
||||
((local [(define (func-id arg-id (unsyntax @racketidfont{...}))
|
||||
body-expr)]
|
||||
func-id)
|
||||
arg-expr (unsyntax @racketidfont{...}))
|
||||
(local [(define (func-name arg-name (unsyntax @racketidfont{...})) body-expression)]
|
||||
(func-name arg-expression (unsyntax @racketidfont{...})))
|
||||
]}
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
@section{@racket[case]}
|
||||
@defform/none[(let name ([name expression] ...) expression)]{
|
||||
|
||||
@defform[(case expr [(choice ...) expr] ... [(choice ...) expr])]{
|
||||
An alternate syntax for @racket[recur].}
|
||||
|
||||
A @racket[case] form contains one or more ``lines'' that are
|
||||
surrounded by parentheses or square brackets. Each line contains a
|
||||
sequence of choices---numbers and names for symbols---and an answer
|
||||
@racket[expr]. The initial @racket[expr] is evaluated, and the
|
||||
resulting value is compared to the choices in each line, where the
|
||||
lines are considered in order. The first line that contains a matching
|
||||
choice provides an answer @racket[expr] whose value is the result of
|
||||
the whole @racket[case] expression. If none of the lines contains a
|
||||
matching choice, it is an error.}
|
||||
|
||||
@defform/none[#:literals (case else)
|
||||
(case expr [(choice ...) expr] ... [else expr])]{
|
||||
|
||||
This form of @racket[case] is similar to the prior one, except that
|
||||
the final @racket[else] clause is always taken if no prior line
|
||||
contains a choice matching the value of the initial @racket[expr]. In
|
||||
other words, so there is no possibility to ``fall off the end'' of
|
||||
the @racket[case] form.}
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
@section{@racket[match]}
|
||||
|
||||
@defform[(match expr [pattern expr] ...)]{
|
||||
@defform[(case expression [(choice ...) expression] ... [(choice ...) expression])]{
|
||||
|
||||
A @racket[match] form contains one or more ``lines'' that are
|
||||
surrounded by parentheses or square brackets. Each line contains a
|
||||
pattern---a description of a value---and an answer @racket[expr].
|
||||
The initial @racket[expr] is evaluated, and the resulting value
|
||||
is matched against the pattern in each line, where the lines are
|
||||
considered in order. The first line that contains a matching pattern
|
||||
provides an answer @racket[expr] whose value is the result of the
|
||||
whole @racket[match] expression. This @racket[expr] may reference
|
||||
identifiers bound in the matching pattern. If none of the lines
|
||||
contains a matching pattern, it is an error.}
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
@section{@racket[when] and @racket[unless]}
|
||||
|
||||
@defform[(when expr expr)]{
|
||||
|
||||
The first @racket[expr] (known as the ``test'' expression) is
|
||||
evaluated. If it evaluates to @racket[true], the result of the
|
||||
@racket[when] expression is the result of evaluating the second
|
||||
@racket[expr], otherwise the result is @racket[(void)] and the second
|
||||
@racket[expr] is not evaluated. If the result of evaluating the test
|
||||
@racket[expr] is neither @racket[true] nor @racket[false], it is an
|
||||
A @racket[case] form contains one or more clauses. Each clause contains a
|
||||
choices (in parentheses)---either numbers or names---and an answer
|
||||
@racket[expression]. The initial @racket[expression] is evaluated, and its
|
||||
value is compared to the choices in each clause, where the lines are considered
|
||||
in order. The first line that contains a matching choice provides an answer
|
||||
@racket[expression] whose value is the result of the whole @racket[case]
|
||||
expression. Numbers match with the numbers in the choices, and symbols match
|
||||
with the names. If none of the lines contains a matching choice, it is an
|
||||
error.}
|
||||
|
||||
@defform[(unless expr expr)]{
|
||||
@defform/none[#:literals (case else)
|
||||
(case expression [(choice ...) expression] ... [else expression])]{
|
||||
|
||||
Like @racket[when], but the second @racket[expr] is evaluated when the
|
||||
first @racket[expr] produces @racket[false] instead of @racket[true].}
|
||||
This form of @racket[case] is similar to the prior one, except that the final
|
||||
@racket[else] clause is taken if no clause contains a choice matching the value
|
||||
of the initial @racket[expression].}
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
|
||||
@defform[(match expression [pattern expression] ...)]{
|
||||
|
||||
A @racket[match] form contains one or more clauses that are surrounded by
|
||||
square brackets. Each clause contains a pattern---a description of a value---and
|
||||
an answer @racket[expression]. The initial @racket[expression] is evaluated,
|
||||
and its value is matched against the pattern in each clause, where the clauses are
|
||||
considered in order. The first clause that contains a matching pattern provides
|
||||
an answer @racket[expression] whose value is the result of the whole
|
||||
@racket[match] expression. This @racket[expression] may reference identifiers
|
||||
bound in the matching pattern. If none of the clauses contains a matching
|
||||
pattern, it is an error.}
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
|
||||
@defform[(when test-expression body-expression)]{
|
||||
|
||||
If @racket[test-expression] evaluates to @racket[true], the result of the
|
||||
@racket[when] expression is the result of evaluating the
|
||||
@racket[body-expression], otherwise the result is @racket[(void)] and the
|
||||
@racket[body-expression] is not evaluated. If the result of evaluating the
|
||||
@racket[test-expression] is neither @racket[true] nor @racket[false], it is an
|
||||
error.}
|
||||
|
||||
@defform[(unless test-expression body-expression)]{
|
||||
|
||||
Like @racket[when], but the @racket[body-expression] is evaluated when the
|
||||
@racket[test-expression] produces @racket[false] instead of @racket[true].}
|
||||
|
||||
|
||||
@section[#:tag "advanced-common-syntax"]{Common Syntax}
|
||||
|
||||
|
||||
@(intermediate-forms lambda
|
||||
quote
|
||||
quasiquote
|
||||
unquote
|
||||
unquote-splicing
|
||||
local
|
||||
letrec
|
||||
let*
|
||||
let
|
||||
time)
|
||||
|
||||
|
||||
@(define-forms/normal define)
|
||||
|
||||
@(prim-forms ("advanced")
|
||||
define
|
||||
lambda
|
||||
define-struct
|
||||
define-wish
|
||||
cond
|
||||
else
|
||||
if
|
||||
and
|
||||
or
|
||||
check-expect
|
||||
check-within
|
||||
check-error
|
||||
check-member-of
|
||||
check-range
|
||||
require)
|
||||
|
||||
@; ----------------------------------------
|
||||
|
||||
@section[#:tag "advanced-prim-ops"]{Primitive Operations}
|
||||
@section[#:tag "advanced-pre-defined"]{Pre-Defined Functions}
|
||||
|
||||
@prim-op-defns['(lib "htdp-advanced.rkt" "lang") #'here '()]
|
||||
@prim-op-defns['(lib "htdp-advanced.ss" "lang") #'here '()]
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
@section[#:tag "advanced-unchanged"]{Unchanged Forms}
|
||||
|
||||
@deftogether[(
|
||||
@defform[(local [definition ...] expr)]
|
||||
@defform[(letrec ([id expr-for-let] ...) expr)]
|
||||
@defform[(let* ([id expr-for-let] ...) expr)]
|
||||
)]{
|
||||
|
||||
The same as Intermediate's @|intm-local|, @|intm-letrec|, and
|
||||
@|intm-let*|.}
|
||||
|
||||
|
||||
@deftogether[(
|
||||
@defform[(cond [expr expr] ... [expr expr])]
|
||||
@defidform[else]
|
||||
)]{
|
||||
|
||||
The same as Beginning's @|beg-cond|, except that @racket[else] can be
|
||||
used with @racket[case].}
|
||||
|
||||
|
||||
|
||||
@defform[(if expr expr expr)]{
|
||||
|
||||
The same as Beginning's @|beg-if|.}
|
||||
|
||||
@deftogether[(
|
||||
@defform[(and expr expr expr ...)]
|
||||
@defform[(or expr expr expr ...)]
|
||||
)]{
|
||||
|
||||
The same as Beginning's @|beg-and| and @|beg-or|.}
|
||||
|
||||
|
||||
@defform[(time expr)]{
|
||||
|
||||
The same as Intermediate's @|intm-time|.}
|
||||
|
||||
|
||||
@deftogether[(
|
||||
@defform[(check-expect expr expr)]
|
||||
@defform[(check-within expr expr expr)]
|
||||
@defform*[[(check-error expr expr)
|
||||
(check-error expr)]]
|
||||
@defform[(check-member-of expr expr expr ...)]
|
||||
@defform[(check-range expr expr expr)]
|
||||
)]{
|
||||
|
||||
The same as Beginning's @|beg-check-expect|, etc.}
|
||||
|
||||
|
||||
|
||||
@deftogether[(
|
||||
@defthing[empty empty?]
|
||||
@defthing[true boolean?]
|
||||
@defthing[false boolean?]
|
||||
)]{
|
||||
|
||||
Constants for the empty list, true, and false.}
|
||||
|
||||
@defform[(require module-path)]{
|
||||
|
||||
The same as Beginning's @|beg-require|.}
|
||||
|
|
|
@ -2,18 +2,6 @@
|
|||
@(require "common.rkt" "std-grammar.rkt" "prim-ops.rkt"
|
||||
(for-label lang/htdp-beginner-abbr))
|
||||
|
||||
@(define-syntax-rule (bd beg-define beg-define-struct beg-cond beg-if beg-and beg-or beg-check-expect beg-require)
|
||||
(begin
|
||||
(require (for-label lang/htdp-beginner))
|
||||
(define beg-define @racket[define])
|
||||
(define beg-define-struct @racket[define-struct])
|
||||
(define beg-cond @racket[cond])
|
||||
(define beg-if @racket[if])
|
||||
(define beg-and @racket[and])
|
||||
(define beg-or @racket[or])
|
||||
(define beg-check-expect @racket[check-expect])
|
||||
(define beg-require @racket[require])))
|
||||
@(bd beg-define beg-define-struct beg-cond beg-if beg-and beg-or beg-check-expect beg-require)
|
||||
|
||||
|
||||
@title[#:style 'toc #:tag "beginner-abbr"]{Beginning Student with List Abbreviations}
|
||||
|
@ -21,96 +9,94 @@
|
|||
@declare-exporting[lang/htdp-beginner-abbr]
|
||||
|
||||
@racketgrammar*+qq[
|
||||
#:literals (define define-struct lambda cond else if and or empty true false require lib planet
|
||||
#:literals (define define-struct lambda cond else if and or require lib planet
|
||||
check-expect check-within check-error)
|
||||
(check-expect check-within check-error require)
|
||||
(check-expect check-within check-member-of check-range check-error require)
|
||||
[program (code:line def-or-expr ...)]
|
||||
[def-or-expr definition
|
||||
expr
|
||||
expression
|
||||
test-case
|
||||
library-require]
|
||||
[definition (define (id id id ...) expr)
|
||||
(define id expr)
|
||||
(define id (lambda (id id ...) expr))
|
||||
(define-struct id (id ...))]
|
||||
[expr (code:line (id expr expr ...) (code:comment @#,seclink["beginner-call"]{function call}))
|
||||
(code:line (prim-op expr ...) (code:comment @#,seclink["beginner-prim-call"]{primitive operation call}))
|
||||
(cond [expr expr] ... [expr expr])
|
||||
(cond [expr expr] ... [else expr])
|
||||
(if expr expr expr)
|
||||
(and expr expr expr ...)
|
||||
(or expr expr expr ...)
|
||||
empty
|
||||
id
|
||||
(code:line @#,elem{@racketvalfont{'}@racket[_quoted]} (code:comment @#,seclink["beginner-abbr-quote"]{quoted value}))
|
||||
(code:line @#,elem{@racketvalfont{`}@racket[_quasiquoted]} (code:comment @#,seclink["beginner-abbr-quasiquote"]{quasiquote}))
|
||||
[definition (define (name variable variable ...) expression)
|
||||
(define name expression)
|
||||
(define name (lambda (variable variable ...) expression))
|
||||
(define-struct name (name ...))]
|
||||
[expression (code:line (name expression expression ...))
|
||||
(code:line (prim-op expression ...))
|
||||
(cond [expression expression] ... [expression expression])
|
||||
(cond [expression expression] ... [else expression])
|
||||
(if expression expression expression)
|
||||
(and expression expression expression ...)
|
||||
(or expression expression expression ...)
|
||||
name
|
||||
(code:line @#,elem{@racketvalfont{'}@racket[_quoted]})
|
||||
(code:line @#,elem{@racketvalfont{`}@racket[_quasiquoted]})
|
||||
number
|
||||
true
|
||||
false
|
||||
string
|
||||
character]
|
||||
]
|
||||
|
||||
@|prim-nonterms|
|
||||
@prim-nonterms[("beginner-abbr") define define-struct]
|
||||
|
||||
@prim-ops['(lib "htdp-beginner-abbr.rkt" "lang") #'here]
|
||||
@prim-variables[("beginner-abbr") empty true false]
|
||||
|
||||
@; ----------------------------------------
|
||||
|
||||
@section[#:tag "beginner-abbr-quote"]{Quote}
|
||||
@section[#:tag "beginner-abbr-syntax"]{Syntax for Abbreviations}
|
||||
|
||||
|
||||
@deftogether[(
|
||||
@defform/none[(unsyntax @elem{@racketvalfont{'}@racket[quoted]})]
|
||||
@defform[(quote quoted)]
|
||||
@defform/none[(unsyntax @elem{@racketvalfont{'}@racket[name]})]
|
||||
@defform/none[(unsyntax @elem{@racketvalfont{'}@racket[part]})]
|
||||
@defform[(quote name)]
|
||||
@defform/none[(quote part)]
|
||||
)]{
|
||||
|
||||
Creates symbols and abbreviates nested lists.
|
||||
A quoted name is a symbol. A quote part is an abbreviation for a nested lists.
|
||||
|
||||
Normally, this form is written with a @litchar{'}, like
|
||||
Normally, this quotation is written with a @litchar{'}, like
|
||||
@racket['(apple banana)], but it can also be written with @racket[quote], like
|
||||
@racket[(@#,racket[quote] (apple banana))].}
|
||||
|
||||
@; ----------------------------------------
|
||||
|
||||
@section[#:tag "beginner-abbr-quasiquote"]{Quasiquote}
|
||||
|
||||
@deftogether[(
|
||||
@defform/none[(unsyntax @elem{@racketvalfont{`}@racket[quasiquoted]})]
|
||||
@defform[(quasiquote quasiquoted)]
|
||||
@defform/none[(unsyntax @elem{@racketvalfont{`}@racket[name]})]
|
||||
@defform/none[(unsyntax @elem{@racketvalfont{`}@racket[part]})]
|
||||
@defform[(quasiquote name)]
|
||||
@defform/none[(quasiquote part)]
|
||||
)]{
|
||||
|
||||
Creates symbols and abbreviates nested lists, but also allows escaping
|
||||
to expression ``unquotes.''
|
||||
Like @racket[quote], but also allows escaping to expression ``unquotes.''
|
||||
|
||||
Normally, this form is written with a backquote, @litchar{`}, like
|
||||
@racket[`(apple ,(+ 1 2))], but it can also be written with
|
||||
Normally, quasi-quotations are written with a backquote, @litchar{`}, like
|
||||
@racket[`(apple ,(+ 1 2))], but they can also be written with
|
||||
@racket[quasiquote], like
|
||||
@racket[(@#,racket[quasiquote] (apple ,(+ 1 2)))].}
|
||||
|
||||
|
||||
@deftogether[(
|
||||
@defform/none[(unsyntax @elem{@racketvalfont{,}@racket[quasiquoted]})]
|
||||
@defform[(unquote expr)]
|
||||
@defform/none[(unsyntax @elem{@racketvalfont{,}@racket[expression]})]
|
||||
@defform[(unquote expression)]
|
||||
)]{
|
||||
|
||||
Under a single quasiquote, @racketfont{,}@racket[expr] escapes from
|
||||
the quote to include an evaluated expression whose result is inserted
|
||||
Under a single quasiquote, @racketfont{,}@racket[expression] escapes from
|
||||
the quote to include an evaluated expression whose value is inserted
|
||||
into the abbreviated list.
|
||||
|
||||
Under multiple quasiquotes, @racketfont{,}@racket[expr] is really
|
||||
@racketfont{,}@racket[quasiquoted], decrementing the quasiquote count
|
||||
by one for @racket[quasiquoted].
|
||||
Under multiple quasiquotes, @racketfont{,}@racket[expression] is really
|
||||
the literal @racketfont{,}@racket[expression], decrementing the quasiquote count
|
||||
by one for @racket[expression].
|
||||
|
||||
Normally, an unquote is written with @litchar{,}, but it can also be
|
||||
written with @racket[unquote].}
|
||||
|
||||
|
||||
@deftogether[(
|
||||
@defform/none[(unsyntax @elem{@racketvalfont[",@"]@racket[quasiquoted]})]
|
||||
@defform[(unquote-splicing expr)]
|
||||
@defform/none[(unsyntax @elem{@racketvalfont[",@"]@racket[expression]})]
|
||||
@defform[(unquote-splicing expression)]
|
||||
)]{
|
||||
|
||||
Under a single quasiquote, @racketfont[",@"]@racket[expr] escapes from
|
||||
Under a single quasiquote, @racketfont[",@"]@racket[expression] escapes from
|
||||
the quote to include an evaluated expression whose result is a list to
|
||||
splice into the abbreviated list.
|
||||
|
||||
|
@ -121,70 +107,34 @@ Normally, a splicing unquote is written with @litchar{,}, but it can
|
|||
also be written with @racket[unquote-splicing].}
|
||||
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
@section[#:tag "beginner-abbr-common-syntax"]{Common Syntax}
|
||||
|
||||
@(define-forms/normal define)
|
||||
@(define-form/explicit-lambda define lambda)
|
||||
|
||||
|
||||
@prim-forms[("beginner-abbr")
|
||||
define
|
||||
lambda
|
||||
define-struct
|
||||
define-wish
|
||||
cond
|
||||
else
|
||||
if
|
||||
and
|
||||
or
|
||||
check-expect
|
||||
check-within
|
||||
check-error
|
||||
check-member-of
|
||||
check-range
|
||||
require]
|
||||
|
||||
|
||||
@; ----------------------------------------
|
||||
|
||||
@section[#:tag "beginner-abbr-prim-ops"]{Primitive Operations}
|
||||
@section[#:tag "beginner-abbr-pre-defined"]{Pre-defined Functions}
|
||||
|
||||
@prim-op-defns['(lib "htdp-beginner-abbr.rkt" "lang") #'here '()]
|
||||
@prim-op-defns['(lib "htdp-beginner-abbr.ss" "lang") #'here '()]
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
@section{Unchanged Forms}
|
||||
|
||||
@deftogether[(
|
||||
@defform[(define (id id id ...) expr)]
|
||||
@defform/none[#:literals (define)
|
||||
(define id expr)]
|
||||
@defform/none[#:literals (define lambda)
|
||||
(define id (lambda (id id ...) expr))]
|
||||
@defidform[lambda]
|
||||
)]{
|
||||
|
||||
The same as Beginning's @|beg-define|.}
|
||||
|
||||
|
||||
@defform[(define-struct structid (fieldid ...))]{
|
||||
|
||||
The same as Beginning's @|beg-define-struct|.}
|
||||
|
||||
|
||||
@deftogether[(
|
||||
@defform[(cond [expr expr] ... [expr expr])]
|
||||
@defidform[else]
|
||||
)]{
|
||||
|
||||
The same as Beginning's @|beg-cond|.}
|
||||
|
||||
@defform[(if expr expr expr)]{
|
||||
|
||||
The same as Beginning's @|beg-if|.}
|
||||
|
||||
@deftogether[(
|
||||
@defform[(and expr expr expr ...)]
|
||||
@defform[(or expr expr expr ...)]
|
||||
)]{
|
||||
|
||||
The same as Beginning's @|beg-and| and @|beg-or|.}
|
||||
|
||||
@deftogether[(
|
||||
@defform[(check-expect expr expr)]
|
||||
@defform[(check-within expr expr expr)]
|
||||
@defform*[[(check-error expr expr)
|
||||
(check-error expr)]]
|
||||
@defform[(check-member-of expr expr expr ...)]
|
||||
@defform[(check-range expr expr expr)]
|
||||
)]{
|
||||
|
||||
The same as Beginning's @|beg-check-expect|, etc.}
|
||||
|
||||
@deftogether[(
|
||||
@defthing[empty empty?]
|
||||
@defthing[true boolean?]
|
||||
@defthing[false boolean?]
|
||||
)]{
|
||||
|
||||
Constants for the empty list, true, and false.}
|
||||
|
||||
@defform[(require module-path)]{
|
||||
|
||||
The same as Beginning's @|beg-require|.}
|
||||
|
|
|
@ -8,373 +8,65 @@
|
|||
@declare-exporting[lang/htdp-beginner #:use-sources (lang/htdp-beginner lang/private/teachprims)]
|
||||
|
||||
@racketgrammar*+library[
|
||||
#:literals (define define-struct lambda cond else if and or empty true false require lib planet
|
||||
#:literals (define define-struct lambda cond else if and or require lib planet
|
||||
check-expect check-within check-error)
|
||||
(check-expect check-within check-error require)
|
||||
(check-expect check-within check-member-of check-range check-error require)
|
||||
[program (code:line def-or-expr ...)]
|
||||
[def-or-expr definition
|
||||
expr
|
||||
expression
|
||||
test-case
|
||||
library-require]
|
||||
[definition (define (id id id ...) expr)
|
||||
(define id expr)
|
||||
(define id (lambda (id id ...) expr))
|
||||
(define-struct id (id ...))]
|
||||
[expr (code:line (id expr expr ...) (code:comment @#,seclink["beginner-call"]{function call}))
|
||||
(code:line (prim-op expr ...) (code:comment @#,seclink["beginner-prim-call"]{primitive operation call}))
|
||||
(cond [expr expr] ... [expr expr])
|
||||
(cond [expr expr] ... [else expr])
|
||||
(if expr expr expr)
|
||||
(and expr expr expr ...)
|
||||
(or expr expr expr ...)
|
||||
empty
|
||||
id
|
||||
(code:line id (code:comment @#,seclink["beginner-id"]{identifier}))
|
||||
(code:line @#,elem{@racketvalfont{'}@racket[id]} (code:comment @#,seclink["beginner-quote"]{symbol}))
|
||||
[definition (define (name variable variable ...) expression)
|
||||
(define name expression)
|
||||
(define name (lambda (variable variable ...) expression))
|
||||
(define-struct name (name ...))]
|
||||
[expression (code:line (name expression expression ...))
|
||||
(cond [expression expression] ... [expression expression])
|
||||
(cond [expression expression] ... [else expression])
|
||||
(if expression expression expression)
|
||||
(and expression expression expression ...)
|
||||
(or expression expression expression ...)
|
||||
name
|
||||
(code:line @#,elem{@racketvalfont{'}@racket[name]})
|
||||
number
|
||||
true
|
||||
false
|
||||
string
|
||||
character]
|
||||
]
|
||||
|
||||
@|prim-nonterms|
|
||||
@prim-nonterms[("beginner") define define-struct]
|
||||
|
||||
@prim-ops['(lib "htdp-beginner.rkt" "lang") #'here]
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
@section{@racket[define]}
|
||||
|
||||
@defform[(define (id id id ...) expr)]{
|
||||
|
||||
Defines a function. The first @racket[id] inside the parentheses is
|
||||
the name of the function. All remaining @racket[id]s are the names of
|
||||
the function's arguments. The @racket[expr] is the body of the
|
||||
function, evaluated whenever the function is called. The name of the
|
||||
function cannot be that of a primitive or another definition.}
|
||||
|
||||
@defform/none[#:literals (define)
|
||||
(define id expr)]{
|
||||
|
||||
Defines a constant @racket[id] as a synonym for the value produced by
|
||||
@racket[expr]. The defined name cannot be that of a primitive or
|
||||
another definition, and @racket[id] itself must not appear in
|
||||
@racket[expr].}
|
||||
|
||||
|
||||
@defform/none[#:literals (define lambda)
|
||||
(define id (lambda (id id ...) expr))]{
|
||||
|
||||
An alternate form for defining functions. The first @racket[id] is the
|
||||
name of the function. The @racket[id]s in parentheses are the names of
|
||||
the function's arguments, and the @racket[expr] is the body of the
|
||||
function, which evaluated whenever the function is called. The name
|
||||
of the function cannot be that of a primitive or another definition.}
|
||||
|
||||
@defidform[lambda]{
|
||||
|
||||
The @racket[lambda] keyword can only be used with @racket[define] in
|
||||
the alternative function-definition syntax.}
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
@section{@racket[define-struct]}
|
||||
|
||||
@defform[(define-struct structid (fieldid ...))]{
|
||||
|
||||
Define a new type of structure. The structure's fields are named by
|
||||
the @racket[fieldid]s in parentheses. After evaluation of a
|
||||
define-struct form, a set of new primitives is available for creation,
|
||||
extraction, and type-like queries:
|
||||
|
||||
@itemize[
|
||||
|
||||
@item{@racketidfont{make-}@racket[structid] : takes a number of
|
||||
arguments equal to the number of fields in the structure type,
|
||||
and creates a new instance of the structure type.}
|
||||
|
||||
@item{@racket[structid]@racketidfont{-}@racket[fieldid] : takes an
|
||||
instance of the structure and returns the field named by
|
||||
@racket[structid].}
|
||||
|
||||
@item{@racket[structid]@racketidfont{?} : takes any value, and returns
|
||||
@racket[true] if the value is an instance of the structure type.}
|
||||
|
||||
@item{@racket[structid] : an identifier representing the structure
|
||||
type, but never used directly.}
|
||||
|
||||
]
|
||||
|
||||
The created names must not be the same as a primitive or another defined name.}
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
@;{ ------- COMMENTED OUT FOR NOW ---------
|
||||
@section{@racket[define-wish]}
|
||||
|
||||
@defform[(define-wish id)]{
|
||||
|
||||
Defines a function named @racket[id] that we wish exists but have not implemented yet.
|
||||
The name of the function cannot be that of a primitive or another definition.
|
||||
The wished-for function can be called with one argument: @racket[(id _expr)].
|
||||
|
||||
Wished-for functions are reported in the test report for the current program.}
|
||||
|
||||
@defform/none[#:literals (define-wish)
|
||||
(define-wish id expr)]{
|
||||
Similar to the above form, defines a wished-for function named @racket[id]. If the
|
||||
wished-for function is called with one value, the result of @racket[expr] is
|
||||
returned as the default value. }
|
||||
}
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
@section[#:tag "beginner-call"]{Function Calls}
|
||||
|
||||
@defform/none[(id expr expr ...)]{
|
||||
|
||||
Calls a function. The @racket[id] must refer to a defined function,
|
||||
and the @racket[expr]s are evaluated from left to right to produce the
|
||||
values that are passed as arguments to the function. The result of the
|
||||
function call is the result of evaluating the function's body with
|
||||
every instance of an argument name replaced by the value passed for
|
||||
that argument. The number of argument @racket[expr]s must be the same
|
||||
as the number of arguments expected by the function.}
|
||||
|
||||
@defform[(#%app id expr expr ...)]{
|
||||
|
||||
A function call can be written with @racket[#%app], though it's
|
||||
practically never written that way.}
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
@section[#:tag "beginner-prim-call"]{Primitive Calls}
|
||||
|
||||
@defform/none[(prim-op expr ...)]{
|
||||
|
||||
Like a @seclink["beginner-call"]{function call}, but for a primitive
|
||||
operation. The @racket[expr]s are evaluated from left to right, and
|
||||
passed as arguments to the primitive operation named by
|
||||
@racket[prim-op]. A @racket[define-struct] form creates new
|
||||
primitives.}
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
@section{@racket[cond]}
|
||||
|
||||
@defform[(cond [expr expr] ... [expr expr])]{
|
||||
|
||||
A @racket[cond] form contains one or more ``lines'' that are
|
||||
surrounded by parentheses or square brackets. Each line contains two
|
||||
@racket[expr]s: a question @racket[expr] and an answer
|
||||
@racket[expr].
|
||||
|
||||
The lines are considered in order. To evaluate a line, first evaluate
|
||||
the question @racket[expr]. If the result is @racket[true], then the
|
||||
result of the whole @racket[cond] expression is the result of
|
||||
evaluating the answer @racket[expr] of the same line. If the result of
|
||||
evaluating the question @racket[expr] is @racket[false], the line is
|
||||
discarded and evaluation proceeds with the next line.
|
||||
|
||||
If the result of a question @racket[expr] is neither @racket[true] nor
|
||||
@racket[false], it is an error. If none of the question @racket[expr]s
|
||||
evaluates to @racket[true], it is also an error.}
|
||||
|
||||
@defform/none[#:literals (cond else)
|
||||
(cond [expr expr] ... [else expr])]{
|
||||
|
||||
This form of @racket[cond] is similar to the prior one, except that
|
||||
the final @racket[else] clause is always taken if no prior line's test
|
||||
expression evaluates to @racket[true]. In other words, @racket[else]
|
||||
acts like @racket[true], so there is no possibility to ``fall off the
|
||||
end'' of the @racket[cond] form.}
|
||||
|
||||
@defidform[else]{
|
||||
|
||||
The @racket[else] keyword can be used only with @racket[cond].}
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
@section{@racket[if]}
|
||||
|
||||
@defform[(if expr expr expr)]{
|
||||
|
||||
The first @racket[expr] (known as the ``test'' @racket[expr]) is
|
||||
evaluated. If it evaluates to @racket[true], the result of the
|
||||
@racket[if] expression is the result of evaluating the second
|
||||
@racket[expr] (often called the ``then'' @racket[expr]). If the text
|
||||
@racket[expr] evaluates to @racket[false], the result of the
|
||||
@racket[if] expression is the result of evaluating the third
|
||||
@racket[expr] (known as the ``else'' @racket[expr]). If the
|
||||
result of evaluating the test @racket[expr] is neither @racket[true]
|
||||
nor @racket[false], it is an error.}
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
@section{@racket[and]}
|
||||
|
||||
@defform[(and expr expr expr ...)]{
|
||||
|
||||
The @racket[expr]s are evaluated from left to right. If the first
|
||||
@racket[expr] evaluates to @racket[false], the @racket[and] expression
|
||||
immediately evaluates to @racket[false]. If the first @racket[expr]
|
||||
evaluates to @racket[true], the next expression is considered. If all
|
||||
@racket[expr]s evaluate to @racket[true], the @racket[and] expression
|
||||
evaluates to @racket[true]. If any of the expressions evaluate to a
|
||||
value other than @racket[true] or @racket[false], it is an error.}
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
@section{@racket[or]}
|
||||
|
||||
@defform[(or expr expr expr ...)]{
|
||||
|
||||
The @racket[expr]s are evaluated from left to right. If the first
|
||||
@racket[expr] evaluates to @racket[true], the @racket[or] expression
|
||||
immediately evaluates to @racket[true]. If the first @racket[expr]
|
||||
evaluates to @racket[false], the next expression is considered. If all
|
||||
@racket[expr]s evaluate to @racket[false], the @racket[or] expression
|
||||
evaluates to @racket[false]. If any of the expressions evaluate to a
|
||||
value other than @racket[true] or @racket[false], it is an error.}
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
@section{Test Cases}
|
||||
|
||||
@defform[(check-expect expr expr)]{
|
||||
|
||||
A test case to check that the first @racket[expr] produces the same
|
||||
value as the second @racket[expr], where the latter is normally an
|
||||
immediate value.}
|
||||
|
||||
@defform[(check-within expr expr expr)]{
|
||||
|
||||
Like @racket[check-expect], but with an extra expression that produces
|
||||
a number @racket[_delta]. The test case checks that each number in the
|
||||
result of the first @racket[expr] is within @racket[_delta] of each
|
||||
corresponding number from the second @racket[expr].}
|
||||
|
||||
@defform*[[(check-error expr expr)
|
||||
(check-error expr)]]{
|
||||
|
||||
A test case to check that the first @racket[expr] signals an error,
|
||||
where the error messages matches the string produced by the second
|
||||
@racket[expr], if it is present.}
|
||||
|
||||
@defform[(check-member-of expr expr expr ...)]{
|
||||
|
||||
A test case to check that the first @racket[expr] produces an element
|
||||
that is equivalent to one of the following @racket[expr]s.}
|
||||
|
||||
@defform[(check-range expr expr expr)]{
|
||||
|
||||
A test case to check that the first @racket[expr] produces a number
|
||||
inbetween the numbers produced by the second and third @racket[expr]s,
|
||||
inclusive.}
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
@section{@racket[empty]}
|
||||
|
||||
@defthing[empty empty?]{
|
||||
|
||||
The empty list.}
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
@section[#:tag "beginner-id"]{Identifiers}
|
||||
|
||||
@defform/none[id]{
|
||||
|
||||
An @racket[id] refers to a defined constant or argument within a
|
||||
function body. If no definition or argument matches the @racket[id]
|
||||
name, an error is reported. Similarly, if @racket[id] matches the name
|
||||
of a defined function or primitive operation, an error is reported.}
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
@section[#:tag "beginner-quote"]{Symbols}
|
||||
@prim-variables[("beginner") empty true false]
|
||||
@section[#:tag "beginner-syntax"]{Syntax}
|
||||
|
||||
@deftogether[(
|
||||
@defform/none[(unsyntax @elem{@racketvalfont{'}@racket[id]})]
|
||||
@defform[(quote id)]
|
||||
@defform/none[(unsyntax @elem{@racketvalfont{'}@racket[name]})]
|
||||
@defform[(quote name)]
|
||||
)]{
|
||||
|
||||
A quoted @racket[id] is a symbol. A symbol is a constant, like
|
||||
@racket[0] and @racket[empty].
|
||||
|
||||
Normally, a symbol is written with a @litchar{'}, like
|
||||
@racket['apple], but it can also be written with @racket[quote], like
|
||||
@racket[(@#,racket[quote] apple)].
|
||||
|
||||
The @racket[id] for a symbol is a sequence of characters not including
|
||||
a space or one of the following:}
|
||||
|
||||
@t{@hspace[2] @litchar{"} @litchar{,} @litchar{'} @litchar{`}
|
||||
@litchar{(} @litchar{)} @litchar{[} @litchar{]}
|
||||
@litchar["{"] @litchar["}"] @litchar{|} @litchar{;}
|
||||
@litchar{#}}
|
||||
A quoted @racket[name] is a symbol. A symbol is a value, just like
|
||||
@racket[0] or @racket[empty].}
|
||||
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
@(define-forms/normal define)
|
||||
@(define-form/explicit-lambda define lambda)
|
||||
|
||||
@section{@racket[true] and @racket[false]}
|
||||
@(prim-forms ("beginner")
|
||||
define
|
||||
lambda
|
||||
define-struct
|
||||
define-wish
|
||||
cond
|
||||
else
|
||||
if
|
||||
and
|
||||
or
|
||||
check-expect
|
||||
check-within
|
||||
check-error
|
||||
check-member-of
|
||||
check-range
|
||||
require)
|
||||
|
||||
@defthing[true boolean?]{
|
||||
|
||||
The true value.}
|
||||
|
||||
@defthing[false boolean?]{
|
||||
|
||||
The false value.}
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
@section{@racket[require]}
|
||||
|
||||
@defform[(require string)]{
|
||||
|
||||
Makes the definitions of the module specified by @racket[string]
|
||||
available in the current module (i.e., current file), where @racket[string]
|
||||
refers to a file relative to the enclosing file.
|
||||
|
||||
The @racket[string] is constrained in several ways to avoid problems
|
||||
with different path conventions on different platforms: a @litchar{/}
|
||||
is a directory separator, @litchar{.} always means the current
|
||||
directory, @litchar{..} always means the parent directory, path
|
||||
elements can use only @litchar{a} through @litchar{z} (uppercase or
|
||||
lowercase), @litchar{0} through @litchar{9}, @litchar{-}, @litchar{_},
|
||||
and @litchar{.}, and the string cannot be empty or contain a leading
|
||||
or trailing @litchar{/}.}
|
||||
|
||||
@defform/none[#:literals (require)
|
||||
(require module-id)]{
|
||||
|
||||
Accesses a file in an installed library. The library name is an
|
||||
identifier with the same constraints as for a relative-path string,
|
||||
with the additional constraint that it must not contain a
|
||||
@litchar{.}.}
|
||||
|
||||
@defform/none[#:literals (require lib)
|
||||
(require (lib string string ...))]{
|
||||
|
||||
Accesses a file in an installed library, making its definitions
|
||||
available in the current module (i.e., current file). The first
|
||||
@racket[string] names the library file, and the remaining
|
||||
@racket[string]s name the collection (and sub-collection, and so on)
|
||||
where the file is installed. Each string is constrained in the same
|
||||
way as for the @racket[(require string)] form.}
|
||||
|
||||
|
||||
@defform/none[#:literals (require planet)
|
||||
(require (planet string (string string number number)))]{
|
||||
|
||||
|
||||
Accesses a library that is distributed on the internet via the PLaneT
|
||||
server, making it definitions available in the current module (i.e.,
|
||||
current file).}
|
||||
|
||||
@; ----------------------------------------
|
||||
|
||||
@section[#:tag "beginner-prim-ops"]{Primitive Operations}
|
||||
@section[#:tag "beginner-pre-defined"]{Pre-defined Functions}
|
||||
|
||||
@prim-op-defns['(lib "htdp-beginner.rkt" "lang") #'here '()]
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#lang scheme/base
|
||||
#lang racket/base
|
||||
|
||||
(require scribble/manual)
|
||||
|
||||
|
|
|
@ -2,196 +2,116 @@
|
|||
@(require "common.rkt" "std-grammar.rkt" "prim-ops.rkt"
|
||||
(for-label lang/htdp-intermediate-lambda))
|
||||
|
||||
@(define-syntax-rule (bd intm-define intm-define-struct intm-local intm-letrec intm-let intm-let* intm-time)
|
||||
(begin
|
||||
(require (for-label lang/htdp-intermediate))
|
||||
(define intm-define @racket[define])
|
||||
(define intm-define-struct @racket[define-struct])
|
||||
(define intm-local @racket[local])
|
||||
(define intm-letrec @racket[letrec])
|
||||
(define intm-let @racket[let])
|
||||
(define intm-let* @racket[let*])
|
||||
(define intm-time @racket[time])))
|
||||
@(bd intm-define intm-define-struct intm-local intm-letrec intm-let intm-let* intm-time)
|
||||
|
||||
@(define-syntax-rule (bbd beg-define beg-define-struct beg-cond beg-if beg-and beg-or beg-check-expect beg-require)
|
||||
(begin
|
||||
(require (for-label lang/htdp-beginner))
|
||||
(define beg-define @racket[define])
|
||||
(define beg-define-struct @racket[define-struct])
|
||||
(define beg-cond @racket[cond])
|
||||
(define beg-if @racket[if])
|
||||
(define beg-and @racket[and])
|
||||
(define beg-or @racket[or])
|
||||
(define beg-check-expect @racket[check-expect])
|
||||
(define beg-require @racket[require])))
|
||||
@(bbd beg-define beg-define-struct beg-cond beg-if beg-and beg-or beg-check-expect beg-require)
|
||||
|
||||
|
||||
@title[#:style 'toc #:tag "intermediate-lam"]{Intermediate Student with Lambda}
|
||||
|
||||
@declare-exporting[lang/htdp-intermediate-lambda]
|
||||
|
||||
@racketgrammar*+qq[
|
||||
#:literals (define define-struct lambda λ cond else if and or empty true false require lib planet
|
||||
local let let* letrec time check-expect check-within check-error)
|
||||
(check-expect check-within check-error require)
|
||||
#:literals (define define-struct lambda λ cond else if and or require lib planet
|
||||
local let let* letrec time check-expect check-within check-member-of check-range check-error)
|
||||
(check-expect check-within check-member-of check-range check-error require)
|
||||
[program (code:line def-or-expr ...)]
|
||||
[def-or-expr definition
|
||||
expr
|
||||
expression
|
||||
test-case
|
||||
library-require]
|
||||
[definition (define (id id id ...) expr)
|
||||
(define id expr)
|
||||
(define-struct id (id ...))]
|
||||
[expr (lambda (id id ...) expr)
|
||||
(λ (id id ...) expr)
|
||||
(local [definition ...] expr)
|
||||
(letrec ([id expr] ...) expr)
|
||||
(let ([id expr] ...) expr)
|
||||
(let* ([id expr] ...) expr)
|
||||
(code:line (expr expr expr ...) (code:comment @#,seclink["intermediate-lambda-call"]{function call}))
|
||||
(cond [expr expr] ... [expr expr])
|
||||
(cond [expr expr] ... [else expr])
|
||||
(if expr expr expr)
|
||||
(and expr expr expr ...)
|
||||
(or expr expr expr ...)
|
||||
(time expr)
|
||||
empty
|
||||
(code:line id (code:comment @#,seclink["intermediate-id"]{identifier}))
|
||||
(code:line prim-op (code:comment @#,seclink["intermediate-lambda-prim-op"]{primitive operation}))
|
||||
(code:line @#,elem{@racketvalfont{'}@racket[_quoted]} (code:comment @#,seclink["beginner-abbr-quote"]{quoted value}))
|
||||
(code:line @#,elem{@racketvalfont{`}@racket[_quasiquoted]} (code:comment @#,seclink["beginner-abbr-quasiquote"]{quasiquote}))
|
||||
[definition (define (name variable variable ...) expression)
|
||||
(define name expression)
|
||||
(define-struct name (name ...))]
|
||||
[expression (lambda (variable variable ...) expression)
|
||||
(λ (variable variable ...) expression)
|
||||
(local [definition ...] expression)
|
||||
(letrec ([name expression] ...) expression)
|
||||
(let ([name expression] ...) expression)
|
||||
(let* ([name expression] ...) expression)
|
||||
(code:line (expression expression expression ...))
|
||||
(cond [expression expression] ... [expression expression])
|
||||
(cond [expression expression] ... [else expression])
|
||||
(if expression expression expression)
|
||||
(and expression expression expression ...)
|
||||
(or expression expression expression ...)
|
||||
(time expression)
|
||||
(code:line name)
|
||||
(code:line prim-op)
|
||||
(code:line @#,elem{@racketvalfont{'}@racket[_quoted]})
|
||||
(code:line @#,elem{@racketvalfont{`}@racket[_quasiquoted]})
|
||||
number
|
||||
true
|
||||
false
|
||||
string
|
||||
character]
|
||||
]
|
||||
|
||||
@|prim-nonterms|
|
||||
@prim-nonterms[("intermediate-w-lambda") define define-struct]
|
||||
|
||||
@prim-variables[("intermedia-w-lambda") empty true false]
|
||||
|
||||
@prim-ops['(lib "htdp-intermediate-lambda.rkt" "lang") #'here]
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
@section[#:tag "intermediate-lambda-define"]{@racket[define]}
|
||||
@section[#:tag "intermediate-lambda-syntax"]{Syntax for Intermediate with Lambda}
|
||||
|
||||
@deftogether[(
|
||||
@defform[(define (id id id ...) expr)]
|
||||
@defform/none[#:literals (define)
|
||||
(define id expr)]
|
||||
)]{
|
||||
|
||||
The same as Intermediate's @|intm-define|. No special case is needed
|
||||
for @racket[lambda], since a @racket[lambda] form is an expression.}
|
||||
@defform[(lambda (variable variable ...) expression)]{
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
Creates a function that takes as many arguments as given @racket[variables]s,
|
||||
and whose body is @racket[expression].}
|
||||
|
||||
@section[#:tag "intermediate-lambda"]{@racket[lambda]}
|
||||
|
||||
@defform[(lambda (id id ...) expr)]{
|
||||
|
||||
Creates a function that takes as many arguments as given @racket[id]s,
|
||||
and whose body is @racket[expr].}
|
||||
|
||||
@defform[(λ (id id ...) expr)]{
|
||||
@defform[(λ (variable variable ...) expression)]{
|
||||
|
||||
The Greek letter @racket[λ] is a synonym for @racket[lambda].}
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
@section[#:tag "intermediate-lambda-call"]{Function Calls}
|
||||
|
||||
@defform/none[(expr expr expr ...)]{
|
||||
@defform/none[(expression expression expression ...)]{
|
||||
|
||||
Like a Beginning @seclink["beginner-call"]{function call}, except that
|
||||
the function position can be an arbitrary expression---perhaps a
|
||||
@racket[lambda] expression or a @racket[_prim-op].}
|
||||
Calls the function that results from evaluating the first
|
||||
@racket[expression]. The value of the call is the value of function's body when
|
||||
every instance of @racket[name]'s variables are replaced by the values of the
|
||||
corresponding @racket[expression]s.
|
||||
|
||||
@defform[(#%app expr expr expr ...)]{
|
||||
The function being called must come from either a definition appearing before the
|
||||
function call, or from a @racket[lambda] expression. The number of argument
|
||||
@racket[expression]s must be the same as the number of arguments expected by
|
||||
the function.}
|
||||
|
||||
A function call can be written with @racket[#%app], though it's
|
||||
practically never written that way.}
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
@section[#:tag "intermediate-lambda-prim-op"]{Primitive Operation Names}
|
||||
@(intermediate-forms lambda
|
||||
quote
|
||||
quasiquote
|
||||
unquote
|
||||
unquote-splicing
|
||||
local
|
||||
letrec
|
||||
let*
|
||||
let
|
||||
time)
|
||||
|
||||
@defform/none[prim-op]{
|
||||
|
||||
The name of a primitive operation can be used as an expression. It
|
||||
produces a function version of the operation.}
|
||||
|
||||
@prim-op-defns['(lib "htdp-intermediate-lambda.rkt" "lang") #'here '()]
|
||||
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
@section[#:tag "intermediate-lambda-unchanged"]{Unchanged Forms}
|
||||
@section[#:tag "intermediate-lambda-common-syntax"]{Common Syntax}
|
||||
|
||||
@defform[(define-struct structid (fieldid ...))]{
|
||||
@(define-forms/normal define)
|
||||
|
||||
The same as Intermediate's @|intm-define-struct|.}
|
||||
@(prim-forms ("beginner")
|
||||
define
|
||||
lambda
|
||||
define-struct
|
||||
define-wish
|
||||
cond
|
||||
else
|
||||
if
|
||||
and
|
||||
or
|
||||
check-expect
|
||||
check-within
|
||||
check-error
|
||||
check-member-of
|
||||
check-range
|
||||
require)
|
||||
|
||||
@section[#:tag "intermediate-lambda-pre-defined"]{Pre-defined Functions}
|
||||
|
||||
@deftogether[(
|
||||
@defform[(local [definition ...] expr)]
|
||||
@defform[(letrec ([id expr-for-let] ...) expr)]
|
||||
@defform[(let ([id expr-for-let] ...) expr)]
|
||||
@defform[(let* ([id expr-for-let] ...) expr)]
|
||||
)]{
|
||||
@prim-op-defns['(lib "htdp-intermediate-lambda.ss" "lang") #'here '()]
|
||||
|
||||
The same as Intermediate's @|intm-local|, @|intm-letrec|, @|intm-let|,
|
||||
and @|intm-let*|.}
|
||||
|
||||
|
||||
@deftogether[(
|
||||
@defform[(cond [expr expr] ... [expr expr])]
|
||||
@defidform[else]
|
||||
)]{
|
||||
|
||||
The same as Beginning's @|beg-cond|.}
|
||||
|
||||
|
||||
|
||||
@defform[(if expr expr expr)]{
|
||||
|
||||
The same as Beginning's @|beg-if|.}
|
||||
|
||||
@deftogether[(
|
||||
@defform[(and expr expr expr ...)]
|
||||
@defform[(or expr expr expr ...)]
|
||||
)]{
|
||||
|
||||
The same as Beginning's @|beg-and| and @|beg-or|.}
|
||||
|
||||
|
||||
@defform[(time expr)]{
|
||||
|
||||
The same as Intermediate's @|intm-time|.}
|
||||
|
||||
|
||||
@deftogether[(
|
||||
@defform[(check-expect expr expr)]
|
||||
@defform[(check-within expr expr expr)]
|
||||
@defform*[[(check-error expr expr)
|
||||
(check-error expr)]]
|
||||
@defform[(check-member-of expr expr expr ...)]
|
||||
@defform[(check-range expr expr expr)]
|
||||
)]{
|
||||
|
||||
The same as Beginning's @|beg-check-expect|, etc.}
|
||||
|
||||
|
||||
@deftogether[(
|
||||
@defthing[empty empty?]
|
||||
@defthing[true boolean?]
|
||||
@defthing[false boolean?]
|
||||
)]{
|
||||
|
||||
Constants for the empty list, true, and false.}
|
||||
|
||||
@defform[(require module-path)]{
|
||||
|
||||
The same as Beginning's @|beg-require|.}
|
||||
|
|
|
@ -2,242 +2,94 @@
|
|||
@(require "common.rkt" "std-grammar.rkt" "prim-ops.rkt"
|
||||
(for-label lang/htdp-intermediate))
|
||||
|
||||
@(define-syntax-rule (bd beg-define beg-define-struct beg-cond beg-if beg-and beg-or beg-check-expect beg-require)
|
||||
(begin
|
||||
(require (for-label lang/htdp-beginner))
|
||||
(define beg-define (racket define))
|
||||
(define beg-define-struct (racket define-struct))
|
||||
(define beg-cond (racket cond))
|
||||
(define beg-if (racket if))
|
||||
(define beg-and (racket and))
|
||||
(define beg-or (racket or))
|
||||
(define beg-check-expect (racket check-expect))
|
||||
(define beg-require (racket require))))
|
||||
@(bd beg-define beg-define-struct beg-cond beg-if beg-and beg-or beg-check-expect beg-require)
|
||||
|
||||
@title[#:style 'toc #:tag "intermediate"]{Intermediate Student}
|
||||
|
||||
@declare-exporting[lang/htdp-intermediate]
|
||||
|
||||
@racketgrammar*+qq[
|
||||
#:literals (define define-struct lambda cond else if and or empty true false require lib planet
|
||||
#:literals (define define-struct lambda cond else if and or require lib planet
|
||||
local let let* letrec time check-expect check-within check-error)
|
||||
(check-expect check-within check-error require)
|
||||
(check-expect check-within check-member-of check-range check-error require)
|
||||
[program (code:line def-or-expr ...)]
|
||||
[def-or-expr definition
|
||||
expr
|
||||
expression
|
||||
test-case
|
||||
library-require]
|
||||
[definition (define (id id id ...) expr)
|
||||
(define id expr)
|
||||
(define id (lambda (id id ...) expr))
|
||||
(define-struct id (id ...))]
|
||||
[expr (local [definition ...] expr)
|
||||
(letrec ([id expr-for-let] ...) expr)
|
||||
(let ([id expr-for-let] ...) expr)
|
||||
(let* ([id expr-for-let] ...) expr)
|
||||
(code:line (id expr expr ...) (code:comment @#,seclink["intermediate-call"]{function call}))
|
||||
(code:line (prim-op expr ...) (code:comment @#,seclink["beginner-prim-call"]{primitive operation call}))
|
||||
(cond [expr expr] ... [expr expr])
|
||||
(cond [expr expr] ... [else expr])
|
||||
(if expr expr expr)
|
||||
(and expr expr expr ...)
|
||||
(or expr expr expr ...)
|
||||
(time expr)
|
||||
empty
|
||||
(code:line id (code:comment @#,seclink["intermediate-id"]{identifier}))
|
||||
(code:line prim-op (code:comment @#,seclink["intermediate-prim-op"]{primitive operation}))
|
||||
(code:line @#,elem{@racketvalfont{'}@racket[_quoted]} (code:comment @#,seclink["beginner-abbr-quote"]{quoted value}))
|
||||
(code:line @#,elem{@racketvalfont{`}@racket[_quasiquoted]} (code:comment @#,seclink["beginner-abbr-quasiquote"]{quasiquote}))
|
||||
[definition (define (name variable variable ...) expression)
|
||||
(define name expression)
|
||||
(define name (lambda (variable variable ...) expression))
|
||||
(define-struct name (name ...))]
|
||||
[expression (local [definition ...] expression)
|
||||
(letrec ([name expr-for-let] ...) expression)
|
||||
(let ([name expr-for-let] ...) expression)
|
||||
(let* ([name expr-for-let] ...) expression)
|
||||
(code:line (name expression expression ...) )
|
||||
(cond [expression expression] ... [expression expression])
|
||||
(cond [expression expression] ... [else expression])
|
||||
(if expression expression expression)
|
||||
(and expression expression expression ...)
|
||||
(or expression expression expression ...)
|
||||
(time expression)
|
||||
(code:line name)
|
||||
(code:line @#,elem{@racketvalfont{'}@racket[_quoted]})
|
||||
(code:line @#,elem{@racketvalfont{`}@racket[_quasiquoted]})
|
||||
number
|
||||
true
|
||||
false
|
||||
string
|
||||
character]
|
||||
[expr-for-let (lambda (id id ...) expr)
|
||||
expr]
|
||||
[expr-for-let (lambda (variable variable ...) expression)
|
||||
expression]
|
||||
]
|
||||
|
||||
@|prim-nonterms|
|
||||
@prim-nonterms[("intermediate") define define-struct]
|
||||
|
||||
@prim-variables[("intermediate") empty true false]
|
||||
|
||||
@prim-ops['(lib "htdp-intermediate.rkt" "lang") #'here]
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
@section[#:tag "intermediate-define"]{@racket[define]}
|
||||
@section[#:tag "intermediate-syntax"]{Syntax for Intermediate}
|
||||
|
||||
@deftogether[(
|
||||
@defform[(define (id id id ...) expr)]
|
||||
@defform/none[#:literals (define)
|
||||
(define id expr)]
|
||||
@defform/none[#:literals (define lambda)
|
||||
(define id (lambda (id id ...) expr))]
|
||||
)]{
|
||||
Besides working in @racket[local], definition forms are
|
||||
the same as Beginning's @|beg-define|.}
|
||||
|
||||
@defidform[lambda]{
|
||||
|
||||
As in Beginning, @racket[lambda] keyword can only be used with
|
||||
@racket[define] in the alternative function-definition syntax.}
|
||||
@(intermediate-forms lambda
|
||||
quote
|
||||
quasiquote
|
||||
unquote
|
||||
unquote-splicing
|
||||
local
|
||||
letrec
|
||||
let*
|
||||
let
|
||||
time)
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
@section[#:tag "intermediate-define-struct"]{@racket[define-struct]}
|
||||
@section[#:tag "intermediate-common-syntax"]{Common Syntax}
|
||||
|
||||
@defform[(define-struct structid (fieldid ...))]{
|
||||
@(define-forms/normal define)
|
||||
@(define-form/explicit-lambda define lambda)
|
||||
|
||||
Besides working in @racket[local], this form is the same as Beginning's
|
||||
@|beg-define-struct|.}
|
||||
@(prim-forms
|
||||
("beginner")
|
||||
define
|
||||
lambda
|
||||
define-struct
|
||||
define-wish
|
||||
cond
|
||||
else
|
||||
if
|
||||
and
|
||||
or
|
||||
check-expect
|
||||
check-within
|
||||
check-error
|
||||
check-member-of
|
||||
check-range
|
||||
require)
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
@section{@racket[local]}
|
||||
|
||||
@defform[(local [definition ...] expr)]{
|
||||
|
||||
Groups related definitions for use in @racket[expr]. Each
|
||||
@racket[definition] is evaluated in order, and finally the body
|
||||
@racket[expr] is evaluated. Only the expressions within the
|
||||
@racket[local] form (including the right-hand-sides of the
|
||||
@racket[definition]s and the @racket[expr]) may refer to the names
|
||||
defined by the @racket[definition]s. If a name defined in the
|
||||
@racket[local] form is the same as a top-level binding, the inner one
|
||||
``shadows'' the outer one. That is, inside the @racket[local] form,
|
||||
any references to that name refer to the inner one.
|
||||
|
||||
Since @racket[local] is an expression and may occur anywhere an
|
||||
expression may occur, it introduces the notion of lexical
|
||||
scope. Expressions within the local may ``escape'' the scope of the
|
||||
local, but these expressions may still refer to the bindings
|
||||
established by the local.}
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
@section{@racket[letrec], @racket[let], and @racket[let*]}
|
||||
|
||||
@defform[(letrec ([id expr-for-let] ...) expr)]{
|
||||
|
||||
Similar to @racket[local], but essentially omitting the
|
||||
@racket[define] for each definition.
|
||||
|
||||
A @racket[expr-for-let] can be either an expression for a constant
|
||||
definition or a @racket[lambda] form for a function definition.}
|
||||
|
||||
@defform[(let ([id expr-for-let] ...) expr)]{
|
||||
|
||||
Like @racket[letrec], but the defined @racket[id]s can be used only in
|
||||
the last @racket[expr], not the @racket[expr-for-let]s next to the
|
||||
@racket[id]s.}
|
||||
|
||||
@defform[(let* ([id expr-for-let] ...) expr)]{
|
||||
|
||||
Like @racket[let], but each @racket[id] can be used in any subsequent
|
||||
@racket[expr-for-let], in addition to @racket[expr].}
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
@section[#:tag "intermediate-call"]{Function Calls}
|
||||
|
||||
@defform/none[(id expr expr ...)]{
|
||||
|
||||
A function call in Intermediate is the same as a Beginning
|
||||
@seclink["beginner-call"]{function call}, except that it can also call
|
||||
@racket[local]ly defined functions or functions passed as
|
||||
arguments. That is, @racket[id] can be a function defined in
|
||||
@racket[local] or an argument name while in a function.}
|
||||
|
||||
@defform[(#%app id expr expr ...)]{
|
||||
|
||||
A function call can be written with @racket[#%app], though it's
|
||||
practically never written that way.}
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
@section{@racket[time]}
|
||||
|
||||
@defform[(time expr)]{
|
||||
|
||||
This form is used to measure the time taken to evaluate
|
||||
@racket[expr]. After evaluating @racket[expr], Racket prints out the
|
||||
time taken by the evaluation (including real time, time taken by the
|
||||
cpu, and the time spent collecting free memory) and returns the result
|
||||
of the expression.
|
||||
|
||||
(The reported time is measured as the number of milliseconds of CPU time
|
||||
required to obtain this result, the number of “real” milliseconds required
|
||||
for the result, and the number of milliseconds of CPU time (included in the
|
||||
first result) spent on garbage collection. The reliability of the timing
|
||||
numbers depends on the platform.)
|
||||
}
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
@section[#:tag "intermediate-id"]{Identifiers}
|
||||
|
||||
@defform/none[id]{
|
||||
|
||||
An @racket[id] refers to a defined constant (possibly local), defined
|
||||
function (possibly local), or argument within a function body. If no
|
||||
definition or argument matches the @racket[id] name, an error is
|
||||
reported.}
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
@section[#:tag "intermediate-prim-op"]{Primitive Operations}
|
||||
|
||||
@defform/none[prim-op]{
|
||||
|
||||
The name of a primitive operation can be used as an expression. If it
|
||||
is passed to a function, then it can be used in a function call within
|
||||
the function's body.}
|
||||
@section[#:tag "intermediate-pre-defined"]{Pre-defined Functions}
|
||||
|
||||
@prim-op-defns['(lib "htdp-intermediate.rkt" "lang") #'here '()]
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
@section[#:tag "intermediate-unchanged"]{Unchanged Forms}
|
||||
|
||||
@deftogether[(
|
||||
@defform[(cond [expr expr] ... [expr expr])]
|
||||
@defidform[else]
|
||||
)]{
|
||||
|
||||
The same as Beginning's @|beg-cond|.}
|
||||
|
||||
|
||||
@defform[(if expr expr expr)]{
|
||||
|
||||
The same as Beginning's @|beg-if|.}
|
||||
|
||||
@deftogether[(
|
||||
@defform[(and expr expr expr ...)]
|
||||
@defform[(or expr expr expr ...)]
|
||||
)]{
|
||||
|
||||
The same as Beginning's @|beg-and| and @|beg-or|.}
|
||||
|
||||
|
||||
@deftogether[(
|
||||
@defform[(check-expect expr expr)]
|
||||
@defform[(check-within expr expr expr)]
|
||||
@defform*[[(check-error expr expr)
|
||||
(check-error expr)]]
|
||||
@defform[(check-member-of expr expr expr ...)]
|
||||
@defform[(check-range expr expr expr)]
|
||||
)]{
|
||||
|
||||
The same as Beginning's @|beg-check-expect|, etc.}
|
||||
|
||||
|
||||
@deftogether[(
|
||||
@defthing[empty empty?]
|
||||
@defthing[true boolean?]
|
||||
@defthing[false boolean?]
|
||||
)]{
|
||||
|
||||
Constants for the empty list, true, and false.}
|
||||
|
||||
@defform[(require module-path)]{
|
||||
|
||||
The same as Beginning's @|beg-require|.}
|
||||
|
|
|
@ -1,14 +1,21 @@
|
|||
#reader scribble/reader
|
||||
#lang scheme/base
|
||||
(require "common.rkt"
|
||||
#lang racket/base
|
||||
(require "common.ss"
|
||||
scribble/decode
|
||||
scribble/struct
|
||||
scribble/scheme
|
||||
scheme/list
|
||||
scheme/pretty
|
||||
syntax/docprovide)
|
||||
scribble/racket
|
||||
racket/list
|
||||
racket/pretty
|
||||
syntax/docprovide
|
||||
(for-syntax racket/base)
|
||||
)
|
||||
|
||||
(provide prim-ops
|
||||
(provide prim-variables
|
||||
prim-forms
|
||||
define-forms/normal
|
||||
define-form/explicit-lambda
|
||||
intermediate-forms
|
||||
prim-ops
|
||||
prim-op-defns)
|
||||
|
||||
(define (maybe-make-table l t)
|
||||
|
@ -48,6 +55,411 @@
|
|||
(to-paragraph
|
||||
(typeset-type (cadr func)))))
|
||||
|
||||
(define-syntax-rule (prim-variables (section-prefix) empty true false)
|
||||
(make-splice
|
||||
(list
|
||||
|
||||
@section[#:tag (string-append section-prefix " Pre-Defined Variables")]{Pre-Defined Variables}
|
||||
@defthing[empty empty?]{
|
||||
|
||||
The empty list.}
|
||||
|
||||
@defthing[true boolean?]{
|
||||
|
||||
The true value.}
|
||||
|
||||
@defthing[false boolean?]{
|
||||
|
||||
The false value.}
|
||||
|
||||
)))
|
||||
|
||||
(define-syntax-rule (define-forms/normal define)
|
||||
|
||||
(make-splice
|
||||
(list
|
||||
@defform*[[(define (... (name variable variable ...)) expression)]]{
|
||||
|
||||
Defines a function named @racket[name]. The @racket[expression] is the body
|
||||
of the function. When the function is called,
|
||||
the values of the arguments are inserted into the body in place of the
|
||||
@racket[variable]s. The function returns the value of that new expression.
|
||||
|
||||
The function name's cannot be the same as that of another function or
|
||||
variable.}
|
||||
|
||||
@defform/none[#:literals (define) (define name expression)]{
|
||||
|
||||
Defines a variable called @racket[name] with the the value of
|
||||
@racket[expression]. The variable name's cannot be the same as that of
|
||||
another function or variable, and @racket[name] itself must not appear in
|
||||
@racket[expression].}
|
||||
|
||||
)))
|
||||
|
||||
(define-syntax-rule (define-form/explicit-lambda define lambda)
|
||||
|
||||
(make-splice
|
||||
(list
|
||||
|
||||
@defform/none[#:literals (define lambda)
|
||||
(... (define name (lambda (variable variable ...) expression)))]{
|
||||
|
||||
An alternate way on defining functions. The @racket[name] is the name of
|
||||
the function, which cannot be the same as that of another function or
|
||||
variable.
|
||||
|
||||
@defidform/inline[lambda] cannot be used outside of this alternate syntax.
|
||||
}
|
||||
)))
|
||||
|
||||
|
||||
(define-syntax-rule (prim-forms
|
||||
(section-prefix)
|
||||
define
|
||||
lambda
|
||||
define-struct
|
||||
define-wish
|
||||
cond
|
||||
else
|
||||
if
|
||||
and
|
||||
or
|
||||
check-expect
|
||||
check-within
|
||||
check-error
|
||||
check-member-of
|
||||
check-range
|
||||
require)
|
||||
(make-splice
|
||||
(list
|
||||
|
||||
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
|
||||
@defform*[[(... (define-struct structure-name (field-name ...)))]]{
|
||||
|
||||
Defines a new structure called @racket[field-name]. The structure's fields are
|
||||
named by the @racket[field-name]s. After the @racket[define-struct], the following new
|
||||
functions are available:
|
||||
|
||||
@itemize[
|
||||
|
||||
@item{@racketidfont{make-}@racket[structure-name] : takes in a number of
|
||||
arguments equal to the number of fields in the structure,
|
||||
and creates a new instance of that structure.}
|
||||
|
||||
@item{@racket[structure-name]@racketidfont{-}@racket[field-name] : takes in an
|
||||
instance of the structure and returns the value in the field named by
|
||||
@racket[field-name].}
|
||||
|
||||
@item{@racket[structure-name]@racketidfont{?} : takes in any value, and returns
|
||||
@racket[true] if the value is an instance of the structure.}
|
||||
|
||||
]
|
||||
|
||||
The name of the new functions introduced by @racket[define-struct] must not be the same as that of other functions or
|
||||
variables, otherwise @racket[define-struct] reports an error.}
|
||||
|
||||
#|
|
||||
|
||||
@defform*[[(define-wish name)]]{
|
||||
|
||||
Defines a function called @racket[name] that we wish exists but have not
|
||||
implemented yet. The wished-for function can be called with one argument, and
|
||||
are reported in the test report for the current program.
|
||||
|
||||
The name of the function cannot be the same as another function or variable.}
|
||||
|
||||
|
||||
@defform/none[#:literals (define-wish)
|
||||
(define-wish name expression)]{
|
||||
Similar to the above form, defines a wished-for function named @racket[name]. If the
|
||||
wished-for function is called with one value, it returns the values of @racket[expression]. }
|
||||
|#
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
|
||||
@defform*[[(... (name expression expression ...))]]{
|
||||
|
||||
Calls the function named @racket[name]. The value of the call is the value of
|
||||
@racket[name]'s body when every one of the function's variables are
|
||||
replaced by the values of the corresponding @racket[expression]s.
|
||||
|
||||
The function named @racket[name] must defined before it can be called. The
|
||||
number of argument @racket[expression]s must be the same as the number of arguments
|
||||
expected by the function.}
|
||||
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
|
||||
@defform*[#:literals (cond else)
|
||||
[(... (cond [question-expression answer-expression] ...))
|
||||
(... (cond [question-expression answer-expression] ... [else answer-expression]))]]{
|
||||
|
||||
Chooses a clause base on a condition. @racket[cond] finds the first
|
||||
@racket[question-expression] which evaluates to @racket[true], then it evaluates
|
||||
the corresponding @racket[answer-expression].
|
||||
|
||||
If none of the @racket[question-expression]s evaluates to @racket[true],
|
||||
@racket[cond]'s value is the @racket[answer-expression] of the
|
||||
@racket[else] clause. If there is no @racket[else], @racket[cond] reports
|
||||
an error. If the result of a @racket[question-expression] is neither
|
||||
@racket[true] nor @racket[false], @racket[cond] also reports an error.
|
||||
|
||||
|
||||
@defidform/inline[else] cannot be used outside of @racket[cond].
|
||||
}
|
||||
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
|
||||
@defform*[[(if test-expression then-expression else-expression)]]{
|
||||
|
||||
When the value of the @racket[test-expression] is @racket[true],
|
||||
@racket[if] evaluates the @racket[then-expression]. When the test is
|
||||
@racket[false], @racket[if] evaluates the @racket[else-expression].
|
||||
|
||||
If the @racket[test-expression] is neither @racket[true] nor
|
||||
@racket[false], @racket[if] reports an error.}
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
|
||||
@defform*[[(... (and expression expression expression ...))]]{
|
||||
|
||||
@racket[and] evaluates to @racket[true] if all the @racket[expression]s are
|
||||
@racket[true]. If any @racket[expression] is false, the @racket[and]
|
||||
expression immediately evaluates to @racket[false] (the expressions to the
|
||||
right of that expression are not evaluated.)
|
||||
|
||||
If any of the expressions evaluate to a value other than @racket[true] or
|
||||
@racket[false], it is an error.}
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
|
||||
@defform*[[(... (or expression expression expression ...))]]{
|
||||
|
||||
@racket[or] evaluates to @racket[true] as soon as one of the
|
||||
@racket[expression]s is @racket[true] (the expressions to the right of that
|
||||
expression are not evaluated.) If all the @racket[expression] are false,
|
||||
@racket[or] is @racket[false].
|
||||
|
||||
If any of the expressions evaluate to a value other than @racket[true] or
|
||||
@racket[false], @racket[or] reports an error.}
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
|
||||
@defform*[[(check-expect expression expected-expression)]]{
|
||||
|
||||
Checks that the first @racket[expression] evaluates to the same value as the
|
||||
@racket[expected-expression].}
|
||||
|
||||
@defform*[[(check-within expression expected-expression delta-expression)]]{
|
||||
|
||||
Checks that the first @racket[expression] evaluates to a value within
|
||||
@racket[delta-expression] of the @racket[expected-expression]. If
|
||||
@racket[delta-expression] is not a number, @racket[check-within] report an
|
||||
error.}
|
||||
|
||||
@defform*[[(check-error expression expression)
|
||||
(check-error expression)]]{
|
||||
|
||||
Checks that the first @racket[expression] reports an error,
|
||||
where the error messages matches the string produced by the second
|
||||
@racket[expression], if it is present.}
|
||||
|
||||
@defform*[[(... (check-member-of expression expression expression ...))]]{
|
||||
|
||||
Checks that the first @racket[expression] produces the same value as one of
|
||||
the following @racket[expression]s.}
|
||||
|
||||
@defform*[[(check-range expression expression expression)]]{
|
||||
|
||||
Checks that the first @racket[expression] produces a number in between the numbers
|
||||
produced by the second and third @racket[expression]s, inclusive.}
|
||||
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
|
||||
@defform*[[(require string)]]{
|
||||
|
||||
Makes the definitions of the module specified by @racket[string]
|
||||
available in the current module (i.e., the current file), where @racket[string]
|
||||
refers to a file relative to the current file.
|
||||
|
||||
The @racket[string] is constrained in several ways to avoid problems
|
||||
with different path conventions on different platforms: a @litchar{/}
|
||||
is a directory separator, @litchar{.} always means the current
|
||||
directory, @litchar{..} always means the parent directory, path
|
||||
elements can use only @litchar{a} through @litchar{z} (uppercase or
|
||||
lowercase), @litchar{0} through @litchar{9}, @litchar{-}, @litchar{_},
|
||||
and @litchar{.}, and the string cannot be empty or contain a leading
|
||||
or trailing @litchar{/}.}
|
||||
|
||||
@defform/none[#:literals (require)
|
||||
(require module-name)]{
|
||||
|
||||
Accesses a file in an installed library. The library name is an identifier
|
||||
with the same constraints as for a relative-path string (though without the
|
||||
quotes), with the additional constraint that it must not contain a
|
||||
@litchar{.}.}
|
||||
|
||||
@defform/none[#:literals (require lib)
|
||||
(... (require (lib string string ...)))]{
|
||||
|
||||
Accesses a file in an installed library, making its definitions
|
||||
available in the current module (i.e., the current file). The first
|
||||
@racket[string] names the library file, and the remaining
|
||||
@racket[string]s name the collection (and sub-collection, and so on)
|
||||
where the file is installed. Each string is constrained in the same
|
||||
way as for the @racket[(require string)] form.}
|
||||
|
||||
|
||||
@defform/none[#:literals (require planet)
|
||||
(require (planet string (string string number number)))]{
|
||||
|
||||
|
||||
Accesses a library that is distributed on the internet via the PLaneT
|
||||
server, making it definitions available in the current module (i.e.,
|
||||
current file).}
|
||||
|
||||
)))
|
||||
|
||||
|
||||
(define-syntax-rule
|
||||
(intermediate-forms lambda
|
||||
quote
|
||||
quasiquote
|
||||
unquote
|
||||
unquote-splicing
|
||||
local
|
||||
letrec
|
||||
let*
|
||||
let
|
||||
time)
|
||||
|
||||
(make-splice
|
||||
(list
|
||||
|
||||
@deftogether[(
|
||||
@defform/none[(unsyntax @elem{@racketvalfont{'}@racket[name]})]
|
||||
@defform/none[(unsyntax @elem{@racketvalfont{'}@racket[part]})]
|
||||
@defform[(quote name)]
|
||||
@defform/none[(quote part)]
|
||||
)]{
|
||||
|
||||
A quoted name is a symbol. A quote part is an abbreviation for a nested lists.
|
||||
|
||||
Normally, this quotation is written with a @litchar{'}, like
|
||||
@racket['(apple banana)], but it can also be written with @racket[quote], like
|
||||
@racket[(@#,racket[quote] (apple banana))].}
|
||||
|
||||
|
||||
@deftogether[(
|
||||
@defform/none[(unsyntax @elem{@racketvalfont{`}@racket[name]})]
|
||||
@defform/none[(unsyntax @elem{@racketvalfont{`}@racket[part]})]
|
||||
@defform[(quasiquote name)]
|
||||
@defform/none[(quasiquote part)]
|
||||
)]{
|
||||
|
||||
Like @racket[quote], but also allows escaping to expression ``unquotes.''
|
||||
|
||||
Normally, quasi-quotations are written with a backquote, @litchar{`}, like
|
||||
@racket[`(apple ,(+ 1 2))], but they can also be written with
|
||||
@racket[quasiquote], like
|
||||
@racket[(@#,racket[quasiquote] (apple ,(+ 1 2)))].}
|
||||
|
||||
|
||||
@deftogether[(
|
||||
@defform/none[(unsyntax @elem{@racketvalfont{,}@racket[expression]})]
|
||||
@defform[(unquote expression)]
|
||||
)]{
|
||||
|
||||
Under a single quasiquote, @racketfont{,}@racket[expression] escapes from
|
||||
the quote to include an evaluated expression whose result is inserted
|
||||
into the abbreviated list.
|
||||
|
||||
Under multiple quasiquotes, @racketfont{,}@racket[expression] is really
|
||||
the literal @racketfont{,}@racket[expression], decrementing the quasiquote count
|
||||
by one for @racket[expression].
|
||||
|
||||
Normally, an unquote is written with @litchar{,}, but it can also be
|
||||
written with @racket[unquote].}
|
||||
|
||||
|
||||
@deftogether[(
|
||||
@defform/none[(unsyntax @elem{@racketvalfont[",@"]@racket[expression]})]
|
||||
@defform[(unquote-splicing expression)]
|
||||
)]{
|
||||
|
||||
Under a single quasiquote, @racketfont[",@"]@racket[expression] escapes from
|
||||
the quote to include an evaluated expression whose result is a list to
|
||||
splice into the abbreviated list.
|
||||
|
||||
Under multiple quasiquotes, a splicing unquote is like an unquote;
|
||||
that is, it decrements the quasiquote count by one.
|
||||
|
||||
Normally, a splicing unquote is written with @litchar{,}, but it can
|
||||
also be written with @racket[unquote-splicing].}
|
||||
|
||||
@defform[(... (local [definition ...] expression))]{
|
||||
|
||||
Groups related definitions for use in @racket[expression]. Each
|
||||
@racket[definition] can be either a variable definition, a function
|
||||
definition, or a structure definition, using the usual syntax.
|
||||
|
||||
When evaluating @racket[local], each @racket[definition] is evaluated in
|
||||
order, and finally the body @racket[expression] is evaluated. Only the
|
||||
expressions within the @racket[local] (including the right-hand-sides of
|
||||
the @racket[definition]s and the @racket[expression]) may refer to the
|
||||
names defined by the @racket[definition]s. If a name defined in the
|
||||
@racket[local] is the same as a top-level binding, the inner one
|
||||
``shadows'' the outer one. That is, inside the @racket[local], any
|
||||
references to that name refer to the inner one.}
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
|
||||
@defform[(... (letrec ([name expr-for-let] ...) expression))]{
|
||||
|
||||
Like @racket[local], but with a simpler syntax. Each @racket[name] defines
|
||||
a variables (or a functions) with the value of the corresponding
|
||||
@racket[expr-for-let]. If @racket[expr-for-let] is a @racket[lambda],
|
||||
@racket[letrec] defines a function, otherwise it defines a variable.}
|
||||
|
||||
@defform[(... (let* ([name expr-for-let] ...) expression))]{
|
||||
|
||||
Like @racket[letrec], but each @racket[name] can only be used in
|
||||
@racket[expression], and in @racket[expr-for-let]s occuring after that
|
||||
@racket[name].}
|
||||
|
||||
@defform[(... (let ([name expr-for-let] ...) expression))]{
|
||||
|
||||
Like @racket[letrec], but the defined @racket[name]s can be used only in
|
||||
the last @racket[expression], not the @racket[expr-for-let]s next to the
|
||||
@racket[name]s.}
|
||||
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
|
||||
@defform[(time expression)]{
|
||||
|
||||
Measures the time taken to evaluate @racket[expression]. After evaluating
|
||||
@racket[expression], @racket[time] prints out the time taken by the
|
||||
evaluation (including real time, time taken by the cpu, and the time spent
|
||||
collecting free memory). The value of @racket[time] is the same as that of @racket[expression].}
|
||||
)))
|
||||
|
||||
(define (prim-ops lib ctx-stx)
|
||||
(let ([ops (map (lambda (cat)
|
||||
(cons (car cat)
|
||||
|
@ -60,7 +472,8 @@
|
|||
(make-flow
|
||||
(list
|
||||
(make-paragraph
|
||||
(list "A " (racket _prim-op) " is one of:")))))
|
||||
(list "In function calls, the function appearing immediatly after the open parenthesis can be any functions
|
||||
defined with " (racket define) " or " (racket define-struct) ", or any one of:")))))
|
||||
(apply
|
||||
append
|
||||
(map (lambda (category)
|
||||
|
@ -110,6 +523,7 @@
|
|||
(defthing/proc
|
||||
id
|
||||
(to-paragraph (typeset-type (cadr func)))
|
||||
(cons "Purpose: " desc-strs))))))
|
||||
desc-strs)))))
|
||||
(sort-category category)))))
|
||||
ops)))))
|
||||
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
#reader scribble/reader
|
||||
#lang scheme/base
|
||||
(require "common.rkt"
|
||||
scribble/decode
|
||||
(for-label lang/htdp-beginner-abbr))
|
||||
#lang racket/base
|
||||
(require "common.ss"
|
||||
scribble/decode)
|
||||
|
||||
(provide prim-nonterms
|
||||
racketgrammar*+library
|
||||
|
@ -12,17 +11,17 @@
|
|||
|
||||
(define-syntax-rule (racketgrammar*+library
|
||||
#:literals lits
|
||||
(check-expect check-within check-error require)
|
||||
(check-expect check-within check-member-of check-range check-error require)
|
||||
form ...)
|
||||
(racketgrammar*
|
||||
#:literals lits
|
||||
form ...
|
||||
[test-case @#,racket[(check-expect expr expr)]
|
||||
@#,racket[(check-within expr expr expr)]
|
||||
@#,racket[(check-member-of expr expr (... ...))]
|
||||
@#,racket[(check-range expr expr expr)]
|
||||
@#,racket[(check-error expr expr)]
|
||||
@#,racket[(check-error expr)]]
|
||||
[test-case @#,racket[(check-expect expression expression)]
|
||||
@#,racket[(check-within expression expression expression)]
|
||||
@#,racket[(check-member-of expression expression (... ...))]
|
||||
@#,racket[(check-range expression expression expression)]
|
||||
@#,racket[(check-error expression expression)]
|
||||
@#,racket[(check-error expression)]]
|
||||
(...
|
||||
[library-require @#,racket[(require string)]
|
||||
@#,racket[(require (lib string string ...))]
|
||||
|
@ -32,14 +31,14 @@
|
|||
|
||||
(define-syntax-rule (racketgrammar*+qq
|
||||
#:literals lits
|
||||
(check-expect check-within check-error require)
|
||||
(check-expect check-within check-member-of check-range check-error require)
|
||||
form ...)
|
||||
(racketgrammar*+library
|
||||
#:literals lits
|
||||
(check-expect check-within check-error require)
|
||||
(check-expect check-within check-member-of check-range check-error require)
|
||||
form ...
|
||||
(...
|
||||
[quoted id
|
||||
[quoted name
|
||||
number
|
||||
string
|
||||
character
|
||||
|
@ -49,22 +48,23 @@
|
|||
@#,elem{@racketfont{,}@racket[quoted]}
|
||||
@#,elem{@racketfont[",@"]@racket[quoted]}])
|
||||
(...
|
||||
[quasiquoted id
|
||||
[quasiquoted name
|
||||
number
|
||||
string
|
||||
character
|
||||
@#,racket[(quasiquoted ...)]
|
||||
@#,elem{@racketvalfont{'}@racket[quasiquoted]}
|
||||
@#,elem{@racketvalfont{`}@racket[quasiquoted]}
|
||||
@#,elem{@racketfont{,}@racket[expr]}
|
||||
@#,elem{@racketfont[",@"]@racket[expr]}])))
|
||||
@#,elem{@racketfont{,}@racket[expression]}
|
||||
@#,elem{@racketfont[",@"]@racket[expression]}])))
|
||||
|
||||
(define-syntax-rule (prim-nonterms (section-prefix) define define-struct)
|
||||
|
||||
(define prim-nonterms
|
||||
(make-splice
|
||||
(list
|
||||
|
||||
@t{An @racket[_id] is a sequence of characters not including a
|
||||
space or one of the following:}
|
||||
@t{An @racket[_name] or a @racket[_variable] is a sequence of characters
|
||||
not including a space or one of the following:}
|
||||
|
||||
@t{@hspace[2] @litchar{"} @litchar{,} @litchar{'} @litchar{`}
|
||||
@litchar{(} @litchar{)} @litchar{[} @litchar{]}
|
||||
|
@ -74,13 +74,22 @@ space or one of the following:}
|
|||
@t{A @racket[_number] is a number such as @racket[123], @racket[3/2], or
|
||||
@racket[5.5].}
|
||||
|
||||
@t{A @racket[_symbol] is a quote character followed by a name. A
|
||||
symbol is a value, just like 0 or empty.}
|
||||
|
||||
@t{A @racket[_string] is enclosed by a pair of @litchar{"}. Unlike
|
||||
symbols, strings may be split into characters and manipulated by a
|
||||
variety of primitive functions. For example, @racket["abcdef"],
|
||||
variety of functions. For example, @racket["abcdef"],
|
||||
@racket["This is a string"], and @racket[#,ex-str] are all strings.}
|
||||
|
||||
@t{A @racket[_character] begins with @litchar{#\} and has the
|
||||
name of the character. For example, @racket[#\a], @racket[#\b],
|
||||
and @racket[#\space] are characters.}
|
||||
|
||||
@t{In @seclink[(string-append section-prefix "-syntax")]{function calls}, the function appearing
|
||||
immediatly after the open parenthesis can be any functions defined
|
||||
with @racket[define] or @racket[define-struct], or any one of the
|
||||
@seclink[(string-append section-prefix "-pre-defined")]{pre-defined functions}.}
|
||||
|
||||
)))
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user