8.3

## Dan Scheme

 #lang dan-scheme package: dan-scheme
This is a little Scheme-like language for situations in which simplicity is preferred over convenience.

### 1Pairs

 procedure(cons a d) → pair? a : any/c d : any/c
Creates a pair whose car is a and whose cdr is d.

 procedure(car p) → any/c p : pair?
Finds the first element of p.

 procedure(cdr p) → any/c p : pair?
Finds the second element of p.

 procedure(pair? p) → boolean? p : any/c
Returns #t if p is a pair of the sort built with cons, or #f otherwise.

### 2Quotations

 syntax(quote e)
Suspends evaluation of e, constructing an S-expression data structure. Often written with an apostrophe.

 syntax(quasiquote e)
Suspends evaluation of e, allowing a return to evaluation using unquote. Often written with a back-quote.

 syntax(unquote e)
Resumes evaluation of e within a quasiquote. Often written with a comma.

### 3Equality Predicates

 procedure(equal? a b) → boolean? a : any/c b : any/c
Recursively compares a and b for equality. Return #f if a difference is found, or #t if not.

 procedure(eqv? x y) → boolean? x : any/c y : any/c
Non-recursively compares x and y for equality. Return #f if a difference is found, or #t if not. This should be used to compare symbols.

### 4Arithmetic

 procedure(number? v) → boolean? v : any/c
Checks whether v is a number.

 procedure(+ x ...) → number? x : number?
Computes the sum of x .... If no numbers are provided, returns 0.

 procedure(- x0 x1 ...) → number? x0 : number? x1 : number?
Computes the difference of x0 and x1 ....

 procedure(* x ...) → number? x : number?
Computes the product of x .... If no numbers are provided, returns 1.

 procedure(/ x0 x1 ...) → number? x0 : number? x1 : number?
If exactly one number x0 is provided, returns its reciprocal. Otherwise, the quotient of x0 and the product of x1 ... is returned.

 procedure(add1 x) → number? x : number?
Returns one greater than x.

 procedure(sub1 x) → number? x : number?
Returns one less than x.

### 5Numeric Comparisons

 procedure(= x0 x1 x2 ...) → boolean? x0 : number? x1 : number? x2 : number?
Checks whether all arguments are equal numbers.

 procedure(< x0 x1 x2 ...) → boolean? x0 : number? x1 : number? x2 : number?
Checks whether x0 x1 x2 ... form a strictly increasing sequence of numbers.

 procedure(> x0 x1 x2 ...) → boolean? x0 : number? x1 : number? x2 : number?
Checks whether x0 x1 x2 ... form a strictly decreasing sequence of numbers.

 procedure(<= x0 x1 x2 ...) → boolean? x0 : number? x1 : number? x2 : number?
Checks whether x0 x1 x2 ... form an increasing sequence of numbers.

 procedure(>= x0 x1 x2 ...) → boolean? x0 : number? x1 : number? x2 : number?
Checks whether x0 x1 x2 ... form a decreasing sequence of numbers.

### 6Membership

 procedure(memv needle haystack) → (or/c #f list?) needle : any/c haystack : list?
Returns the first pair of haystack whose car is eqv? with needle, or #f if no such pair exists in haystack.

 procedure(assv key associations) → (or/c #f pair?) key : any/c associations : list?
Returns the first pair found in associations whose car is eqv? with key, or #f if the key has no association in associations.

### 7Lists

 procedure(list? v) → boolean? v : any/c
Checks whether v is a proper list.

 procedure(list-ref haystack n) → any/c haystack : list? n : number?
Finds the nth element of haystack, where the first element is 0.

 procedure(map f list) → list? f : procedure? list : list?
Apply f to each element of list in order, constructing a new list of the results.

### 8Functions

 procedure(apply f arg ... args) → any/c f : procedure? arg : any/c args : list?
Apply f to the argument list constructed from arg ... and args.

 syntax(lambda (x ...) body) (lambda args body)
In the first form, construct a function that binds x ... in body. In the second form, construct a function that binds args to the entire list of arguments. However, in Dan Scheme, the second form of lambda must pass its argument list directly to a helper.

 syntax(λ (x ...) body) (λ args body)
See lambda.

### 9Booleans

 syntax(and b ...)
If any of b ... are #f, this form evaluates to #f. Otherwise, it evaluates to the last b, or #t if b ... is empty.

 syntax(or b ...)
If all of b ... are #f, this form evaluates to #f. Otherwise, it evaluates to the first non-#f b, or #f if b ... is empty.

 procedure(not b) → boolean? b : any/c
Evaluates to #t if b is #f, or #f otherwise.

 procedure(boolean? v) → boolean? v : any/c
Evaluates to #t if v is either #t or #f, or #f if v is anything else.

 syntax(if c t e)
Evaluates to t if c is not #f, or e otherwise.

 syntax(cond (c e) ...) (cond (c e) ... (else e2))
Evaluates each c in turn, until one is non-"#f". The result is the corresponding "e". If there is an else-clause, it is used if non of the c ... are non-#f.

### 10Symbols

 procedure(symbol? v) → boolean? v : any/c
#t if v is a symbol, #f otherwise.

### 11Definitions and Other Binders

syntax

 (define x e)
 (define (f x ...) e)
In the first form, binds x to the value of e. The second form is equivalent to (define f (lambda (x ...) e)).

 syntax(let ((x e) ...) body)
Binds each x ... to the value of the corresponding e ... in body.

### 12Macros

syntax

 (define-syntax op (syntax-rules (literal ...) (pattern expr) ...))
Associates the new special form op with the macro defined by the syntax-rules form. In Dan Scheme, define-syntax must be followed by syntax-rules.

 syntax(syntax-rules (literal ...) (pattern stx) ...)
Attempts to match each pattern against the syntax being transformed, hygienically expanding to the corresponding stx when one matches. The identifiers in literal ... are matched directly as keywords.

 syntax
Specifies zero or more repetitions of a form.

### 13Modules

Because simplicity is not always to be valued over convenience, Dan Scheme supports importing Racket identifiers. See Racket’s documentation for the meanings of require, provide, all-defined-out, and for-syntax.