Control Feature Procedures¶
Overview¶
This section documents procedures that do not operate on a specific data type but instead provide general-purpose facilities for program control, execution, and convenience.
Control and Evaluation
eval and apply are the core meta-programming facilities inherited from
Scheme’s Lisp heritage. eval allows programs to construct and evaluate
expressions at runtime, bridging the gap between data and code — a natural
consequence of Scheme’s homoiconicity, where code and data share the same list
representation. apply allows a procedure to be called with its arguments
supplied as a list, which is invaluable when the number of arguments is not
known until runtime. Both are standard R7RS procedures, though this
implementation’s eval deviates in being unary — evaluation always takes
place in the global environment.
System Interface
load reads and evaluates a file of Scheme source code, providing the
primary mechanism for organising programs across multiple files. exit
terminates the interpreter with an optional status code, following the Unix
convention that zero denotes success and non-zero denotes failure. The boolean
shorthand — #t for success, #f for failure — is a convenience that
maps naturally onto Scheme idioms. command-line provides access to the
arguments passed to a script, enabling programs to behave differently based on
their invocation context.
Polymorphic Convenience Procedures
len, idx, and rev are non-standard extensions that provide a
uniform interface across the ordered and compound types: lists, vectors,
bytevectors, and strings. Rather than remembering which type-specific procedure
applies in a given context — string-length versus vector-length versus
list-length — these procedures dispatch automatically on the type of their
argument. They are particularly useful in generic or polymorphic code where the
specific sequence type is not known in advance, and in interactive use where
brevity is valued. Code that requires the clarity of explicit type dispatch
should prefer the type-specific procedures.
Procedure Documentation¶
eval¶
- (eval expr)
Evaluates expr as a Scheme expression in the global environment and returns the result. expr may be any object that has a valid external representation as an expression, including a quoted list representing a procedure call.
Note
This implementation’s
evalis unary and always evaluates in the global environment. R7RS specifies a second argument for the environment in which evaluation takes place (e.g.(interaction-environment)), but first-class environments are not currently supported. Any environment argument passed will be silently ignored.- Parameters:
expr (any) – The expression to evaluate.
- Returns:
The result of evaluating expr.
- Return type:
any
Example:
--> (eval '(+ 1 2)) 3 --> (eval '(define x 42)) --> x 42 --> (eval (list '+ 1 2 3)) 6 --> (let ((op '+)) (eval (list op 10 20))) 30
apply¶
- (apply proc arg1 ... args)
Calls proc with the elements of the list formed by appending any individual arg1 … arguments to the final args list as its actual arguments. The final argument must be a proper list; all preceding arguments after proc are prepended to it individually.
applyis implemented as a tail call: the result is returned as a tail-call sentinel to the interpreter’s evaluator for further evaluation, meaning it participates correctly in tail-call optimisation and does not consume additional stack depth.- Parameters:
proc (procedure) – The procedure to call.
arg1 (any) – Zero or more individual arguments to prepend to args.
args (list) – A proper list of the remaining arguments to pass to proc.
- Returns:
The result of calling proc with the assembled argument list.
- Return type:
any
Example:
--> (apply + '(1 2 3)) 6 --> (apply + 1 2 '(3 4)) 10 --> (apply string '(#\h #\e #\l #\l #\o)) "hello" --> (apply max '(3 1 4 1 5 9 2 6)) 9 --> (apply map (list char-upcase '("hello" "world"))) ("HELLO" "WORLD")
load¶
- (load filename)
Reads and evaluates Scheme expressions and definitions from the file named by filename sequentially in the global environment. Returns
#ton success, or#fif an error is encountered during loading, in which case a message is printed to standard error.Note
R7RS specifies an optional second environment argument to
load. This implementation always loads into the global environment; no environment argument is supported.- Parameters:
filename (string) – The path to a file containing Scheme source code.
- Returns:
#ton success,#fon error.- Return type:
boolean
Example:
--> (load "mylib.scm") #t --> (load "init.scm") #f
exit¶
- (exit [code])
Terminates the running program. If code is omitted, exits with status
0(success). If code is a boolean,#tmaps to exit status0and#fmaps to exit status1. If code is an integer, it is passed directly to the system as the exit status code. If running in the REPL, the session history is saved before exiting.- Parameters:
code (boolean or integer) – An optional exit status. A boolean
#texits with0,#fexits with1, and an integer exits with that value directly.- Returns:
This procedure does not return.
Example:
--> (exit) --> (exit #t) --> (exit #f) --> (exit 42)
command-line¶
- (command-line)
Returns a list of command-line arguments passed to the script being interpreted. The zeroth element is always the script name. When called from the REPL, returns the empty list.
Script arguments must be separated from interpreter arguments using
--, so that the interpreter can distinguish between arguments intended for itself and those intended for the script. For example:$ cozenage myscript.scm -- arg1 arg2
- Returns:
A list of strings representing the command-line arguments, or the empty list when called from the REPL.
- Return type:
list
Example:
--> (command-line) ()
When invoked as
cozenage myscript.scm -- foo bar, withinmyscript.scm:--> (command-line) ("myscript.scm" "foo" "bar")
len¶
- (len obj)
Returns the length of obj as an exact integer. Accepts lists, vectors, bytevectors, strings, sets, and hashes. For strings, returns the number of characters (Unicode code points), not the number of underlying bytes. For sets and hashes, returns the number of members or key-value pairs respectively. Raises an error if obj is not a compound or sequence type.
Note
This is a non-standard convenience procedure. For type-specific length procedures, see
list-length,vector-length,string-length, andbytevector-length.- Parameters:
obj (list, vector, bytevector, string, set, or hash) – A compound or sequence object.
- Returns:
The length of obj.
- Return type:
integer
Example:
--> (len '(1 2 3)) 3 --> (len #(1 2 3)) 3 --> (len "café") 4 --> (len #{1 2 3}) 3 --> (len #["a" 1 "b" 2]) ; For hashes, key/value pairs count as one item 2 --> (len "") 0
idx¶
- (idx seq i)
- (idx seq start end)
- (idx seq start end step)
Polymorphic subscript and slicing procedure. With a single index i, returns the element of seq at that position. With start and end, returns a new sequence containing elements from start (inclusive) to end (exclusive). With step, returns every step-th element in that range. Accepts lists, vectors, bytevectors, and strings. All indices are zero-based.
With a single index, delegates to the type-specific ref procedure for each type (
list-ref,vector-ref,bytevector-ref,string-ref). Slicing is supported for lists and vectors; bytevectors and strings support single-element access only.Note
This is a non-standard convenience procedure.
- Parameters:
seq (list, vector, bytevector, or string) – A sequence to subscript or slice.
i (integer) – A zero-based index for single-element access.
start (integer) – The index of the first element to include in a slice.
end (integer) – The index past the last element to include in a slice.
step (integer) – The stride between selected elements. Defaults to
1.
- Returns:
The selected element or a new sequence containing the selected elements.
- Return type:
any, list, or vector
Example:
--> (idx '(a b c d) 1) b --> (idx #(10 20 30 40 50) 2) 30 --> (idx '(a b c d e) 1 4) (b c d) --> (idx #(0 1 2 3 4 5 6) 0 7 2) #(0 2 4 6) --> (idx "hello" 1) #\e
rev¶
- (rev seq)
Returns a new sequence containing the elements of seq in reverse order. Accepts lists, vectors, bytevectors, and strings. For strings, reversal is grapheme-aware: multi-codepoint grapheme clusters (such as accented characters and emoji with combining sequences) are kept intact rather than having their constituent code points reversed independently.
Note
This is a non-standard convenience procedure. For the type-specific list procedure, see
reverse.- Parameters:
seq (list, vector, bytevector, or string) – A sequence to reverse.
- Returns:
A new sequence with the elements of seq in reverse order.
- Return type:
list, vector, bytevector, or string
Example:
--> (rev '(1 2 3)) (3 2 1) --> (rev #(1 2 3)) #(3 2 1) --> (rev "hello") "olleh" --> (rev "café") "éfac"