|
|
Oberon microsystems |

|
Brief comparison of Component
Pascal and Java
Cuno Pfister, Oberon microsystems
Component Pascal is to Pascal what Java is to C and C++:
a modern and safe next-generation language that combines the
flexibility of dynamic languages with the robustness of
static languages. Like Java, it builds on decades of
experience, and makes reuse of existing skills easy. Like
Java, it supports component software much better than its
predecessors. Compared to Java, it is easier to learn and
allows to produce more efficient code.
The most obvious difference is the "look and feel" of the
two languages. Component Pascal is syntactically clearly in
the Pascal family, while Java is in the C family. But this
is a relatively superficial difference. Concerning the more
important "design for safety", Java and Component Pascal are
closely related, while C and even original Pascal (e.g.,
untagged variant records) are comparatively unsafe. Among
other things, safety also implies automatic garbage
collection. Garbage collection is necessary to avoid memory
leaks and, more importantly, dangling pointers. Both Java
and Component Pascal support the dynamic loading of code and
metaprogramming (reflection). As a result, both languages
can use virtually the same run-time system. This is proven
by the real-time operating systemJBed
(http://www.jbed.com/) and a Component Pascal compiler
that produces standard Java byte code class files. Note that
C or C++ could not be translated into Java byte code,
due to their inherent lack of safety. In this fundamental
respect, Component Pascal and Java are closer than Java is
to C++!
Component Pascal is more efficient than Java. Unlike
Java, it also supports static (stack-allocated) data
structures and has variable (VAR) parameters (with IN and
OUT variants). Depending on the application, this can have a
measureable impact on efficiency. For example, consider the
Component Pascal method call
font.GetMeasures(ascender, descender, maxWidth)
which returns three values as OUT parameters. In Java,
there is no efficient way to express this simple statement.
Instead, a Java method could allocate, set up, and return an
auxiliary object which contains the three result values.
This is usually too heavyweight, since it not only implies
heap allocation, but also the introduction of a new class
and class file. Another solution would be to provide three
different methods, one for every result parameter. This
means three method calls instead of only one. Finally, VAR
parameters could be emulated using arrays of length 1. Apart
from the ugly misuse of arrays, this would imply unnecessary
range checks, type checks, and heap allocation of auxiliary
objects. Extensive heap allocation is undesirable in
particular in real-time systems, because the need for
real-time allocation severely restricts the freedom to
choose efficient and flexible memory management algorithms.
Finally, Component Pascal has more efficiently implementable
arrays, which can be important for numerical and other
computation-intensive applications.
Java has built-in support for threads. Component Pascal
doesn't provide this feature in the language, because it
leads to unportable software: Java threads can behave
differently on different platforms. Furthermore, the Java
thread scheme is too limited for hard real-time software:
Java threads only support ten different user-assignable
priorities. Hard real-time systems on the other hand require
deadline-driven scheduling policies such as Earliest
Deadline First scheduling, which dynamically apply a
virtually unlimited number of priorities.
Unlike Component Pascal, Java has exception handling
support. This works quite well, except for real-time
systems. The problem is that Java exceptions are used also
for debugging purposes, which in principle has nothing to do
with exception handling. Due to this unfortunate mixture,
the Java stack must be frozen and copied when an exception
occurs, which is expensive and causes unpredictable delays.
Java has another feature which is problematic for
real-time systems: its initialization semantics. The
initialization of a Java class is delayed until it is used
for the first time. This is reasonable for Internet
software, since it allows to avoid (down)loading of classes
that are never used. For real-time systems, however, this is
fatal: an interrupt handler that should respond in 20
microseconds must not cause several milliseconds
initialization time just because it is used for the first
time... Moreover, implementing lazy initialization is fine
for an interpreter, but it forces a compiler to generate
suboptimal code.
[ Note that JBed
adds a real-time API that overcomes the limitations of the
built-in thread mechanism of Java, and it strictly separates
exception handling from debugging. As for the initialization
problem, it remains to be seen whether Sun can relax the
language definition to allow earlier initialization. Lazy
initialization is not difficult to implement, but it is
never what you want in a real-time system. In spite of this
minor ugliness, Java is still a far better language than
C++, even for real-time systems.]
Component Pascal adds a few new features (e.g.,
implement-only export, explicit NEW attribute for newly
introduced methods, EMPTY methods, LIMITED records) that
specifically help to keep large evolving component-software
systems under control, by making refactoring less risky.
Basically, Component Pascal allows to better express design
patterns explicitly in a framework's interface, so that the
compiler can check for consistency of components with their
component frameworks. This is crucial for getting closer to
the ultimate goal of safe plug & play of independently
developed components - in other words: to inexpensive
component software.
Probably the most important difference is complexity: the
language definition of Java includes over thirty classes
with over 300 methods. Moreover, the language features (and
sometimes even the standard classes) interlock very tightly,
which often makes it difficult to truly understand one
feature without already having understood the others. As a
result, casual use of Java has proven difficult and more
time-consuming than expected. Component Pascal is a much
smaller and less complex language than Java. There are two
main reasons. First, Component Pascal is, despite its small
size, a language that can be understood and used
incrementally, by progressively disclosing new features when
they are needed. Second, Component Pascal leaves many Java
features to libraries. The above mentioned thread and
synchronization mechanisms are an example. As a result,
further clean layering of mechanisms and abstractions is
encouraged, while Java and large parts of the class library
seem to form a vast and conceptually flat "web" of concepts.
(c) 1997-1999 Oberon microsystems, Inc.
|
Oberon
microsystems, Inc.
Technoparkstrasse 1
8005 Zürich
Switzerland
|
Tel
(+41 1 ) 445 1751
Fax (+41 1) 445 1752
Net info (at) oberon.ch | |