Hacker News new | past | comments | ask | show | jobs | submit login
Java’s Forgotten Forebear (2009) (ieee.org)
122 points by charlysl 3 months ago | hide | past | web | favorite | 80 comments

"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


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



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


Indeed, according to "The Most Important Software Innovations" [1]:

In computer programming, “a pseudo-code or p-code machine is a specification of a CPU whose instructions are expected to be executed in software rather than in hardware (ie, interpreted).” Basic Combined Programming Language (BCPL) is a computer programming language designed by Martin Richards of the University of Cambridge in 1966. He developed a way to make it unusually portable, by splitting the compiler into two parts: a compiler into an intermediate pseudo-code (which he called O-code), and a back-end that translated that into the actual machine code. Since the intermediate code could be exchanged between arbitrary machines, it enabled portability. Urs Ammann, a student of Wirth’s at the Swiss Federal Institute of Technology Zurich, used the same approach in the 1970s to implement Pascal; this intermediate pseudo-machine code was called p-code, and popularized the technique (see Wirth’s “Recollections about the development of Pascal” ) Java is based on this fundamental approach, which enables compiled code to be run unchanged on different computer architectures (see “Java’s Forgotten Forbear”). Even many text adventure games have been built with this approach, most famously the Z-machine used to implement many Infocom games (such as Zork). BCPL also significantly influenced the C programming language, including its use of curly brackets {...}. No patent identified.

[1] https://dwheeler.com/innovation/innovation.html

And Infocom's Z-machine is from 1979: https://en.wikipedia.org/wiki/Z-machine

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.

SCUMM which is late eighties on to early 2000s

Odd. I was using uscd-pascal in the early 90s...

I even found some p-system style Pascal source in the mid 90s, so it didn't die in the mid 80s. IIRC p-system was running on everything from 8bit CPM to Unix boxen too.

I know they're referring to compiling to an abstract machine, but there's also been binary translators that treat the machine code of one machine like abstract code that gets translated binary-to-binary to the hardware it's running on.

I recall reading about one around the late 80's (perhaps an AT&T machine) that was doing things like inlining and using actual runtime branch optimizations to run faster on the second architecture.

Also Perl, ran on multiple platforms fairly well.

Tcl and Rexx were around in the same time period as well. And most "personal computers" had a BASIC interpreter at the time (albeit with lots of platform specifics).

> a program compiled only once to run on more than one kind of computer

This is referring to portable object code. Perl, Tcl, and Rexx aren't compiled, but do have source-level portability.

Perl and TCL do have a VM and bytecode, it's just not used for distribution. The initial releases of Java didn't have a JIT.

This is referring to pseudo code for a virtual machine — "compiled into p-code" — aka a byte code interpreter.

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.

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.

> I can tell you first hand that when James Gosling was developing Oak/Greentalk which became Java, Pascal never came up ... the focus was much more on C++ and what to keep and what to discard.

The interesting thing is that at the time Java was released and then aggressively marketed by Sun, the AT&T folks had already come up with Limbo (the successor to Alef, and running on the Dis virtual machine), which was technically quite similar to the Java/JVM solution, and in some ways quite superior. But nobody ever mentions Limbo in connection with Java, or even with Go (which it - along with its predecessor Alef - was a clear influence on). History is written by the winners, and Java was a winning language/platform for quite some time.

Even here on HN, people bring up Plan 9 all the time, forgetting that Inferno and Limbo were actually the end of the road and Plan 9 just a middle step.

Great point about Smalltalk. It had been around a long time by the time of UCSD Pascal, and had a byte code engine from the start.

Along similar lines, Burroughs had a line of machines that swapped in language-specific microcode on a task-switch basis(!!!!!) so the idea of language-specific instruction sets has a long history.

At that point, Smalltalk (and I think Self) had JIT too in terms of VM state of the art.

Deutsch Schiffman dynamic-translation.

pdf "A Brief History of Just-In-Time"


That's a great paper thank you. My own Zelig-like role was doing the 1st port of Smalltalk (HPS) to Microsoft Windows, hence my familiarity.

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.

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

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"};

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++.

Nothing like a good C++ flamewar, but we already have a fine compilation of the case against the language - https://yosefk.com/c++fqa/

Java is tremendously influenced by C and C++. Any experienced C++ programmer can learn Java easily because it has a similar syntax but a much simpler palette of language constructs.

I am glad that Java didn't copy these aspects of C and C++: https://www.nayuki.io/page/undefined-behavior-in-c-and-cplus... ; https://www.nayuki.io/page/near-duplicate-features-of-cplusp...

Undefined behavior is very useful, and Java doesn't replace it with anything better for high-performance CPU programming.

In particular, C loops can only be optimized because signed loop counters are assumed not to overflow. Java also doesn't have SIMD, and a very weak form of arrays as value types leads to pointer chasing.

And Objective-C, stuff like interfaces, resource bundles, lightweight metaclasses, APIs for distributed computing (J2EE was based on an internal OpenSTEP framework).

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...

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

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).

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):


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.


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



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.



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.



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.

Tom Stambaugh described how Smalltalk inspired Owen Densmore's PostScript object oriented system in NeWS.

A point he didn't mention is that PostScript is directly descendent from Interpress, which was developed at Xerox PARC and reincarnated as PostScript at Adobe by Chuck Geschke and John Warnock:


Brian Reid's deep detailed historic dive "PostScript and Interpress: a comparison":


I also think PostScript owes a lot to Lisp (it's dynamic, homoiconic, polymorphic, symbolic), even more so than Forth.


Tom Stambaugh wrote:

It seems to me that Forth is to stacks what LispLanguage is to lists. Forth demonstrated the advantages of a stack-centric paradigm in which each pushed or popped item could be evaluated as an expression or a primitive. Postscript reflects the application of that paradigm to the world of typography, 2-d graphics, and page layout. My own recollection is that Postscript's primary contribution was the use of splines to describe character glyphs, allowing them to be effectively rendered at virtually any resolution desired. If anything, Postscript owes more to TexLanguage and DonaldKnuth than to Forth. I view the stack-based language paradigm as a convenient afterthought rather than a central organizing principle.

I also think we should note the contribution that OwenDensmore, at Sun, made in demonstrating how to use Postscript dictionaries to create a dynamically-bound object-oriented runtime environment. This was the fundamental premise of the Sun window server that ultimately became the NetworkExtensibleWindowSystem. Owen and I discussed his "crazy" idea at a poolside table at the now-demolished Hyatt Palo Alto, on El Camino. I told him that it made sense to me, we scribbled furiously on napkins, and I helped him see how he might adopt some learnings from Smalltalk. It was one of those afternoons that could only have happened at that time in that place in that culture. -- TomStambaugh

I've extracted Owen Densmore's paper from the news.tape.tar (marked PD), "Object Oriented programming in NeWS", and uploaded it:

https://ia802600.us.archive.org/5/items/pdfy-1U9Ry1_Qj0LPSR6... [fixed link]

It would require some modification to run in other postscript environments, but not much, I think. It was developed after the 1st Edition Postscript manual but before the second, so it's considered a Level 1.5 Postscript environment. It uses dictionaries freely, but the << /Level-2 (syntax) >> had not yet been invented. So it uses a number of nonstandard operators for dictionary construct. These would need to be simulated or the routines rewritten to use Level 2 syntax. -- luserdroog

comp.lang.forth discussion on "Why is Postscript not Forth?":


Forth/PostScript discussion with Mitch Bradley:


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.

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.

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.

> Java was also many developers' first introduction to a language runtime with a "fail fast" approach to fault handling.

Java wasn't just "fail fast" in some loose and hard-to-pin-down sense, it was memory safe. This was a killer feature in competing with C++ as the standard 'enterprise' language, and Sun rightly focused on it in their marketing of the language and platform.

Edit: And yes, as a sibling comment says, the "batteries included" factor was probably important in making the language popular with developers.

And the free as in beer factor ;-)

And the dancing in the browser future of the Internet factor :-)

> It doesn't matter how good your language is if nobody has heard of it.

Or how bad it is, if you can shove it down people's throats. But that is true for any software, not just programming languages...

> Java has the shallowest learning curve

[citation needed]

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.

Not having headers seems enough to prove that.

But making Java easy to learn by taking the features out didn't make it easier to build programs with it. It's kind of like making a surgeon wear boxing gloves.

Surely not if the comparison is with C++.

And not only that, Java came with portable standard libraries for pretty much everything: collections, threads, networking, GUI, database interface, etc, which are as much part of Java as the language itself: the Java runtime. C and C++ had some standard libs too, but nowhere near as many. So, it was not only that you could rely on your compiled code to be portable, you could rely on many crucial libs and dependencies being portable too, something which we may take for granted these days.

Yes, Java was a whole product, and that was a great thing. Also: helpful error messages.

But was your choice to learn Java somehow related to it being popular in industry?

More so in the past, portability - meaning not being locked-in to a specific vendor who could then screw you - was a big deal in industry. Today, there's much less heterogeneity (x86, ARM and...?).

Part of Oracle's pitch for their database was that they ported it to different machines, so users weren't locked in (even if they didn't actually use it on different machines).

Ironically, portability was one of the main drawcards (well, that and being able to embed it in web pages) when I first learned it, but I quickly found that a Java application was far less portable, in reality, than an i386 Windows executable. That one friend with a Mac might be able to run it but nobody else could without downloading 65MB of JRE.

"write once, debug everywhere"

> But was your choice to learn Java somehow related to it being popular in industry?

Yes, but only partly. I had evaluated becoming one of Java, C++, or Oracle programmer (I know the last one is not the same thing, but was a career option nonetheless).

Sun spent a whole lot of cash advocating for Java. From some very nice, slick books to their own salespeople. It was the "internet language" with Javascript supposed to be its lesser cousin. I was going to teach a programming class at an out of the way community college in fall of 96 and someone from Sun called me about it. I took it they were a bit serious. It was also billed as a better C++. I don't think anyone since has put that much juice behind a language. The nearest thing is Apple with Swift which is still platform limited.

I don't have enough first hand experience to back this up, but I think I read someone claim that the early JVM was very close to the p-machine. I think a lot of mid era (late 70's early 80's) programmers learned the p-machine in school. Wouldn't be a stretch that it was the informal template.

Reason p-code didn't take off was because it was too slow on personal computers.

Well, this is very much the case according to the article, where James Gosling is quoted as saying:

“Then fast-forward a bunch of years, when I was trying to do the project that Java came out of. I had to do this architecture-neutral distribution format, and then I just went ka-ching! You know, this p-code translator thing would actually just drop in there.”

The article explained before how Gosling learned about the p-machine:

Gosling could have done this by making the requisite fussy changes in every application program and recompiling. But he found an easier way: He wrote code that turned the VAX into a p-machine.

Standing on the shoulders of giants.

> I think I read someone claim that the early JVM was very close to the p-machine

Looking at P-code descriptions, I can't say it resembles JVM bytecode all that much. It seems to be somewhat more low-level.


On a lower level, I think Intel did the same for 8086 assembly. Their documentation was volumes and included everything you ever needed to know, including all operating system integrations (IRQs, syscalls, etc)

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.

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

No, not that one.

The first public release of Java had the hooks to add a JIT.

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?

(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."

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.

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!

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.

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.

Erlang is not single threaded!

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

It still gives you OS independence. And, at least in the case of something like the BEAM for Erlang et al, you can optimize the VM for the language.

Heck, besides Java and Erlang, you’ve got Apple with Bitcode for the Watch.


If you only care about mainstream computers, x86/64 and ARM/64 might seem like the only ones left standing.

However, when one looks how broad the embedded market is, there are plenty of CPUs around, many of those do actually have some variation of Java compilers available to them.

Also bytecode as portable executable format allows to take advantage of CPU improvements inside the same family as well. For example, on x64 the Oracle, IBM and Azul JIT compilers will take advantage of AVX512 if present.

Likewise on Android phones, it may say ARM, but each OEM licensed silicon looks quite different.

If anything, with bitcode for Apple watchOS, DEX on Android, MSIL on Windows Store, WASM on the Web, and the old mainframe variants still in use, we are seeing a rise on its use.

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.

"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 :)

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

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).

Maybe better titled "JVM's Forgotten Forebear"

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

Before the JVM there was a Smalltalk VM ;-)

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.

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


ANDF is definitely under-appreciated. If it had gained more traction, it might have gotten us to "write once, run everywhere" with adequate performance earlier than actually happened with Java. The basic ideas were fundamentally sound, and worked out to an impressive degree for that time. Unfortunately, few nowadays would be able to see that past some superficial details that seem dated to those blessed with hindsight.

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


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

[1] http://www.drdobbs.com/open-source/bob-a-tiny-object-oriente...

> ...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.


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.

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.


>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.

Applications are open for YC Summer 2019

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact