Article View: comp.lang.java
Article #233Re: Will Java kill C++?
From: Alan L. Lovejoy
Date: Sun, 14 Apr 1996 08:04
Date: Sun, 14 Apr 1996 08:04
232 lines
12729 bytes
12729 bytes
Doug Bell wrote:
(with parts where substantial agreement has been reached left out)
> "Alan L. Lovejoy" <alovejoy@concentric.net> wrote:
> > Firstly, if Java is to be used to code applets on WWW pages, then it will
> > always be interpreted (when used for that purpose)--unless the world happens
> > to standardize on exactly one instruction set to the exclusion of all others.
>
> Here's my opportunity to teach you something. :)
>
> Currently, Java is executed through interpretation. This is already
> starting to change as the first "just in time" compilers (or JIT
> compilers) for java are becoming available. A JIT compiler will translate
> the machine-independent byte-codes of Java into directly executable
> machine code. This translation happens as the code is loaded off the
> network, and in fact should occur faster than the code is downloaded
> across the network, so there should be *no* additional delays imposed by
> this translation. The resulting machine code is then executed. Web
> browsers most certainly will use JIT compilers in the near future. Stand
> alone Java applications can either be translated as they are loaded, or
> translated once for a platform.
>
> The performance of this translated code is yet to be determined, but it
> should be able to achieve somewhere between 50% and 100% the speed of
> natively compiled C or C++ code.
>
> In addition, Sun is already working on processors which will execute the
> Java bytecodes directly. How these will affect the market remains
> unclear, but it serves to point out that there are even greater
> performance possibilities already in the works.
For the past ten years, the ParcPlace (now ParcPlace-Digitalk) VM has worked
more or less as you describe the JIT compiler--although there are differences.
This is why the recently reported benchmarks show Smalltalk as being many
times faster than Java. I fully expect this to change over the next year.
Xerox PARC developed not just Smalltalk, but Smalltalk workstations that
used bit-sliced microcoded processors to execute Smalltalk bytecodes in
hardware. There was a university project in the 80's that developed a
Smalltalk CPU called SOAR.
But these specialized processors suffered the same fate as the infamous
"LISP machines." The commerical RISC processors ate their lunch, for several
reasons:
1. The general purpose RISCs would run all software, not just Smalltalk
or LISP.
2. They were often faster than the special purpose processors, because
more resources were expended in their design and manufacture--because
the return on investment was higher.
3. The world wanted to standardize on MS-DOS and UNIX.
Another point to consider: Smalltalk (and LISP) would probably benefit from
a Java processor as much as would Java itself. At the "bytecode" level,
syntax differences and static typing are no longer relevant.
> > The main differences between Java and Smalltalk (as languages, not as
> development
> > environments or delivery platforms):
> >
> > 1. Java is statically typed, Smalltalk is not (although both use dynamic
> binding).
>
> Maybe this my lack of understanding (as I bow to the Gods of OOP who have
> traveled the road farther than I), but I view Java's strongly typed
> behavior as a benefit. I realize this is probably different from what you
> mean by statically typed.
You have been blindsided by a common misuse of technical terminology.
The terms "static typing" and "strong typing" are often wrongfully used as
though they were synonyms. This misuse is endemic, and many are misled by
it.
The correct definition of "static typing" is that a) type constraints are
enforced during program translation ("compilation"); and b) the type of
of an object is always determinable by lexical analysis of the program text.
The correct definition of "strong typing" is that type errors are prevented
from occuring. An example of a type error would be applying the integer
addition machine instruction to a 32-bit floating point value, and then
using the result as though it meant something.
Smalltalk, LISP and Java are all strongly typed. Only Java is also statically
typed. Type errors can occur in both C and C++, so they are statically
but not strongly typed.
Whether static typing is good or not is another religious issue that
I will refrain from addressing.
> > 2. Smalltalk has block closures. Java doesn't even have function pointers.
>
> I keep seeing this. What is a block closure?
Glad you asked!
First, let me introduce Smalltalk-like "block closures" into C.
C already has "blocks." They're the things bracketed by "{" and "}".
The syntax is roughly: Block ::= "{" Statement {";" Statement} "}".
For example: while (index <= 10) {printf("%i", index); index = index + 1}.
To convert these into block closures, we first have to make them values
that can be assigned to variables and passed as parameters. So we have
to introduce the datatype "block." Then we can write code like this:
block countingBlock;
int index;
countingBlock = {printf("%i", index); index = index + 1};
index = 1;
while (index <= 10) countingBlock;
Next, we have to be able to pass parameters into a block--just like it
was a function. In fact, you can think of a Smalltalk block as an
anonymous function. Such a parameterized block in C might look like
this: {(int index): printf("%i", index)}. Then we can write code
like this:
block printBlock;
int i;
printBlock = {(int index): printf("%i", index)};
for (i = 1; i <= 10; i++) printBlock(i);
Note that "printBlock" could just as easily have been passed in as a parameter
to the function that will execute it instead of being declared just before use.
Finally, we have to give the blocks closure semantics. This defines the
meaning of external references (reads and writes to variables declared
outside the scope of the block itself) in a precise way. Specifically,
the resolution of variable references external to the block has to be
closed at the time the block definition code is executed. This requires
that function contexts be allocated on the heap and not on the stack,
because a variable that is referred to by a closure is "live" as long as
the closure is. Another way to think of this is that variables declared
outside the closure, but referenced by the closure, are in effect implied
reference parameters.
One of the most powerful uses of blockClosures is for iterating over the
contents of a collection. Let me use my extended C again to illustrate:
Suppose we have defined a binary tree data structure, whose nodes are
structs. There is a typedef for this struct named BinaryTreeNode,
and a set of functions that implement the usual operations on binary
trees. Additionaly, we have defined three tree enumeration functions:
inOrderDo(), inPreOrderDo(), and inPostOrderDo(). All three functions
take a one-argument "block" as an argument:
typedef
BinaryTreeNode struct {void *left, *right, *value};
BinaryTreeBlock block {BinaryTreeNode * node};
void doInOrder(BinaryTreeNode node; BinaryTreeBlock enumerationBlock) {...};
void doInPreOrder(BinaryTreeNode node; BinaryTreeBlock enumerationBlock) {...};
void doInPostOrder(BinaryTreeNode node; BinaryTreeBlock enumerationBlock) {...};
One can then iterate over all nodes in a binary tree, applying whatever logic
to each node that can be coded by a block closure:
doInOrder(
tree,
{(BinaryTreeNode * node):
addBTReeNode(copyOfTree, bTreeNodeCopy(node))}
);
Block closures are also useful for creating new control structures. In Smalltalk,
all the traditional control structures are implemented using block closures.
Of course, Smalltalk block closures aren't just "values." They're objects.
You can send them messages. They have a class. You can add methods to that
class.
> > 3. Smalltalk is highly reflexive and permits metaprogramming. Java isn't and
> > doesn't (compared to Smalltalk).
>
> English please... (sorry)
A real explanation would take longer than I have. The IRS wants some of my time
right about now (sorry). But here are some key points:
1) In Smalltalk, all values are objects.
2) Classes are values--and hence they are objects. Just like any other object, a class
is itself an instance of a class. A class whose instances are themselves classes is
called a metaclass. A metaclass is an object, and just like any other object, it is
an instance of a class. Specifically, a metaclass is an instance of the class
Metaclass. Metaclass is an object, and just like any other object, it is an
instance of a class--and that class is an instance of Metaclass, so the relationship
is circular. Both Metaclass and its class are instances of their own instances.
3) Classes can be assigned to variables, passed as parameters and sent messages,
just like any other object.
4) You can ask any object for its class. This is an example of reflection.
5) You can add methods to any class, including system classes (for example, the
classes Object, CompiledMethod, BlockClosure, Class and Metaclass--doing this is
an example of metaprogramming).
6) You can subclass, reparent or redefine any class--including the system classes.
7) You can make the system use different classes than those specified by the system
vendor for most system functions (there are some exceptions, and it would be easy
for the system vendor to prevent the substitution of certain classes if that was
required for system security). For example, you could make the system use some
class other than Metaclass to instantiate metaclasses, or some class other than
CompiledMethod to instantiate methods. More metaprogramming.
8) You can create/modify/remove classes programmatically as the program is running.
Yet more metaprogramming.
9) You can programmatically create annonymous/lightweight classes for special purposes.
Even more powerful metaprogramming.
10) The execution context is a value--and hence an object. This object represents
the state of a thread of execution: the method activation stack, the program counter,
the temporary variables and method arguments. Each thread (called a process in
Smalltalk) stores an object that represents the current state of thread execution
for that thread. And there is a pseudo-variable 'thisContext' that refers to
the execution state of the current thread. An execution context can answer questions
such as "what is the CompiledMethod that is currently executing," or "what object is
the receiver of the message that was sent to invoke this method," or "what is the value
of the third method argument" or "what context sent the message that invoked this method."
This is deep reflection.
11) You can ask a class what instance variables its instances have, what messages
its instances will understand and what code will actually execute when messages are sent
to the instances--among other things. And you can ask methods what messages are sent
in the body of the method, what instance variables are accessed (read or written),
and what global values are accessed. This, too, is deep reflection.
I could go on, but hopefully this begins to give you an idea of the capabilities.
These metaprogramming and reflective capabilities can be used to do things such as sending
objects over the net when the receiver of the objects has never seen or heard of the classes
of the objects (and you can't send source code because the receiver does not have a compiler),
or sharing of distrubuted objects by processes on different computers connected over the net.
--Alan
Technical Details
Message-ID:
<3170B180.51A8@concentric.net>Path:
arc1-ca.pugleaf.net!newsfeed.concentric.net!newsReferences:
<31682FFE.2781E494@bbn.com> <DpJyGG.FKK@hkuxb.hku.hk> <denatale-1004960822260001@grail1506.nando.net> <dbell-1104960125190001@wholder2.cts.com> <goochb.327.000893D1@rwi.com> <dbell-1104961159050001@wholder2.cts.com> <316D8523.74D7@concentric.net> <dbell-1104962256020001@wholder2.cts.com> <316E3FB6.38F7@concentric.net> <dbell-1204961508460001@wholder2.cts.com> <316F8A35.5189@concentric.net> <dbell-1304961718060001@wholder2.cts.com>Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!newsfeed.concentric.net!news From: "Alan L. Lovejoy" <alovejoy@concentric.net> Newsgroups: comp.lang.java,comp.lang.c++,comp.lang.smalltalk Subject: Re: Will Java kill C++? Date: Sun, 14 Apr 1996 01:04:16 -0700 Organization: Modulation Message-ID: <3170B180.51A8@concentric.net> References: <31682FFE.2781E494@bbn.com> <DpJyGG.FKK@hkuxb.hku.hk> <denatale-1004960822260001@grail1506.nando.net> <dbell-1104960125190001@wholder2.cts.com> <goochb.327.000893D1@rwi.com> <dbell-1104961159050001@wholder2.cts.com> <316D8523.74D7@concentric.net> <dbell-1104962256020001@wholder2.cts.com> <316E3FB6.38F7@concentric.net> <dbell-1204961508460001@wholder2.cts.com> <316F8A35.5189@concentric.net> <dbell-1304961718060001@wholder2.cts.com> NNTP-Posting-Host: cnc009054.concentric.net Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Mailer: Mozilla 2.01Gold (Win95; U)