Deviations
- Tail calls are proper on WebAssembly and in the interpreter, and on the JVM only where
they become a loop. Compiled to WebAssembly (
-o prog.wasm,--component) and run by the interpreter (rontolisp prog.scm, the REPL), every call in tail position runs in constant stack. On the JVM that holds for a namedletordo, a procedure calling itself in tail position, and procedures that call each other in tail position (even?/odd?, a state machine, an evaluator'seval/apply) when they are the top-level procedures of a file, the internal definitions of one body or thelambdabindings of oneletrec; a tail call through a procedure value (an argument, a variable,apply) uses stack there: a procedure calling itself through an argument overflows about 16,000 calls deep compiled to the JVM, on its 16 MiB stack (-Drontolisp.stackraises it). call/ccis escape-only. A continuation can be called while itscall/ccis still running, once. There is no re-entry, so no generators or coroutines through it, anddynamic-windruns itsbeforeexactly once.call-with-valuesis a direct binding when both arguments are written aslambdaexpressions; any other shape goes through a list.- Exceptions are caught after the unwinding. A
guardruns its clauses after its body has been left, so when none is taken the object is raised again from theguard: a handler outside it cannot resume araise-continuableof the body. The handler of awith-exception-handlerruns whereraise,raise-continuableanderrorstand, but for an error a built-in procedure signals it runs after thethunkhas been left. On WebAssembly a string index out of range is not checked (string-refpast the end answers a character). An uncaughterrorends the program with its message and irritants, an uncaughtraisewith its object. - Calling a parameter object with an argument is an error; Gauche sets its value.
evalrefusesparameterizeby name. - A
case-lambdacalled with a number of arguments no clause accepts raises an error object;evalrefusescase-lambdaby name. - A port is textual or binary, never both:
binary-port?of a string port is#f(a Gauche port is both). The standard ports are textual, soread-u8,write-u8and the other binary procedures need a bytevector or binary file port argument.char-ready?andu8-ready?always answer#t. with-input-from-fileandwith-output-to-fileclose the file however the thunk is left, an escape or a raised object included (Gauche leaves it open). A file that cannot be opened for output raises an errorfile-error?answers#tfor, as R7RS says.- A record prints in Common Lisp's
#S(...)syntax.equal?compares records by identity. Adefine-record-typein a body makes one type where it is written, not a new one each time the body runs (Gauche does the latter). writeprints'xas(quote x), and the unspecified value as#!unspecific. It is one object, true in a test.exitruns theafterthunks of thedynamic-winds it is inside, then ends the process with its status; onlyemergency-exitends the process where it stands.- There are no complex numbers:
(sqrt -4),(log -1)and(asin 2)end the program with an error naming the procedure. - Error messages spell Common Lisp names (
CAR). utf8->stringdecodes a byte that begins no valid UTF-8 sequence to the character with that byte's code instead of signalling an error.- A library found in a file is looked up beside the file the program started from, with
no search path. A
define-librarywritten in a file is seen by that file alone: a fileloaded beside it finds the library only as a.sldfile. A name an exported macro's template uses that its library neither defines nor imports means what it means where the macro is used. A record type a library defines prints its names with the library's name in front of them. Importing one name from two libraries is not refused; the later import wins. - A
cond-expandis decided when the program is read, against the features every backend shares;(features)names no operating system or processor. One no clause of which holds, with noelse, is an error. Insideeval,(library ...)holds for the standard libraries only.
Not yet
The other libraries. Importing one is refused by name when the file is read.