662 lines
19 KiB
Racket
662 lines
19 KiB
Racket
#lang scribble/manual
|
|
@(require planet/scribble
|
|
planet/version
|
|
planet/resolver
|
|
scribble/eval
|
|
scribble/bnf
|
|
racket/sandbox
|
|
racket/port
|
|
racket/list
|
|
(only-in racket/contract any/c)
|
|
racket/runtime-path
|
|
"scribble-helpers.rkt"
|
|
"../js-assembler/get-js-vm-implemented-primitives.rkt")
|
|
|
|
@(require racket/runtime-path)
|
|
@(define-runtime-path git-head-path "../.git/refs/heads/master")
|
|
|
|
|
|
@(require (for-label (this-package-in js))
|
|
(for-label (this-package-in lang/base))
|
|
(for-label (this-package-in resource)
|
|
(for-label (this-package-in web-world))))
|
|
|
|
|
|
|
|
@inject-javascript-inline|{
|
|
var _gaq = _gaq || [];
|
|
_gaq.push(['_setAccount', 'UA-24146890-1']);
|
|
_gaq.push(['_trackPageview']);
|
|
|
|
(function() {
|
|
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
|
|
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
|
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
|
|
})();
|
|
}|
|
|
|
|
|
|
@inject-javascript-src{http://hashcollision.org/whalesong/examples/runtime.js}
|
|
|
|
|
|
@(define-runtime-path whalesong-path "..")
|
|
|
|
|
|
@;; I may need an evaluator for some small examples.
|
|
@(define my-evaluator
|
|
(call-with-trusted-sandbox-configuration
|
|
(lambda ()
|
|
(parameterize ([sandbox-output 'string]
|
|
[sandbox-error-output 'string])
|
|
(make-evaluator 'racket)))))
|
|
|
|
|
|
|
|
@title{Whalesong Internals}
|
|
@author+email["Danny Yoo" "dyoo@hashcollision.org"]
|
|
|
|
|
|
|
|
|
|
@section{Installing Whalesong from github}
|
|
|
|
Although Whalesong has been deployed to
|
|
@link["http://planet.racket-lang.org"]{PLaneT}, you can download the
|
|
sources from the github repository and run from there instead. Doing
|
|
so requires doing a little bit of manual work. The steps are:
|
|
|
|
@itemlist[
|
|
@item{Check Whalesong out of Github.}
|
|
@item{Set up the PLaneT development link to your local Whalesong instance.}
|
|
@item{Run @link["http://docs.racket-lang.org/raco/setup.html"]{@tt{raco setup}} over Whalesong to finish the installation}]
|
|
|
|
We can check it out of the source repository in
|
|
@link["https://github.com/"]{GitHub}; the repository can be checked out by
|
|
using @tt{git clone}. At the command-line, clone the tree
|
|
with: @verbatim|{ $ git clone git://github.com/dyoo/whalesong.git }|
|
|
This should check the repository in the current directory.
|
|
|
|
|
|
|
|
Next, let's set up a @link["http://docs.racket-lang.org/planet/Developing_Packages_for_PLaneT.html#(part._devlinks)"]{PLaneT development link}. Make sure you are in the
|
|
parent directory that contains the @filepath{whalesong} repository, and
|
|
then run this on your command line:
|
|
@verbatim|{
|
|
$ planet link dyoo whalesong.plt 1 5 whalesong
|
|
}|
|
|
(You may need to adjust the @tt{1} and @tt{5} major/minor numbers a bit to be larger
|
|
than the latest version that's on PLaneT at the time.)
|
|
|
|
|
|
Let's make the @filepath{whalesong} launcher somewhere appropriate. Run Racket with the following
|
|
@racket[require]:
|
|
@racketblock[
|
|
(require (planet dyoo/whalesong/make-launcher))
|
|
]
|
|
This will create a @filepath{whalesong} executable in the current working directory.
|
|
|
|
|
|
Finally, we need to set up Whalesong with @tt{raco setup}.
|
|
Here's how to do this at the command
|
|
line:
|
|
@verbatim|{
|
|
$ raco setup -P dyoo whalesong.plt 1 5
|
|
}|
|
|
This should compile Whalesong. Any time the source code in
|
|
@filepath{whalesong} changes, we should repeat this @tt{raco setup}
|
|
step again.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
@section{Internals}
|
|
@;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
Please skip this section if you're a regular user: this is really
|
|
notes internal to Whalesong development, and is not relevant to most
|
|
people.
|
|
|
|
|
|
These are notes that describe the internal details of the
|
|
implementation, including the type map from Racket values to
|
|
JavaScript values. It should also describe how to write FFI
|
|
bindings, eventually.
|
|
|
|
@subsection{Architecture}
|
|
|
|
The basic idea is to reuse most of the Racket compiler infrastructure.
|
|
We use the underlying Racket compiler to produce bytecode from Racket
|
|
source; it also performs macro expansion and module-level
|
|
optimizations for us. We parse that bytecode using the
|
|
@racketmodname[compiler/zo-parse] collection to get an AST,
|
|
compile that to an
|
|
intermediate language, and finally assemble JavaScript.
|
|
|
|
@verbatim|{
|
|
AST IL
|
|
parse-bytecode.rkt -----> compiler.rkt ----> assembler.rkt
|
|
|
|
}|
|
|
|
|
The IL is intended to be translated straightforwardly. We currently
|
|
have an assembler to JavaScript @filepath{js-assembler/assemble.rkt},
|
|
as well as a simulator in @filepath{simulator/simulator.rkt}. The
|
|
simulator allows us to test the compiler in a controlled environment.
|
|
|
|
|
|
@subsection{parser/parse-bytecode.rkt}
|
|
|
|
(We try to insulate against changes in the bytecode structure by
|
|
using the version-case library to choose a bytecode parser based on
|
|
the Racket version number. Add more content here as necessary...)
|
|
|
|
@subsection{compiler/compiler.rkt}
|
|
|
|
This translates the AST to the intermediate language. The compiler has its
|
|
origins in the register compiler in @link[ "http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-35.html#%_sec_5.5"
|
|
]{Structure and Interpretation of
|
|
Computer Programs} with some significant modifications.
|
|
|
|
Since this is a stack machine,
|
|
we don't need any of the register-saving infrastructure in the
|
|
original compiler. We also need to support slightly different linkage
|
|
structures, since we want to support multiple value contexts. We're
|
|
trying to generate code that works effectively on a machine like the
|
|
one described in @url{http://plt.eecs.northwestern.edu/racket-machine/}.
|
|
|
|
|
|
The intermediate language is defined in @filepath{il-structs.rkt}, and a
|
|
simulator for the IL in @filepath{simulator/simulator.rkt}. See
|
|
@filepath{tests/test-simulator.rkt} to see the simulator in action, and
|
|
@filepath{tests/test-compiler.rkt} to see how the output of the compiler can be fed
|
|
into the simulator.
|
|
|
|
The assumed machine is a stack machine with the following atomic
|
|
registers:
|
|
@itemlist[
|
|
@item{val: value}
|
|
@item{proc: procedure}
|
|
@item{argcount: number of arguments}
|
|
]
|
|
and two stack registers:
|
|
@itemlist[
|
|
@item{env: environment stack}
|
|
@item{control: control stack}
|
|
]
|
|
|
|
@subsection{js-assembler/assemble.rkt}
|
|
The intent is to potentially support different back end generators
|
|
for the IL. @filepath{js-assembler/assemble.rkt} provides a backend
|
|
for JavaScript.
|
|
|
|
The JavaScript assembler plays a few tricks to make things like tail
|
|
calls work:
|
|
|
|
@itemlist[
|
|
@item{Each basic block is translated to a function taking a MACHINE
|
|
argument.}
|
|
|
|
@item{ Every GOTO becomes a function call.}
|
|
|
|
@item{ The head of each basic-blocked function checks to see if we
|
|
should trampoline
|
|
(@url{http://en.wikipedia.org/wiki/Trampoline_(computers)})}
|
|
|
|
@item{We support a limited form of computed jump by assigning an
|
|
attribute to the function corresponding to a return point. See
|
|
the code related to the LinkedLabel structure for details.}
|
|
]
|
|
|
|
Otherwise, the assembler is fairly straightforward. It depends on
|
|
library functions defined in @filepath{runtime-src/runtime.js}. As soon as the compiler
|
|
stabilizes, we will be pulling in the runtime library in Moby Scheme
|
|
into this project. We are right in the middle of doing this, so expect
|
|
a lot of flux here.
|
|
|
|
|
|
The assembled output distinguishes between Primitives and Closures.
|
|
Primitives are only allowed to return single values back, and are not
|
|
allowed to do any higher-order procedure calls. Closures, on the
|
|
other hand, have full access to the machine, but they are responsible
|
|
for calling the continuation and popping off their arguments when
|
|
they're finished.
|
|
|
|
|
|
|
|
|
|
@;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
@subsection{Values}
|
|
@;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
All values should support the following functions
|
|
|
|
@itemlist[
|
|
@item{plt.runtime.toDomNode(x, mode): produces a dom representation. mode can be either 'write', 'display', or 'print'}
|
|
|
|
@item{plt.runtime.equals(x, y): tests if two values are equal to each other}
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
@subsubsection{Numbers}
|
|
|
|
Numbers are represented with the
|
|
@link["https://github.com/dyoo/js-numbers"]{js-numbers} JavaScript
|
|
library. We re-exports it as a @tt{plt.baselib.numbers} namespace
|
|
which provides the numeric tower API.
|
|
|
|
Example uses of the @tt{plt.baselib.numbers} library include:
|
|
|
|
@itemlist[
|
|
@item{Creating integers: @verbatim{42} @verbatim{16}}
|
|
|
|
@item{Creating big integers: @verbatim{plt.baselib.numbers.makeBignum("29837419826")}}
|
|
|
|
@item{Creating floats: @verbatim{plt.baselib.numbers.makeFloat(3.1415)}}
|
|
|
|
@item{Predicate for numbers: @verbatim{plt.baselib.numbers.isSchemeNumber(42)}}
|
|
|
|
@item{Adding two numbers together: @verbatim{plt.baselib.numbers.add(42, plt.baselib.numbers.makeFloat(3.1415))}}
|
|
|
|
@item{Converting a plt.baselib.numbers number back into native JavaScript floats: @verbatim{plt.baselib.numbers.toFixnum(...)}}
|
|
]
|
|
|
|
Do all arithmetic using the functions in the @tt{plt.baselib.numbers} namespace.
|
|
One thing to also remember to do is apply @tt{plt.baselib.numbers.toFixnum} to any
|
|
native JavaScript function that expects numbers.
|
|
|
|
|
|
|
|
|
|
@subsubsection{Pairs, @tt{NULL}, and lists}
|
|
|
|
Pairs can be constructed with @tt{plt.runtime.makePair(f, r)}. A pair
|
|
is an object with @tt{first} and @tt{rest} attributes. They can be
|
|
tested with @tt{plt.runtime.isPair()};
|
|
|
|
The empty list value, @tt{plt.runtime.NULL}, is a single,
|
|
distinguished value, so compare it with @tt{===}.
|
|
|
|
Lists can be constructed with @tt{plt.runtime.makeList}, which can take in
|
|
multiple arguments. For example,
|
|
@verbatim|{ var aList = plt.runtime.makeList(3, 4, 5); }|
|
|
constructs a list of three numbers.
|
|
|
|
The predicate @tt{plt.runtime.isList(x)} takes an argument x and
|
|
reports if the value is chain of pairs, terminates by NULL. At the
|
|
time of this writing, it does NOT check for cycles.
|
|
|
|
|
|
|
|
|
|
@subsection{Vectors}
|
|
Vectors can be constructed with @tt{plt.runtime.makeVector(x ...)}, which takes
|
|
in any number of arguments. They can be tested with @tt{plt.runtime.isVector},
|
|
and support the following methods and attributes:
|
|
@itemlist[
|
|
@item{ref(n): get the nth element}
|
|
@item{set(n, v): set the nth element with value v}
|
|
@item{length: the length of the vector }]
|
|
|
|
|
|
|
|
|
|
@subsection{Strings}
|
|
|
|
Immutable strings are represented as regular JavaScript strings.
|
|
|
|
Mutable strings haven't been mapped yet.
|
|
|
|
|
|
|
|
@subsection{VOID}
|
|
|
|
The distinguished void value is @tt{plt.runtime.VOID}; functions
|
|
implemented in JavaScript that don't have a useful return value should
|
|
return @tt{plt.runtime.VOID}.
|
|
|
|
|
|
@subsection{Undefined}
|
|
The undefined value is JavaScript's @tt{undefined}.
|
|
|
|
|
|
@subsection{EOF}
|
|
The eof object is @tt{plt.runtime.EOF}
|
|
|
|
|
|
@subsubsection{Boxes}
|
|
Boxes can be constructed with @tt{plt.runtime.makeBox(x)}. They can be
|
|
tested with @tt{plt.runtime.isBox()}, and they support two methods:
|
|
@verbatim|{
|
|
box.get(): returns the value in the box
|
|
box.set(v): replaces the value in the box with v
|
|
}|
|
|
|
|
|
|
|
|
|
|
|
|
@subsubsection{Structures}
|
|
|
|
structure types can be made with plt.runtime.makeStructureType. For example,
|
|
@verbatim|{
|
|
var Color = plt.runtime.makeStructureType(
|
|
'color', // name
|
|
false, // parent structure type
|
|
3, // required number of arguments
|
|
0, // number of automatically-filled fields
|
|
false, // OPTIONAL: the auto-v value
|
|
false // OPTIONAL: a guard procedure
|
|
);
|
|
}|
|
|
|
|
@tt{makeStructuretype} is meant to mimic the @racket[make-struct-type]
|
|
function in Racket. It produces a structure type value with the
|
|
following methods:
|
|
@itemlist[
|
|
|
|
@item{@tt{constructor}: create an instance of a structure type.
|
|
|
|
For example,
|
|
@verbatim|{
|
|
var aColor = Color.constructor(3, 4, 5);
|
|
}|
|
|
creates an instance of the Color structure type.
|
|
}
|
|
|
|
|
|
@item{@tt{predicate}: test if a value is of the given structure type.
|
|
|
|
For example,
|
|
@verbatim|{
|
|
Color.predicate(aColor) --> true
|
|
Color.predicate("red") --> false
|
|
}|
|
|
}
|
|
|
|
|
|
@item{@tt{accessor}: access a field of a structure.
|
|
|
|
For example,
|
|
@verbatim|{
|
|
var colorRed = function(x) { return Color.accessor(x, 0); };
|
|
var colorGreen = function(x) { return Color.accessor(x, 1); };
|
|
var colorBlue = function(x) { return Color.accessor(x, 2); };
|
|
}|
|
|
}
|
|
@item{@tt{mutator}: mutate a field of a structure.
|
|
|
|
For example,
|
|
@verbatim|{
|
|
var setColorRed = function(x, v) { return Color.mutator(x, 0, v); };
|
|
}|
|
|
|
|
}
|
|
]
|
|
In addition, it has a @tt{type} whose @tt{prototype} can be changed in order
|
|
to add methods to an instance of a structure type. For example,
|
|
@verbatim|{
|
|
Color.type.prototype.toString = function() {
|
|
return "rgb(" + colorRed(this) + ", "
|
|
+ colorGreen(this) + ", "
|
|
+ colorBlue(this) + ")";
|
|
};
|
|
}|
|
|
should add a toString method for instances of the @tt{Color} structure.
|
|
|
|
|
|
|
|
@;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
@subsection{Tests}
|
|
@;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
The test suite in @filepath{tests/test-all.rkt} runs the test suite.
|
|
You'll need to
|
|
run this on a system with a web browser, as the suite will evaluate
|
|
JavaScript and make sure it is producing values. A bridge module
|
|
in @filepath{tests/browser-evaluate.rkt} brings up a temporary web server
|
|
that allows us
|
|
to pass values between Racket and the JavaScript evaluator on the
|
|
browser for testing output.
|
|
|
|
|
|
|
|
|
|
@;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
@subsection{What's in @tt{js-vm} that's missing from Whalesong?}
|
|
@;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
(This section should describe what needs to get done next.)
|
|
|
|
The only types that are mapped so far are
|
|
@itemlist[
|
|
@item{immutable strings}
|
|
@item{numbers}
|
|
@item{pairs}
|
|
@item{null}
|
|
@item{void}
|
|
@item{vectors}
|
|
]
|
|
We need to bring around the following types previously defined in @tt{js-vm}:
|
|
(This list will shrink as I get to the work!)
|
|
@itemlist[
|
|
@item{immutable vectors}
|
|
@item{regexp}
|
|
@item{byteRegexp}
|
|
@item{character}
|
|
@item{placeholder}
|
|
@item{path}
|
|
@item{bytes}
|
|
@item{immutable bytes}
|
|
@item{keywords}
|
|
@item{hash}
|
|
@item{hasheq}
|
|
@item{struct types}
|
|
@item{exceptions}
|
|
@item{thread cells}
|
|
|
|
@item{big bang info}
|
|
@item{worldConfig}
|
|
@item{effectType}
|
|
@item{renderEffectType}
|
|
@item{readerGraph}
|
|
]
|
|
|
|
|
|
|
|
@(define missing-primitives
|
|
(let ([in-whalesong-ht (make-hash)])
|
|
(for ([name whalesong-primitive-names])
|
|
(hash-set! in-whalesong-ht name #t))
|
|
(filter (lambda (name)
|
|
(not (hash-has-key? in-whalesong-ht name)))
|
|
js-vm-primitive-names))))
|
|
|
|
|
|
What are the list of primitives in @filepath{js-vm-primitives.js} that we
|
|
haven't yet exposed in whalesong? We're missing @(number->string (length missing-primitives)):
|
|
@(apply itemlist (map (lambda (name)
|
|
(item (symbol->string name)))
|
|
missing-primitives))
|
|
|
|
|
|
|
|
(I should catalog the bug list in GitHub, as well as the feature list,
|
|
so I have a better idea of what's needed to complete the project.)
|
|
|
|
|
|
(We also need a list of the primitives missing that prevent us from
|
|
running @racketmodname[racket/base]; it's actually a short list that
|
|
I'll be attacking once things stabilize.)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@section{The Whalesong language}
|
|
|
|
@defmodule/this-package[lang/base]
|
|
|
|
This needs to at least show all the bindings available from the base
|
|
language.
|
|
|
|
@defthing[true boolean]{The boolean value @racket[#t].}
|
|
@defthing[false boolean]{The boolean value @racket[#f].}
|
|
@defthing[pi number]{The math constant @racket[pi].}
|
|
@defthing[e number]{The math constant @racket[pi].}
|
|
@defthing[null null]{The empty list value @racket[null].}
|
|
|
|
@defproc[(boolean? [v any/c]) boolean?]{Returns true if v is @racket[#t] or @racket[#f]}
|
|
|
|
|
|
|
|
@defform[(let/cc id body ...)]{}
|
|
@defform[(null? ...)]{}
|
|
@defform[(not ...)]{}
|
|
@defform[(eq? ...)]{}
|
|
@defform[(equal? ...)]{}
|
|
@defform[(void ...)]{}
|
|
@defform[(quote ...)]{}
|
|
@defform[(quasiquote ...)]{}
|
|
|
|
|
|
|
|
@subsection{IO}
|
|
@defform[(current-output-port ...)]{}
|
|
@defform[(current-print ...)]{}
|
|
@defform[(write ...)]{}
|
|
@defform[(write-byte ...)]{}
|
|
@defform[(display ...)]{}
|
|
@defform[(newline ...)]{}
|
|
@defform[(format ...)]{}
|
|
@defform[(printf ...)]{}
|
|
@defform[(fprintf ...)]{}
|
|
@defform[(displayln ...)]{}
|
|
|
|
|
|
|
|
@subsection{Numeric operations}
|
|
@defform[(number? ...)]{}
|
|
@defform[(+ ...)]{}
|
|
@defform[(- ...)]{}
|
|
@defform[(* ...)]{}
|
|
@defform[(/ ...)]{}
|
|
@defform[(= ...)]{}
|
|
@defform[(add1 ...)]{}
|
|
@defform[(sub1 ...)]{}
|
|
@defform[(< ...)]{}
|
|
@defform[(<= ...)]{}
|
|
@defform[(> ...)]{}
|
|
@defform[(>= ...)]{}
|
|
@defform[(abs ...)]{}
|
|
@defform[(quotient ...)]{}
|
|
@defform[(remainder ...)]{}
|
|
@defform[(modulo ...)]{}
|
|
@defform[(gcd ...)]{}
|
|
@defform[(lcm ...)]{}
|
|
@defform[(floor ...)]{}
|
|
@defform[(ceiling ...)]{}
|
|
@defform[(round ...)]{}
|
|
@defform[(truncate ...)]{}
|
|
@defform[(numerator ...)]{}
|
|
@defform[(denominator ...)]{}
|
|
@defform[(expt ...)]{}
|
|
@defform[(exp ...)]{}
|
|
@defform[(log ...)]{}
|
|
@defform[(sin ...)]{}
|
|
@defform[(sinh ...)]{}
|
|
@defform[(cos ...)]{}
|
|
@defform[(cosh ...)]{}
|
|
@defform[(tan ...)]{}
|
|
@defform[(asin ...)]{}
|
|
@defform[(acos ...)]{}
|
|
@defform[(atan ...)]{}
|
|
@defform[(sqr ...)]{}
|
|
@defform[(sqrt ...)]{}
|
|
@defform[(integer-sqrt ...)]{}
|
|
@defform[(sgn ...)]{}
|
|
@defform[(make-rectangular ...)]{}
|
|
@defform[(make-polar ...)]{}
|
|
@defform[(real-part ...)]{}
|
|
@defform[(imag-part ...)]{}
|
|
@defform[(angle ...)]{}
|
|
@defform[(magnitude ...)]{}
|
|
@defform[(conjugate ...)]{}
|
|
@defform[(string->number ...)]{}
|
|
@defform[(number->string ...)]{}
|
|
@defform[(random ...)]{}
|
|
@defform[(exact? ...)]{}
|
|
@defform[(integer? ...)]{}
|
|
@defform[(zero? ...)]{}
|
|
|
|
@subsection{String operations}
|
|
@defform[(string? s)]{}
|
|
@defform[(string ...)]{}
|
|
@defform[(string=? ...)]{}
|
|
@defform[(string->symbol ...)]{}
|
|
@defform[(string-length ...)] {}
|
|
@defform[(string-ref ...)] {}
|
|
@defform[(string-append ...)] {}
|
|
@defform[(string->list ...)] {}
|
|
@defform[(list->string ...)] {}
|
|
|
|
|
|
|
|
@subsection{Character operations}
|
|
@defform[(char? ch)]{}
|
|
@defform[(char=? ...)]{}
|
|
|
|
|
|
|
|
|
|
@subsection{Symbol operations}
|
|
@defform[(symbol? ...)]{}
|
|
@defform[(symbol->string? ...)]{}
|
|
|
|
|
|
|
|
@subsection{List operations}
|
|
@defform[(pair? ...)]{}
|
|
@defform[(cons ...)]{}
|
|
@defform[(car ...)]{}
|
|
@defform[(cdr ...)]{}
|
|
@defform[(list ...)]{}
|
|
@defform[(length ...)]{}
|
|
@defform[(append ...)]{}
|
|
@defform[(reverse ...)]{}
|
|
@defform[(map ...)]{}
|
|
@defform[(for-each ...)]{}
|
|
@defform[(member ...)]{}
|
|
@defform[(list-ref ...)]{}
|
|
@defform[(memq ...)]{}
|
|
@defform[(assq ...)]{}
|
|
|
|
|
|
|
|
@subsection{Vector operations}
|
|
@defform[(vector? ...)]{}
|
|
@defform[(make-vector ...)]{}
|
|
@defform[(vector ...)]{}
|
|
@defform[(vector-length ...)]{}
|
|
@defform[(vector-ref ...)]{}
|
|
@defform[(vector-set! ...)]{}
|
|
@defform[(vector->list ...)]{}
|
|
@defform[(list->vector ...)]{}
|
|
|