- JDK 1.1 limitations
- The core of SILK with generic functions is supported in JDK 1.1.
However, the following features are missing or restricted:
- Because of access limitations, (describe object) only describes
public fields. In JDK 1.2, all the fields of an object can be seen.
- (get-field) and (set-field) are similarly limited.
- build.CompilingClassLoader and silk.SchemeCLassLoader are
currenly JDK 1.2 specific.
- Classes that import from the package javax.swing will not
compile and will not therefore be in jar/scheme.jar. elf.GCMonitor
is such an example class.
- Applet and JLIB issues
- SILK will run in an Applet using JLIB. See the examples in the
applet directory.
To use JLIB in the generic environment, use the libraries/Java2.scm version which has
been changed slightly to avoid name conflicts. For a working example,
see src/scheme/schemegui.html.
- Applet loads slow
- On a 266 MHz Pentium II, in Netscape 4.5, the time it takes to
start Scheme is about 20 to 35 seconds. When using Scheme as an
application, it takes about a second in JDK 1.2 and JDK 1.1.6.
On an iteration benchmark (essentially a consing benchmark):
(define (f x) (if (= x 0) #f (f (- x 1))))
(time (f 1000000))
Netscape seems to be twice as slow as JDK 1.2. JDK 1.1.6 is slightly
faster. Including this difference, we still have a factor of 10 to
account for.
- Java Strings
-
Strings in Scheme are represented as Java char[]. When Scheme calls a
Java method the expects a String, a Scheme string or symbol is
converted into a Java String. When a Java method returns a String as
a value, it is converted into a Scheme symbol (since they are
immutable).
Thus (toString x) converts x to a symbol, rather than a
string. So if you want a string, say (symbol->string (toString
x)) or (string-append x).
- String memory leak
- A memory leak occurs because Java
Strings are converted into Scheme symbols, which are interned. So, a
application such as src/elf/GCmonitor.scm
which essentially generates a random string every half second can
continually grow. GCMonior grows at 1MB/hour. The Java version does not grow.
- Primitive arrays
- A Scheme array is represented as a Java Object[]. Primitive
arrays, such as String[] can be constructed using
(java-vector CLASS element1 ...) which constructs an array
with elements of type CLASS containing the elements
element1 .... The procedure (make-java-vector CLASS
SIZE) will make a particular class of Java array of size SIZE.
The procedures(vector-ref) and (vector-set!) can be
used to get or set an array element of any type of array.
- Primitive values
- However, to insert an element into an primitive array, one must construct
an appopriae value. The Scheme side of SILK supports only a few
primitive types: boolean, char, int, and double. So, filling an array
of a primitive type can be tricky. For example, to produce a value
that would go into a byte[], you need to construct a Byte in Scheme.
Byte has two constructors:
public Byte(String);
public Byte(byte);
The second version can't be used in Scheme unless you have a Byte
already. This forces you to use the kludge:
(import "java.lang.Byte")
(Byte (string-append 3)) ; returns a Byte representing 3.
See the class silk.Coerce which
provides conversion between primitive types.
- Method lookup ambiguities
- Generic function method lookup uses the runtime types of its
arguments to decide which method to invoke. There are some ambiguity
to this process. For example, a null argument provides no runtime
type information. However, while the lookup process works generally,
it has some flaws that cause it to fail occasionally. The workaround
for such cases is to use (method)to select the method you
want to invoke.
- Few numeric types
- SILK's Scheme side only support Integer and Double as numeric
types. However, SILK's implementation will somewhat handle the other
types. For example:
> (import "java.lang.Shor")
importing java.lang.Short in 40 ms.
> (+ (Short "3") (Short "4"))
7.0
Precision can be lost, so when dealing with Long's, convert them to
Double's first. Here's code that deals with file cration times:
(define (last-modified file)
;; KRA 05AUG99: We need this kludge because SILK does not deal with Longs.
(Double (toString (lastModified file))))
(define (needs-recompile class-file java-file)
(if (not (exists java-file)) (error java-file " does not exist!"))
(or (not (exists class-file))
(> (last-modified java-file) (last-modified class-file))))