Java’s Forgotten Forebear (2009)
spectrum.ieee.org
spectrum.ieee.org
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
Chapter 2 "VMs for Portability: BCPL" in "Virtual Machines" Iain D. Craig
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
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.
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 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.
This is referring to portable object code. Perl, Tcl, and Rexx aren't compiled, but do have source-level portability.
Not to take anything away from UCSD Pascal, it was a great system and very fun.
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.
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.
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.
pdf "A Brief History of Just-In-Time"
http://eecs.ucf.edu/~dcm/Teaching/COT4810-Spring2011/Literat...
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.
- 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++.
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...
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.
[1] https://medium.com/@donhopkins/the-shape-of-psiber-space-oct...
(NeWS was an implementation/extension of PostScript, but PS was invented by an entirely different group of people).
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
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/...
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/...
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.
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:
https://en.wikipedia.org/wiki/Interpress
Brian Reid's deep detailed historic dive "PostScript and Interpress: a comparison":
https://tech-insider.org/unix/research/1985/0301.html
I also think PostScript owes a lot to Lisp (it's dynamic, homoiconic, polymorphic, symbolic), even more so than Forth.
http://wiki.c2.com/?ForthPostscriptRelationship
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?":
https://donhopkins.com/home/archive/forth/ps-vs-forth.txt
Forth/PostScript discussion with Mitch Bradley:
https://donhopkins.com/home/archive/forth/forth-postscript.t...
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.
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 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 dancing in the browser future of the Internet factor :-)
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...
[citation needed]
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.
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).
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).
Reason p-code didn't take off was because it was too slow on personal computers.
“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.
Looking at P-code descriptions, I can't say it resembles JVM bytecode all that much. It seems to be somewhat more low-level.
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.
"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."
Even for 90s programming systems I recommend you try Erlang.
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.
Heck, besides Java and Erlang, you’ve got Apple with Bitcode for the Watch.
https://thenextweb.com/apple/2015/06/17/apples-biggest-devel...
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.
Funny how the meaning of commonly used terms shift over time. I had to read that a few times before it made sense :)
[0] https://github.com/dbetz/bob
[1] http://www.drdobbs.com/open-source/bob-a-tiny-object-oriente...
I had no idea Packard-Bell had a history before producing low-cost PC clones for consumers.
http://www.computerhistory.org/collections/catalog/102630088
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.
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
>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.
https://sites.google.com/site/dicknewsite/home/computing/byt...