Per's blog

JavaFX 1.0 was a next-generation GUI/client platform. It had a new Node-based GUI APIs and used a new language, JavaFX Script, whose goal was to make it easier to program Rich Client applications. (Yours truly was hired by Sun to work on the JavaFX Script compiler.) In 2010 the JavaFX Script language was cancelled: JavaFX would still refer to a new GUI based API based on many of the same concepts, but the primary programming language would be Java, rather than JavaFX Script.

Java is a relatively low-level and clumsy language for writing Rich Client appliations, though it's not too painful. Still, there was a reason we worked on JavaFX Script: It had a number of features to make such programs more convenient. Luckily, other JVM languages - and specifically Kawa-Scheme can take up the slack. Below I'll show you a simple Hello-World-type example, and then explain how you can try it yourself. In later acticles I'll show different examples.

Simple buttons and events

Our first example is just 3 buttons and 2 trivial event handlers. It is translated from HelloButton.java written in Java by Richard Bair.

(require 'javafx-defs)
(javafx-application)

(javafx-scene
 title: "Hello Button"
 width: 600 height: 450
 (Button
  text: "Click Me"
  layout-x: 25
  layout-y: 40
  on-action: (lambda (e) (format #t "Event: ~s~%" e))
  on-key-released: (lambda (e) (format #t "Event: ~s~%" e)))
 (Button
  text: "Click Me Too"
  layout-x: 25
  layout-y: 70)
 (Button
  text: "Click Me Three"
  layout-x: 25
  layout-y: 100))

For those new to Scheme, the basic syntactic building block has the form:

(operator argument1 ... argumentN)
The operator can be a function (like format), an arithmetic operator in prefix form (like (+ 3 4)), a command, a keyword (like lambda), or a user-defined macro. This general format makes for a lot of flexibility.

The first two lines in HelloButton.scm are boiler-plate: The require imports various definitions and aliases, while the (javafx-application) syntax declares this module is a JavaFX Application.

The javafx-scene form (a macro) creates a scene, which is a collection of graphical objects. The Scene has certain named properties (title, width, and height), specified using keyword arguments. The Scene also has 3 Button children. Finally, the make-scene command puts the scene on the stage (the window) and makes it visible.

Each Button form is an object constructor. For example:

(Button
 text: "Click Me Three"
 layout-x: 25
 layout-y: 100)
is equivalent to the Java code:
javafx.scene.control.Button tmp = new javafx.scene.control.Button();
tmp.setText("Click Me Three");
tmp.setLayoutX(25);
tmp.setLayoutY(100);
return tmp;

The on-action and on-key-released properties on the first Button bind event handlers. Each handler is a lambda expression or anonymous function that takes an event e as a parameter. The Kawa compiler converts the handler to an suitable event handler object using SAM-conversion features. (This conversion depends on the context, so if you don't have a literal lambda expression you have to do the conversion by hand using an object operator.)

Getting it to run

Downloading JavaFX 2.x beta

For now JavaFX is only available for Windows, but Mac and GNU/Linux ports are being worked on and mostly work. (I primarily use Fedora Linux.) The primary JavaFX site has lots of information, including a link to the download site. You will need to register, as long the software is beta. Download the zipfile and extract it to some suitable location.

In the following, we assume the variable JAVAFX_HOME is set to the build you've installed. For example (if using plain Windows):

set JAVAFX_HOME=c:\javafx-sdk2.0-beta
The file %JAVAFX_HOME%\rt\lib\jfxrt.jar should exist.

Downloading and building Kawa

The JavaFX support in Kawa is new and experimental (and unstable), so for now you will have to get the Kawa source code from SVN.

There are two ways to build Kawa. The easiest is to use Ant - on plain Windows do:

ant -Djavafx.home=%JAVAFX_HOME%
or on other platforms (including Cygwin):
ant -Djavafx.home=$JAVAFX_HOME

Alternatively, you can use configure and make (but note that on Windows you will need to have Cygwin installed to use this approach):

$ KAWA_DIR=path_to_Kawa_sources
$ cd $KAWA_DIR
$ ./configure --with-javafx=$JAVAFX_HOME
$ make

Running the example

On Windows, the easiest way to run the example is to use the kawa.bat created when building Kawa. It sets up the necessary pats for you.

%KAWA_HOME%\bin\kawa.bat HelloButton.scm

On Cygwin (or Unix/Linux) you can use the similar kawa.sh. I suggest setting you your PATH to find kawa.bat or kawa.sh, so you can just do:

kawa HelloButton.scm

Using the kawa command is equivalent to

java -classpath classpath kawa.repl HelloButton.scm
but it sets the classpath automatically. If you do it by hand you need to include %JAVAFX_HOME%\rt\lib\jfxrt.jar and %KAWA_DIR%\kawa-version.jar.

This is what pops up:

HelloButton.png

If you click the first button the action event fires, and you should see something like:

Event: javafx.event.ActionEvent[source=Button@3a5794[styleClass=button]]

If you type a key (say n) while that button has focus (e.g. after clicking it), then when you release the key a key-released event fires:

Event: KeyEvent [source = Button@3a5794[styleClass=button],
target = Button@3a5794[styleClass=button], eventType = KEY_RELEASED,
consumed = false, character = , text = n, code = N]

Note: Running JavaFX application from the Kawa read-eval-print-loop (REPL) doesn't work very well at this point, but I'm exploring ideas to make it useful.

Compiling the example

You can compile HelloButton.scm to class files:

kawa --main -C HelloButton.scm

You can execute the resulting application in the usual way:

java -classpath classpath HelloButton
or use the kawa command:
kawa HelloButton

Next

JavaFX-using-Kawa-animation
Created 28 Jul 2011 11:06 PDT. Last edited 5 Aug 2011 11:22 PDT. Tags:

Read JavaFX-using-Kawa-intro first. That introduces JavaFX and how you can use Kawa to write rich GUI applications.

This example demonstrates simple animation: A rectangle that moves smoothly left to right and back again continuously. This is example is converted from HelloAnimation.java written in Java by Kevin Rushforth. Here is the entire program HelloAnimation.scm:

(require 'javafx-defs)
(javafx-application)

(define rect
  (Rectangle
   x: 25  y: 40  width: 100  height: 50
   fill: Color:RED))

(javafx-scene
 title: "Hello Animation"
 width: 600 height: 450  fill: Color:LIGHTGREEN
 rect)

((Timeline
  cycle-count: Timeline:INDEFINITE
  auto-reverse: #t
  (KeyFrame
   (Duration:valueOf 500)
   (KeyValue (rect:xProperty) 200))):play)

The first two lines are boilerplate, as in JavaFX-using-Kawa-intro. The (define rect (Rectange ...)) defines a variable rect, and initializes it to a new Rectangle, using an object constructor as seen before.

The (javafx-scene ...) operations creates the scene with the specified title, width, height and fill (background color) properties. It adds the rect to the scene, and then creates a window to make it visible.

Finally, we animate rect. This requires some background explanation.

Key values and key frames

To animate a scene you create a TimeLine data structure, which describes what properties to modify and when to do so. Once you have done so, call play on the TimeLine, which instructs JavaFX's animation engine to start running the animation. In this example, the animation continuous indefinitely: When done, it reverses (because auto-reverse was set to true) and starts over.

The timeline is divided into a fixed number of key frames, which are associated with a specific point in time. In the current example there is the implicit starting key-frame at time 0, and an explicit key-frame at time 500 (milliseconds). (The KeyFrame specifies a duration or ending time, where the start time is the ending time of the previous key-frame, or 0 in the case of the first key-frame.) The animator (or programmer) specifies various properties (such as positions and sizes of objects) at each key-frame, and then the computer smoothly interpolates between the key-frames. By default the interpolation is linear, but you can specify other kinds of interpolation.

Each KeyFrame consists of some KeyValue objects. A KeyValue species which property to modify and the ending value that the property will have at the end of the key-frame. In the example, we have a single KeyValue to modify rect:x, ending at 200. (The start value is 25, as set when rect was constructed.)

In JavaFX, the properties to animate are specified using Property objects. Typeically, a property is a reference to a specific field in a specific object instance. You register the property with the animation engine (as shown in the sample), and then the animation engine uses the property to modify the field. In the example the expression (rect:xProperty) (equivalent to the Java method call rect.xProperty()) returns a property that references the x property of the rect object. The Property object also has ways to register dependencies (rather like change listeners) so that things get updated when the property is changed. (For example the rectangle is re-drawn when its x property changes.)

Here is a static screenshot - obviously an animiated gif would be nicer here! HelloAnimation.png

More information

ToDo: Links to documentation and other JavaFX examples.
Created 28 Jul 2011 11:05 PDT. Last edited 1 Aug 2011 11:16 PDT. Tags:
The Java Architecture for XML Binding (JAXB) 2.0 lets you use annotations to how specify Java class instances get printed (serialized) as XML documents. Kawa recently gained support for annotations, so let us look at an example. You will need Java 6 for the JAXB 2.0 support, and Kawa from SVN (or Kawa 1.12 when it comes out). Nothing else is needed.

Our example is a simple bibliography database of books and some information about them. The DTD and sample input data are taken from the XML Query Use Cases. The complete example is in the file testuite/jaxb-annotations3.scm in the Kawa source distribution.

Defining the Java classes and their XML mapping

We start with some define-alias declarations, which serve the role of Java's import:
(define-alias JAXBContext javax.xml.bind.JAXBContext)
(define-alias StringReader java.io.StringReader)
(define-alias XmlRegistry javax.xml.bind.annotation.XmlRegistry)
(define-alias XmlRootElement javax.xml.bind.annotation.XmlRootElement)
(define-alias XmlElement javax.xml.bind.annotation.XmlElement)
(define-alias XmlAttribute javax.xml.bind.annotation.XmlAttribute)
(define-alias BigDecimal java.math.BigDecimal)
(define-alias ArrayList java.util.ArrayList)
The bibliography is represented by a Java singleton class Bib, which has a books field, which is an ArrayList collection of Book objects:
(define-simple-class Bib ( ) (@XmlRootElement name: "bib")
  (books (@XmlElement name: "book" type: Book) ::ArrayList))

The XmlRootElement annotation says that the Bib is represented in XML as a root element (document element) named <bib>. Each Book is represented using a <book> element. Note the annotation value name: "book" is needed because I decided to use the plural books for the field name (because it is an List), but the singular book for the tag name for each book element.

Each book is represented using the class Book, which has the fields year, title, publisher (all strings), authors and editors (both ArrayLists), and price (a BigDecimal). Note that the while the other fields get mapped to XML child elements, the year is mapped to an XML attribute, also named year.

(define-simple-class Book ()
  (year (@XmlAttribute required: #t) ::String)
  (title (@XmlElement) ::String)
  (authors (@XmlElement name: "author" type: Author) ::ArrayList)
  (editors (@XmlElement name: "editor" type: Editor) ::ArrayList)
  (publisher (@XmlElement) ::String)
  (price (@XmlElement) ::BigDecimal))

Finally, the Author and Editor classes, both of which inherit from Person:

(define-simple-class Person ()
  (last (@XmlElement) ::String)
  (first (@XmlElement) ::String))

(define-simple-class Author (Person))

(define-simple-class Editor (Person)
  (affiliation (@XmlElement) ::String))

Setting up the JAXB context

Next we need to specify a JAXBContext, which manages the mapping between Java classes and the XML document schema (structure). Once JAXB knows the classes involved, it can figure out the XML representation by analyzing the classes and their annotations (using reflection). A simple way to do this is to just list the needed classes when creating the JAXBContext:

(define jaxb-context ::JAXBContext
  (JAXBContext:newInstance Bib Book Person Editor))

(Actually, you don't need to list all the classes: if you just list the root class Bib, JAXB can figure out the rest.)

An alternative is to make use of an ObjectFactory. Specifically, if the element classes are in a package named my.package then you need to create a class ObjectFactory (in the same package), and specify the package name to the JAXBContext factory method newInstance. The ObjectFactory class needs to have a factory method for at least the root class Bib:

(define jaxb-context ::JAXBContext
  (JAXBContext:newInstance "my.package"))
(define-simple-class ObjectFactory () (@XmlRegistry)
  ((createBib) ::Bib (Bib)))

Unmarshalling - reading XML and creating objects

At this point actually parsing the XML and creating objects is trivial. You create an Unmarshaller from the JAXBContext, and then just invoke one of the Unmarshaller unmarshall methods.

(define (parse-xml (in ::java.io.Reader)) ::Bib
  ((jaxb-context:createUnmarshaller):unmarshal in))
(define bb (parse-xml (current-input-port)))

Update the values

The whole point of unmarshalling the XML is presumably so you can do something with the data. First, an example of modifying existing records: let's deal with inflation and increase all the prices by 10%:

;; Multiply the price of all the books in bb by ratio.
(define (adjust-prices (bb::Bib) (ratio::double))
  (let* ((books bb:books)
         (nbooks (books:size)))
    (do ((i :: int 0 (+ i 1))) ((>= i nbooks))
      (let* ((book ::Book (books i)))
        (set! book:price (adjust-price book:price ratio))))))

;; Multiply old by ratio to yield an updated 2-decimal-digit BigDecimal.
(define (adjust-price old::BigDecimal ratio::double)::BigDecimal
  (BigDecimal (round (* (old:doubleValue) ratio 100)) 2))

(adjust-prices bb 1.1)

Next, let's add a new book:

(bb:books:add
 (Book year: "2006"
       title: "JavaScript: The Definitive Guide (5th edtion)"
       authors: [(Author last: "Flanagan" first: "David")]
       publisher: "O'Reilly"
       price: (BigDecimal "49.99")))

Notice the use of square brackets (a new Kawa feature) for the authors single-element sequence.

Marshalling - writing XML from objects

Finally, we might want to write the updated data out to an XML file. For that we create a Marshaller. It has a number of marshall methods that take a jaxbElement and a target specification, and serializes the former to the latter as XML. For example, you could just pass in a File to specify the name of the XML output file. However, Kawa includes an XML pretty-printer, and it would be nice to have pretty-printed and indented XML. To do that we have to use a SAX2 ContentHandler as the bridge between JAXB and Kawa's XML tools. The Kawa XMLFilter implements ContentHandler and can forward XML-like data to an XMLPrinter. The latter doesn't do pretty-printing by default - you have to set the *print-xml-indent* fluid variable to the symbol 'pretty.

;; Write bb as pretty-printed XML to an output port.
(define (write-bib (bb ::Bib) (out ::output-port))::void
  (let ((m (jaxb-context:createMarshaller)))
    (fluid-let ((*print-xml-indent* 'pretty))
      ;; We could marshal directly to 'out' (which extends java.io.Writer).
      ;; However, XMLPrinter can pretty-print the output more readably.
      ;; We use XMLFilter as glue that implements org.xml.sax.ContentHandler.
      (m:marshal bb (gnu.xml.XMLFilter (gnu.xml.XMLPrinter out))))))

(write-bib bb (current-output-port))
Created 3 Jan 2011 18:31 PST. Last edited 7 Jan 2011 11:46 PST. Tags:
Kawa 1.11 is now evailable from the usual places:
ftp://ftp.gnu.org/pub/gnu/kawa/kawa-1.11.tar.gz (source code)
ftp://ftp.gnu.org/pub/gnu/kawa/kawa-1.11.jar (runnable jar)

For a full list of changes, see the news page. Below are some highlights.

Improved object initialization

When constructing an object and there is no matching constructor method, look for "add" methods in addition to "set" methods. Also, allow passing constructor args as well as keyword setters. These features make it more convenient to allocate and initialize complex objects. See here for details and examples, including a simple but complete Swing application.

SAM-conversion

In a context that expects a Single Abstract Method (SAM) type (for example java.lang.Runnable), if you pass a lambda you will get an object where the lambda implements the abstract method. For example, you can just write:

(button:addActionListener
  (lambda (e) (do-something)))
instead of the equivalent but more long-winded:
(button:addActionListener
  (object (java.awt.event.ActionListener)
    ((actionPerformed (e ::java.awt.event.ActionEvent))::void
     (do-something))))
See here for more information.

Enumerations

A new define-enum form, contributed by Jamison Hope, makes it easy to define enuration types and values compatible with Java5 enums.

(define-enum colors (red blue green))
For more details and examples, see here.

New Kawa logo

Kawa new has a logo contributed by Jakub Jankiewicz:

Kawa logo

Created 15 Nov 2010 12:11 PST. Last edited 15 Nov 2010 13:48 PST. Tags:
Q2 is the (temporary?) name of a project where I'm exploring some ideas in programming languages. At this point it is not a complete or coherent language, but you might find some ideas of interest. This article looks at the overall syntactic structure of Q2 programs. Future articles will look at other issues (declarations and patterns; logic variables and unification; sequences and loop comprehensions) as they get implemented.

To try the examples get the SVN development sources and build them. You can then run Q2 code by passing the --q2 language switch on the kawa command line, or using the .q2 file extension. There are some examples in the gnu/q2/testsuite directory.

Extensible syntax with no reserved identifiers

There are many virtues of traditional Lisp/Scheme syntax, primarily a minimal fixed core syntax, combined with a very flexible and extensible structural syntax. There are no reserved identifiers, and the pre-defined syntax for definitional forms and control flow is not hard-coded: they can in principle be defined in the language itself, and you can replace and add to them.

Q2 follows these goals: There is a fixed core (lexical) syntax of tokens and delimiters, which is read by a (Lisp-like) reader. Name-resolution and high-level syntactic forms are processed later at macro-expansion time.

Support infix operators with precedence

Infix operators with multiple precedence levels may not be as elegant as Lisp-style prefix notation, but most people are familiar with the former, and it seems to make for somewhat more readable programs. Thus Q2 supports it. This expression:
b := x + 1 > 3 + y * 2
means the same as:
b := ((x + 1) > (3 + (y * 2)))
Assignment (set!) uses the operator :=, while numerical equality uses == (for now). The plan is to use = for definitional equality - and ultimately unification.

Infix operators appear to conflict with the goal extensible syntax with no reserved identifiers, if we allow user-defined operator tokens, operator tokens are just regular identifiers and which could be re-defined (as say a function), and we allow forward references (at least of functions). How can we tell that * is the built-in binary operator, or if it gets redefined a function later in the script? The solution is for the lexical parser (reader) to just return a list of tokens. Splitting the token list according to operator precedence is done later - just like macro-expansion is.

Use juxtaposition for function application

Haskell and ML use juxtaposition for function application, rather than parentheses and commas. For example to call the atan function with two arguments x and y:
atan x y

This is compact, easy to type, and easy to read. It is similar to the syntax of many command languages including sh.

Naming a zero-argument function applies it

The complication is how do you distinguish a variable reference from a call to a zero-argument function? This can get tricky in a language with first-class functions, since the value of a variable can be a function value. (This is not an issue in Haskell or other pure lazy function language, since there is no difference between applying a zero-argument function and accessing a lazily-initialized variable.) Some languages use a special syntax or operator for force function application of zero-argument functions, but I think that is backwards, and inconsistent with command languages. For example, if foo is a function that can take zero or one arguments, then

foo1     # Called with zero arguments
foo1 10  # Called with one argument

The exact rule for a distinguishing between a variable reference and a zero-argument function application isn't decided yet. For now it just depends on the run-time type of the identifier: If the value of the variable is a function that can take zero arguments, apply the function, otherwise return the value. An alternative rule is to apply the function only if the identifier is lexically bound to a function definition.

Flexible token format

Expressions are constructed from lexical tokens. A token can be (among other things) a name (an identifier), a literal, or an operator. Supporting an extensible syntax with infix operators suggests that an operator should just be an identifier using non-alphanumeric characters. Extensibility is also helped if programmers can add new kinds of literals. So it seems like a good idea be be rather flexible and open-ended in terms of what characters can comprise a token or an identifier. Many languages only allow alphanumeric characters (with perhaps one or two extra characters allowed), but Lisp-family languages traditionally allows a wider class of characters, include arithmetic symbols like +. Q2 follows this tradition.

The downside is that more spaces are needed to separate adjacent tokens. That seems a good trade-off - the spaces are probably a good idea for readability, regardless. Furthermore, if we're using spaces to separate function arguments, it seem reasonable to also require spaces to separate infix operators from operands.

Use indentation for grouping

Some languages (including Haskell and Python) indicate block structure based on the indentation of the lines of a program. I think this makes sense - it allows for a cleaner layout with fewer redundant delimiters (redundant because good programmers use indentation anyway). It also avoids the common annoyance of noise lines that only contain a closing delimiter.

However, it is more of a challenge to make use of indentation in a Lisp-like language without a fixed syntax. There are some experiments where essentially a pre-processor adds parentheses based on indentation, but just using indentation just as syntactic sugar for parentheses doesn't make for nice-looking programs.

The basic use of indentation is Q2 is simple. For example:

f1 a b c d
  f2 e f
    f3 g
    h
  f4 i j
is equivalent to:
f1 a b c d (f2 e f (f3 g) (h)) (f4 i j)
I.e. there are implicit grouping parentheses around each line and each following line that is indented more.

We'd like to add local variable and function definitions inside an indented block, but first a digression.

Block expressions yield multiple values

Many languages provide blocks, consisting of zero or more declarations, expressions, and other statements. In an expression language, the value of the block is usually the value of the final expression. In Q2 instead the value of the block is the value of all as a tuple or multiple values. For example:

(10-7; 2+2; 4+1)
The above is a block with 3 sub-expressions, which evaluates to 3 values: 3, 4, and 5. If this is a top-level expression then all 3 values are printed. Note that the parentheses are just for grouping, so are optional if this is the outermost expression.

The semi-column is a special delimiter that cannot appear in identifiers, but semantically it is a binary infix operator that concatenates the values of the operands.

Note that multiple values are not the same as sequences or lists: for one thing multiple values do not nest:

((1;2); (3; 4))
This evaluates to 4 values, not 2.

If we think of declaration, assignments, and other statements as expressions that return zero results, then it all works out. This example (which uses the old-style Scheme define for now) evaluates to a vector with a single element valued 10:

vector (define v 5; v + v)

Newlines are roughly equivalent to semi-colons in that they concatenate multiple values. Here is an example of the the top-level of a script, which is a block of 4 sub-expressions:

define x 10
x + 2
define y (3 * x)
x + y
This evaluates to 4 sub-results, where the two declarations yield zero results, and the additions yield 12 and 40, for a total of 2 values.

Multiple values becomes multiple arguments

If an argument expression evaluates to multiple values, these becomes multiple arguments in the function application:
fun2 (3;4) (5;6)
evaluates to the same result as:
fun2 3 4 5 6

Indentation as blocks

Now let's slightly change a previous example to include an inner local variable definition:
f1 a b
  f2 e f
    define x (g + 10)
    2 * x
  f4 i j

This works nicely if we slightly change the rewrite rules to make use of blocks. Roughly, each newline becomes a semicolon. The result is:

f1 a b c d (f2 e f (define x (g + 10); 2 * x); f4 i j)
Each block can evaluate to zero, one, or multiple values. The inner block has two sub-expressions: The define provides 0 values, and the other yields a single number. Thus f2 is called with 3 arguments: e, f, and the value of 2 * x. The other block consist of the calls two f2 and f4. Assuming these each return a single value, as do a and b, then f1 is called with 4 parameters.

Works well with a REPL

While the read-eval-print-loop will need more tuning, the current behavior is quite reasonable. Typing in commands consisting of one or more space-separated tokens on a line is convenient and familiar from shells. (In fact building a command shell on top of Q2 is a tempting project.)

In an interactive REPL there is an issue of whether to read ahead to check the indentation of the following line, or in general to see if the current command is terminated. Reading the following line before evaluating and printing the current command of course makes for a confusing experience, so the REPL uses the single-line mode of the parser: Reading the following lines is avoided unless we're nested inside parentheses or the current commands ends with a binary operator.

Scheme macro and special form compatibility

For now Q2 support most of the syntax of Scheme tokens, and most Scheme builtins, including lexical forms. This is not necessarily a long-term goal, but it provides something we can use until Q2-specific replacements are been designed and implemented.

For example here is a possible definition of the foo1 used above:

define counter 0
define (foo1 #!optional (x 10)) (
  counter := counter + 1
  format #t "foo called x=~s counter=~s!~%~!" x counter)
Created 14 Nov 2010 13:28 PST. Last edited 15 Nov 2010 07:26 PST. Tags:

(This is an update of the 2009 version, which was an update of the original 2008 version.)

Google's phone operating system "Android" is based on a custom Java virtual machine on top of GNU/Linux. So it occurred to me: How difficult would it be to get a Kawa application running on Android? Not that difficult, it turns out.

Here is "Hello world" written in Kawa Scheme:

(require 'android-defs)
(activity hello
  (on-create-view
   (android.widget.TextView (this)
    text: "Hello, Android from Kawa Scheme!")))
(A more interesting text-to-speech example app is on Santosh Rajan's Android-Scheme blog.)

The following instructions have been tested on GNU/Linux, specifically Fedora 13, but if you've managed to build Android applications under (say) Windows, you should be able to appropriately modify these instructions.

Getting and building Kawa and Android

First download the Android SDK. Unzip in a suitable location, which we'll refer to as ANDROID_HOME.

$ export ANDROID_HOME=/path/to/android-sdk-linux_86
$ PATH=$ANDROID_HOME/tools:$PATH

Next you have to get the appropriate platform SDK:

$ android update sdk
Select SDK Platform Android 2.2 or whatever and click Install.

You need to select an Android platform. Platform 8 corresponds to Android 2.2 (Froyo).

ANDROID_PLATFORM=android-8

You need to get the Kawa source code (version 1.11 or later).

Set JAVA_HOME to where your JDK tree is, for example:

$ export JAVA_HOME=/opt/jdk/1.6.0

If using Ant (as is recommended on Windows):

$ ant -Denable-android=true

Alternatively, you can use configure and make:

$ KAWA_DIR=path_to_Kawa_sources
$ cd $KAWA_DIR
$ ./configure --with-android=$ANDROID_HOME/platforms/$ANDROID_PLATFORM/android.jar --disable-xquery --disable-jemacs
$ make

Creating the application

Next, we need to create a project or activity, in the target directory KawaHello, with the main activity being a class named hello in a package kawa.android:

$ android create project --target $ANDROID_PLATFORM --name KawaHello --activity hello --path ./KawaHello --package kawa.android

Replace the skeleton hello.java by the Scheme code at the top of this note:

$ cd KawaHello
$ HELLO_APP_DIR=`pwd`
$ cd $HELLO_APP_DIR/src/kawa/android/
$ rm hello.java
$ emacs hello.scm

We need to copy/link the Kawa jar file so the Android SDK can find it:

$ cd $HELLO_APP_DIR
$ ln -s $KAWA_DIR/kawa-1.10.jar libs/kawa.jar

Optionally, you can use kawart-1.10.jar, which is slightly smaller, but does not support eval, and does not get built by the Ant build:

$ ln -s $KAWA_DIR/kawart-1.10.jar libs/kawa.jar

We also need to modify the Ant build.xml so it knows how to compile Scheme code:

$ patch < build-xml-patch.txt

Finally, we can build our application:

$ ant debug

Running the application on the Android emulator

First you need to create an Android Virtual Device (avd). Start:

android
then select Virtual Devices, then click New.... Pick a Name (we use avd8 in the following), a Target (to match $ANDROID_PLATFORM), and optionally change the other properties, before clicking Create AVD.

Start up the Android emulator:

$ emulator -avd avd8 &

Wait until Android has finished booting (you will see the Android home screen), click the menu and home buttons. Now install our new application:

adb install bin/KawaHello-debug.apk

The new hello application should show up. Click it, and you should see something like: HelloKawa2.png

Running the application on your phone

If the emulator is running, kill it:

$ kill %emulator

On the phone, enable USB debugging. (This is settable from the Settings application, under Applications / Development.)

Connect the phone to your computer with the USB cable. Verify that the phone is accessible to adb:

$ adb devices
List of devices attached 
0A3A560F0C015024	device

If you don't see a device listed, it may be permission problem. You can figure out which device corresponds to the phone by doing:

$ ls -l /dev/bus/usb/*
/dev/bus/usb/001:
total 0
...
crw-rw-rw- 1 root wheel 189, 5 2010-10-18 16:52 006
...

The timestamp corresponds to when you connected the phone. Make it readable:

$ sudo chmod a+w /dev/bus/usb/001/006

Obviously if you spend time developing for an Androd phone you'll want to automate this process; this link or this link may be helpful.

Anyway, once adb can talk to the phone, you install in the same way as before:

adb install bin/KawaHello-debug.apk

Some debugging notes

You will find a copy of the SDK documentation in $ANDROID_HOME/docs/index.html.

If the emulator complains that your application has stopped unexpectedly, do:

$ adb logcat

This shows log messages, stack traces, output from the Log.i logging method, and other useful information. (You can alternatively start ddms (Dalvik Debug Monitor Service), click on the kawa.android line in the top-left sub-window to select it, then from the Device menu select Run logcat....)

To uninstall your application, do:

$ adb uninstall kawa.android
Created 18 Oct 2010 14:27 PDT. Last edited 10 Apr 2011 11:55 PDT. Tags:

Updated: Now with numbers for chameneos-redux (chameneosredux.scm) and meteor-contest (meteor.scm) contributed by Jamison Hope.

The Computer Language Shootout Benchmarks Game has implementations in a number of different languages of a number of different programs.

We now have Kawa-Scheme versions of all the current programs. You can find them in the testsuite directory of the Kawa source code.

You can look at the raw measurements.csv or data.csv, but the table below (generated with a Scheme script) summarizes the results. The numbers are relative cpu-time, as divided by the fastest Java version. (For now I'm focusing on single-CPU performance. I'll look into multi-threaded solutions later, after I get a quad-core laptop to test with.) Each cell may have multiple numbers, indicating multiple programs for a given language and problem. In the Java column, at least one of the results will be 1.00, as expected.

JavaScalaClojureJRubyKawaKawa/FTC
binarytrees1.001.05 1.46 1.0427.361.103.72
chameneosredux1.00 3.92 1.850.99 4.0846.430.951.96
fannkuchredux1.00 1.431.23 0.943.5461.661.381.34
fasta1.001.33 0.675.32 4.3271.36 58.501.725.46
knucleotide1.06 1.002.16 1.467.93 7.2210.54 8.9311.11 1.6211.18 1.71
mandelbrot1.00 1.01 1.06 1.091.19 1.16 1.102.28186.491.051.05
meteor2.16 1.0013.2541.80 26.301.252.11
nbody1.001.232.25128.501.031.05
pidigits1.000.30 0.831.280.630.63
regexdna1.29 1.00 1.001.51 1.27 1.001.634.20 2.80 1.821.051.04
revcomp1.000.81 23.729.52 5.557.151.43 1.171.44 1.17
spectralnorm1.00 1.051.02 1.03137.54 174.761.058.98
threadring8.07 1.005.8416.02 21.030.960.96

All of the languages first compile to .class files, which are then executed by the JVM. The Kawa column is Kawa with the default calling convention, while the Kawa/FTC column is the same Kawa programs compiled using the --full-tailcalls flag. The latter is a bit slower, especially for programs that do many function calls, but not as bad I had feared. (The --full-tailcalls mechanism has not been optimized/profiled as much as I'd like, though it's generally going to be slower.) The Kawa programs do use type annotations, and are generally written with performance in mind.

As expected, Scala and Kawa come closest to Java performance. Note that the Scala and Kawa versions of pidigits are actually faster than the Java version, but that is because this test depends heavily on bignum (infinite-precision integer) calculations, and the standard Java BigInteger class is not as efficient as it could be. (Alternative Java version of pidigits use the gmp library.) Clojure is bit slower, while JRuby is substantially slower.

Version notes

The tests were run on a Lenovo ThinkPad T400, with Intel Core2 Duo CPU P8600 (2.40GHz stepping 06), and 3GB of main memory. The operating system was Fedora GNU/Linux 13, updated.

The Java VM used was OpenJDK version 1.6.0_21. The JRuby version was 1.5.3. Clojure was version 1.2.0. Scala was version 2.8.0.final. Kawa was version 1.11.

Created 11 Oct 2010 09:25 PDT. Last edited 11 Nov 2010 23:29 PST. Tags:
XML literals are a new feature in Kawa. They make it more convenient to write XML data objects, especially if you're familar with XML syntax. (This is an extract from the SVN version of the Kawa manual.)

You can write XML literals directly in Scheme code, following a #. Notice that the outermost element needs to be prefixed by #, but nested elements do (and must not).

     #<p>The result is <b>final</b>!</p>

Actually, these are not really literals since they can contain enclosed expressions:

     #<em>The result is &{result}.</em>

The value of result is substituted into the output, in a similar way to quasi-quotation. (If you try to quote one of these “XML literals”, what you get is unspecified and is subject to change.)

An xml-literal is usually an element constructor, but there some rarely used forms (processing-instructions, comments, and CDATA section) we'll cover later.

     xml-literal ::= #xml-constructor
     xml-constructor ::= xml-element-constructor
       | xml-PI-constructor
       | xml-comment-constructor
       | xml-CDATA-constructor

Element constructors

     xml-element-constructor ::=
         <QName xml-attribute*>xml-element-datum...</QName >
       | <xml-name-form xml-attribute*>xml-element-datum...</>
       | <xml-name-form xml-attribute*/>
     xml-name-form ::= QName
       | xml-enclosed-expression
     xml-enclosed-expression ::=
         {expression}
       | (expression...)

The first xml-element-constructor variant uses a literal QName, and looks like standard non-empty XML element, where the starting QName and the ending QName must match exactly:

     #<a href="next.html">Next</a>

As a convenience, you can leave out the ending tag(s):

     <para>This is a paragraph in <emphasis>DocBook</> syntax.</>

You can use an expression to compute the element tag at runtime - in that case you must leave out the ending tag:

     #<p>This is <(if be-bold 'strong 'em)>important</>!</p>

You can use arbitrary expression inside curly braces, as long as it evaluates to a symbol. You can leave out the curly braces if the expression is a simple parenthesised compound expression. The previous example is equivalent to:

     #<p>This is <{(if be-bold 'strong 'em)}>important</>!</p>

The third xml-element-constructor variant above is an XML “empty element”; it is equivalent to the second variant when there are no xml-element-datum items.

(Note that every well-formed XML element, as defined in the XML specifications, is a valid xml-element-constructor, but not vice versa.)

Elements contents (children)

The “contents” (children) of an element are a sequence of character (text) data, and nested nodes. The characters &, <, and > are special, and need to be escaped.

     xml-element-datum ::=
         any character except &, or <.
       | xml-constructor
       | xml-escaped
     xml-escaped ::=
         &xml-enclosed-expression
       | &xml-entity-name;
       | xml-character-reference
     xml-character-reference ::=
         &#decimal-digit+;
       | &#xhex-digit+;

Here is an example shows both hex and decimal character references:

     #<p>A&#66;C&#x44;E</p>  ⇒  <p>ABCDE</p>

Currently, the only supported values for xml-entity-name are the builtin XML names lt, gt, amp, quot, and apos, which stand for the characters <, >, &, ", and ', respectively. The following two expressions are equivalent:

     #<p>&lt; &gt; &amp; &quot; &apos;</p>
     #<p>&{"< > & \" '"}</p>

Attributes

     xml-attribute ::=
         xml-name-form=xml-attribute-value
     xml-attribute-value ::=
         "quot-attribute-datum*"
       | 'apos-attribute-datum*'
     quot-attribute-datum ::=
         any character except ", &, or <.
       | xml-escaped
     apos-attribute-datum ::=
         any character except ', &, or <.
       | xml-escaped

If the xml-name-form is either xmlns or a compound named with the prefix xmlns, then technically we have a namespace declaration, rather than an attribute.

QNames and namespaces

The names of elements and attributes are qualified names (QNames), which are represented using compound symbols (see Namespaces). The lexical syntax for a QName is either a simple identifier, or a (prefix,local-name) pair:

     QName ::= xml-local-part
        | xml-prefix:xml-local-part
     xml-local-part ::= identifier
     xml-prefix ::= identifier

An xml-prefix is an alias for a namespace-uri, and the mapping between them is defined by a namespace-declaration. You can either use a define-namespace form, or you can use a namespace declaration attribute:

     xml-namespace-declaration-attribute ::=
         xmlns:xml-prefix=xml-attribute-value
       | xmlns=xml-attribute-value

The former declares xml-prefix as a namespace alias for the namespace-uri specified by xml-attribute-value (which must be a compile-time constant). The second declares that xml-attribute-value is the default namespace for simple (unprefixed) element tags. (A default namespace declaration is ignored for attribute names.)

     (let ((qn (element-name #<gnu:b xmlns:gnu="http://gnu.org/"/>)))
       (list (symbol-local-name qn)
             (symbol-prefix qn)
             (symbol-namespace-uri qn)))
     ⇒ ("b" "gnu" "http://gnu.org/")
     

Other XML types

Processing instructions

An xml-PI-constructor can be used to create an XML processing instruction, which can be used to pass instructions or annotations to an XML processor (or tool). (Alternatively, you can use the processing-instruction type constructor.)

     xml-PI-constructor ::= <?xml-PI-target xml-PI-content?>
     xml-PI-target ::= NCname (i.e. a simple (non-compound) identifier)
     xml-PI-content ::= any characters, not containing ?>.

For example, the DocBook XSLT stylesheets can use the dbhtml instructions to specify that a specific chapter should be written to a named HTML file:

     #<chapter><?dbhtml filename="intro.html" ?>
     <title>Introduction</title>
     ...
     </chapter>
XML comments

You can cause XML comments to be emitted in the XML output document. Such comments can be useful for humans reading the XML document, but are usually ignored by programs. (Alternatively, you can use the comment type constructor.)

     xml-comment-constructor ::= <!--xml-comment-content-->
     xml-comment-content ::= any characters, not containing --.
CDATA sections

A CDATA section can be used to avoid excessive use of xml-entity-ref such as &amp; in element content.

     xml-CDATA-constructor ::= <![CDATA[xml-CDATA-content]]>
     xml-CDATA-content ::= any characters, not containing ]]>.

The following are equivalent:

     #<p>Specal characters <![CDATA[< > & ' "]]> here.</p>
     #<p>Specal characters &lt; &gt; &amp; &quot; &apos; here.</p>

Kawa remembers that you used a CDATA section in the xml-element-constructor and will write it out using a CDATA constructor.

Created 21 Jun 2010 15:46 PDT. Last edited 21 Jun 2010 19:21 PDT. Tags:
This article talks about Kawa's support for compound symbols and namespaces. The basic support has been there for a while, but some features are new, and the documentation is more complete. (This is an extract from the SVN version of the Kawa manual.)

Namespaces and compound symbols

Different applications may want to use the same symbol to mean different things. To avoid such name clashes we can use compound symbols, which have two string parts: a local name and a namespace URI. The namespace-uri can be any string, but it is recommended that it have the form of an absolute URI. It would be too verbose to write the full URI all the time, so one usually uses a namespace prefix (namespace alias) as a short local alias to refer to a namespace URI.

Compound symbols are usually written using the infix colon operator:

     prefix:local-name

where prefix is is namespace alias bound to some (lexically-known) namespace URI.

Compound symbols are used for namespace-aware XML processing.

Namespace objects

A namespace is a mapping from strings to symbols. The string is the local-name of resulting symbol. A namespace is similar to a Common Lisp package.

A namespace has a namespace-uri, which a string; it recommended that it have the form of an absolute URI. A namespace may optionally have a prefix, which is a string used when printing out symbols belonging to the namespace. (If you want for “equivalent symbols” (i.e. those that have the same local-name and same uri) to be the identical symbol object, then you should use namespaces whose prefix is the empty string.)

— Constructor: namespace name [prefix]

Return a namespace with the given name and prefix. If no such namespace exists, create it. The namespace-name is commonly a URI, especially when working with XML, in which case it is called a namespace-URI. However, any non-empty string is allowed. The prefix can be a string or a simple symbol. (If a symbol is used, then the symbol's local-name is used.) The default for prefix is the empty string. Multiple calls with the same arguments will yield the same namespace object.

The reader macro #,namespace is equivalent to the namespace function, but it is invoked at read-time:

     #,(namespace "http://www.w3.org/1999/XSL/Transform" xsl)
     (eq? #,(namespace "foo") (namespace "foo")) ⇒ #t

The form (,#namespace "" "") returns the default empty namespace, which is used for simple symbols.

— Procedure: namespace-uri namespace

Return the namespace-uri of the argument namespace, as a string.

— Procedure: namespace-prefix namespace

Return the namespace prefix of the argument namespace, as a string.

Compound symbols

A compound symbol is one that belongs to a namespace other than the default empty namespace, and (normally) has a non-empty namespace uri. (It is possible for a symbol to belong to a non-default namespace and have an empty namespace uri, but that is not recommended.)

— Constructor: symbol local-name namespace-spec
— Constructor: symbol local-name [uri [prefix]]

Construct a symbol with the given local-name and namespace. If namespace-spec is a namespace object, then find (or if needed construct) a symbol with the given local-name belonging to the namespace. Multiple calls to symbol with the same namespace and local-name will yield the same symbol object.

If uri is a string (optionally followed by a prefix), then:

          (symbol lname uri [prefix])

is equivalent to:

          (symbol lname (namespace uri [prefix]))

Using #t for the namespace-spec is equivalent to using the empty namespace #,(namespace "").

Using #!null or #f for the namespace-spec creates an uninterned symbol, which does not belong to any namespace.

— Procedure: symbol-local-name symbol

Return the local name of the argument symbol, as an immutable string. (The string is interned, except in the case of an uninterned symbol.)

— Procedure: symbol-prefix symbol

Return the prefix of the argument symbol, as an immutable (and interned) string.

— Procedure: symbol-namespace-uri symbol

Return the namespace uri of the argument symbol, as an immutable (and interned) string.

— Procedure: symbol-namespace symbol

Return the namespace object (if any) of the argument symbol. Returns #!null if the symbol is uninterned.

— Procedure: symbol=? symbol1 symbol2 symbol3 ...

Return #t if the symbols are equivalent as symbols, i.e., if their local-names and namespace-uris are the same. They may have different values of symbol-prefix and symbol-namespace. If a symbol is uninterned (or is #!null) then symbol=? returns the same result as eq?.

Two symbols are equal? or eqv? if they're symbol=?.

Namespace aliases

A namespace is usually referenced using a shorter namespace alias, which is is a lexical definition that binds a namespace prefix to a namespace object (and thus a namespace uri). This allows using compound symbols as identifiers in Scheme programs.

— Syntax: define-namespace name namespace-name

Defines name as a namespace prefix - a lexically scoped "nickname" for the namespace whose full name is namespace-name, which should be a non-empty string literal. It is customary for the string have syntactic form of an absolute URI, but any non-empty string is acceptable and is used without further interpretation.

Any symbols in the scope of this definitions that contain a colon, and where the part before the colon matches the name will be treated as being in the package/namespace whose global unique name is the namespace-name.

Has mostly the same effect as:

          (define-constant name #,(namespace namespace-name)

However, using define-namespace (rather than define-constant) is recommended if you want to use compound symbols as names of variables, especially local variables, or if you want to quote compound symbols.

Note that the prefix is only visible lexically: it is not part of the namespace, or thus indirectly the symbols, and so is not available when printing the symbol. You might consider using define-xml-namespace as an alternative.

A namespace is similar to a Common Lisp package, and the namespace-name is like the name of the package. However, a namespace alias belongs to the lexical scope, while a Common Lisp package nickname is global and belongs to the package itself.

If the namespace-name starts with the string "class:", then the name can be used for invoking Java methods and accessing fields.

You can use a namespace as an abbreviation or renaming of a class name, but as a matter of style define-alias is preferred.

— Syntax: define-private-namespace name namespace-name

Same as define-namespace, but the prefix name is local to the current module.

For example you might have a set of a geometry definitions defined under the namespace-uri "http://foo.org/lib/geometry":

     (define-namespace geom "http://foo.org/lib/geometry")
     (define (geom:translate x y)
       (java.awt.geom.AffineTransform:getTranslateInstance x y))
     (define geom:zero (geom:translate 0 0))
     geom:zero
       ⇒ AffineTransform[[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]]

You could have some other definitions for complex math:

     (define-namespace complex "http://foo.org/lib/math/complex")
     (define complex:zero +0+0i)

You can use a namespace-value directly in a compound name:

     (namespace "http://foo.org/lib/geometry"):zero
       ⇒ AffineTransform[[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]]

The variation define-xml-namespace is used for creating XML nodes.

— Syntax: define-xml-namespace prefix "namespace-uri"

Defines a namespace with prefix prefix and URI namespace-uri. This is similar to define-namespace but with two important differences:

  • Every symbol in the namespace automatically maps to an element-constructor-type, as with the html namespace.
  • The prefix is a component of the namespace object, and hence indirectly of any symbols belongining to the namespace.

Thus the definition is roughly equivalent to:

          (define-constant name #,(namespace namespace-name name)

along with an infinite set of definitions, for every possible tag:

          (define (name:tag . rest) (apply make-element 'name:tag rest))
     $ kawa --output-format xml
     #|kawa:1|# (define-xml-namespace na "Namespace1")
     #|kawa:2|# (define-xml-namespace nb "Namespace1")
     #|kawa:3|# (define xa (na:em "Info"))
     #|kawa:4|# xa
     <na:em xmlns:na="Namespace1">Info</na:em>
     #|kawa:5|# (define xb (nb:em "Info"))
     #|kawa:6|# xa
     <nb:em xmlns:nb="Namespace1">Info</nb:em>

Note that the prefix is part of the qualified name (it is actually part of the namespace object), and it is used when printing the tag. Two qualified names (symbols) that have the same local-name and the same namespace-name are considered equal, even if they have different prefix. You can think of the prefix as annotation used when printing, but not otherwise part of the “meaning” of a compound symbol. They are the same object if they also have the same prefix. This is an important different from traditional Lisp/Scheme symbols, but it is how XML QNames work.

     #|kawa:7|# (instance? xb na:em)
     true
     #|kawa:8|# (eq? 'na:em 'nb:em)
     false
     #|kawa:9|# (equal? 'na:em 'nb:em)
     true
     #|kawa:10|# (eqv? 'na:em 'nb:em)
     true

(Note that #t is printed as true when using XML formatting.)

The predefined html prefix could be defined thus:

     (define-xml-namespace html "http://www.w3.org/1999/xhtml")
Created 21 Jun 2010 00:05 PDT. Last edited 21 Jun 2010 19:29 PDT. Tags:

JavaFX using Kawa - introduction
Created 28 Jul 2011 11:06 PDT. Last edited 5 Aug 2011 11:22 PDT.

JavaFX using Kawa - simple animation
Created 28 Jul 2011 11:05 PDT. Last edited 1 Aug 2011 11:16 PDT.

Using JAXB Annotations to read/write XML
Created 3 Jan 2011 18:31 PST. Last edited 7 Jan 2011 11:46 PST.

Kawa 1.11 released
Created 15 Nov 2010 12:11 PST. Last edited 15 Nov 2010 13:48 PST.

Q2 - extensible syntax with indentation
Created 14 Nov 2010 13:28 PST. Last edited 15 Nov 2010 07:26 PST.

Hello world in Scheme for Android
Created 18 Oct 2010 14:27 PDT. Last edited 10 Apr 2011 11:55 PDT.

Kawa in Languages shootout
Created 11 Oct 2010 09:25 PDT. Last edited 11 Nov 2010 23:29 PST.

XML literals
Created 21 Jun 2010 15:46 PDT. Last edited 21 Jun 2010 19:21 PDT.

Namespaces and compound symbols
Created 21 Jun 2010 00:05 PDT. Last edited 21 Jun 2010 19:29 PDT.

Lots of Kawa changes
Created 13 Mar 2009 19:51 PDT. Last edited 13 Mar 2009 20:27 PDT.

Hello world in Scheme for Android
Created 17 Jan 2009 16:12 PST. Last edited 10 Apr 2011 11:53 PDT.

Hello world in Scheme for Android
Created 24 Dec 2008 11:59 PST. Last edited 10 Apr 2011 11:57 PDT.

Per's Scheme blog entries
Created 9 Oct 2008 15:45 PDT. Last edited 9 Oct 2008 15:45 PDT.

JVM Languages summit
Created 4 Oct 2008 18:39 PDT. Last edited 4 Oct 2008 19:52 PDT.

A Swing-based read-eval-print interface
Created 11 Sep 2007 08:52 PDT. Last edited 11 Sep 2007 08:52 PDT.

Created 20 Jun 2010 23:56 PDT. Last edited 20 Jun 2010 23:56 PDT.
Tags: