The elusive universal Web bytecode
mozakai.blogspot.com
mozakai.blogspot.com
It boggles me that the prevalence of the assumption that there should be a single bytecode. Not all tasks are the same. In real world computing an ATMega is sometimes a better choice than an ARM or an x86.
When Notch released the DCPU16 specification there were multiple compatible emulators running within 24 hours. After 3 days there were compilers. Supporting a bytecode can be easy. Optimizing for speed makes for a much more difficult task, but not all architectures must target the same goals.
The article lists the goals of Fast, Portable, and Safe. I would add to that list more goals. Deterministic and Efficient are two that spring to mind. I would advocate multiple bytecodes that favour some goals over others. The 8 bit AVR of the Arduino would be a good pick for a bytecode that has a light footprint that would be ideal for small tasks.
I wouldn't want a free-for-all with a massive proliferation of architectures, but at least three would mean there is a much better chance of having the right tool for the right job.
Having a C-like bytecode and a Java-like bytecode and a Haskell-like bytecode would be more reasonable, but it would also be a huge pain for browser makers. One highly optimized VM is complex enough...
Having a single "this works for me so it should work for everyone" is dumb. Like only supporting png as your only image format.
So every time I think about the web, my sense of software design is rebelling. It should just be constructed the other way around, with a nice VM on the client, that contains a browser if it is supposed to present structured hypertext. That communicates to a server over TCP/IP, without reinventing TCP atop of HTTP and a server that is actually tailored to whatever it is supposed to do. ( Before anybody accuses me of advocating Java, I want all of this nicely implemented.) But unfortunately, it is probably a billion users too late to start again from scratch.
There may be a way to incrementally approach this architecture by reimplementing existing functionality as modules that run inside some kind of VM and then deprecate the old hardcoded version.
Hopefully, but if the history of computing is any indication: Layers of abstraction can only be added, not removed.
So... I take it that in your opinion the reasons why Java (and to a lesser Flash) didn't supercede the web have to do with its implementation flaws, not its concept?
1. Reusable styles plus case-by-case overrides--very important in a world where graphic design is so central to what we do. To me, CSS beats your typical GUI builder any day.
2. Flow. HTML/CSS have a sophisticated model for automatically flowing text and sizing elements to fit. The content below gets pushed down by the content above, automatically and as much as necessary. Other GUI models have similar things, but I prefer the web's take on it.
3. URLs. These are a beautiful concept. A string that uniquely identifies a certain resource, be that resource a document, a certain screen in an interactive interface, a record, whatever.
Now, you might say you could build all these things into your ideal client. But if you did, what would you have? Seems to me you'd have a web browser.
I do agree with your argument about the network protocols, though. We started with TCP, then we put HTTP on top of it to transfer documents. Then we started sending lots of HTTP requests back and forth for interactivity, and even having the client poll the server as a hack for pushing. Like you said, it started to look like TCP on top of HTTP on top of TCP.
But now we have websockets, which in my opinion is a pretty lean and mean protocol on top of TCP. I like to think of it as regular TCP with a few conveniences like negotiation. Granted, it is not in use everywhere, and I still use the TCP-on-top-of-HTTP-on-top-of-TCP approach for most of my stuff, mostly out of technical conservatism. But I think it'll get there.
As to the statelessness of regular HTTP, it still has its place. Sometimes stateless connections can be very beneficial. Imagine a site like Wikipedia. You wouldn't want everyone who's currently reading a page to have an open socket. With HTTP, you open the socket, you transfer the document, and you close the socket. Done. It's unfortunate that we have to open a new socket for every image, CSS file, etc., but I also expect that situation to improve over time.
A potentially interesting way around this is to make the client open source and get it shipped by all the Linux distributions. That would give application developers an initial audience which would help solve the chicken-and-egg problem.
The good news is that in 1995 we will have a good operating system and
programming language; the bad news is that they will be Unix and C++.
Javascript seems to exhibit much of Gabriel's "New Jersey approach".http://arewefastyet.com/#machine=12&view=breakdown&s... http://arewefastyet.com/#machine=12&view=breakdown&s...
for more current numbers. Many are better than 2x slower than native.
The first prototype was basically a few months of work by 1 engineer specifically on OdinMonkey, building on a few years of work on the more general IonMonkey optimizing compiler. Those are far far smaller amounts of time than have been spent on compilers like gcc and clang, so it is not surprising there is a performance difference. But it will get much smaller.
The problem that many people have with web browsers is that they have evolved from retrieving text to become bloated, Frankensteinish wannabe operating systems that perform redundant operations at slower speeds. It is the job of the underlying operating to execute programs, not the web browser's. Constructing a redundant operating system and executing code at half the possible speed (at best!) is not progress.
1. The browser executes programs in a totally platform-independent way, which the underlying OS cannot (a website should be able to run on all browsers and on all OSes). So having the browser run code is useful too.
2. That "half speed" number was the status as of a few months ago, and is still improving.
JS has different scripting engines and different dialects, so it isn't really platform independent in the sense that the same code will execute the same way on every computer. In fact, it's possible for JS to execute in different ways on the same computer when you run the code on browsers with different engines. There are plenty of instances were a page will not render the same way in different browsers (although this is usually because HTML use isn't consistent).
> That "half speed" number was the status as of a few months ago, and is still improving.
It's still an effort to reinvent the wheel. When a 1:1 ratio is reached, you (not you in particular) will still have ended up spending time implementing a feature that already exists on your OS, instead of improving the original program. For example, browsers have pdf readers baked in. Now you have a dedicated pdf reader on the desktop, and a slower, buggier pdf reader on the browser.
The problem is that programs on the desktop don't communicate well with each other to get the same kind of integration you get on a browser, or the underlying OS doesn't include programs to implement features that you want to include on your web page. I understand that it may be simpler to turn a web browser into a mini OS rather than get OS authors to change their OS (the Chromebook is a misguided attempt to take this to its logical end), but it is still an ugly and redundant solution.
I've ported lots of apps to JS, and generally they just work across browsers. Even the Unreal Engine 3 demo runs on Chrome, JS was not what was holding it back.
> It's still an effort to reinvent the wheel. When a 1:1 ratio is reached, you (not you in particular) will still have ended up spending time implementing a feature that already exists on your OS
The OS can run it, but native apps are not portable, as I said before. That is what makes it worth reinventing some parts of OSes in browsers.
Further, a significant number of my current OS processes are currently executing programs themselves (with various degrees of dynamic compilation). I'm not clear on when it's okay for a process to itself execute a program. Is interpretation ever okay? Or does it always need to be dynamically compiled? Also, what's the rule on compilation of turing complete languages like Postscript?
IMHO, any kind of new web bytecode standard will be immediately broken by Microsoft into an incompatible variant that we won't be able to nicely hack around and will thus fragment the market in their favor. The code base and runtime installed base of Javascript is so massive now that they can't easily fragment it.
Microsoft is no longer in a position to unilaterally destroy the web anymore, and I see no high probability of them regaining that position in the forseeable future. (Too much stuff going mobile, and they're still not strong enough in that space to dictate.... to put it lightly.)
Microsoft can slow the adoption of web standards (and just via the desktop), but they don't have any real control now. And the only reason WebGL isn't in IE 10 is because they didn't want to offend the DX/D3D team. Once IE supports WebGL, D3D will die.
On the bright side, I've seen rumors that IE11 will support WebGL, but that is of little use to people stuck on XP, Vista, or W7 due to compatibility requirements of other legacy apps. As you say, IE doesn't have the dominance it once did, but for some reason it's still used in certain market segments.
Indeed. But it's what we actually have today, not what we wish to have tomorrow.
You misread.
For me the limitation that stands out is Javascript cannot pre-empt.
while(true){};
locks things until some magical supervisor (which _can_ pre-empt) notices and Tells you something went wrong.
You can use workers for long operations but you can't communicate with them while they do it.
look at the example for Web Workers
http://www.whatwg.org/specs/web-apps/current-work/multipage/...
It pumps out a series of primes, but you can't tell it to stop or switch to Fibonacci without killing it and making a brand new one.
(Of course there is one way to support all the things at maximal speed: Use a native platform as your VM. x86 can run Java, LuaJIT and JS all at maximal speed almost by definition. It can even be sandboxed in various ways. But it has lost the third property of being platform-independent.)
The argument is made that any bytecode is probably going to have most of the flaws of Javascript anyhow. However, it's a long standing truism that most problems in Comp Sci can be solved with another level of indirection. The TAOS VM was a virtual Instruction Set Architecture which could be Just In Time translated to a real instruction set architecture and run as fast as it could be read off disk. Since it is not a real ISA, it would also be platform-independent.
http://www.uruk.org/emu/Taos.html
Using such a VM would truly allow one to support any language on the web, at something like 80% "native" speeds. NaCL, LLVM, or even ASM.js could be grown into such a VM.
Additional levels of indirection are apt to create problems as well as solve them, however. Such an undertaking as an overarching standard would be very complex -- so much so, that it may never come to pass, so ASM.js may still be preferable, since it's much closer to actually existing.
I considered C# a few months ago; I know that things like Script# and JSIL can translate C# or CLI bytecode to JS. But I figured there would be subtle semantic mismatches that would require anyone working with such code to know both C# and JS anyway. So arguably JS requires less working knowledge.
The most obvious semantic mismatch between JS and other mainstream languages is that the other languages usually (if not always) support multiple threads with shared state. Consequently, the standard libraries of these other languages tend to have blocking APIs. This seems to me like a good reason to use JS for new client-side development, rather than trying to make another language compile to JS. One can convincingly argue that not supporting multiple threads with shared state is a good thing, anyway.
The only limitation in JS that really bothers me, if it still even exists, is that AFAIK the largest possible integer is 2^53.
But JavaScript actually has some advantages for debugging. The generated code is much more readable than x86 or ARM, and it's trivial to instrument code while debugging, http://mozakai.blogspot.com/2012/06/debugging-javascript-is-...
For better or for worse, we're stuck with javascript for the foreseeable future.
http://mozakai.blogspot.com/2011/11/code-size-when-compiling...
What we really need are toolchains that cross-compile (the same codebase) to both asm.js and PNaCl. What's nice is the asm.js also works on browsers that support neither.
At this point our hope is improved Javascript features in the next release...
A counter example to your argumentation: Many people deploy products in PHP aswell, though we've all decided PHP is something we need to move away from..
The problem is how to make a standard if organizations like Mozilla are not part of that? I think it is not so difficult: don't have a VM? emulate it with asm.js. Do you have a VM? run your application at full speed in more advanced browsers. When Google Chrome came with a faster Javascript engine, others needed to catch up.