<per@bothner.com> <bothner@portolagroup.com>
Javacan be thought of as two different things:
scriptinglanguages especially useful.
scripting) languages usually have:
javac
is a batchtranslator from Java to
.class
files.
gnu.math
package implements Scheme numbers
with extensions.
Responsiveness | Execution | |
Interpreter written in Java: | Good | Slow |
Translate to Java source: | Poor | Fast |
Translate to Java bytecode: | Good | Fast |
Simpleexpressions are interpreted for even faster response.
.class
es for future use.
goto
).
public abstract class Procedure { public abstract Object applyN(Object[] args); }
Procedure
.
E.g. +
is implemented by a class whose applyN
adds the arguments.
Procedure
,
with the Scheme body compiled into the body of applyN
.
Procedure
sub-class
creates Scheme procedure value.
static context(inherited lexical environment) a la inner classes. A closure is an instance of such a class.
(define (f1 a) (define (f2 b) (list a b)) (cons a f2))
class F1 extends Procedure1 { public Object apply1(Object a) { F2 f2 = new F2(); f2.a = a; return Cons.apply(f2.a, f2); } }
class F2 extends Procedure1 { Object a; public Objet apply1(Object b) { return List.apply(this.a, b); } }
(define-class T (S1 ... Sn) field-spec ... method-spec ...)Here
T
is a name in the regular Scheme name-space,
for a class value. Kawa compiles
T
to corresponding Java class.
Scheme class instanceis a java
Class
plus a captured cnstructor environment.
CLOS-likemultiple inheritance:
Slots(fields) multiply inherited are merged.
(define-class S () a)
public interface S { public Object getA(); public void setA(Object a); } public class S$class implements S { Object a; public Object getA() { return a; } public void setA(Object a) { this.a = a; } }
(define-class S () a) (define-class T () a b) (define-class U (S T) c)
public interface U extends S, T { public Object getC(); public void setC(Object c); } public class U$class implements U { Object a, b, c; public Object getA() { return a; } public void setA(Object a) { this.a = a; } public Object getB() { return b; } public void setB(Object b) { this.b = b; } public Object getC() { return c; } public void setC(Object c) { this.c = c; } }
T
is
allocated, we actually allocate an instance of the
translated T$class
class.
T
(define u :: U (make U)) (set-slot u 'b x)is translated into:
U u = new U$class; u.setB(x);
.class
,
plus sometimes other non-public classes.
run
method.
gnu.jemacs.buffer
contains classes for
building an Emacs-style text editor.
Buffer
contains a DefaultStyledDocument
,
buffer name, filename, buffer-local keymap, etc.
Window
extends JTextPane
.
Multiple Window
s can display the same Buffer
.
BufferKeymap
manages all the keymaps "active" for
a given Buffer
, and implements Emacs key search rules,
prefix keys, etc.
Binding
concept which should do.
lambda
keyword, which do basically the ame, but they are incompatible!
Imlementing these is straight-forwards, if tedious.
nil
, which Emacs uses for both
empty list and false.
doc1
:
(doc-upcase doc1)gives us an abstract document whose charcters are the upper-case equivalent of those in
doc1
.
Here doc-update
is a document transformer; it transforms
the input document doc1
to a new abstract document.
(delete-element 'hr)You can apply the resulting transformation to an input document:
((delete-element 'hr) doc2)This gives you an output document, which is the same as
doc2
,
except that the hr
elements in doc2
has been removed.
doc-upcase
is a document transformer in itself, while delete-element
is a function that returns a document transformer.
(doc-upcase ((delete-element 'hr) doc2))This implements a pipeline, where first we delete
hr
elements, and then uppercase the characters in the result.
element
can be used to generate
concrete document fragments.
(element 'p "You can get the " (element 'a href: "http:/my.com/text.html" "Document source " (element 'code "text.html")))corresponds to this HTML:
<p>You can get the <a href="http:/my.com/text.html"> Document source <code>text.html</code></a></p>
element
is a normal function, not
magic syntax. All of the parameters can be arbitrary expressions
that evaluate to attributes, strings, or sub-documents.
element
function lets you
to embed (or rather generate) HTML inside Scheme. Which approach
is more convenient depends on whether the HTML or the code
dominate.
<blink>
tags by <em>
:
(define blink-to-em (filter-elements ((blink) #t (element 'em (process-childen)))))
filter-elements
form contains a list of clauses,
which are tried in order. Each clause contains a list of tags
(in the example (blink)
;
followed by a guard expression (in the example #t
,
which always succeeds); followed by result fragment expressions.
filter-elements
transformation
tries to match each clause against each element in the input
document; this means the element's tag must be one of those
listed in the clause, and the guard expression must evaluate to true.
If the clause matches, then the result fragment expression are evaluated.
the resulting fragments are included in the output document.
(process-childen)
means to
recursively apply the filter-elements
transformation
to the sub-documents contained in the elements, and to include the
transformed result in the output.
blink-to-em
like a pre-defined transformer:
(define fixed-document (blink-to-em bad-document))This takes
bad-document
as input, passes it through
blink-to-em
and defines the variable fixed-document
as the name for the result.
handle
message, which takes a handler.
A handler is something that uses a document, for example printing it,
or passing it through some transformation to aother output handler.
DocumentCallbackHandler
intreface, which is an extension of the SAX's DocumentHandler
.
filter-elements
clause will happen each time handle
is invoked
on the resulting document specifier. Hence side effects in transformers
ar usually a bad idea.
However, there is a transformer build-dom
that takes
an abstract document, and builds a concrete document (DOM).
You can use that to force side-effects to happen at a controlled time.
http://www.gnu.org/software/kawa/
.