|
|
General Notes
Both FunJava and MiniJava are derived from Java.
Unless otherwise noted, the syntax and semantics follow what is outlined in
the Java Language Specification.
MiniJava--which forms the basis for FunJava--is intended to be a simple, proper
sub-set of Java.
This is, essentially, the case, except that Java does not allow nested
/* */ comments (see: Appel A.1 vs. JLS 3.7).
On the other hand, FunJava is quite clearly not a sub-set of Java.
Notable differences are the addition of nested functions, type naming, and
type expressions which permit function types and functional programming.
FunJava is also not a Java super-set.
However, FunJava is a super-set of MiniJava.
Restricted vs. Full FunJava
There are actually two versions of FunJava that will be used with this course.
Graduate students (CSc 583A) will implement a version that supports functions
as first-class types. This version will be referred to as full FunJava.
Undergraduates (CSc 435) will implement a restricted version, which we'll call
restricted FunJava, that does not allow functions (as values) to
escape the stack-context in which they are "instantiated".
Specifically, functions may be passed as parameters in restricted FunJava, but
they may not be used as return values, nor can they be saved into the heap
(i.e. field variables or arrays).
The significance of this distiction will become apparent when we consider how
to implement function types...
General Semantics
The following points apply to the semantics of both FunJava and MiniJava:
- Fields have no access modifier, hence they are viewed as having
"default" access (see: JLS 6.6.1).
This means that classes have access to fields defined in a parent.
Note:
This is the only case where a field can be directly referenced outside
of its defining class.
While the grammar does permit arbitrary field access expressions, valid
expressions are limited (through semantic checks) to those of the form
<array>.length.
- The single parameter to
main is not accessible.
The syntax is retained for compatibility--that is, MiniJava->FunJava
and MiniJava->Java.
- Method overriding is permitted and should have the same
virtual dispatch semantics as regular Java methods.
- Method overloading is not supported.
top |
home "/>
FunJava vs. MiniJava
FunJava is described in chapter 15.1 of Appel. Some of the finer points, as
well as some differences from the Appel version are outlined below:
Lexical Differences
- FunJava programs are restricted to ASCII characters.
(This is also true of MiniJava, although it is not stated explicitly.)
-
length is not a keyword in
FunJava. However, proper use is enforced by semantic checks on an
input program.
-
main is not a keyword in
FunJava. However, the main class in a FunJava program must have a
single, public static void method named "main".
-
type is a keyword in FunJava.
It is used to define a name for a type expression, as described in 15.1
of Appel.
-
String is treated as a keyword in FunJava
and refers to a built-in type which is similar to java.lang.String.
- As stated in section A.1 of Appel, identifiers are
formed from a sequence of ASCII letters, digits and underscores
(
_). FunJava also permits identifiers that begin with an
underscore.
- FunJava supports hexadecimal and
octal integer literals similar to those found in Java.
Note:
According to A.1 of Appel, the literal
09 is a valid
integer. This is not permitted in FunJava, as the 0 prefix
indicates an octal value (thus 07 is valid).
- FunJava supports string literals similar to those
found in Java.
However, in FunJava, the content of a string literal must be printable
ASCII (i.e. space through ~, that is values 0x20..0x7E).
The following escape sequences are allowed:
\b,
\t,
\n,
\f,
\r,
\",
\\ and
\ooo (where ooo is a 3-digit ASCII code in octal).
Operators
FunJava includes the MiniJava operators
(&&,
<,
+,
- and
*)
as defined in section A.1 of Appel.
FunJava also includes the following operators:
== (equals) and
!= (not-equals)
- Arbitrary data comparison with Java-like semantics--that is, value
comparison for primitives and reference/object-identity comparison
for complex entities (objects, arrays and functions).
[Grads] Note:
In full FunJava different closure instantiations of the same function
should be treated as not equal.
|| (logical or)
- Same as Java's operator on two
boolean values.
Note:
Evaluation is 'short-circuit' style (similar to &&).
In the case of logical-or, if the first (left) operand evaluates to
true the second (right) operand is not evaluated.
- cond-exp
? true-exp : false-exp
(conditional expression)
- The Java syntax is used instead of the 'if' expression described in
section 15.1 of Appel.
Note:
As in Java, the true-exp and false-exp must be of the
same type. This requirement removes the need to try to infer a
common parent for two object-types.
> (greater-than),
<= (less-than-or-equals) and
>= (greater-than-or-equals)
- Integer comparison operators.
A simple supplement to MiniJava's lone
< (less-than)
operator.
/ (division) and
% (remainder)
- Integer division and division-remainder operators.
A simple supplement to MiniJava's lone
* (multiply)
operator.
-> (map)
- Used in type expressions to define the mapping from domain to range for
a function, eg.
int->boolean is a
function that accepts an integer and returns a boolean.
This operator is right-associative, as per Appel 15.1.
[] (array)
- This sequence, which may contain whitespace, is treated as a (post-fix)
type modifier, promoting its operand to an array type.
This operator has lower precedence than
->
when constructing type expressions.
Grammatical Differences
- The
main method in a FunJava program may contain local
definitions (variables and functions) and zero or more statements.
This is in contrast to MiniJava, where the main method contains a
single statement.
- Any code block (a method or function body, or a block statement) may
begin with local variable and local (nested) function definitions.
Local definitions take precedence over those in an outer scope.
Note:
Nested local definitions that hide entities with the same name in an
outer scope are not permitted in Java (see: JLS 14.4.2).
FunJava does allow nested definitions to obscur outer
versions, however a compiler warning should be issued when such a case
is detected.
- The
public modifier on methods (other than
main) and functions is optional in FunJava.
In the case of methods, all methods are defined in the same file and
hence are all in the same package (from a Java point of view).
This means all methods are accessible anywhere in the program (see:
JLS 6.6.1), and thus the public modifier is
redundant in both MiniJava and FunJava.
Furthermore, the modifier is meaningless when applied to local function
definitions.
Note:
This differs from Appel A.1 and 15.1.
- FunJava allows arrays of any type--even other arrays and, in full
FunJava, arrays of functions.
However, there is no support for instantiating multi-dimensional arrays
in a single expression (see: JLS 15.10).
- FunJava permits a more general form of assignment L-value.
Specifically, any expression that evaluates to an array type, followed
by an index is permitted. This is most useful for multi-dimensional
access (eg.
a[1][0] = 2). Some more obscur
possibilities include f(x)[0] = 1 or
(new int[10])[0] = 1.
- Since functions become values in FunJava, the target of an invoke may
be computed.
A simple example from full FunJava might be
f(x)(y).
Here, the function f is called with parameter
x, the result is a function that is then called with the
parameter y.
Another example, which is valid in restricted FunJava, is
(cond?f:g)(x).
Here the condition selects which function to invoke with the parameter
x.
Functional Differences
- FunJava includes the additional built-in
System.exit(), which accepts an integer
value and causes the program to terminate with the given value as the
exit code.
- The
System.out.println() built-in also
accepts String values (in addition to integers).
- The built-in
String type is treated as a
(non-extendable) object type that supports the following methods:
.length(),
.equals(String),
.compareTo(String),
.concat(String),
.substring(int,int),
The methods work as described in the API for java.lang.String.
top |
home "/>
The FunJava Grammar
top |
home "/>
Examples
Sample.fj
- The example from Appel (Program 15.1) presented in class, with some
corrections.
ConstructionExample.fj
- Some tricks to get around the lack of constructor methods in FunJava.
NullExample.fj
- There is no
null literal in FunJava.
We can compensate by leveraging the default initialization behavior:
object references are null by default.
top |
home "/>
References
- [1]
A. Appel.
Modern Compiler Implementation in Java, Second Edition.
- [2]
J. Gosling, B. Joy, G. Steele, and G. Bracha.
The Java Language Specification, Second Edition.
top |
home "/>
|