The ProfessorJ Java + dynamic extends Java with a new type keyword, dynamic, and the ability to directly
import libraries written in Scheme as well as Java.
The paper Fine Grained Interoperability through
Mirrors and Contracts presents the full details of this
extension.
Importing
Scheme libraries
|
In the Java + dynamic language, the import statement
| import scheme.lib.mred.mred; |
directs the compiler to allow the current program to use values
provided by the PLT library collection mred.ss located in the mred
directory.
The import statement
| import
scheme.interp.scripts; |
directs the compiler to allow the current program to use values
provided by the script.ss module located in the interp directory, found
using the standard classpath
Within the body of the Java program, a Scheme value is accessed using
the same style as a static member of a class (where a module is seen as
a class).
So,
in a program importing MrEd allows the Java programmer to access the
class of the MrEd library. Within the Java program, this value carries
no static type information and can legally appear in any Java value
context. During execution, dynamic checks will ensure that Java type
guarantees are not violated.
Scheme functions and methods may be called within the Java program, and
Java values may be passed in as arguments,
| scripts.buildTaxEnv(new
TaxCalc()) |
The Java value is embedded within a contract that ensures Java type
guarantees are not violated when the Scheme program accesses the Java
value.
In Java + dynamic, any position that expects a type (except an instanceof expression) can have
the type dynamic as well
as the original Java types. Such a declaration ensures that no static
errors may arise due to the use of the value with this specified type.
Any necessary checks to ensure Java's other static type guarantees will
be performed at run time.
An example of using dynamic follows
class X {
dynamic three = 3;
int four = three + 1;
String getThree() {
three = "Three";
return three;
}
} |
In this example, the value assigned to the variable three is at one point an
integer and at another point a String.
Both assignments are permissible as no static checks are associated
with three. During
evaluation of the addition to generate four,
a runtime check will ensure that the value of three is an integer; and during
the return from the getThree
method, a different runtime check will ensure that the value is a String.
A value with a dynamic
type may be treated as any value within Java, including an instance of
a particular class or as an instance of an unknown class with any field
or method. In the above example, we saw a variable with a dynamic type
used in a context that specifically requires an instance of the class String.
class X {
dynamic
result( dynamic computer ) {
if (computer.on())
return computer.add();
else
return computer.error;
}
} |
In this example, the
dynamic parameter computer
is treated as an instance of a class containing a method on, as an instance of a class
containing a method add,
and an instance of a class containing a field error. It is not guaranteed
that there is any one class that contains these three members, and in
fact it is not dynamically necessary that any class contain more than
two of these members. There is a dynamic requirement that add return a boolean to ensure
the proper functioning of Java's if
statement, and this requires a dynamic check that the compiler inserts.
Java
Values within Scheme
|
Within a Scheme program, Java values are accessed like their Scheme
counterparts. Numbers, booleans, and characters convert into
appropriate Scheme values. String objects are converted into Scheme
strings. Other Java objects enter Scheme with an interface appropriate
to a Scheme object.
Calling a method getThree
on a Java object within Scheme is written (send obj get-three). When a
method is overloaded in Java, the Scheme programmer will have to
explicitly specify the method desired by adding the types of the
arguments on to the name of the method.
To access a field of a Java object, the Scheme programmer must also
use a method. So accessing a field three uses a method get-three~f, and modifying the
value that is bound to three
uses set-three~f.
A name in Scheme is not necessarily a name in Java, further the
standard naming convention in Java does not match the standard naming
convention in Scheme.
While Java + dynamic does not attempt to solve all problems arising due
to the different allowable names/ different naming conventions between
these two languages, it does attempt to alleviate some burden from
programmers.
Automatic conversions are performed on names in the appropriate
direction in the following cases:
Scheme Name
|
<-->
|
Java Name
|
Example
|
name-name
|
|
nameName
|
make-foo <-->
makeFoo
|
| name? |
|
nameP |
eq? <--> eqP
|
name->name
|
|
nameToName
|
foo->string
<--> fooToString
|
| name! |
|
nameSet |
set-foo-baz!
<--> setFooBazSet
|
| name% |
|
nameObj |
frame% <--> frameObj
|
If a name cannot be used and does not fit into these conventions, the
programmer may need to manually provide an indirection with an
appropriate name.
| Java + dynamic and the Teaching languages
|
The Java+dynamic language simplifies the process of writing libraries
to allow students to interact with the MrEd graphics within their Java
programs.
Within the htdch collection, the graphics library (importable into any
program in a teaching language) incorporates MrEd graphics into the
student environment. Students may build and manipulate Image objects,
containing embedded MrEd graphics. ProfessorJ provides a small amount
of special support in the display of these objects (and in reading them
in), removing the Image class wrapping during display to allow students
to observe better observe their images.

Drawing Library
Imported images are used directly as values within the DrScheme
environment. The MrEd library controls the drawing, while the Java
wrapper support uses dynamic to present an appropriate interface to
students.
|

Drawing commands
Images are Java objects, that just happen to contain Scheme values.
Students see none of this and library implementors don't need to worry
about students encountering type inconsistencies.
|
|