Per's Scheme blog entries
Kawa has seemingly been pretty quiet, but lately I'm been making a lot of little improvements.
While it's going to take a while before Kawa can claim to implement R6RS, I've made a bunch of changes that bring it closer:
Support the R6RS
importkeyword, including support for renaming.Implemented the
(rnrs sorting)library.Various little changes in character literal and string literal syntax.
The comment prefix
#;skips the following S-expression, as specified by SRFI-62.All the R6RS exact bitwise arithmetic functions are now implemented and documented in the manual. The new standard functions (for example
bitwise-and) are now preferred over the old functions (for examplelogand).
Kawa also support some new SRFIs:
SRFI-62 (S-expression comments);
SRFI-64 (Scheme API for test suites);
SRFI-95 (Sorting and Merging);
SRFI-97 (Names for SRFI Libraries). The last is a naming convention for R6RS
import statements to reference SRFI libraries.
Also a lot of other changes and performance improvements. See the Kawa news page for more information.
It is (way past) time for an actual release, which will be called Kawa 1.10. I think we've got enough features (I'm hopying to add JSR-223 support before I call it done), but there is lots of little cleanups, plus documentation to write.
(This is an update of AndroidHelloScheme.)
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
(let ((tv (android.widget.TextView (this))))
(tv:setText "Hello, Android from Kawa Scheme!")
tv)))
The following instructions have been tested on GNU/Linux, specifically Fedora 10, but if you've managed to build Android applications under (say) Windows, you should be able to appropriately modify these instructions. The article Android Phone development from the Linux command-line helped me figure out what to do.
Getting and building Kawa and Android
First download the Android SDK. Unzip in a suitable location,
which we'll refer to as ANDROID_HOME.
$ ANDROID_HOME=/path/to/android-sdk-linux_x86-1.0_r2 $ PATH=$ANDROID_HOME/tools:$PATH
To get things to work I had to make some modest changes to Kawa, so you will need to get the Kawa developer sources from SVN.
You need to configure and make Kawa appropriately:
$ KAWA_DIR=path_to_Kawa_sources $ cd $KAWA_DIR $ ./configure --with-android=$ANDROID_HOME/android.jar --disable-xquery $ 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:
$ activitycreator --out KawaHello kawa.android.hello
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.9.3.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 compile our application:
$ ant
Running the application on the Android emulator
Start up the Android emulator:
$ emulator&
Wait until Android has finished booting, clisk the menu and home buttons. Click the tab above the menu key to show the installed applications. Now install our new application:
adb install bin/hello-debug.apk
The new hello application should show up.
Click it, and you should see something like:
Running the application on the G1 phone
If the emulator is running, kill it:
$ kill %emulator
Connect the phone to your computer with the USB cable.
Verify that the phone is accessible to adb:
$ adb devices List of devices attached HT849GZ17337 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 2009-01-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/hello-debug.apk
Some debugging notes
You will find a copy of the SDK documentation in
$ANDROID_HOME/docs/documentation.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
(This has been updated here.)
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:
(module-extends android.app.Activity)
(module-name kawa.android.hello)
(define (onCreate (savedInstanceState :: android.os.Bundle)) :: void
(invoke-special android.app.Activity (this) 'onCreate savedInstanceState)
(let ((tv :: android.widget.TextView (make android.widget.TextView (this))))
(tv:setText "Hello, Android from Kawa Scheme!")
((this):setContentView tv)))
It's got some annoying boiler-plate, though it's similar to the Java version; hopefully we can simplify later.
Here is how to get this program running on the Android emulator on GNU/Linux. (I haven't yet figured out how to get it working on the actual phone.) This article Android Phone development from the Linux command-line was helpful in figuring out what to do.
First you need to download the Android SDK. Unzip, in a suitable location,
which we'll refer to as ANDROID_HOME:
ANDROID_HOME=/path/to/android-sdk-linux_x86-1.0_r2 PATH=$ANDROID_HOME/tools:$PATH
To get this to work I had to make some modest changes to Kawa, so you will need to get the Kawa developer sources from SVN.
You need to configure and make Kawa appropriately:
KAWA_DIR=path_to_Kawa_sources cd $KAWA_DIR ./configure --with-android=$ANDROID_HOME/android.jar make
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:
activitycreator --out KawaHello kawa.android.hello
Replace the skeleton hello.java by the
Scheme code we started out with:
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.9.3.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
Finally, we can compile our application:
ant
Next start up the Android emulator:
emulator&
Wait until Android has finished booting, clisk the menu and home buttons. Click the tab above the menu key to show the installed applications. Now install our new application:
adb install bin/hello-debug.apk
The new hello application should show up.
Click it, and you should see something like:
Some debugging notes
You will find a copy of the SDK documentation in
$ANDROID_HOME/docs/documentation.html.
If the emulator complains that your application
has stopped unexpectedly
, 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....
This shows log messages, stack traces, output from the Log.i
loggin method, and other useful information.
To uninstall your application, do:
adb uninstall kawa.android
I talked about Scheme, XQuery, and JavaFX: Compiling using Kawa or Javac on September 26, 2008 at the JVM Language Summit. Slides are available here.
I've long been interested in improved commend-line interfaces. The latest Kawa (in SVN) has a new implementation of a command interface window. If you start up Kawa with the -w flag:
kawa -w
you get a new Swing JFrame, whose
interesting component is a JTextPane
for typing in expressions, and displaying the results.
The following example uses Kawa's default language Scheme,
but works for other Kawa languages, including XQuery.

Color coding
Here the command prompt is in green, and the input command is in bold-face, because it seems useful to emphasize the input as a way of visually separating one command from the previous. The standard error output is in red. Standard output has the plain default style. This is because standard output may have embedded in it other objects and nested styled text.
All of these are implemented using Swing style objects. There is currently no mechanism to modify one these styles, except by modifying the source code, but at some point we will support that.
Input editing
While the color-coding is pretty, even more important is
command-line editing. That is you can move the input cursor
along the input line, and insert, delete, or replace text
before hitting Enter.
This is previously available using
the GNU readline library, which has some nice features, including
a searchable history mechanism. However, you cannot move the
cursor using the mouse, which is surprising to many.
Currently, the entire text pane is editable using the
default JTextPane keystrokes and mouse handlers.
(It would be better that at least the prompt be non-editable.)
Nothing gets sent to the receiving reader until you type
Enter. At that point the entire line containing
the cursor, except for the prompt, is sent to the reader.
(More precisely: If the cursor is at or after the output position,
the rest of the line after the output position is sent.
Otherwise, usually it's a way of repeating or modifying a previous
line. In that case the contents of that line, except any initial
prompt segment, are first copied to the end of the text buffer,
as if typed there, before being sent to the reader.)
If you paste a multi-line string (commonly using ctrl-V),
then ReplPane magically interleaves the prompt string and
output with the input text. For example if you paste the following text:
(display "foo") (newline) (display "bar") (newline)
You get this result:

Note that the prompt for line 4 is different because it's a continuation line. (Alas, this feature is not very robust; it is easy to get Swing exceptions.)
Embedding Components
A powerful feature is that you "print" java.awt.Component
objects. These are embedded in the JTextPane.
The following Scheme example creates a list of 3 JButton
objects, and that list is then "printed":

We can of course save a reference to the button in a variable:

That allows us to modify properies of the button.
Here we change its text property, in line 4,
and the button is updated as soon as we hit enter:

One anomaly when "printing" a Component
is that a Component can only appear once.
If we "print" it a second time, it is as a side-effect
removed from the first place it was printed:

This isn't really the right behavior, but it's unavoidable
when "printing" a Component.
To avoid the problem, we need to "print" a some kind of
"model" object rather than "view" objects.
Embedding Viewable objects
The experimental swing-gui library provides
"viewable model" objects that can also be "printed" to a TextPane.
For example, the gnu.kawa.models.Button class
goes beyond Swing's ButtonModel in also having
text and an action procedure.
When a gnu.kawa.models.Button is "printed" the
implementation automatically creates a JButton that
is co-ordinated with the gnu.kawa.models.Button:

Again, we can change the text property:

Here we do some more complex layout,
creating a Row displaying the same button twice,
separated by a spacer. Then we create a column
that displays the same row twice, separated by a text field.
(For some reason the text field isn't displaying properly.)

Playing with composable Java2D pictures
The swing-gui library also provides
convenience wrappers to the
gnu.kawa.models.Paintable interface,
which makes it easy to create, compose, and transform Java2D Shape
objects.

Issues
- The
ReplPaneis not very solid. It's not hard to type something which causes a Swing exception, which is usually not recoverable. - There should be a
Viewmenu to modify fornts and styles, and a standardEditmenu to Cut/Copy/Paste, at least. TheFilemenu should have a way to save the typescript. - The
Utilities->Purge Buffermenu item doesn't work. - The display should be integrated with the Kawa pretty-printer, so that changing the window width recalculates line-breaks.
- It would be nice to emit styled "inline" (text) objects,
such as a "red string".
Maybe we should be using Swing's
HTMLDocumentinstead ofDefaultStyledDocument. Another toolkit to consider is Flying Saucer.