;;; ;;; General Utilities (not included in standard library) ;;; ;;; Pretty printer for functions: (define PP (rlambda [call env esc cont] (normalize (arg 1 call) env esc (lambda [proc] (let [[name 'lambda] [proc \proc]] (begin (cond [(closure proc) "ok"] [(function proc) (letseq [[string (externalize call)] [index (string-search " " string)]] (begin (print ps "We'll assume you meant to type " (substring 1 index string) #↑ (substring (1+ index) (string-length string) string) cr) (set proc ↑proc)))] [$true (error "Unknown structure type")]) (cond [(reflective-closure proc) (set name 'rlambda) (set proc (extract-simple-closure proc))] [(macro-closure proc) (set name 'mlambda) (set proc (extract-simple-closure proc))] [$true "ok"]) (if (primitive-closure proc) (print ps "Primitive:" cr) "ok") ; (pp-printer proc name) (print ps '(,name ,(pattern proc) ,(body proc)) cr) (cont '"ok"))))))) ;;; (define PP-PRINTER ;;; (lambda [proc name] ;;; (if (not (= ↑(closure-environment proc) ↑global)) ;;; (let [[vars (contour-variables (closure-environment proc))]] ;;; ;;; ... this will not be trivial to write ... ;;; ;;; Pretty printer for functions. Pretty trivial: prints out a pseudo-redex ;;; with the procedure name cons'ed onto the pattern. So (help +) returns ;;; '(+ number-1 number-2) (define HELP (rlambda [call env esc cont] (normalize (arg 1 call) env esc (lambda [proc] (cont ↑(pcons (arg 1 call) (pattern proc))))))) (let [[helper (lambda [comparator] (letrec [[loop (lambda [current remaining] (if (null remaining) current (loop (if (comparator current (first remaining)) current (first remaining)) (rest remaining))))]] (lambda args (if (null args) (error "Too few arguments" 'MIN/MAX) (loop (first args) (rest args))))))]] [(define MIN (helper <)) (define MAX (helper >))]) (define 1st first) (define 2nd second) (define 3rd third) (define 4th fourth) (define 5th fifth) (define carriage-return cr) (define MAPPEND (lambda args (append . (map . args)))) ;;; (COLLECT predicate selector sequence) designates the sequence ;;; of (selector element) for each element of sequence for which ;;; (predicate element) is true. (define COLLECT (lambda [predicate selector sequence] (mappend (lambda [element] (if (predicate element) [(selector element)] [])) sequence))) (define FILTER (lambda [predicate sequence] (mappend (lambda [element] (if (predicate element) [element] [])) sequence))) ;;; General purposes COMPOSE: ;;; ;;; ((compose f1 f2 ... fk) a1 a2 ... an) ; 1 =< k ;;; ;;; => (f1 (f2 ... (fk a1 a2 ... an)...)) ; 0 =< n (define COMPOSE (lambda funs (cond [(null funs) (lambda args args)] [(null (rest funs)) (first funs)] [$true (lambda args ((first funs) ((compose . (rest funs)) . args)))]))) (define CONSTANT (lambda [constant] (lambda args constant))) (define ERROR-PROTECT (mlambda [call] '(,↑cps-error-protect ,(arg 1 call) ,↑id ,(arg 2 call)))) (define EVERY-CHARACTER (lambda [predicate string] (cond [(string-null string) $true] [(predicate (string-first string)) (every-character predicate (string-rest string))] [$true $false]))) ;;; DYNAMIC-CATCH ;;; DYNAMIC-THROW ;;; ============= (define DYNAMIC-CATCH (rlambda [call env esc cont] (cont (normalize (arg 1 call) env esc id)))) (define DYNAMIC-THROW (rlambda [call env esc cont] (normalize (arg 1 call) env esc id)))