by Per Bothner
So-called scripting languages
are now very visible, but they have a long history, even on the Java platform. Of languages still in use and active development today, Kawa and Netrexx are (to my knowledge) the oldest, both created in 1996. (Java was publicly launched in 1995.) Kawa appears to have been the first scripting language to be compiled directly to Java bytescodes, and is the oldest still-active functional language on the JVM. Kawa was based on a simple Scheme interpreter written by Alex Milowski, but I re-wrote it as a compiler while I worked for Cygnus Solutions, probably the first company to commercialize Free Software. Kawa is now GNU software, available under an MIT license.
Kawa is still used for a number of projects. As an example MIT App Inventor(previously Google App Inventor) for Android is built on top of Kawa.
Scripting vs programming languages
Kawa tries to combine the advantages of scripting languages with those of Java-like programming languages
.
Like other scripting languages, Kawa avoids boilerplate such as having to define a class and main
method. Since Kawa is an expression language, the minimal Hello, world
program is just:
"Hello, world!"
Macros allow syntactic extension, and can be defined in libraries just like functions. It is trivial to implement a domain-specific language
on top of Scheme, at least as long as you use the core S-expression datum
syntax. Kawa has convenient syntactic short-hands like colon notation.
Kawa is quite dynamic: It has eval
, and a read-eval-print-loop. If you type in an expression or load a file to be evaluated, it is automatically(and quickly) compiled down to bytecode.
You don't need to specify the types of variables – but you can: Doing so helps document your program, may allow the compiler to generate faster code, and may allow the compiler to catch errors and inconsistencies.
Kawa also has the advantages a more conventional programming
language, like Java or Scala. You can compile to a class
file, which can be an application (with an automatically-generated main
), an applet, a servlet, or other specified class. It has an optimizing compiler which does decent data-flow analysis and type interface. This combined with optional type declarations make it straightforward to write code that is as efficient as Java or Scala – and many times faster than languages like JRuby or Clojure. The compiler is good at detecting and reporting errors, which avoids many painful debugging sessions. Kawa's primary visibility boundary is a sourcefile modules, which is natural and easy for both human readers and compilers.
In the rest of this article I will touch on some cool features of Kawa; maybe one of them will inspire you to try it out.
Object construction
Kawa has a convenient terse syntax for object construction. For example, this creates a Swing JButton
that calls do-it
when pressed:
(javax.swing.JButton
text: "Do it!"
action-listener:
(lambda (e) (do-it)))
Groovy has a SwingBuilder that allows similar compact object construction. However, Kawa's is built in: It works for any bean
-like class with standard set
or add
methods. Kawa is also more efficient, since it doesn't create a helper object. Instead the compiler translates the constructor call to code like what you'd write by hand in Java.
Android
Of course sometimes just using the beans
naming convention isn't quite enough to yield a pleasant constructor API. For example, in the Android API you construct a tree of View
objects. Each View
constructor requires a parameter which is the current Activity
, which looks like this:
(TextView (this) text: "Hello world!")
The reference (this)
to the current Activity
is tedious boiler-plate. That is why Kawa defines some special handling so you can leave out the (this)
:
(TextView text: "Hello world!")
This special handling for View
classes is not hard-wired but is defined in an Android-specific library.
Read how to build and run Android applicationsand more about Android View
expressions.
JavaFX
Kawa also has some special handling to ease JavaFX programming. This page has a simple example and up-to-date instructions. Also check out two slightly older blog articles: an introduction, and about animation.
Self-configuring web server
It is easy to write web services using Kawa. No setup or additional software is needed if using the server built in to JDK (version 6 or later). Just start Kawa like this:
kawa --http-auto-handler / appdir --http-start 8888
Here is a web page scriptthat replies back with the name of the requesting (client) host:
;; Hello world page script written in -*- scheme -*-
#<p>Hello, <b>&(request-remote-host)</b>!</p>
The script uses an XML literal with an embedded expression. Put this file in appdir/path
, and point your browser to http://localhost:8888/path
. Kawa will find the file, recognize the string
in the first line and realize it is a Scheme script, then compile (if necessary) and evaluate it, and return the result to the browser.-*- scheme -*-
You can use the same page scripts on a servet container such as Tomcat or Glassfish, instead of using JDK's builtin server.
Lazy evaluation
A pure functional language
uses lazy evaluation – i.e. an expression is only evaluated when the value is needed. Impure
functional languages like Scheme use strict evaluation, familiar from Java and most commonly-used languages. Kawa has a hybrid functionality: The expression (delay E)
evaluates to a promise
P
that will evaluate the expression E
when requested. You can call (force P)
to explicitly force the resulting promise: It returns the result of evaluating E
. The expression E
is only evaluated once, and the result remembered in case P
is forced later.
The forms delay
and delay
are standard. Kawa also supports implicit forcing, as you'd find in a pure functional language: If the promise is used in a context that requires a real non-promise value, such as (* P 2)
the P
then the result is as you wrote: (* (force P) 2)
. It makes it more convenient to use lazy values.
Kawa also has futures; these are also automatically forced when needed.
Meta: this post is part of the Java Advent Calendar and is licensed under the Creative Commons 3.0 Attribution license. If you like it, please spread the word by sharing, tweeting, FB, G+ and so on! Want to write for the blog? We are looking for contributors to fill all 24 slot and would love to have your contribution! Contact Attila Balazs to contribute!