Standard package includes special forms and built-in functions listed in Scheme Standard.
quote datum) evaluates to datum. Datum may be
any external representation of a Scheme object. This notation is used to
include literal constants in Scheme code.
(quote a) ==> a (quote #(a b c)) ==> #(a b c) (quote (+ 1 2)) ==> (+ 1 2)
(quote datum) may be abbreviated as
'datum. The two notations are equivalent in all respects.
'a ==> a '#(a b c) ==> #(a b c) '() ==> () '(+ 1 2) ==> (+ 1 2) '(quote a) ==> (quote a) ''a ==> (quote a)
A lambda expression evaluates to a procedure. The environment in
effect when the lambda expression was evaluated is remembered as
part of the procedure. When the procedure is later called with some
actual arguments, the environment in which the lambda expression
was evaluated will be extended by binding the variables in the formal
argument list to fresh locations, the corresponding actual argument
values will be stored in those locations, and the expression in the body
of the lambda expression will be evaluated sequentially in the
extended environment. The result of the last expression in the body will
be returned as the result of the procedure call.
(lambda (x) (+ x x)) ==> a procedure
((lambda (x) (+ x x)) 4) ==> 8
(define reverse-subtract
(lambda (x y) (- y x)))
(reverse-subtract 7 10) ==> 3
(define add4
(let ((x 4))
(lambda (y) (+ x y))))
(add4 6) ==> 10
Formals should have one of the following forms:
((lambda x x) 3 4 5 6) ==> (3 4 5 6)
((lambda (x y . z) z) 3 4 5 6) ==> (5 6)
(define (f a b &optional c) (list a b c)) (f 1 2 3) ==> (1 2 3) (f 1 2) ==> (1 2 '()) (define (f a b &optional (c 10)) (list a b c)) (f 1 2 3) ==> (1 2 3) (f 1 2) ==> (1 2 10) (define (f a b &rest rest) (list a b rest)) (f 1 2 3 4 5) ==> (1 2 (3 4 5)) (define (f a b &key c) (list a b c)) (f 1 2 :c 12) ==> (1 2 12) (f 1 2) ==> (1 2 '()) (define (f a b &key (c 100) (d 200)) (list a b c d)) (f 1 2 :d 4 :c 3) ==> (1 2 3 4) (f 1 2) ==> (1 2 100 200) (define (f a b &optional (args) &key c) args) (f 1 2 3 4 5 :c 100) ==> (3 4 5) (define (f a b &optional (args) &rest rest &key c) args) (f 1 2 3 4 5 :c 100) ==> (3 4 5) (define (f a b &optional (args) &rest rest &key c) rest) (f 1 2 3 4 5 :c 100) ==> (:c 100)
(define variable (lambda (formals) body))
In the third form, formal should be a single variable. This form is equivalent to
(define variable (lambda formal body))
At the top level of a program, a definition
(define variable expression)
has essentially the same effect as the assignment expression
(set! variable expression)
if variable is bound. If variable is not bound, however,
then the definition will bind variable to a new location before
performing the assignment, whereas it would be an error to perform
set! on an unbound variable.
(define add3 (lambda (x) (+ x 3))) (add3 3) ==> 6 (define first car) (first '(1 2)) ==> 1
Definitions may occur at the beginning of a body (that is, the
body of a lambda, let, let*, letrec,
let-syntax, or letrec-syntax expression). Such definitions
are known as internal definitions as opposed to the top level
definitions described above. The variable defined by an internal
definition is local to the body. That is, variable is bound
rather than assigned, and the scope of the binding is the entire
body. For example,
(let ((x 5)) (define foo (lambda (y) (bar x y))) (define bar (lambda (a b) (+ (* a b) a))) (foo (+ x 3))) ==> 45
A body containing internal definitions can always be converted
into a completely equivalent letrec expression. For example, the
let expression in the above example is equivalent to
(let ((x 5))
(letrec ((foo (lambda (y) (bar x y)))
(bar (lambda (a b) (+ (* a b) a))))
(foo (+ x 3))))
Just as for the equivalent letrec expression, it must be possible
to evaluate each expression of every internal definition in a
body without assigning or referring to the value of any
variable being defined.
An if expression is evaluated as follows: first, test is
evaluated. If it yields a true value, then consequent is evaluated
and its value is returned. Otherwise alternate is evaluated and
its value is returned. If test yields a false value and no
alternate is specified, then the result of the expression is
unspecified.
(if (> 3 2) 'yes 'no) ==> yes (if (> 2 3) 'yes 'no) ==> no (if (> 3 2) (- 3 2) (+ 3 2)) ==> 1
set! expression or at top
level. The result of the set! expression is unspecified.
(define x 2) (+ x 1) ==> 3 (set! x 4) (+ x 1) ==> 5
set!, but returns the value of expression
(define x 1) (set! x 10) ==> #<unspecified> (set-value! x 20) ==> 20
(test expression ...)
where test is any expression. Alternatively, a clause may be of the form
(test => expression)
The last clause may be an "else clause," which has the form
(else expression1 expression2 ...)
A cond expression is evaluated by evaluating the test
expression of successive clause's in order until one of them
evaluates to a true value. When a test evaluates to a true value,
then the remaining expression's in its clause are evaluated
in order, and the result of the last expression in the
clause is returned as the result of the entire cond
expression. If the selected clause contains only the test
and no expression's, then the value of the test is returned
as the result. If the selected clause uses the => alternate
form, then the expression is evaluated. Its value must be a
procedure that accepts one argument; this procedure is then called with
the value of the test as the only argument and the value returned
by this procedure is returned by the cond expression. If all
test's evaluate to false values, and there is no else clause, then
the result of evaluation of the cond expression is unspecified;
if there is an else clause, then its expression's are evaluated,
and the value of the last one is returned.
(cond ((> 3 2) 'greater)
((< 3 2) 'less)) ==> greater
(cond ((> 3 3) 'greater)
((< 3 3) 'less)
(else 'equal) ==> equal
(cond ((assv 'b '((a 1) (b 2))) => cadr)
(else #f)) ==> 2
((datum1 ...) expression1 expression2 ...)
where each datum is an identifier or a literal. All the datum's must be distinct. The last clause may be an "else clause," which has the form
(else expression1 expression2 ...)
A case expression is evaluated as follows. Key is evaluated
and its result is compared against each datum. If the result of
evaluating key is equivalent (in the sense of eqv?) to a
datum, then the expressions in the corresponding clause are
evaluated from left to right and the result of the last expression in
the clause is returned as the result of the case expression. If
the result of evaluating key is different from every datum,
then if there is an else clause its expressions are evaluated and the
result of the last is the result of the case expression;
otherwise the result of the case expression is unspecified.
(case (* 2 3) ((2 3 5 7) 'prime) ((1 4 6 8 9) 'composite)) ==> composite (case (car '(c d)) ((a) 'a) ((b) 'b)) ==> #<unspecified> (case (car '(c d)) ((a e i o u) 'vowel) ((w y) 'semivowel) (else 'consonant)) ==> consonant
#t is returned.
(and (= 2 2) (> 2 1)) ==> #t (and (= 2 2) (< 2 1)) ==> #f (and 1 2 'c '(f g)) ==> (f g) (and) ==> #t
#f is returned.
(or (= 2 2) (> 2 1)) ==> #t
(or (= 2 2) (< 2 1)) ==> #t
(or #f #f #f) ==> #f
(or (memq 'b '(a b c))
(/ 3 0)) ==> (b c)
(or) ==> #f
((variable1 init1) ...)
where each init is an expression, and body should be a sequence of one or more expressions. It is an error for a variable to appear more than once in the list of variables being bound.
The init's are evaluated in the current environment (in some unspecified order), the variable's are bound to fresh locations holding the results, the body is evaluted in the extended environment, and the value of the last expression of body is returned. Scope of each variable is restricted to body.
(let ((x 2) (y 3))
(* x y)) ==> 6
(let ((x 2) (y 3))
(let ((x 7)
(z (+ x y)))
(* z x))) ==> 35
let" is a variant on the syntax of let which
provides a more general looping construct than do and may also be
used to express recursions. It has the same syntax and semantics as
ordinary let except that variable is bound within
body to a procedure whose formal arguments are the bound variables
and whose body is body. Thus the execution of body may be
repeated by invoking the procedure named by variable.
(let loop ((numbers '(3 -2 1 6 -5))
(nonneg '())
(neg '()))
(cond ((null? numbers) (list nonneg neg))
((>= (car numbers) 0)
(loop (cdr numbers)
(cons (car numbers) nonneg)
neg))
((< (car numbers) 0)
(loop (cdr numbers)
nonneg
(cons (car numbers) neg)))))
==> ((6 1 3) (-5 -2))
((variable1 init1) ...)
where each init is an expression, and body should be a sequence of one or more expressions.
let* is similar to let, but the bindings are performed
sequentially from left to right, and the region of a binding indicated
by (variable init) is that part of the let*
expression to the right of the binding. Thus the second binding is done
in an environment in which the first binding is visible, and so on.
(let ((x 2) (y 3))
(let* ((x 7)
(z (+ x y)))
(* z x))) ==> 70
((variable1 init1) ...)
and body should be a sequence of one or more expressions. It is an error for a variable to appear more than once in the list of variables being bound.
The variable's are bound to fresh locations holding undefined
values, the init's are evaluated in the resulting environment (in
some unspecified order), each variable is assigned to the result
of the corresponding init, the body is evaluated in the
resulting environment, and the value of the last expression in
body is returned. Scope of each binding of a variable is
the entire letrec expression, making it possible to define
mutually excursive procedures.
(letrec ((even?
(lambda (n)
(if (zero? n)
#t
(odd? (- n 1)))))
(odd?
(lambda (n)
(if (zero? n)
#f
(even? (- n 1))))))
(even? 88))
==> #t
One restriction on letrec is very important: it must be possible
to evaluate each init without assigning or referring to the value
of any variable. If this restriction is violated, then it is an
error. The restriction is necessary because Scheme passes arguments by
value rather than by name. In the most common uses of letrec, all
the init's are lambda expressions and the retriction is
satisfied automatically.
(define x 0)
(begin (set! x 5) (+ x 1)) ==> 6
(begin (display "4 plus 1 equals ")
(display (+ 4 1))) ==> prints "4 plus 1 equals 5", and
returns #<unspecified>
((variable1 init1 step1) ...),
the test-clause should have the form
(test expression ...),
and the body should be a sequence of one or more expressions.
do is an iteration construct. It specifies a set of variables to
be bound, how they are to be initialized at the start, and how they are
to be updated on each iteration. When a termination condition is met,
the loop exits after evaluating the expression's.
do expressions are evaluated as follows: The init
expressions are evaluated (in sompe unspecified order), the
variable's are bound to fresh locations, the results of the
init expressions are stored in the bindings of the
variable's, and then the iteration phase begins.
Each iteration begins by evaluating test; if the result is false, then the expressions in the body are evaluated in order for effect, the step expressions are evaluated in some unspecified order, the variable's are bound to fresh locations, the results of the step's are stored in the bindings of the variable's, and the next iteration begins.
If test evaluates to a true value, then the expression's in
the test-clause evalutated from left to right and the value of the
last expression is returned. If no expression's are present,
then the value of the do expression is unspecified.
Scope of the binding of a variable is the entire do
expression except for the init's. It is an error for a
variable to appear more than once in the list of do
variables.
A step may be omitted, in which case the effect is the same as if (variable init variable) had been written instead of (variable init).
(do ((vec (make-vector 5))
(i 0 (+ i 1)))
((= i 5) vec)
(vector-set! vec i i)) ==> #(0 1 2 3 4)
(let ((x '(1 3 5 7 9)))
(do ((x x (cdr x))
(sum 0 (+ sum (car x))))
((null? x) sum))) ==> 25
$car number.txt
123
$ ksm
> (let ((port (open-input-file "number.txt")))
(prog1 (read port)
(close-input-port port)))
=> 123
@source{base/base.c} @use{none}
`(list ,(+ 1 2) 4) ==> (list 3 4)
(let ((name 'a))
`(list ,name ',name)) ==> (list a (quote a))
`(a ,(+ 1 2) ,@(map abs '(4 -5 6)) b)
==> (a 3 4 5 6 b)
`((foo ,(- 10 3)) ,@(cdr '(c)) . ,(car '(cons)))
==> ((foo 7) . cons)
`#(10 5 ,(sqrt 4) ,@(map sqrt '(16 9)) 8)
==> #(10 5 2 4 3 8)
Quasiquote forms may be nested. Substitutions are made only for unquoted components appearing at the same nesting level as the outermost backquote. The nesting level increases by one inside each successive quasiquotation, and decreases by one inside each unquotation.
`(a `(b ,(+ 1 2) ,(foo ,(+ 1 3) d) e) f)
==> (a `(b ,(+ 1 2) ,(foo 4 d) e) f)
(let ((name1 'x)
(name2 'y))
`(a `(b ,,name1 ,',name2 d) e))
==> (a `(b ,x ,'y d) e)
The two notations `qq-template and (quasiquote
qq-template) are identical in all respects. ,expression is
identical to (unquote expression), and ,@expression
is identical to (unquote-splicing expression).
syntax-rules. The top-level syntactic
environment is extended by binding the keyword to the specified
transformer.
(pattern template)
The pattern in a syntax-rule is a list pattern that begins with the keyword for the macro.
A pattern is either an identifier, a constant, or one of the following.
(pattern ...) (pattern pattern ... . pattern) (pattern ... pattern ellipsis) #(pattern ...) #(pattern ... pattern ellipsis)
and a template is either an identifier, a constant, or one of the following
(element ...) (element ... . template) #(element ....)
where an element is a template optionally followed by an ellipsis and an ellipsis is the identifier "..." (which cannot be used as an identifier in either a template or a pattern).
An instance of syntax-rules produces a new macro transformer by
specifying a sequence of hygienic rewrite rules. A use of a macro whose
keyword is associated with a transformer specified by
syntax-rules is matched against the patterns contained in the
syntax-rule's, beginning with the leftmost syntax-rule. When
a match is found, the macro use is transcribed hygienically according to
the template.
An identifier that appears in the pattern of a syntax-rule is a pattern variable, unless it is the keyword the begins the pattern, is listed in literals, or is the identifier "...". Pattern variables match arbitrary input elements and are used to refer to elements of the input in the template. It is an error for the same pattern variable to appear more than once in a patter.
Th keyword at the beginning of the pattern in a syntax-rule is not involved in the matching and is not considered a pattern variable or literal identifier.
Identifiers that appear in literals are interpreted as literal identifiers to be matched against corresponding subforms of the input. A subform in the input matches a literal identifier if the two identifiers are equal.
A subpattern followed by ... can match zero or more elements of the input. It is an error for ... to appear in literals. Within a pattern the identifier ... must follow the last element of a nonempty sequence of subpatterns.
More formally, an input form F matches a pattern P if and only if:
equal?
procedure.
It is an error to use a macro keyword, within the scope of its binding, in an expression that does not match any of the patterns.
When a macro use is transcribed according to the template of the matching syntax-rule, pattern variables that occur in the template are replaced by the subforms they match in the input. Pattern variables that occur in subpatterns followed by one or more instances of the identifier "..." are allowed only in subtemplates that are followed by as many instances of "...". They are replaced in the output by all of the subforms they match in the input, distributed as indicated. It is an error if the output cannot be built up as specified.
Identifiers that appear in the template but are not pattern variables or
the identifier ... are inserted into the output as literal
identifiers. If a literal identifier is inserted as a free identifier
then it refers to the binding of that identifier within whose scope the
instance of syntax-rules appears. If a literal identifier is
inserted as a bound identifier then it is in effect renamed to prevent
inadvertent captures of free identifiers.
((keyword transformer-spec) ...)
Each keyword is an identifier, each transformer-spec is an
instance of syntax-rules, and body should be a sequence of
one or more expressions. It is an error for a keyword to appear
more than once in the list of keywords being bound.
The body is expanded in the syntactic environment obtained by
extending the syntactic environment of the let-syntax expression
with macros whose keywords are the keyword's, bound to the
specified transformers. Scope of binding of a keyword is body.
(let-syntax ((when (syntax-rules ()
((when test stmt1 stmt2 ...)
(if test
(begin stmt1
stmt2 ...))))))
(let ((if #t))
(when if (set! if 'now))
if)) ==> now
(let ((x 'outer))
(let-syntax ((m (syntax-rules () ((m) x))))
(let ((x 'inner))
(m)))) ==> outer
letrec-syntax
expression with macros whose keywords are the keyword's, bound to
the specified transformers. Scope of each binding of a keyword is
the bindings as well as the body, so the transformers can
transcribe expressions into uses of the macros introduced by the
letrec-syntax expression.
(letrec-syntax
((my-or (syntax-rules ()
((my-or) #f)
((my-or e) e)
((my-or e1 e2 ...)
(let ((temp e1))
(if temp
temp
(my-or e2 ...)))))))
(let ((x #f)
(y 7)
(temp 8)
(let odd?)
(if even?))
(my-or x
(let temp)
(if y)
y))) ==> 7
delay construct is used together with the procedure
force to implement lazy evaluation or call by need.
(delay expression) returns an object called a
promise which at some point in the future may be asked (by the
force procedure) to evaluate expression, and deliver the
resulting value.
(force (delay (+ 1 2))) ==> 3
(let ((p (delay (+ 1 2))))
(list (force p) (force p)) ==> (3 3)
(define a-stream
(letrec ((next
(lambda (n)
(cons n (delay (next (+ n 1)))))))
(next 0)))
(define head car)
(define tail
(lambda (stream) (force (cdr stream))))
(head (tail (tail a-stream))) ==> 2
force and delay are mainly intended for programs written
in functional style. The following examples should not be considered to
illustrate good programming style, but they illustrate the property that
only one value is computed for a promise, no matter how many times it is
forced.
(define count 0)
(define p
(delay (begin (set! count (+ count 1))
(if (> count x)
count
(force p)))))
(define x 5)
p ==> #<promise>
(force p) ==> 6
p ==> #<promise>
(begin (set! x 10)
(force p)) ==> 6
eqv? procedure defines a useful equivalence relation on
objects. Briefly, it returns #t if obj1 and obj2
should normally be regarded as the same object. This relation is left
slightly open to interpretation, but the following partial specification
of eqv? holds for all implementations of Scheme
The eqv? procedure returns #t if:
#t or both #f
(string=? (symbol->string obj1)
(symbol->string obj2))
==> #t
char=? procedure.
The eqv? procedure returns #f if:
#t but the other is
#f.
(string=? (symbol->string obj1)
(symbol->string obj2))
==> #f
= procedure
returns #f.
char=?
procedure returns #f.
(eqv? 'a 'a) ==> #t
(eqv? 'a 'b) ==> #f
(eqv? 2 2) ==> #t
(eqv? '() '()) ==> #t
(eqv? 100000000 100000000) ==> #t
(eqv? (cons 1 2) (cons 1 2)) ==> #f
(eqv? (lambda () 1)
(lambda () 2)) ==> #f
(eqv? #f 'nil) ==> #f
(let ((p (lambda (x) x)))
(eqv? p p)) ==> #t
The following examples in KSM-Scheme illustrate cases in which the boave
rules do not fully specify the behavior of eqv?.
(eqv? "" "") ==> #f in KSM-Scheme
(eqv? '#() '#()) ==> #f in KSM-Scheme
(eqv? (lambda (x) x)
(lambda (x) x)) ==> #f in KSM-Scheme
(eqv? (lambda (x) x)
(lambda (y) y)) ==> #f in KSM-Scheme
eq? is similar to eqv? except that in some cases it is
capable of discerning distinctions finer than those detectable by
eqv?.
eq? and eqv? are guaranteed to have the same behavior on
symbols, booleans, the empty list, pairs, procedures, and non-empty
strings and vectors. eq?'s behavior on numbers and characters is
implementation-dependent, but it will always return either true or
false, and will return true only when eqv? would also return
true. eq? may also behave differently from eqv? on empty
vectors and empty strings.
(eq? 'a 'a) ==> #t (eq? '(a) '(a)) ==> #f in KSM-Scheme (eq? (list 'a) (list 'a)) ==> #f (eq? "a" "a") ==> #f in KSM-Scheme (eq? "" "") ==> #f in KSM-Scheme (eq? '() '()) ==> #t (eq? 2 2) ==> #f in KSM-Scheme (eq? #\A #\A) ==> #f in KSM-Scheme (eq? car car) ==> #t (let ((n (+ 2 3))) (eq? n n)) ==> #t in KSM-Scheme (let ((x '(a))) (eq? x x)) ==> #t (let ((x '#())) (eq? x x)) ==> #t (let ((p (lambda (x) x))) (eq? x x)) ==> #t
equal? recursively compares the contents of pairs, vectors, and
strings, applying eqv? on other objects such as numbers and
symbols. A rule of thumb is that objects are generally equal? if
they print the same. equal? may fail to terminate if its
arguments are circular data structures.
(equal? 'a 'a) ==> #t
(equal? '(a) '(a)) ==> #t
(equal? '(a (b) c)
'(a (b) c)) ==> #t
(equal? "abc" "abc") ==> #t
(equal? 2 2) ==> #t
(equal? (make-vector 5 'a)
(make-vector 5 'a)) ==> #t
(equal? (lambda (x) x)
(lambda (y) y)) ==> #f in KSM-Scheme
#t if the object is of the
named type, and otherwise they return #f. In general, if a type
predicate is true of a number then all higher type predicates are also
true of that number. Consequently, if a type predicate is false of a
number, then all lower type predicates are also false of that number.
If z is an inexact complex number, then (real? z) is
true if and only if (zero? (imag-part z)) is
true. If x is an inexact real number, then (integer?
x) is true if and only if (= x (round
x)).
(complex? 3+4i) ==> #t (complex? 3) ==> #t (real? 3) ==> #t (real? -2.5+0.0i) ==> #t (real? #e1e10) ==> #t (rational? 6/10) ==> #t (rational? 6/3) ==> #t (integer? 3+0i) ==> #t (integer? 3.0) ==> #t (integer? 8/4) ==> #t (integer? 6) ==> #t
(exact? 1) ==> #t (exact? 1/2) ==> #t (exact? 1.2) ==> #f (exact? 1.0) ==> #f (inexact? 1.2) ==> #t (inexact? 1.0+2.0i) ==> #t (inexact? 1) ==> #f
#t if their arguments are (respectively):
equal, monotonically increasing, monotonically decreasing, monotonically
nondecreasing, or monotonically noincreasing.
#t or #f.
(max 3 4) ==> 4 (max 3.9 4) ==> 4 in KSM-Scheme
(+ 3 4) ==> 7 (+ 3) ==> 3 (* 4) ==> 4 (*) ==> 1
(- 3 4) ==> -1 (- 3 4 5) ==> -6 (- 3) ==> -3 (/ 3 4 5) ==> 3/20 (/ 3) ==> 1/3
abs returns the absolute value of its argument.
(abs -7) ==> 7
(quotient n1 n2) ==> n1/n2 (remainder n1 n2) ==> 0 (modulo n1 n2) ==> 0
If n1/n2 is not an integer
(quotient n1 n2) ==> nq (remainder n1 n2) ==> nr (modulo n1 n2) ==> nm
where nq is n1/n2 rounded towards zero, 0 < |nr| < |n2|, 0 < |nm| < |n2|, nr and nm differ from n1 by a multiple of n2, nr has the same sign as n1, and nm has the same sign as n2.
From this we can conclude that for integers n1 and n2 with n2 not equal to 0,
(= n1 (+ (* n2 (quotient n1 n2))
(remainder n1 n2)))
==> #t
provided all numbers involved in that computation are exact.
(modulo 13 4) ==> 1 (remainder 13 4) ==> 1 (modulo -13 4) ==> 3 (remainder -13 4) ==> -1 (modulo 13 -4) ==> -3 (remainder 13 -4) ==> 1 (modulo -13 -4) ==> -1 (remainder -13 -4) ==> -1 (remainder -13 -4.0) ==> -1.0 ; inexact
(gcd 32 -36) ==> 4 (gcd) ==> 9 (lcm 32 -36) ==> 288 (lcm 32.0 -36) ==> #<error> in KSM-Scheme (lcm) ==> 1
(numerator (/ 6 4)) ==> 3 (denominator (/ 6 4)) ==> 2 (denominator (exact->inexact (/ 6 4))) ==> #<error> in KSM-Scheme
floor returns the largest
integer not larger than x. ceiling returns the smallest
integer not smaller than x. truncate returns the integer
closest to x whose absolute value is not larger than the absolute
value of x. If x is halfway between two integers,
round returns the one with larger absolute value. This behavior
is in accord with rint() in C library, and is different from
Scheme Standard which states that round returns the even integer.
(floor -4.3) ==> -5.0 (ceiling -4.3) ==> -4.0 (truncate -4.3) ==> -4.0 (round -4.3) ==> -4.0 (floor 3.5) ==> 3.0 (ceiling 3.5) ==> 4.0 (truncate 3.5) ==> 3.0 (round 3.5) ==> 4.0 ; inexact (round 4.5) ==> 5.0 in KSM-Scheme (it is 4.0 in Scheme Standard) (round 7/2) ==> 4.0 ; exact (round 7) ==> 7
rationalize procedure is not supported in KSM-Scheme. It is an
error to call this procedure.
log
computes the natural logarithm of z (not the base ten
logarithm).
(make-rectangular x y) ==> z (make-polar r theta) ==> z (real-part z) ==> x (imag-part z) ==> y (magnitude z) ==> |r| (angle z) ==> theta
unit of theta is radian.
exact->inexact returns an inexact representation of z. The
value returned is the inexact number that is numerically closest to the
argument. If z is an inexact number, it returns z.
inexact->exact returns an exact representation of z. The
value returned is the exact number that is numerically closest to the
argument. If z is an exact number, it returns z.
number->string
takes a number and a radix and returns as a string an external
representation of the given number in the given radix such that
(let ((number n)
(radix r))
(eqv? number
(string->number (number->string number radix)
radix)))
is true.
If z is other than an integer, the radix shoule be 10.
The result returned by number->string never contains an explicit
radix prefix.
(number->string 100) ==> "100" (number->string 100 2) ==> "1100100" (number->string 100 8) ==> "144" (number->string 100 16) ==> "64"
string->number returns #f.
(string->number "64" 16) ==> 100 (string->number "1100100" 2) ==> 100 (string->number "hello") ==> #f
#t if obj is false, and returns #f
otherwise.
(not #t) ==> #f (not 3) ==> #f (not (list 3)) ==> #f (not #f) ==> #t (not '()) ==> #f (not (list)) ==> #f (not 'nil) ==> #f
#t if obj is either #t or #f, and
returns #f otherwise.
(boolean? #f) ==> #t (boolean? #t) ==> #t (boolean? 0) ==> #f (boolean '()) ==> #f
#t if obj is a pair, and otherwise returns
#f.
(pair? '(a . b)) ==> #t (pair? '(a b c)) ==> #t (pair? '()) ==> #f (pair? '#(a b)) ==> #f
eqv?) from every existing object.
(cons 'a '()) ==> (a)
(cons '(a) '(b c d)) ==> ((a) b c d)
(cons "a" '(b c)) ==> ("a" b c)
(cons 'a 3) ==> (a . 3)
(cons '(a b) 'c) ==> ((a b) . c)
(car '(a b c)) ==> a (car '((a) b c d)) ==> (a) (car '(1 . 2)) ==> 1 (car '()) ==> #<error>
(cdr '((a) b c d)) ==> (b c d) (cdr '(1 . 2)) ==> 2 (cdr '()) ==> #<error>
set-car! is unspecified.
(define p (cons 1 2)) p ==> (1 . 2) (set-car! p 3) p ==> (3 . 2)
set-cdr! is unspecified.
car and cdr, where
for example caddr could be defined by
(define caddr (lambda (x) (car (cdr (cdr x)))))
Arbitrary compositions, up to four deep, are provided. There are twenty-eight of these procedures in all.
(caar '((a b) (c d))) ==> a (cdadr '((a b) (c d))) ==> (d)
#t if obj is the empty list, otherwise returns
#f.
(null? '()) ==> #t (null? '(1)) ==> #f (null? 'a) ==> #f
#t if obj is a list, otherwise returns
#f. By definition, all lists have finite length and are
terminated by the empty list.
(list? '(a b c)) ==> #t (list? '()) ==> #t (list? '(a . b)) ==> #f (let ((x (list 'a))) (set-cdr! x x) (list? x)) ==> #f
(list 'a (+ 3 4) 'c) ==> (a 7 c) (list) ==> ()
(length '(a b c)) ==> 3 (length '(a (b) (c d e))) ==> 3 (length '()) ==> 0
(append '(x) '(y)) ==> (x y) (append '(a) '(b c d)) ==> (a b c d) (append '(a (b)) '((c))) ==> (a (b) (c))
The resulting list is always newly allocated, except that it shares structure with the last list argument. The last argument may actually be any object; an improper list results if the last argument is not a proper list.
(append '(a b) '(c . d)) ==> (a b c . d) (append '() 'a) ==> a
(reverse '(a b c)) ==> (c b a) (reverse '(a (b c) d (e (f)))) ==> ((e (f)) d (b c) a)
(list-tail '(1 2 3 4 5) 2) ==> (3 4 5) (list-tail '(1 2 3 4 5) 0) ==> (1 2 3 4 5) (list-tail '(1 2 3 4 5) 5) ==> () (list-tail '(1 2 3 4 5) 6) ==> #<error>
(list-ref '(1 2 3 4 5) 0) ==> 1 (list-ref '(1 2 3 4 5) 2) ==> 3
#f (not the empty
list) is returned. memq uses eq? to compare obj with
the elements of list, while memv uses eqv? and
member uses equal?.
(memq 'a '(a b c)) ==> (a b c)
(memq 'b '(a b c)) ==> (b c)
(memq 'a '(b c d)) ==> #f
(memq (list 'a) '(b (a) c)) ==> #f
(member (list 'a)
'(b (a) c)) ==> ((a) c)
(memq 101 '(100 101 102)) ==> #f in KSM-Scheme
(memv 101 '(100 101 102)) ==> (101 102)
#f (not the empty list) is
returned. assq uses eq? to compare obj with the car
fields of the pairs in alist, while assv uses eqv?
and assoc uses equal?.
(define e '((a 1) (b 2) (c 3)))
(assq 'a e) ==> (a 1)
(assq 'b e) ==> (b 2)
(assq 'd e) ==> #f
(assq (list 'a) '(((a)) ((b)) ((c))))
==> #f
(assoc (list 'a) '(((a)) ((b)) ((c))))
==> ((a))
(assq 5 '((2 3) (5 7) (11 13)))
==> #f in KSM-Scheme
(assv 5 '((2 3) (5 7) (11 13)))
==> (5 7)
#t if obj is a symbol, otherwise returns #f.
(symbol? 'foo) ==> #t (symbol? (car '(a b))) ==> #t (symbol? "bar") ==> #f (symbol? 'nil) ==> #t (symbol? '()) ==> #f (symbol? #f) ==> #f
(symbol->string 'flying-fish) ==> "flying-fish" (symbol->string 'Martin) ==> "Martin" in KSM-Scheme (symbol->string (string->symbol "Malvina")) ==> "Malvina"
(eq? 'mISSISSIpi 'mississippi) ==> #f in KSM-Scheme
(string->symbol "mISSISSIppi") ==> mISSISSIppi
(eq? 'bitBLT (string->symbol "bitBLT"))
==> #t in KSM-Scheme
(eq? 'JollyWog
(string->symbol
(symbol->string 'JollyWog)))
==> #t
(string=? "K. Harper, M.D."
(symbol->string
(string->symbol "K. Harper, M.D.")))
==> #t
#t if obj is a character, otherwise returns
#f.
char=? et cetera, but they treat
upper case and lower case letters as the same. In KSM-Scheme, case of
characters outside the ASCII range (outside 0x00-0x7f) is handled
properly.
(char-ci=? #\A #\a) ==> #t
(char-ci=? #\U{2174} #\U{2164}) ==> #t
#t if their arguments are alphabetic,
numeric, whitespace, upper case, or lower case characters, respectively,
otherwise they return #f. In KSM-Scheme, char-alphabetic?,
char-numeric?, and char-whitespace? currently support
characters in the ASCII range (0x00 through 0x7f). For characters
outside this range, they return #f. char-upper-case? and
char-lower-case? support all the Unicode characters.
(char-alphabetic? #\a) ==> #t (char-numeric? #\2) ==> #t (char-whitespace #\space) ==> #t (char-upper-case? #\A) ==> #t (char-lower-case? #\a) ==> #t
char->integer returns an integer that is the
Unicode code value of the character. Given an integer,
integer->char interpretes the number as a Unicode code value and
returns a character corresponding to that code.
(char->integer #\a) ==> 97 (integer->char 90) ==> #\Z
char-upcase returns the upper case of the char if there is
one, otherwise returns the char itself. char-downcase
returns the lower case of the char if there is one, otherwise
returns the char itself. Both procedures support all Unicode
characters.
#t if obj is a string, otherwise returns #f.
(string? "abc") ==> #t (string? 'abc) ==> #f
make-string returns a newly allocated string of length
k. If char is given, then all elements of the string are
initialized to char, otherwise the contents of the string
are unspecified except its length.
(make-string 3 #\a) ==> "aaa"
(string #\h #\e #\l #\l #\o) ==> "hello"
(string-length "abcdefg") ==> 7
string-ref returns character
k of string using zero-origin indexing.
(string-ref "abcdefg" 0) ==> #\a (string-ref "abcdefg" 2) ==> #\c (string-ref "abcdefg" 7) ==> #<error>
string-set! stores char
in element k (zero-origin indexing) and returns an unspecified
value.
(define str "abcdefg") str ==> "abcdefg" (string-set! str 2 #\X) ==> #<unspecified> str ==> "abXdefg"
string=? returns #t if the two strings are the same length
and contain the same characters in the same positions, otherwise returns
#f. string-ci=? is similar to string=? except that
it treats upper and lower case letters as though they were the same
character. string-ci=? supports all Unicode characters.
(string=? "abcdefg" "abcdefg") ==> #t (string=? "ABCdefg" "abcdefg") ==> #f (string-ci=? "ABCdefg" "abcdefg") ==> #t
string<? uses the
lexicographic ordering on strings induced by the ordering char<?
on characters. If two strings differ in length but are the same up to
the length of the shorter string, the shorter string is considered to be
lexicographically less than the longer string.
(string<? "ABCDEFG" "abcdefg") ==> #f (string-ci<? "ABCDEFG" "abcdefg") ==> #t
0 <= start <= end <= length of string
substring returns a newly allocated string formed from the
characters of string beginning with index start (inclusive)
and ending with index end (exclusive).
(substring "abcdefg" 2 4) ==> "cd" (substring "abcdefg" 0 7) ==> "abcdefg"
(string-append "abc" "d" "efg") ==> "abcdefg"
string->list returns a newly allocated list of the characters
that make up the given string. list->string returns a newly
allocated string formed from the characters in the list, which
must be a list of characters. string->list and
list->string are inverses so far as equal? is concerned.
(string->list "hello") ==> (#\h #\e #\l #\l #\o) (list->string '(#\h #\e #\l #\l #\o)) ==> "hello"
(string-copy "abcdefg") ==> "abcdefg" (eq? "abcdefg" (string-copy "abcdefg")) ==> #f
(define str "abcdefg") str ==> "abcdefg" (string-fill! str #\X) ==> "XXXXXXX"
(string->expr "10") ==> 10 (string->expr "(a b c)") ==> (a b c)
@source{base/base.c} @use{none}
#t if obj is a vector, otherwise returns #f.
(vector? '#(1 2 3)) ==> #t (vector? '(1 2 3)) ==> #f
(make-vector 3 #\a) ==> #(a a a)
list.
(vector 'a 'b 'c) ==> #(a b c)
(vector-length '#(a b c)) ==> 3
vector-ref returns the contents of element k
of vector.
(vector-ref '#(1 1 2 3 5 8 13 21) 5)
==> 8
(vector-ref '#(1 1 2 3 5 8 13 21) 0)
==> 1
vector-set! stores obj in element k of
vector. The value returned by vector-set! is unspecified.
(define vec (vector 0 '(2 2 2 2) "Anna"))
(vector-set! vec 1 '("Sue" "Sue"))
vec ==> #(0 ("Sue" "Sue") "Anna")
vector->list returns a newly allocated list of the objects
contained in the elements of vector. list->vector returns a
newly created vector initialized to the elements of the list.
(vector->list '#(dah dah didah))
==> (dah dah didah)
(list->vector '(dididit dah))
==> #(dididit dah)
vector-fill! is unspecified.
(define vec (vector 1 2 3)) (vector-fill! vec #\A) vec ==> #(A A A)
#t if obj is a procedure, otherwise returns
#f.
(procedure? car) ==> #t
(procedure? 'car) ==> #f
(procedure? (lambda (x) (* x x)))
==> #t
(procedure? '(lambda (x) (* x x)))
==> #f
(call-with-current-continuation procedure?)
==> #t
(apply + '(3 4)) ==> 7
(apply + 1 2 '(3 4)) ==> 10
(define compose
(lambda (f g)
(lambda args
(f (apply g args)))))
((compose sqrt *) 12 75) ==> 30 ; (sqrt (* 12 75))
map applies proc element-wise to the
elements of the list's and returns a list of the results, in
order. The order in which proc is applied to the elements of the
list's is unspecified.
(map cadr '((a b) (d e) (g h)))
==> (b e h)
(map (lambda (n) (expt n n))
'(1 2 3 4 5))
==> (1 3 27 256 3125)
(map + '(1 2 3) '(4 5 6)) ==> (5 7 9)
for-each are like the arguments to map,
but for-each calls proc for its side effects rather than
for its values. Unlike map, for-each is guaranteed to call
proc on the elements of the list's in order from the first
element to the last, and the value returned by for-each is
unspecified.
(let ((v (make-vector 5)))
(for-each (lambda (i)
(vector-set! v i (* i i)))
'(0 1 2 3 4))
v) ==> #(0 1 4 9 16)
call-with-current-continuation packages up the current
continuation as an "escape procedure" and passes it as an argument to
proc. The escape procedure is a Scheme procedure that, if it is
later called, will abandon whatever continuation is in effect at that
later time and will instead use the continuation that was in effect when
the escape procedure was created. Calling the escape procedure may cause
the invocation of before and after thunks installed using
dynamic-wind.
The escape procedure accepts the same number of arguments as the
continuation to the original call to
call-with-current-continuation. Except for continuations created
by the call-with-values procedure, all continuations take exactly
one value. The effect of passing no value or more than one value to
continuations that were not created by call-with-values is
unspecified.
The escape procedure that is passed to proc has unlimited extent just like any other procedure in Scheme. It may be stored in variables or data structures and may be called as many times as desired.
The following examples show only the most common ways in which
call-with-current-continuation is used. If all real uses were as
simple as these examples, there would be no need for a procedure with
the power of call-with-current-continuation.
(call-with-current-continuation
(lambda (exit)
(for-each (lambda (x)
(if (negative? x)
(exit x)))
'(54 0 37 -3 245 19))
#t)) ==> -3
(define list-length
(lambda (obj)
(call-with-current-continuation
(lambda (return)
(letrec ((r
(lambda (obj)
(cond ((null? obj) 0)
((pair? obj)
(+ (r (cdr obj)) 1))
(else (return #f))))))
(r obj))))))
(list-length '(1 2 3 4)) => 4
(list-length '(a b . c)) => #f
When feature of multithread programming is utilized See section Thread, there is a restriction in the usage of continuation: A continuation (or escape procedure) can be invoked only from the thread that packaged the continuation.
(call/cc (lambda (cc) (cc 'ok))) ==> ok
(call/cc (lambda (cc)
(thread:create (lambda () (cc 'no)))))
==> #<error>
call-with-values procedure, all
continuations take exactly one value.
(values 1) ==> 1
call-with-values.
(call-with-values (lambda () (values 4 5))
(lambda (a b) b))
==> 5
(call-with-values * -) ==> -1
When the feature of multithread programming is utilized See section Thread, values should be called within the same thread that
created the continuation by call-with-values.
(call/wv (lambda () (values 'ok))
(lambda (a) a)) ==> ok
(call/wv (lambda ()
(thread:create (lambda () (values 'no))))
(lambda (a) a)) ==> #<error>
call-with-current-continuation the
three arguments are called once each, in order). before is called
whenever execution enters the dynamic extent of the call to thunk
and after is called whenever it exits that dynamic extent. The
dynamic extent of a procedure call is the period between when the call
is initiated and when it returns. In Scheme, because of
call-with-current-continuation, the dynamic extent of a call may
not be a single, connected time period. It is defined as follows:
call-with-current-continuation during the dynamic extent.
If a second call to dynamic-wind occurs within the dynamic extent
of the call to thunk and then a continuation is invoked in such a
way that the after's from these two invocations of
dynamic-wind are both to be called, then the after
associated with the second (inner) call to dynamic-wind is called
first.
If a second call to dynamic-wind occurs within the dynamic extent
of the call to thunk and then a continuation is invoked in such a
way that the before's from these two invocations of
dynamic-wind are both to be called, then the before
associated with the first (outer) call to dynamic-wind is called
first.
If invoking a continuation requires calling the before from one
call to dynamic-wind and the after from another, then the
after is called first.
The effect of using a captured continuation to enter or exit the dynamic extent of a call to before or after is undefined.
(let ((path '())
(c #f))
(let ((add (lambda (s)
(set! path (cons s path)))))
(dynamic-wind
(lambda () (add 'connect))
(lambda ()
(add (call-with-current-continuation
(lambda (c0)
(set! c c0)
'talk1))))
(lambda () (add 'disconnect)))
(if (< (length path) 4)
(c 'talk2)
(reverse path))))
==> (connect talk1 disconnect connect talk2 disconnect)
(interaction-environment).
(eval '(* 7 3)) ==> 21
(eval '(* 7 3) (scheme-report-environment 5))
==> 21
(let ((f (eval '(lambda (f x) (f x x))
(null-environment 5))))
(f + 10))
==>
5. scheme-report-environment returns an environment that
is empty except for all bindings defined in the Revised^5 Report on
Scheme. null-environment returns an environment that is empty
except for the bindings for all syntactic keywords defined in the
Revised^5 Report on Scheme.
Ports represent input and output devices. To Scheme, an input port is a Scheme object that can deliver characters upon command, while an output port is a Scheme object that can accept characters.
call-with-input-file,
the file should already exist; for call-with-output-file the file
is truncated if the file already exists. These procedures cal proc
with one argument: the port obtained by opening the named file for input
or output. If the file cannot be opened, an error is signalled. If
proc returns, then the port is closed automatically and the value
yielded by the proc is returned. If proc does not return,
then the port will not be closed automatically unless it is possible to
prove that the port will never again be used.
Because Scheme's escape procedures have unlimited extent, it is possible
to escape from the current continuation but later to escape back in. If
implementations were permitted to close the port on any escape from the
current continuation, then it would be impossible to write portable code
using both call-with-current-continuation and
call-with-input-file or call-with-output-file.
If encoding is supplied, it should be a string that specifies the
character-set encoding of the input or output file. If it is omitted, it
defaults to "UTF-8", which is the internal encoding in KSM-Scheme.
Acceptable encoding methods are available from iconv --list.
Following expression converts a file encoded in SHIFT-JIS to a new file encoded in EUC-JP.
(call-with-output-file "dst.euc" "EUC-JP"
(lambda (out)
(call-with-input-file "src.sjis" "SHIFT-JIS"
(lambda (in)
(let loop ((ch (read-char in)))
(if (not (eof-object? ch))
(begin
(write-char ch out)
(loop (read-char in)))))))))
#t if obj is an input port or output port,
respectively; otherwise returns #f.
@source{base/base.c} @use{none}
call-with-input-file,
the file should already exist; for call-with-output-file the file
is truncated if the file already exists. The file is opened for input or
output, an input or output port connected to it is made the default
value returned by current-input-port or
current-output-port (and is used by (read), (write
obj), and so forth), and the thunk is called with no
arguments. When the thunk returns, the port is automatically
closed and the previous default is restored. with-input-from-file
and with-output-to-file return the value yielded by
thunk. If an escape procedure is used to escape from the
continuation of these procedures, the previous default is not restored.
If encoding is supplied, it should be a string that specifies the encoding of the input or output file. If it is omitted, it defaults to "UTF-8".
(with-input-from-file "src.euc" "EUC-JP" (lambda () ...)) (with-output-to-file "dst.sjis" "SHIFT-JIS" (lambda () ...))
If encoding is supplied, it should be a string that specifies the character-set encoding of the input file. If it is omitted, it defaults to "UTF-8".
If encoding is supplied, it should be a string that specifies the character-set encoding of the output file. If it is omitted, it defaults to "UTF-8".
read converts external representations of Scheme objects into the
objects themselves. Therefore, it is a Scheme parser. read
returns the next object parsable from the given input port,
updating port to point to the first character past the end of the
external representation of the object.
If an end of file is encountered in the input before any characters are
found that can begin an object, then an end of file object is
returned. The port remains open, and further attempts to read will also
return an end of file object. If an end of file is encountered after a
beginning of an object's external representation and the characters up
to the point consistute a complete representation, read returns
the corresponding object. Next time read is called, it returns an
end of file object. If an end of file is encountered after the beginning
of an object's external representation, but the external representation
is incomplete and therefore not parsable, an error is signalled.
The port argument may be omitted, in which case it defaults to the
value returned by current-input-port. It is an error to read from
a closed port.
current-input-port.
current-input-port.
#t if obj is an end of file object, otherwise
returns #f.
#t if a character is ready on the input port and
returns #f otherwise. If char-ready? returns #t
then the next read-char operation on the given port is
guaranteed not to hang. If the port is at end of file then
char-ready? returns #t. port may be omitted, in
which case it defaults to the value returned by
current-input-port.
$ cat text
Hello, world!
Hello, another world!
$ ksm
> (define in (open-input-file "text"))
> (readline in)
=> "Hello, world!"
> (readline in)
=> "Hello, another world!"
> (close-input-port in)
@source{base/readline.c} @use{none}
#\ notation. write returns an
unspecified value. The port argument may be omitted, in which case
it defaults to the value returned by current-input-port.
write-char instead of write. display returns an
unsepcified value. The port argument may be omitted, in which case
it defaults to the value returned by current-output-port.
current-input-port.
current-output-port.
load procedure reads expressions from the
file and evalutes them sequentially. The results of the expressions are
not automatically printed, in contrast to an interactive
session. load procedure does not affect the value returned by
current-input-port and current-output-port. load
returns an unspecified value.
If encoding is supplied, it must be a string representing the
character-set encoding of the source file. If it is omitted, it defaults
to "UTF-8". While reading the source file, the encoding is automatically
converted to "UTF-8", which is the internal encoding in
KSM-Scheme. Acceptable encoding is available from iconv --list.
(load "example.scm" "EUC-JP") ;; loads source file "example.scm"
;; that is encoded in EUC-JP
$ cat src.scm (write (load-file-name)) (newline) $ ksm > (load "src.scm") "src.scm"
@source{nterp/ext.c} @use{none}
These functions are not supported in KSM-Scheme. If called they do nothing and return an unspecified value.
In Revised^5 Report of Scheme, these functions are described as below.
filename must be a string naming an output file to be created. The
effect of transcript-on is to open the named file for output, and
to cause a transcript of subsequent interaction between the user and the
Scheme system to be written to the file. The transcript is ended by a
call to transcript-off, which closes the transcript file. Only
one transcript may be in progress at any time, though some
implementations may relax this restriction. The values returned by
these procedures are unspecified.
Go to the first, previous, next, last section, table of contents.