ThinScript, an experimental programming language that can compile to WebAssembly
github.com
github.com
- 1 browser tab: Java runtime environment compiled to WebAssembly, loaded by some sort of enterprise app I'll have to use at work
- another browser tab: .NET BCL compiled to WebAssembly, loaded by another sort of enterprise app I'll have to use at work
- yet another browser tab: some sort of other C/C++ runtime compiled to WebAssembly, loaded by fancy site, let's call it XMail
- and yet another browser tab: another C/C++ runtime loaded by another fancy site, let's call it Ywitch
- a million other tabs with Javascript frameworks
From a certain point of view diversity is good, on the other hand there's so much fragmentation. One of the dreams when computers appeared was that programmers will build libraries that everyone will use and people would just build on top of these libraries, reaching ever higher.
Instead, we have I don't know how many re-implementations of things in various incompatible/slightly incompatible languages. And that's just for OSS, nevermind the billion proprietary re-implementations.
Truly the Tower of Babel.
As bad as Javascript is generally considered, from this philosophical point of view at least we seemed to be on the right track...
It's already bad on the desktop -- from duplication of effort, to crappy cross-platform options.
On the web it will be much worse -- each open wasm tab will eat half your battery in an hour.
We're already seeing this weird situation where websites that are perfectly usable in urban areas become impossible to use in the mountains. Urban telcom networks can be upgraded to make a 60mb runtime feel reasonable, but a lot of rural networks don't even work for todays sites.
Bit of a straw man Imo. WASM is specifically designed with page load in mind. It's why the garbage collector specification is so important, as languages with GCs want to use WASM but they don't want to ship their own for fear of slowing down page speeds.
> We're already seeing this weird situation where websites that are perfectly usable in urban areas become impossible to use in the mountains. Urban telcom networks can be upgraded to make a 60mb runtime feel reasonable, but a lot of rural networks don't even work for todays sites.
I agree completely, though for this I blame the companies/devs targeting a specific audience more than anything. Ie, I don't think it's the fault of "the modern web" or what languages/etc we use today for slower page speeds. For the same reason I don't blame languages we have today for desktop applications that aren't as "fast" as they could be.
We have more RAM than we did 20 years ago, and conversely programs use more available RAM. The program might be doing a "better" job (hard to measure, but I imagine UX is the main concern), or it might be doing a worse worse job.. but at the end of the day, developers took the opportunity to use languages/frameworks that used more RAM, for one reason or another.
So, just like the RAM, higher internet speeds and faster browsers have led to developers using more bandwidth than ever before. We use just as much as we can get away with, and always will.
Sure, WASM may change our idea of what is acceptable, but I don't think it will by too much. We're impatient beings, we want the damn page to load fast as hell. How willing do you think the ~2B Facebook users are to wait 30s while it downloads hundreds of MiB of some FB WASM app? I think people would flip out.
As an aside, what I think will be really interesting, will be compiling normal non-web apps WASM, as a deployment target for systems. Hypothetically, it could be the new "native" and vastly easier to deploy to for all OSs. Not intended to run on web, but still WASM. Talk about cool, Imo
Yup, WASM ports to non-web archs quite well. The abstraction overhead in most cases is very minimal.
It bloats the .apk size by quite a bit. From maybe two megs to about 20.
That wouldn't be needed in WASM.
Did you ever profile websites? Loading a NYT article without adblockers and script blockers loads up around that much data
The fact that we have both libraries is due to reasons mostly outside of software development and computer science concerns (licensing, politics, etc.).
I don't see why for any non-vertical domain, in theory, we couldn't manage the complexity of having just one huge standard library available to Java, C#, Python, Ruby, etc.
Verticals are another story, that's where things get scary. But I wouldn't put medical imaging libraries in the standard libraries, anyway :)
I think you can look to pre-existing multi-language ecosystems like the JVM, .NET, etc. that show that this isn't always the greatest idea. Languages have different idioms and ways of approaching problems, and using a standard library geared towards a stateful, OOP language is going to feel out of place and awkward in a functional language (and vice versa).
With the current speed of replacement of evergreen browsers it would take 2-3 years and we could start using it (some immediately if they only targeted specific newer browser versions e.g. for their enterprise apps).
Instead we got exactly what you describe + piling on stuff on top of JS.
I believe that the main thing demonstrated in practice is that everybody [1] just likes one or another Algol derived language, from a small set of languages with superficial differences between them.
Java, C#, Golang and their dynamic cousins, Python, Ruby, Javascript which have suddenly all adopted a longing for static types (Typescript and flow, Python type annotations, etc) and for async execution (asyncio, channels in Golang, async/await in C#, etc), and all piling functional features. It's like they are converging.
Sure, they still have semantic and syntactic differences, but in the end, not that important in the grand scheme of things. I think that not catering to any superficial preference of all programmers can eliminate endless bikeshedding and be hugely beneficial -- it worked wonders for JS both in terms of industry involvement (excellent JITs and tooling from 4 huge vendors), and in terms of traction/community/libs.
What's sad is not that we don't have 20+ languages for the web, but that the one we have was a quick kludge for a totally different use, and not that great for what it's now used.
[1] the casual expression meaning "most people", not the universal quantifier meaning "all with absolute no exceptions".
Bloat is always a concern, but I don't see how WebAssembly materially changes things - as it stands right now, you're downloading the "runtime" for virtually every site you use in the form of a javascript bundle packaging up every library used to make a site function.
As-in, share-nothing, just their existing libraries cross compiled to WebAssembly.
And we will have to use those apps because we will need them for specific purposes (the typical example is enterprise apps, but also government sites, educational sites, etc.)
The average webpage today weighs in at 2.5mb. I don't think that demonstrates an efficiency win over time.
In truth, I'm not really sure what constitutes an average webpage, or even if the quoted number is after gzipped assets are unpacked by the client.
Would be interested to see where that number comes from though.
Videos and JPGs are the worst offenders, but PNG and JS nearly tie for third in page weight. Though I think it isn't measuring gzip, but raw bytes, which changes it up a little.
[0] https://mobiforge.com/research-analysis/the-web-is-doom
[1] http://www.httparchive.org/interesting.php?a=All&l=Apr%201%2...
Slightly off-topic here, but it's my sincere hope is that (of all things) CSS Grid Layout will drastically alleviate HTML bulk. I've been astounded by how much using it has simplified my markup and reduced complexity in my CSS (since you can accomplish complex layouts without intermediary containers).
I'm an optimist but the bloat problem probably isn't going anywhere anytime soon.
Is that a bad thing?
Ext was absolutely HUGE though - multiple MBs huge.
Wasm certainly makes that harder. I cant speak to what broad impact that might have, but it probably impacts me. More so as they add features like direct DOM manipulation (on the roadmap).
What you say may happen but what the primary purpose of WASM is to replace JS as the target of compilation as it is now. They want a more robust and lower level language which can give higher performance as the base kinda like LLVM except for browsers. So languages like Typescript, Dart, Elm don't have to transpile to JS but to WASM which is less work and more performance.
You would need to do memory/etc. management on a level that is either more in line and more optimizable with your language design, or just stick to things as they are.
The thing which you can compile ahead of time is an interpreter, which then checks during runtime what the actual types are and what needs to be done. You can run such an interpreter in WASM, but that will be a lot slower than what the current JS engines are able to do with Just In Time compilation.
I don't know whether it's possible to implement a JIT compiler in WASM (and thereby dynamically output and execute WASM), but running a JIT-in-WASM on top of a native-JIT (the JS engine) sounds not really desirable.
Not used in any meaningful amount, we don't. And in any case, a library transpiled from Elm to JS is usable by some other code that was transpiled from Typescript to JS. Will that be the same with WASM? Will I be able to make easily reusable WASM libraries? Will they all use the same mechanism to do so? All I've seen discussed is entire apps being converted.
https://github.com/WebAssembly/design/blob/master/Modules.md...
By itself that’s the equivalent of dynamic linking; I don’t know if anyone’s written a static linker yet, but it’s an obvious next step.
However, just like with native code, there will be problems with different languages having different representations of strings, arrays, etc., and C and its sparse type system being the least common denominator.
Essentially just wasm-merge [0].
> However, just like with native code, there will be problems with different languages having different representations of strings, arrays, etc.,
This is the biggest hurtle. Someone needs to provide a WASM interface for backends to implement and frontends to target that provides a minimal stdlib. Until then, it's libc and posix by way of emscripten.
In short: No
With the current transpile-to-JS mechanisms all those languages use the same object model (from Javascript), the same string types, the same garbage collector, etc.
Once you compile-to-WASM, you reduce the common API surface to the WASM primitives, which are reading and writing numeric values from locations in byte arrays. To get some interoperability one would need to create a Javascript wrapper for all those WASM modules. Or in the future there might be a shared garbage collector in WASM, but even when that's the case one would require a standardized object model between all languages that compile-to-WASM and would like to interoperate.
(don't get me wrong, WASM is very exciting, but the "it's going to replace Javascript entirely!" argument doesn't convince me)
Citation needed. :)
It is not at all clear that WASM is an easier compilation target for a high level language like TypeScript, Dart, or Elm. You may be able to get better performance, but in return you have to implement and ship an entire runtime, GC, string representation, etc. Also, interaction with the DOM (the thing you need to actually get pixels on screen) is much harder.
[2] https://gotechster.com/2017/04/web-assembly/
[3] http://webassembly.org/docs/use-cases/
The last one is from WASM official site.
Nobody will write directly in WASM just like nobody writes Assembly directly for complex stuff. Also the entire thing is officially supported now in Firefox and Chrome with Edge and safari soon to support. (P.S I am not a web developer and most of my info is from other people so I maybe wrong. If I am do tell me)
About the DOM, see this
[4] http://webassembly.org/docs/gc/
DOM, GC are future goals.
Think of it like this: WASM is effectively a subset of JS. If you're compiling to run in a browser, by targeting that subset, you don't get to use any of the features outside of that subset that browsers already have high performance, battle-tested implementations of. Worse, you then have to reimplement those features yourself and ship them down with the application.
[1]: https://github.com/WebAssembly/design/commit/b2ea1983c0c0e9e...
X-to-JavaScript compilers were available for decades now, still most write their stuff in JavaScript.
What WASM will change, I think, is that libraries or applications, that were native before, now get ported to the browser.
So JS devs will do what they always did, maybe a bit more every year.
And people who didn't write browser apps, will more and more move to do their thing with WASM.
Also, look into enterprises, it will take them an eternity to get new WASM-enabled browsers to their users and even then I could imagine their admins to disable it.
A lot of that is friction and fear of pigeon holing, that using something that transpiles to JS will limit project/career options later more so than plain JS will. I don't see that as a big issue as long as you keep an eye on developments elsewhere, at least it is no bigger issue than using a particular framework for your application. Then again I've out of date in this area (I keep an eye on developments and played with some of them, but have used-in-anger very little newer than jQuery), having specialised somewhat data-side when I'm not working on legacy projects, so I could be wrong there.
> What WASM will change
I think the key difference between JS transpilers and using WASM is that the latter promises significant performance improvements for some work where the former is more syntactic sugar for the developers (improving their performance rather than the application's, or perhaps even sometimes at the cost of a little app performance due to the extra abstraction). I see WASM finding a very useful niche in libraries for number-crunching, AI, and other compute intensive tasks, while the majority of any project's code outside that (where there is no practical performance gain to be had) remains JS.
I work at a 100k+ employees enterprise in the financial sector and our official, sanctioned browser version is about to be one that has wasm enabled by default. The fact that old versions make systems vulnerable to attacks have been changing this enterprise culture of rarely updating software.
As far as I understand it currently uses JS as a target, but might switch to WASM soon.
But don't worry about the abstraction layers, we might even have some more :-) E.g. some kind of intermediate language between WASM and CPU assembly (like LLVM IR). Or the CPU µops which are even below the real assembly. Or Java maven plugins like annotation processors, which transform some Java code into others. Or even on top of that some interface definition languages, which are transformed into Java through code generators.
Not sure if Apache Groovy is a good example of software that might benefit from a WebAssembly target. Somebody already tried creating an edition that compiles to Javascript, but I guess it doesn't get used much because its Wikipedia page is being considered for deletion on the grounds it's "Not a notable software library". [1]
[1] https://en.wikipedia.org/wiki/Wikipedia:Articles_for_deletio...
This is why WebAssembly's lack of a garbage collector (which could be optional) strikes me as strange. What we'll get is every web page including code implementing an informally specified, bug-ridden, slow GC instead of using the excellent ones already present in browsers. I hope this will be fixed.
I understand that not every programmer and not every language wants to pay GC costs, but there are ways around that.
(Even without GC, the same applies to languages that explicitly manage memory for "speed". Their implementations will also have to work hard to provide "fast" allocators on top of the primitives provided.)
As you said some devs/apps are better off without GC, but also I imagine competition would more or less ensure the most performant or overall effective platforms would end up being the de facto standards.
And some platforms (e.g. React, Vue, etc.) may find one GC tends to work better than another for them or want to implement their own.
I'm not sure if WASM can host libraries on CDNs, but if so once a user has that stuff cached from one site or another bloat wont really be a problem either.
Yes, the compiling platform can use WebAssembly's memory primitives to implement its own GC. But (besides the wasted work of implementing it) this is unlikely to be as efficient as a native, tuned GC on the target platform.
> From a certain point of view diversity is good, on the other hand there's so much fragmentation. One of the dreams when computers appeared was that programmers will build libraries that everyone will use and people would just build on top of these libraries, reaching ever higher.
And main reason this hasn't happened is the lack of a good common ABI/runtime. Libraries do get reused cross-language on the JVM or CLR, but only within that platform; outside it only the lowest-common-denominator C ABI exists which means interoperation between high-level languages is basically impossible. Moving everything onto the web is a chance to make that possible.
ClojureScript, Elm, Elixir CoffeScript, Babel and Emscripten all compile to Javascript and ship their own Runtime.
Given the complexity of Javascript it is not a good fit as a compilation target.
https://github.com/01alchemist/turboscript
ThinScript was very impressive because it was put together in a short amount of time to show a language that could compile to either JavaScript or web assembly.
The main tradeoff, IMHO, is memory management. If you go full OO with a lot of object allocations, and with a garbage collector picking up the litter in the background, then you will be freed to focus upon business logic and your development will move faster. If you manage memory yourself, C style, then you are in for a world of pitfalls and potential pain, but you can make your algorithms tighter and faster. What to pick depends upon your priorites. Postgres is written in C, for speed. A lot of modern web apps are written in full stack Javascript, for agility.
I envision the future of web assembly not as a compile target for your entire codebase, but as a way to optimize the tight loops and algorithms that do the heavy lifting, but leave the rest of the web application as Javascript. Also I think that once you go down that road, you have deliberately picked speed over convenience with respect to the methods in question.
The way that it's going to work, I think, is not by having a Javascript-type language compile into WASM, but by having a more low level language which easily compiles to WASM, but which also compiles to (slower) Javascript to support older browsers.
But what do I know ..
I haven't tried it; let us know how it went! Not sure how many hoops you have to jump through to compile the languages' standard libraries.