
Java’s Forgotten Forebear (2009) - charlysl
https://spectrum.ieee.org/computing/software/javas-forgotten-forbear/
======
igouy
_" So from the commercial demise of the UCSD p-System in 1985 until Java was
released in 1995, there was essentially no way for a program compiled only
once to run on more than one kind of computer."_

That seems to be utterly wrong.

\----

Before UCSD-Pascal there's BCPL.

 _" The language was first implemented in 1967…"_

 _" OCODE was specifically designed for BCPL and is a compromise between the
desire for simplicity and the conflicting demands of efficiency and machine
independence. OCODE is an assembly language for an abstract stack based
machine that has a global vector and an area of memory for program and static
data…"_ p152

[https://www.cl.cam.ac.uk/~mr10/bcplman.pdf](https://www.cl.cam.ac.uk/~mr10/bcplman.pdf)

Chapter 2 "VMs for Portability: BCPL" in "Virtual Machines" Iain D. Craig

[https://books.google.com/books?id=vIB-
npHEbd4C](https://books.google.com/books?id=vIB-npHEbd4C)

\----

From 1980 onwards there's Smalltalk-80 —

 _" To support a variety of platforms, Smalltalk uses a virtual machine
approach to portability that allows applications to be easily migrated between
platforms with little or no change to the code."_

"Ubiquitous Applications: Embedded Systems to Mainframe" Comm ACM Oct 1995

[http://www.davethomas.net/papers/ubiquitous1995.pdf](http://www.davethomas.net/papers/ubiquitous1995.pdf)

~~~
wrs
There were plenty more, too. When I implemented NewtonScript as a bytecode
interpreter in 1992 (hey, add that to the list) it seemed like a perfectly
normal thing to do.

~~~
djmips
SCUMM which is late eighties on to early 2000s

------
dbcurtis
UCSD Pascal has a byte code interpreter, sure. And I will grant that it may
have been the first or at least among the first _popular_ ones. But the idea
of a byte code interpreter was already old by then. I worked on a byte code
interpreter in a code base that predated UCSD Pascal. It ran on a CDC
170-series peripheral processor and was used for peripheral diagnostics. I am
sure other byte code interpreters existed in that time frame.

Not to take anything away from UCSD Pascal, it was a great system and very
fun.

~~~
embedded
Pascal was the programming language we used in college in the late 70s, and
although I knew it translated to p-code that was then interpreted, somehow
that never became much of a focus. We just used the language like you would
any other high-level language, and bitched about the shortcomings or
inconsistencies.

I can tell you first hand that when James Gosling was developing Oak/Greentalk
which became Java, Pascal never came up. Sure we all knew and had used it, but
the focus was much more on C++ and what to keep and what to discard. I think
Smalltalk or Self might have even been more of an influence since Dave Ungar
was in the Sun research division at the time and was spreading the gospel of
generational garbage collection.

~~~
ncmncm
What a shame it was that Gosling didn't understand C++ well enough even to
crib from it.

I am astonished, again, whenever I am reminded of what he tried to copy and
got horribly wrong, and what else he copied and should have known better than
to. None of it would matter if Sun had not dumped a billion dollars into
hyping it, so that later generations are now saddled with billions of lines of
it.

What a cruel joke to play on posterity, a fitting companion to x86 ISA and BSD
sockets.

~~~
TheAceOfHearts
Could you give some examples of things which you think were mistakenly copied,
and things which should've been copied but were ignored?

~~~
jcelerier
they focused on C++ as an object-oriented programming language (as did, to be
fair, mostly everyone in the 1990s since it was The Big Thing then) without
seeing where C++'s real value is, which is :

\- value types

\- RAII idiom with exceptions

it's a big, coherent package, which means that you can write code so that e.g.

    
    
        my_type foo{whatever};
    
        file f{"/foo/bar", "w"};
    
        foo.do_stuff();
        f.write(foo);
    

and you can be assured that you won't have null pointers croppying left and
right, much less "new" to write, your objects are always in a valid state, etc
etc.

Java is the opposite: the whole object model revolves around the identity of
objects, and thus any function that looks like `public string whatever()` can
return null, you have to do manual cleanup of your resources most of the time
everytime you _use_ a type (closing files, streams, soundcards, etc etc),
versus every time you _define_ a type in C++.

------
DonHopkins
FWIW, NeWS PostScript [1] and Emacs MockLisp [2] were also fore-bearers of
Java, in the sense that James Gosling created them before creating Java, and
applied a lot of what he learned from their mistakes and experience to Java.

[1] [https://medium.com/@donhopkins/the-shape-of-psiber-space-
oct...](https://medium.com/@donhopkins/the-shape-of-psiber-space-
october-1989-19e2dfa4d91e)

[2]
[https://news.ycombinator.com/item?id=8727085](https://news.ycombinator.com/item?id=8727085)

~~~
noblethrasher
Gosling _created_ PostScript? That's… news to me.

(NeWS was an implementation/extension of PostScript, but PS was invented by an
entirely different group of people).

~~~
DonHopkins
Yes, he created NeWS PostScript. That's NeWS to me, but I explicitly spelled
it out "NeWS PostScript" to be unambiguous. And I purposefully wrote "created"
to be specific, not "invented" to give him too much credit, nor "implemented"
to give him too little credit.

James Gosling said: "There is really nothing new here. It's just putting it
together in a different way."

NeWS was a clean room implementation of a dialect of PostScript that went far
beyond Adobe's PostScript in many important ways, including lightweight
processes, process groups, multitasking support (fork, pause, killprocess,
etc), monitor synchronization locks, strong synchronization guarantees, object
oriented programming, packages, networking, synchronous event handling
(sendevent, expressinterest, unblockinputqueue, etc), interest event handler
templates, multiple arbitrarily shaped canvas drawing surfaces, more built-in
data types, magic dictionaries (integrating native code via dictionary
getters/setters), reflection and introspection (exposing lightweight
processes, events, canvases and other native code and data structures as magic
PostScript dictionaries), debugging support (see my PSIBER paper linked
above), completely different memory model (no more heap based "save" and
"restore" like single threaded printers), reference counting garbage
collection, soft references, obsolete events, etc.

All of those are ideas that influenced Java (the topic of this discussion) one
way or another, which the original Adobe PostScript didn't have. I'd say the
most important NeWS feature that influenced Java was multithreading, which led
to Green threads (at the time, Unix didn't support light weight processes
yet). Followed by garbage collection (by the negative example of NeWS's
reference counting garbage collection), and synchronization (which was where
NeWS really shined in comparison to X-Windows).

And NeWS's object oriented programming system was an original addition to
PostScript by Owen Densmore. Because it was cleanly and simply implemented in
terms of PostScript's existing dictionary stack, it was portable enough that
it could run on Adobe PostScript, but NeWS had optimizations and extensions to
support it efficiently (and eventually integrated magic dictionaries like
canvases and processes as first-class objects, but not at first). We used it
extensively and developed it further to implement several different
generations of user interface toolkits and clients. It was more dynamic like
Smalltalk than static like Java, in that it supported multiple inheritance and
instance specialization (prototypes). See Chapter 6, Object-Oriented
PostScript, in The NeWS Book (1989):

[https://donhopkins.com/home/The_NeWS_Book_1989.pdf](https://donhopkins.com/home/The_NeWS_Book_1989.pdf)

NeWS wasn't just a knock-off of Display PostScript as some temporally confused
people believe, because it came first, and did a lot more, and had a totally
different purpose and design. Display PostScript is just "Fake NeWS". ;)

Why aren't you also pointing out that he didn't invent Lisp either, or Emacs
itself? Didn't you think I was implying that too? That's not what I meant,
either.

So yes, James Gosling created NeWS PostScript and Emacs MockLisp, and the
lessons from their mistakes and successes directly influenced Java. (Not only
technical issues, but also licensing issues -- just ask RMS about "Evil
Software Hoarder Emacs".)

Here are some details of his original design, which he called SunDew before
(unfortunately) renaming it to NeWS:

Methodology of Window Management: F R A Hopgood, D A Duce, E V C Fielding, K
Robinson, A S Williams, 29 April 1985.

[http://www.chilton-
computing.org.uk/inf/literature/books/wm/...](http://www.chilton-
computing.org.uk/inf/literature/books/wm/p005.htm)

This is the Proceedings of the Alvey Workshop at Cosener's House, Abingdon
that took place from 29 April 1985 until 1 May 1985. It was input into the
planning for the MMI part of the Alvey Programme.

The Proceedings were later published by Springer-Verlag in 1986.

5\. SunDew - A Distributed and Extensible Window System - James Gosling

[http://www.chilton-
computing.org.uk/inf/literature/books/wm/...](http://www.chilton-
computing.org.uk/inf/literature/books/wm/p005.htm)

5.1 INTRODUCTION

SunDew is a distributed, extensible window system that is currently being
developed at SUN. It has arisen out of an effort to step back and examine
various window system issues without the usual product development
constraints. It should really be viewed as speculative research into the right
way to build a window system. We started out by looking at a number of window
systems and clients of window systems, and came up with a set of goals. From
those goals, and a little bit of inspiration, we came up with a design.

[...]

DESIGN SKETCH

The work on a language called PostScript [1] by John Warnock and Charles
Geschke at Adobe Systems provided a key inspiration for a path to a solution
that meets these goals. PostScript is a Forth-like language, but has data
types such as integers, reals, canvases, dictionaries and arrays.

Inter process communication is usually accomplished by sending messages from
one process to another via some communication medium. They usually contain a
stream of commands and parameters. One can view these streams of commands as a
program in a very simple language. What happens if this simple language is
extended to being Turing-equivalent? Now, programs do not communicate by
sending messages back and forth, they communicate by sending programs which
are elaborated by the receiver. This has interesting implications on data
compression, performance and flexibility.

What Warnock and Geschke were trying to do was communicate with a printer.
They transmit programs in the PostScript language to the printer which are
elaborated by a processor in the printer, and this elaboration causes an image
to appear on the page. The ability to define a function allows the extension
and alteration of the capabilities of the printer.

This idea has very powerful implications within the context of window systems:
it provides a graceful way to make the system much more flexible, and it
provides some interesting solutions to performance and synchronization
problems. SunDew contains a complete implementation of PostScript. The
messages that client programs send to SunDew are really PostScript programs.

Two pieces of work were done at SUN which provide other key components of the
solution to the imaging problems. One is Vaughan Pratt's Conix [53], a package
for quickly manipulating curve bounded regions, and the other is Craig
Taylor's Pixscene [63], a package for performing graphics operations in
overlapped layers of bitmaps.

Out of these goals and pieces grew a design, which will be sketched here. The
window system is considered in four parts. The imaging model, window
management, user interaction, and client interaction. The imaging model refers
to the capabilities of the graphic system - the manipulation of the contents
of a window. Window management refers to the manipulation of windows as
objects themselves. User interaction refers to the way a user at a workstation
will interact with the window system: how keystrokes and mouse actions will be
handled. Client interaction refers to the way in which clients (programs) will
interact with the window system: how programs make requests to the window
system.

What is usually thought of as the user interface of the window system is
explicitly outside the design of the window system. User interface includes
such things as how menu title bars are drawn and what the desktop background
looks like and whether or not the user can stretch a window by clicking the
left button in the upper right hand corner of the window outline. All these
issues are addressed by implementing appropriate procedures in the PostScript.

[...]

5.4 DISCUSSION

Bono: When you use the word PostScript, do you mean literally that PostScript
is in some way your virtual machine instruction set? It has not been extended
or generalized?

Gosling: It has been extended. It is a superset. We are committed to
implementing everything in the PostScript telephone book that makes sense.
They have a few commands that are particular to their storage allocation and
to the fact that they are going to a printer and these are not implemented. We
have imported some things that are peculiar to a display and a small number of
incompatible changes to the language have been made which we spent a long time
talking to the people at Adobe about to make sure that was reasonable. In
particular, we added garbage collection and lightweight processes. There are
very tiny ways in which the semantics of PostScript's memory allocation
strategy shows through in the printer version because they have a quick and
dirty storage allocation mechanism and that wasn't really useful in this
system.

Bono: The virtual machine was not virtual enough.

Gosling: Right. When we made the generalization to multiple processes, their
storage allocation mechanism just completely broke and so we had to use
garbage collection instead and that necessitated some small semantic changes
but they are not things you are likely to see. All of the important things
such as how you specify a curve, whether you can render an image rotated 37
degrees, all of that is there or intended to be there.

Hopgood: How do you handle input?

Gosling: Input is also handled completely within PostScript. There are data
objects which can provide you with connections to the input devices and what
comes along are streams of events and these events can be sent to PostScript
processes. A PostScript process can register its interest in an event and
specify which canvas (a data object on which a client can draw) and what the
region within the canvas is (and that region is specified by a path which is
one of these arbitrarily curve-bounded regions) so you can grab events that
just cover one circle, for example. In the registration of interest is the
event that you are interested in and also a magic tag which is passed in and
not interpreted by PostScript, but can be used by the application that handles
the event. So you can have processes all over the place handling input events
for different windows. There are strong synchronization guarantees for the
delivery of events even among multiple processes. There is nothing at all
specified about what the protocol is that the client program sees. The idea
being that these PostScript processes are responsible for providing whatever
the application wants to see. So one set of protocol conversion procedures
that you can provide are ones that simply emulate the keyboard and all you
will ever get is keyboard events and you will never see the mouse. Quite often
mouse events can be handled within PostScript processes for things like moving
a window.

Teitelman: The innovation here is not that we are using PostScript. The reason
we chose PostScript is due to a lot of historical connections and proximity to
the people who are doing it. The interesting thing is that all these processes
look as though they are executing in one of those old single address
environments. It is a single user process that James has been able to
implement lightweight processes in. You don't have lightweight processes in
Unix systems, which you really need to implement realistic user interfaces.

Gosling: There is really nothing new here. It's just putting it together in a
different way.

------
tomcam
A history of UCSD Pascal, which compiled to a portable VM called a p-machine.
Doesn't mention the infinitely more successful product inspired by UCSD Pascal
--Turbo Pascal, which was insanely fast but which completely ignored
portability, as it was written in 8088 assembly and generated machine code
directly to memory. Turbo Pascal then become Delphi. Its creator, Anders
Hejlsberg, moved to Microsoft and created C# among other things.

~~~
tapanjk
Java programs are portable. Java is popular.

It feels like the article implies causality, but I fail to see it. My first
programming language was Java (version 1.2) and it was the easiest programming
language to start with because it had everything that a student would need, in
one place: jdk, tutorials, documentation, and language specification. This may
not sound like a big deal now, because many other programming languages
provide similar resources. You just go to xyzlang.org and you find all the
resources, but in those days Java set the standard (or at least that is what I
thought) for providing all the resources in place for someone to get started
with the language. I did not choose Java at that time because it was portable.

~~~
wtracy
On top of what you mentioned:

Java hopped onto the Object Oriented Programming bandwagon just as it was
getting a lot of buzz. To a lot of people, Java and C++ are the canonical
Object Oriented languages. (Sorry, Alan Kay.) Of those two, Java has the
shallowest learning curve.

Java was also many developers' first introduction to a language runtime with a
"fail fast" approach to fault handling. Java featured runtime bounds checking
and runtime type checking. Couple that with the very detailed (for the time)
stack traces that the runtime produced, along with automatic memory
management, and you have a powerful set of tools for building (relatively!)
bug-free software. (For comparison, imagine trying to debug a C++ program that
intermittently crashes on an off-site customer's computer.)

Object Oriented design, garbage collected memory management, and runtime error
checking all had roots in other languages (Smalltalk and Lisp come to mind)
but Java was the first to package all those things together in one well-
documented, industry-oriented tool.

Most of those predecessor languages were widely perceived as by academics for
academics, which brings me to the final piece of the puzzle: Sun nailed
developer outreach. It doesn't matter how good your language is if nobody has
heard of it.

~~~
setpatchaddress
> Java has the shallowest learning curve

[citation needed]

~~~
_ph_
Java 1.0 had a reasonably shallow learning curve. A lot of complexity was
added by later enhancements. I always felt they were not always worth the
complexity tradeoff they brought.

------
WalterBright
We tried the UCSD p-system in the 1980s. Its major problem, being interpreted,
was it was just too slow. MS-DOS systems were so slow, the p-system just
wasn't viable.

The early Java systems were interpreted, too. Steve Russell wrote the first
JIT for Java, which revolutionized Java by compiling the bytecode into machine
code.

~~~
dreamcompiler
THE Steve Russell? The one who wrote the first Lisp implementation?

~~~
WalterBright
No, not that one.

------
snek
This TIOBE index is absolutely hilarious. First it hits you with "The index
can be used to check whether your programming skills are still up to date or
to make a strategic decision about what programming language should be adopted
when starting to build a new software system." Then it says the index is built
from counting the query `+"<language> programming"` in search engines. Is this
why we can't have nice things?

------
DonHopkins
(One kid talking to another, with dad in the background hunched over an Apple
][.)

"Daddy's playing Pascal. That's where you try and see how many dots you can
get before it beeps and you say nasty words."

------
tannhaeuser
Is a bytecode language still a useful concept, though? It might have been when
we had lots of ISAs, especially in education. When Java came up (its original
purpose being used on set-top boxes) we had Power, MIPS, Alpha, 68k, HP-RISC,
Sparc, and many others. Now there's only x86/64 and ARM/64 left.

~~~
bullen
The article is wrong, the advantage of bytecode is not portability; but memory
allocation, failure handling and dynamic classloading. A Java SE process never
crashes unless you leak memory, which is super easy to avoid and profile with
a heap dump, so you can sleep when you release code on servers. That's the
real reason for Java's success. I would never code C for servers. And if I
code for a hydroelectric dam, I would use Java SE! Not kidding!

~~~
astrange
Java is not really safe from mistakes, if you type the wrong code you will
still get the wrong program.

Even for 90s programming systems I recommend you try Erlang.

~~~
bullen
Erlang is single threaded, I would never use Erlang on multi core processors,
ie. I would never use Erlang period!

If you downvoted because Java is not safe from mistakes (duh), I suggest you
try using C/C++ just for fun.

If you use C/C++ on server systems for salary you will burn out.

~~~
astrange
Erlang is not single threaded!

~~~
bullen
You can't share memory between threads. ie. it's single threaded.

------
mark_l_watson
I liked seeing the picture of Ken Bowles in the article. A great guy, he
passed away this year. I wrote a Go program in UCSD Pascal, and it was my at
home hacking language for a few years. It ran surprisingly well on my Apple II
with 2 floppy disk drives.

~~~
tyingq
_" I wrote a Go program in UCSD Pascal"_

Funny how the meaning of commonly used terms shift over time. I had to read
that a few times before it made sense :)

------
alejohausner
In the 1980s I worked with a PDP-11 and wrote fortran programs, which DEC's
compiler compiled into threaded code[1]. Unlike p-code, where each opcode is
an action, in threaded code each opcode is the address of a function. Since
these functions did more work than simple p-code instructions, the overall
size of the compiled program was a lot smaller. This was a necessary tradeoff
when you only had 32K of RAM to work with.

1\.
[http://home.claranet.nl/users/mhx/Forth_Bell.pdf](http://home.claranet.nl/users/mhx/Forth_Bell.pdf)

------
mherdeg
Cool! I have been pretty ignorant about this history and didn't realize that
the Infocom z-machine was working from prior art (the UCSD p-machine).

------
gok
Maybe better titled "JVM's Forgotten Forebear"

~~~
sn41
Precisely. As a language, probably Smalltalk is the forebear of Java. And
Smalltalk is hardly forgotten.

~~~
igouy
Before the JVM there was a Smalltalk VM ;-)

~~~
KMag
And, in fact, Oracle/Sun's HotSpot JIT started out in LongView's Strongtalk
VM, or at least it was written by the same people after Sun acquired LongView.
I haven't read any documentation one way or the other if any of the Strongtalk
source code was directly re-used in HotSpot.

------
sitkack
Java's most recent forebear was Bob [0]. This article on Bob [1] in Dr Dobbs
shows it as basically a PoC for what would later become Java.

[0] [https://github.com/dbetz/bob](https://github.com/dbetz/bob)

[1] [http://www.drdobbs.com/open-source/bob-a-tiny-object-
oriente...](http://www.drdobbs.com/open-source/bob-a-tiny-object-oriented-
language/184409401)

------
ardy42
> ...where he had used a small Packard-Bell PB250 computer to control a
> massive antenna array and to collect data.

I had no idea Packard-Bell had a history before producing low-cost PC clones
for consumers.

[http://www.computerhistory.org/collections/catalog/102630088](http://www.computerhistory.org/collections/catalog/102630088)

~~~
NordSteve
Packard Bell was a well known radio and TV brand that ceased operation in the
1970s.

During the PC clone era, a group purchased the brand as a way to bootstrap
brand awareness. So, other than the brand, there's really no relationship
between the two.

------
DonHopkins
Another thing that likely influenced James Gosling at Sun was Mitch Bradley's
Forthmacs / Open Firmware FORTH system, which was eventually used in the Sun,
Mac and OLPC boot PROMS and hardware device firmware.

James and Mitch both worked at Sun and were friends at the time, and Mitch
ported NeWS to the Amiga, the first NeWS port to other hardware than Sun's. I
think he used his FORTH system on the Amiga to load and run it, and provide
networking and a remote file system over a serial port. (Mitch uses FORTH for
EVERYTHING!)

At the time, Sun was shipping 68K, i386 and SPARC systems, and they needed a
way to make hardware cards with built-in platform independent drivers in PROM,
so they used FORTH byte code.

Not all FORTH systems necessarily implement platform independent byte code,
and Open Firmware also had a built-in assembler and native primitives, but the
device drivers on hardware card PROMS restricted themselves to the device
independent bytecodes and portable features.

[https://en.wikipedia.org/wiki/Open_Firmware](https://en.wikipedia.org/wiki/Open_Firmware)

>Open Firmware, or OpenBoot in Sun Microsystems parlance, is a standard
defining the interfaces of a computer firmware system, formerly endorsed by
the Institute of Electrical and Electronics Engineers (IEEE). It originated at
Sun, and has been used by Sun, Apple, IBM, ARM and most other non-x86 PCI
chipset vendors. Open Firmware allows the system to load platform-independent
drivers directly from the PCI card, improving compatibility.

>Open Firmware Forth Code may be compiled into FCode, a bytecode which is
independent of computer architecture details such as the instruction set and
memory hierarchy. A PCI card may include a program, compiled to FCode, which
runs on any Open Firmware system. In this way, it can provide platform-
independent boot-time diagnostics, configuration code, and device drivers.
FCode is also very compact, so that a disk driver may require only one or two
kilobytes. Therefore, many of the same I/O cards can be used on Sun systems
and Macintoshes that used Open Firmware. FCode implements ANS Forth and a
subset of the Open Firmware library.

>Open Firmware furthermore defines a standard way to describe the hardware of
a system. This helps the operating system to better understand its host
computer, relying less on user configuration and hardware polling.

>Being based upon an interactive programming language, Open Firmware can be
used to efficiently test and bring up new hardware. It allows drivers to be
written and tested interactively. Operational video and mouse drivers are the
only prerequisite for a graphical interface suitable for end-user diagnostics.
Indeed, Apple shipped such a diagnostic "operating system" in many Power
Macintoshes.

------
patrickg_zill
There was ANDF as well, but I think that commercial Unix vendors were leery of
the idea.

[http://wikien3.appspot.com/wiki/ANDF](http://wikien3.appspot.com/wiki/ANDF)

~~~
twic
If we're dredging up sweet examples of early '90s radical madness, let's not
forget TaOS's 'virtual processor' code:

[https://sites.google.com/site/dicknewsite/home/computing/byt...](https://sites.google.com/site/dicknewsite/home/computing/byte-
articles/the-taos-operating-system-1991)

