Kawa (like other Free Software projects) has no lack of tasks and projects to work on. Here are some ideas.
The Kawa compiler currently uses reflection to determine properties
(such as exported function definitions) from referenced classes.
It would be better to read class files.
This should not be too difficult, since the
abstracts over class information read by reflection or class reading.
We’d like a command for compiling compile a list of Java and Scheme
source files thar may have mutual dependencies. A good way
to do this is to hook into
javac, which is quite extensible
One could do something like:
Read the "header" of each Kawa source file, to determine the name of the generated main class.
Enter these class names into the javac tables as “uncompleted” classes.
Start compiling the Java files. When this requires the members of the of the Kawa classes, switch to the Kawa files. From javac, treat these as pre-compiled .class files. I.e. we treat the Kawa compiler as a black box that produces Symbols in the same way as reading class files. At this point we should only need to the initial “scan” phase on Kawa.
If necessary, finish compiling remaining Kawa files.
This approach may not immediately provide as robust mixed-language support as ideal, but it is more amenable to incremental improvement that a standalone stub-generator.
This project is good if you know or want to learn how
Java 7 supports MethodHandles which are meant to provide better performance (ultimately) for dynamic languages. See JSR 292 and the Da Vinci Machine Project. MethodHandles will be used to compile lambdas in Java 8. Kawa can already be compiled to use Methodhandles, but only in one unimportant way. There much more to be done. For example we can start by optimizing arithmetic when the types are unknown at compile-time. They could make implementing generic functions (multimethods) more efficient. At some point we want to compile lambdas in the same way as the Java 8 preview does. This can potenitally be more efficient than Kawa’s current mechanism.
Remi Forax’s vmboiler is a small library on top of ASM that generates optimistically typed bytecodes. It could be useful for ideas.
Kawa has some limited support for parameterized types, but it’s not used much. Improve type inferencing. Support definition of parameterized classes. Better used of parameterized types for sequence class. Support wildcards. (It might be better to have wild-carding be associated with declarations, as in Scala, rather than uses.)
Kawa doesn’t have true function types: Parameter and result types are only handled for “known” functions. Adding first-class function types would be a major task, possibly depending on improvements in Parameterized types.
Currently being worked on.
Add support for full continuations, which is the major feature missing for Kawa to qualify as a “true Scheme”. One way to implement continuations is to add a add that converts the abstract syntax tree to continuation-pass-style, and then exhand the existing full-tail-call support to manage a stack. There are other ways to solve the problem. This may benefit from Faster tailcalls.
--full-tailcalls run faster.
This may depend on (or incorporate)
The TreeList class is a data structure for “flattened” trees. It is used for XML-style nodes, for multiple values, and for the full-tail-call API. The basic concept is fine, but it could do with some re-thinking to make make random-access indexing fast. Also, support for updating is insufficient. (This needs someone into designing and hacking on low-level data-structures, along with lots of profiling and testing.)
C# recently added
for asynchronous programming. Kawa’s recently improved support for lazy programming
seems like a good framework for equivalent functionality:
Instead of an
asynch method that returns a
the Kawa programmer would write a function that returns a
This involves some design work, and modifying the compiler to
rewrite the function body as needed.
This is related to full continuations, as the re-writing is similar.
Currently being worked on.
Improvements to the read-eval-print console. In addition to a traditional Swing console, it would be useful to support using a web browser as a a remote terminal, possibly using web-sockets. (This allows “printing” HTML-expressions, which can be a useful way to learn and experiment with web technologies.) See here for an article on the existing Swing REPL, along with some to-do items. Being able to hide and show different parts of the output might be nice. Being able to link from error messages to source might be nice. Better handling of redefinitions is discussed here in the context of JavaXF Script; this is a general REPL issue, mostly independent of the GUI for it.
It would be nice to update the XQuery (Qexo) support to some subset of XQuery 3.0.
Kawa supports a small subset of the Common Lisp language, but it supports a much larger subset of core Common Lisp concepts and data structure, some designed with Common Lisp functionality in mind. Examples include packages, arrays, expanded function declarations, type specifications, and format. A lot could be done to improve the Common Lisp support with modest effort. Some Common Lisp features could also be useful for Scheme: Documentation strings (or markup) as Java annotations, better MOP-like introspection, and generic methods a la defmethod (i.e. with multiple definition statements, possibly in separate files, as opposed to the current make-procedure) all come to mind. Being able to run some existing Common Lisp code bases with at most modest changes should be the goal. One such package to start with might be a existing test framework, perhaps FivaAM. Full Common Lisp compatibility is nice, but let’s walk before we can run.
A lot of work is needed to make JEmacs useful. One could try to import a useful package and see what works and what fails. Or one may look at basic editing primitives. Enhancements may be needed to core Emacs Lisp language primitives (enhancing Common Lisp support may help), or to the display engine.
Emacs now supports lexical bindings - we should do the same.
There is some Kawa support for Eclipse (Schemeway), and possibly other IDEs (NetBeans, IntelliJ). But many improvements are desirable. REPL improvements may be a component of this.
Kawa-Scheme support for the NetBeans IDE would be useful. One could perhaps build on the Clojure plugin.
Kawa-Scheme support for the Eclipse IDE would be useful. Probably makes sense to enhance SchemeWay. It may also make sense to build on the Dynamic Languages Toolkit, possibly making use of Schemeide, though DLTk seems more oriented towards interpreted non-JVM-based languages.
SLIME is an Emacs mode that provides IDE-like functionality. It supports Kawa.
JDEE is a Java development environment, so might have better hooks to the JVM and Java debugging architecture.
CEDET is a more general framework of development tools.
It would be nice to integrate the pretty-printer with the REPL, so that window re-sizing re-breaks the output lines. It would be nice to enhance the pretty-printer to handle variable-width fonts and other “rich” text. Figuring out how to make the output formatter more flexible, more efficient, and more customizable are also desirable.
Hop is an interesting design for integrating server-side and client-side programming using a Scheme dialect. These ideas seem like they would port quite well to Kawa.
Support localization by extending the SRFI_109 syntax, in the manner of (and compatible with) GNU gettext. I.e. optionally specify a localization key (to use as an index in the translation database); if there is no key specified, default to using the literal parts of the string.
Implement a “bind” mechanism similar to that of JavaFX Script. The idea is when you initialize a variable or field, instead of initializing it to a fixed value, you bind it to an expression depending on other variables. We install “listeners” on those variables, so when those variables change, we update the bound variable. This feature is useful in many application, but the initial focus could be GUI programming and perhaps web programming.
Kawa does a lot of optimizations and inlining. This conflicts with being able to “reload” a module into an already-running interactive environment.
We could add an option to load a module in “reloadable” mode.
Kawa already patches an old function object (a
so existing references to the function get automatically updated.
However, there are problems if the “signature” of the function
changes - for example if the return type (declared or inferred)
becomes more general. In those cases the best thing is to
re-compile any code that depends on the modified function.
Reloading a module that defines a class is even trickier, at least if there are existing instances that should work as the updated class. We can handle the special case where only method bodies change: In reloadable mode, each method body is compiled to a separate function, the actual body indirects to the function. We must also recognize that we compiling a new version of the same class, which requires a textual comparison between the old and new versions, or a structural comparison between the old class and the new code.
When it comes to top-level variables, an issue is when to re-evaluate the initializing expression. It is reasonable to do so if and only if the expression is modified, which again requires a textual comparison.
Implement unsigned arithmetic types
ubyte. These should be primitive types that are represented
using the corresponding signed types, similar to how the
type is represented using
int. Also implement corresponding
“boxed” types as sibling types of
Implement arithmetic, comparisons,
and conversions both at run-time, and optimized when the types are known
(In the latter case there should be no object allocation.)
Use same promotion rules
except that combining
Uniform vector operations
u16vector-ref) should be optimized to return the
primitive values (such as
Kawa currently implements “optimistic” typing: The compiler only
complains if an expression has no values in common with the target type
- for example if assigning a
string expression to an
It would be interesting to experiment with a
--strict-typing option (which would never be the default):
Strict typing would only allow “widening” conversions - i.e.
that the expression type be a subtype of the target type.
For example it would complain if assigning a
number to an
unless you used an explicit cast.
To make this easier to deal with we’d want to introduce a new type
dynamic similar to
C# has: Any expression can be converted
to or from
dynamic without the compiler complaining.
is allowed by the compiler regardless of
name, with all checking
being deferred to run-time. If a variable is declared without a type,
it should default to
is represented in the VM as
object but with an annotation
(like we do with
The type-checker might need some changes to better distinguish implicit conversions from explicit casts.