194 lines
7.3 KiB
Racket
194 lines
7.3 KiB
Racket
#lang at-exp scheme/base
|
|
|
|
(require "teachprims.rkt" "and-or-map.rkt"
|
|
mzlib/etc
|
|
(only-in racket/list argmin argmax)
|
|
syntax/docprovide
|
|
(for-syntax scheme/base))
|
|
|
|
;; Documents the procedures:
|
|
(require "provide-and-scribble.rkt")
|
|
|
|
(provide-and-scribble
|
|
procedures
|
|
|
|
(begin
|
|
(require scribble/manual scribble/eval "sl-eval.rkt")
|
|
(define (isl)
|
|
(define *bsl
|
|
(isl+-eval
|
|
; (require 2htdp/image)
|
|
(define i 3)
|
|
(define a-list '(0 1 2 3 4 5 6 7 8 9))
|
|
(define threshold 3)))
|
|
(set! isl (lambda () *bsl))
|
|
*bsl))
|
|
|
|
(all-from-except beginner: (submod lang/private/beginner-funs without-wrapper) procedures + * / append)
|
|
|
|
("Numbers (relaxed conditions)"
|
|
@defproc[(+ [x number] ...) number]{
|
|
Adds all given numbers.
|
|
In ISL and up: @racket[+] works when applied to only one number or none.
|
|
@interaction[#:eval (isl) (+ 2/3 1/16) (+ 3 2 5 8) (+ 1) (+)]
|
|
}
|
|
@defproc[(* [x number] ...) number]{
|
|
Multiplies all given numbers.
|
|
In ISL and up: @racket[*] works when applied to only one number or none.
|
|
@interaction[#:eval (isl) (* 5 3) (* 5 3 2) (* 2) (*)]
|
|
}
|
|
@defproc[(/ [x number] [y number] ...) number]{
|
|
Divides the first by all remaining numbers.
|
|
In ISL and up: @racket[/] computes the inverse when applied to only one number.
|
|
@interaction[#:eval (isl) (/ 12 2) (/ 12 2 3) (/ 3)]
|
|
}
|
|
)
|
|
|
|
; ("Posn" )
|
|
|
|
("Lists"
|
|
@defproc[((intermediate-append append) [l (listof any)] ...) (listof any)]{
|
|
Creates a single list from several, by juxtaposition of the items.
|
|
In ISL and up: @racket[append] also works when applied to one list or none.
|
|
@interaction[#:eval (isl)
|
|
(append (cons 1 (cons 2 empty)) (cons "a" (cons "b" empty)))
|
|
(append)]})
|
|
|
|
("Higher-Order Functions"
|
|
@defproc[(map [f (X ... -> Z)] [l (listof X)] ...) (listof Z)]{
|
|
Constructs a new list by applying a function to each item on one or more existing lists:
|
|
@codeblock{(map f (list x-1 ... x-n)) = (list (f x-1) ... (f x-n))}
|
|
@interaction[#:eval (isl)
|
|
(map add1 '(3 -4.01 2/5))
|
|
(map (lambda (x) (list 'my-list (+ x 1))) '(3 -4.01 2/5))]
|
|
}
|
|
@defproc[(for-each [f (any ... -> any)] [l (listof any)] ...) void?]{
|
|
Applies a function to each item on one or more lists for effect only:
|
|
@codeblock{(for-each f (list x-1 ... x-n)) = (begin (f x-1) ... (f x-n))}
|
|
@interaction[#:eval (asl-eval)
|
|
(for-each (lambda (x) (begin (display x) (newline))) '(1 2 3))
|
|
]
|
|
}
|
|
@defproc[((intermediate-filter filter) [p? (X -> boolean)] [l (listof X)]) (listof X)]{
|
|
Constructs a list from all those items on a list for which the predicate holds.
|
|
@interaction[#:eval (isl)
|
|
(filter odd? '(0 1 2 3 4 5 6 7 8 9))
|
|
threshold
|
|
(filter (lambda (x) (>= x threshold)) '(0 1 2 3 4 5 6 7 8 9))
|
|
]
|
|
}
|
|
@defproc[((intermediate-foldr foldr) [f (X Y -> Y)] [base Y] [l (listof X)]) Y]{
|
|
@codeblock{(foldr f base (list x-1 ... x-n)) = (f x-1 ... (f x-n base))}
|
|
@interaction[#:eval (isl)
|
|
(foldr + 0 '(0 1 2 3 4 5 6 7 8 9))
|
|
a-list
|
|
(foldr (lambda (x r) (if (> x threshold) (cons (* 2 x) r) r)) '() a-list)
|
|
]
|
|
}
|
|
@defproc[((intermediate-foldl foldl) [f (X Y -> Y)] [base Y] [l (listof X)]) Y]{
|
|
@codeblock{(foldl f base (list x-1 ... x-n)) = (f x-n ... (f x-1 base))}
|
|
@interaction[#:eval (isl)
|
|
(foldl + 0 '(0 1 2 3 4 5 6 7 8 9))
|
|
a-list
|
|
(foldl (lambda (x r) (if (> x threshold) (cons (* 2 x) r) r)) '() a-list)
|
|
]
|
|
}
|
|
@defproc[(build-list [n nat] [f (nat -> X)]) (listof X)]{
|
|
Constructs a list by applying @racket[f] to the numbers between @racket[0] and @racket[(- n 1)]:
|
|
@codeblock{(build-list n f) = (list (f 0) ... (f (- n 1)))}
|
|
@interaction[#:eval (isl)
|
|
(build-list 22 add1)
|
|
i
|
|
(build-list 3 (lambda (j) (+ j i)))
|
|
(build-list 5
|
|
(lambda (i)
|
|
(build-list 5
|
|
(lambda (j)
|
|
(if (= i j) 1 0)))))
|
|
]
|
|
}
|
|
@defproc[((intermediate-build-string build-string) [n nat] [f (nat -> char)]) string]{
|
|
Constructs a string by applying @racket[f] to the numbers between @racket[0] and @racket[(- n 1)]:
|
|
@codeblock{(build-string n f) = (string (f 0) ... (f (- n 1)))}
|
|
@interaction[#:eval (isl)
|
|
(build-string 10 integer->char)
|
|
(build-string 26 (lambda (x) (integer->char (+ 65 x))))]
|
|
}
|
|
@defproc[((intermediate-quicksort quicksort) [l (listof X)] [comp (X X -> boolean)]) (listof X)]{
|
|
Sorts the items on @racket[l], in an order according to @racket[comp] (using the quicksort algorithm).
|
|
@interaction[#:eval (isl)
|
|
(quicksort '(6 7 2 1 3 4 0 5 9 8) <)]
|
|
}
|
|
@defproc[((intermediate-sort sort) [l (listof X)] [comp (X X -> boolean)]) (listof X)]{
|
|
Sorts the items on @racket[l], in an order according to @racket[comp].
|
|
@interaction[#:eval (isl)
|
|
(sort '(6 7 2 1 3 4 0 5 9 8) <)]
|
|
}
|
|
@defproc[((intermediate-andmap andmap) [p? (X -> boolean)] [l (listof X)]) boolean]{
|
|
Determines whether @racket[p?] holds for all items of @racket[l]:
|
|
@codeblock{(andmap p (list x-1 ... x-n)) = (and (p x-1) ... (p x-n))}
|
|
@interaction[#:eval (isl)
|
|
(andmap odd? '(1 3 5 7 9))
|
|
threshold
|
|
(andmap (lambda (x) (< x threshold)) '(0 1 2))
|
|
(andmap even? '())
|
|
]
|
|
}
|
|
@defproc[((intermediate-ormap ormap) [p? (X -> boolean)] [l (listof X)]) boolean]{
|
|
Determines whether @racket[p?] holds for at least one items of @racket[l]:
|
|
@codeblock{(ormap p (list x-1 ... x-n)) = (or (p x-1) ... (p x-n))}
|
|
@interaction[#:eval (isl)
|
|
(ormap odd? '(1 3 5 7 9))
|
|
threshold
|
|
(ormap (lambda (x) (< x threshold)) '(6 7 8 1 5))
|
|
(ormap even? '())
|
|
]
|
|
}
|
|
@defproc[(argmin [f (X -> real)] [l (listof X)]) X]{
|
|
Finds the (first) element of the list that minimizes the output of the function.
|
|
@interaction[#:eval (isl)
|
|
(argmin second '((sam 98) (carl 78) (vincent 93) (asumu 99)))
|
|
]
|
|
}
|
|
@defproc[(argmax [f (X -> real)] [l (listof X)]) X]{
|
|
Finds the (first) element of the list that maximizes the output of the function.
|
|
@interaction[#:eval (isl)
|
|
(argmax second '((sam 98) (carl 78) (vincent 93) (asumu 99)))
|
|
]
|
|
}
|
|
@defproc[(memf [p? (X -> any)] [l (listof X)]) (union false (listof X))]{
|
|
Produces @racket[false] if @racket[p?] produces @racket[false] for all
|
|
items on @racket[l]. If @racket[p?] produces @racket[true] for any of
|
|
the items on @racket[l], @racket[memf] returns the sub-list starting
|
|
from that item.
|
|
@interaction[#:eval (isl)
|
|
(memf odd? '(2 4 6 3 8 0))
|
|
]
|
|
}
|
|
@defproc[(apply [f (X-1 ... X-N -> Y)] [x-1 X-1] ... [l (list X-i+1 ... X-N)]) Y]{
|
|
Applies a function using items from a list as the arguments:
|
|
@codeblock{(apply f (list x-1 ... x-n)) = (f x-1 ... x-n)}
|
|
@interaction[#:eval (isl)
|
|
a-list
|
|
(apply max a-list)
|
|
]
|
|
}
|
|
@defproc[(compose [f (Y -> Z)] [g (X -> Y)]) (X -> Z)]{
|
|
Composes a sequence of procedures into a single procedure:
|
|
@codeblock{(compose f g) = (lambda (x) (f (g x)))}
|
|
@interaction[#:eval (isl)
|
|
((compose add1 second) '(add 3))
|
|
(map (compose add1 second) '((add 3) (sub 2) (mul 4)))
|
|
]
|
|
}
|
|
@defproc[(procedure? [x any]) boolean?]{
|
|
Produces true if the value is a procedure.
|
|
@interaction[#:eval (isl)
|
|
(procedure? cons)
|
|
(procedure? add1)
|
|
(procedure? (lambda (x) (> x 22)))
|
|
]
|
|
}
|
|
)
|
|
)
|