Hacker News new | past | comments | ask | show | jobs | submit login
AssemblyScript: A Subset of TypeScript That Compiles to WebAssembly (github.com/assemblyscript)
205 points by indescions_2017 on Sept 6, 2017 | hide | past | favorite | 73 comments



I get the attraction for compiling a non-web language (say Python) so that you can write Python and have it run in the browser, but since Typescript already compiles to JS I don't really get it. What am I missing? Can it be faster, or do more/different things?


I don't think so.

From what I understand, calling WebAssembly functions from JavaScript (and vice-versa) incur a runtime penalty that's way worse than calling JavaScript functions from JavaScript. As such, WebAssembly makes sense for entire applications that would be compiled—think game engines targeting WebGL, or a font rasterizer targeting canvas, etc.

Since this only supports a subset of TypeScript, you won't even be able to compile your dependencies to WebAssembly, meaning that literally any code you interact with that you did not write has this performance setback.


> From what I understand, calling WebAssembly functions from JavaScript (and vice-versa) incur a runtime penalty that's way worse than calling JavaScript functions from JavaScript.

Can you provide a source for this? I've never heard it and, though it may be correct, this would make wasm much less useful to me.

I have heard that accessing the DOM from wasm will be quite expensive, but that's different from just calling a function.


There is a significant penalty when converting types from ASM.JS or WASM to Javascript. If you stick entirely within ASM then it is much faster but the cost of interacting with JS means that it can work out being quite a lot slower.

Unfortunately you need to interop with JS at the moment in order to interact with the DOM, if you do things entirely in WebGL then ASM is a lot faster.


Do you still have a penalty when e.g. manipulating a TypedArray from JS?

(If so, this seems like a regression compared to unoptimized asm.js.)


No, these have very well optimized fastpaths in all engines.

The method I'd expect for high-throughput communication between js and wasm would be for the wasm code to build structures directly in memory and for JS to traverse those directly using the memory buffer (TypedArray, but really ArrayBuffer).

TypedObjects in ES* will let you directly build lightweight JS objects that are just pointers into an ArrayBuffer.

Edit: Updated to note the fact that I really don't know what the status of TypedObjects is currently..


It's hard to find out. Noone really seems to be talking about it.

It is enabled in Firefox nightly, though I don't know if the API is stable yet:

    > var Point = new TypedObject.StructType({x:TypedObject.int32, y:TypedObject.int32})

    undefined

    > new Point({x:1, y:2})

    InlineTransparentTypedObject { x: 1, y: 2 }


There is a Mozilla bug from last February [https://bugzilla.mozilla.org/show_bug.cgi?id=1336740] that proposes that MDN document that particular TypedObject API, since it was experimentally implemented by Firefox. Florian Scholz of Mozilla then commented:

> The TypedObject proposal predates ES2015 and the yearly release model ECMAScript is on now. That said, the Firefox experimental implementation is not based on current standards work. I'm not sure how useful it is to further advertise or to document it in this case.

Lars T. Hansen of Mozilla added:

> IMO it's premature to document TypedObjects. I think TypedObjects are coming back, but initially to support WebAssembly's interaction with JS, and I would expect the TypedObjects' form to be slightly different from what we have now, more suited to that purpose.

So we may look forward to an eventual revised TC39 proposal for TypedObject, one that explicitly considers interoperability with WebAssembly. But that will probably take a long time. Hopefully someone will write a strawman proposal/polyfill soon.


Thanks, that's really useful info :)


Yeah it's weird. I remember hearing a lot about it a couple years back, and when SpiderMonkey implemented in Firefox it was a noticeable change, largely because we used to call one our hidden type structures "TypeObjects", and that was super confusing when there was a language construct called "TypedObjects", so we renamed our TypeObjects to "ObjectGroup".

Seemed like a really nice proposal for procedural construction of typed views into ArrayBuffers, and perplexing that talk of it seems to have died down...


I haven't looked into it too much, my only experiments were really around DOM manipulation which incurred a huge slowdown.


Sure, but you can't avoid that slowdown by compiling your TypeScript to wasm, can you? DOM is a platform API, and you only get to interact with it in the way the platform allows you to.


That's right. So WASM is only a benefit if you're not doing anything with the DOM.

I see the main use cases outside of games will be intensive computing tasks. For instance Glimmer/Ember could run it's VM on a different thread using WebWorkers and WASM, the same could go for React and it's virtual dom.


Right now, one of the projects I'm working on calls a wasm function which returns a pointer. I then do a lookup in the wasm buffer at the address specified by the pointer and pull out a few numbers with a float64array constructor. Is that an expensive operation?


It's probably best to keep a Float64Array view into the ArrayBuffer around, and use that repeatedly instead of constructing a fresh one each time.

The interpreters and baseline JITs will always construct the object because they can't inline and they don't do whole-method analysis.. and the heavyweight JITs _probably would_ inline the constructor, then notice that the constructed array does not escape, then scalarize the whole thing down to a single read...

but hey, why work the optimizer so hard when you can just make life easy for it and do a single allocation up front, and it runs fast in all performance tiers, and performance isn't predicated on a particular optimization strategy being utilized.


Thanks for the advice, very helpful.


You should ask the profiler.


I've not been that involved with WASM (I've been more or less out of the JS game since around the time asm.js became a thing), but AFAIK the only thing notable is JS -> WASM is more expensive than WASM -> WASM (but should be no worse than JS -> JS); WASM -> JS should be the same as JS -> JS.


One thing is pure call performance (time to invoke a void() function). I don't know where that is, but I guess for WASM<->JS it's slower than WASM<->WASM and JS<->JS, since it can't be inlined.

The more important thing however is the cost of parameter passing. Let's keep in mind that WASM only support numeric types and typed arrays. So in order to make a function call from JS to WASM or the other way around which passes a string as a parameter the string needs to be converted into a format that the other side understands (Javascript string object <-> WASM typed array which contains string in UTFx format). So basically for all more complex data types crossing the boundary costs the [de]serialization of the parameters, which may be huge (and even causes allocations).

If you also only work with integers and typed arrays on the JS side that does not apply. But I guess most people won't be comfortable with that.


> One thing is pure call performance (time to invoke a void() function). I don't know where that is, but I guess for WASM<->JS it's slower than WASM<->WASM and JS<->JS, since it can't be inlined.

…why can't it be inlined? There's no good reason why it can't be inlined.


When I wrote about that I thought about static resolving of where inlining is possible, which would be hard on a boundary to a dynamic language.

But yeah, assuming both WASM and JS run inside the same JITting VM it is probably happening.


... Until the first person ports QT or GTK and suddenly WASM is just pushing 60 PNG frames a second into a canvas.


https://www.destroyallsoftware.com/talks/the-birth-and-death...

Your comment immediately made me think of this. Highly recommended talk for anyone that hasn't seen it. It goes through a "fictional" (maybe not so much anymore) history of javascript until 2035. We are getting pretty close to javascript all the way down.


I am betting WASM will be the revenge of plugins.

And then, just like the ad spams using JS, its advocates will be getting more than they asked for.

Get ready for WASM blockers.


WASM is going to kill spidering. We can't leave HTML if we want google to be able to read the page.

I think Google is very afraid of this. Hence their push for Angular/Polymer/AMP. If they can build a good enough platform in JS they can stall the inevitable.

In the future only marketing parts of the site will use JS/HTML. The "web app" part will be some language compiled to WASM throwing frames to the canvas


In a world where SEO consultants exist, you foresee an inevitable future where Google is killed by a massive wave of companies rewriting their websites to be un-Googleable?


The big players are increasingly doing it already. LinkedIn and Facebook only have very limited spidering.

What Google has liked to do recently is take all your data and replace your service. Search for recipes, jobs, music, or weather for examples.

They're trying to make leaving the homepage irrelevant by using sites data in their search results. Eventually the web will rebel.


But management won't pay to redevelop the whole site, so they'll just embed the content in a QtWebKit widget. We can still block ads at the network level.


Sure they will.

Instead of "why I moved from Angular/React/.... to Vue.js", it will be "why I ported into WASM".


It may get there eventually, but currently, having to pass the JavaScript/wasm chasm for DOM manipulation is really slow. https://github.com/rust-webplatform/rust-webplatform/issues/...


But canvas is faster.


Canvas is part of the DOM. It is a DOM element that JS can draw graphics on.


Not a problem: you can ask the canvas for an arraybuffer to draw on, and pass that to the wasm code. I did this with asm.js in place of wasm (which didn't exist yet) in http://wry.me/hacking/Turing-Drawings/ and you can judge the speed yourself. (As that page describes, there was some overhead from calling from JS to asm.js at least when asm.js first came out. I don't know the current figures.)


asm.js is valid Javascript. It is a valid subset of js that the browser js engines understand, even for the older ones like IE 8. JavaScript has direct access to the DOM, with webassembly, not yet. It may in the future, its still in the proposal phrase (https://github.com/WebAssembly/gc/blob/master/proposals/gc/O...)

So the way to do it today would be WebAssembly -> asm.js/js -> canvas


Good point about the proposal -- that'll be the answer in the end.

asmj.js as JS is irrelevant to the point I was making, because if you access the DOM directly, your code won't verify as the asm.js subset, and so won't run via the asm.js engine.


The asm.js engine is the javascript engine.

asm.js is javascript.

asm.js === javscript


No: that's a choice that Chrome made and Firefox didn't, for example.


> Can it be faster, or do more/different things?

Currently, no.

Ostensibly, there is the possibility for significant execution speed improvements though AOT optimization in the compiler, and simpler (and therefore faster) JIT compilation in the browser.

Currently however, interaction with the DOM API from webassembly is a bad experience, making it a poor choice from most browser-based apps.


It's basically a new language very similar with TS. Think of CoffeScript without the JS legacy, interop and compilation mess.


> It aims to provide everyone with an existing background in TypeScript and standard JavaScript-APIs with a comfortable way to compile to WebAssembly, eliminating the need to switch between languages or to learn new ones just for this purpose.

Learn WASMs APIs without the need to learn another language seems to be the goal.


You get it. It's more of a dying-on-Everest-because-we-can than something you'd actually want to use.


I guess if you wanted source obfuscation that's deeper than a minifier it might be of some use? Not sure what decompiled WASM might look like.


https://serprex.github.io/Befunge hit Run in Chrome & you can see the 500 instruction compilationg of Mandelbrot-in-Befunge to WASM


I love TypeScript! Forgive my ignorance but what purpose does WebAssembly have in this context? I assumed that stuff like ASM was really for other non-native applications. Say for example a C++ game which then can run in the browser or stuff like that.

So as a TypeScript guy with AssemblyScript at my fingertips, what doors does that open for me?

I occasionally have to make HTML5 games in Canvas. Is this the kind of path where WebAssembly could be beneficial?

One day will there simply be an end build step to turn everything into web assembly or is it never intended for use with the DOM?


> Forgive my ignorance but what purpose does WebAssembly have in this context?

Suppose a future web that is language agnostic. Your browser doesn't understand ECMAScript 2015, nor 2016, nor VBScript. It has an extremely optimized and fast virtual machine that works with WebAssembly.

This reduces complexity. It brings diversity to the web ecosystem, you can use any language that compiles to WebAssembly. There are no second class languages on the web.

But to build that future we need to create the tools. You can already use clang to compile many languages to WebAssembly, but ECMAScript nor Typescript are on that list.

WebAssembly should be able to interact with the DOM. But also to more low level APIS like access to USB devices. (https://developers.google.com/web/updates/2016/03/access-usb...)

Many things can go wrong, or can be moved in other directions. But the big success of the Java Virtual Machine shows the power of compile once run everywhere approach.

> Say for example a C++ game which then can run in the browser or stuff like that.

That's already possible using EmScriptem (http://kripken.github.io/emscripten-site/). Game companies like King already use the same C++ code base for their mobile games and browser games. The problem is performance. With WebAssembly it will get more simple and faster.


Regarding the JVM I would also add, that it was common approach on mainframe architectures to use bytecodes + microcoded CPUs, with IBM and Unisys mainframes being the best examples still in production.

PCs and mobile OSes have been catching up with those designs.


>> Is this the kind of path where WebAssembly could be beneficial?

Yes but not exclusively.

Quoth http://webassembly.org/docs/use-cases/ for use cases: Image / video editing. Games. Peer-to-peer applications. Music applications (streaming, caching). Image recognition. Live video augmentation (e.g. putting hats on people’s heads). VR and augmented reality (very low latency). CAD applications. Scientific visualization and simulation. Interactive educational software, and news articles. Platform simulation / emulation (ARC, DOSBox, QEMU, MAME, …). Language interpreters and virtual machines. POSIX user-space environment, allowing porting of existing POSIX applications. Developer tooling (editors, compilers, debuggers, …). Remote desktop. VPN. Encryption. Local web server. Common NPAPI users, within the web’s security model and APIs. Fat client for enterprise applications (e.g. databases).


I'm still hoping that I'll end up on the "Hejlsberg roundabout", i.e. that this whole WebAssembly thingamajig will get me Turbo Pascal productivity again. (I know, we progressed since then in regular IDE land, but for the web, this would be a step forward)


...where "A Subset of TypeScript" = JavaScript?

If I am not using this, what are the other languages I can use today that compile down to WASM?


No, a different subset. JavaScript is unsuited to WebAssembly because of its dynamic nature; this project is taking the type system of TypeScript and using it to allow compilation to WebAssembly, but the dynamic parts of TypeScript/JavaScript are disallowed.

Just as asm.js is a subset of JavaScript that can be optimised more successfully, AssemblyScript is a subset of TypeScript that can be optimised more successfully.


You mean other than C/C++ where you cab take advantage of 30 years of libraries ?

http://kripken.github.io/emscripten-site/


Yes, other than C++.


Rust has a WASM target as well as ASM.JS.

Although, it seems as though it compiles to ASM.JS and then compiles that ASM into WASM, so likely anything that compiles to ASM.JS can also then be further compiled into WASM.


> Instead of reimplementing TypeScript as closely as possible at the expense of performance, AssemblyScript tries to support its features as closely as reasonable while not supporting certain dynamic constructs intentionally:

This sentences, and the examples given with it, show that AssemblyScript is not technically a subset of TypeScript. There are 'features' in the former that aren't available in the latter. For example, explicitly converting the results of binary boolean operators to boolean is something that does not exist in typescript.

It's a subtle but important distinction, although I may be splitting hairs.


This looks really cool to me for a learning environment. E.g. write some typescript, see how it compiles to s-expressions, etc.


So if I get things right :

- ASM.js : basically assembly with a subset of javascript syntax

- WebAssembly : assembly with a different format which doesn't require parsing javascript.

- languages built on top of WebAssembly : C/C++ like languages with explicit memory management/ no garbage collection.

- assemblyscript : C with a typescript syntax ?


- ASM.js: A faster, cut down version of JavaScript

- WebAssembly: The successor to ASM.js, a compiled binary format (as opposed to plain text) with additional features

- languages built on top of WebAssembly: More like languages that can be compiled to the WebAssembly binary format. currently C/C++

- assemblyscript: A subset of a languange (TypeScript) that compiles to JavaScript, but which compiles to WebAssembly instead.


There are already JVM and .NET prototypes.

Rust also supports WebAssembly.


Previously:

* asm.js, LLVM output, Rust MIR->intermediate representation->WASM

Now:

* asm.js, LLVM output, Rust MIR, AssemblyScript->intermediate representation->WASM

Presumably, the goal of AssemblyScript is to make WASM more accessible, as producing asm.js, LLVM output, and Rust MIR is out of reach for most people.


You can have GC languages already today on WebAssembly, the runtime will just be bigger.

After all it is no different than targeting a real processor, I never get the point why people think it is a stumbling block.


Just noticed that quite a few browsers support WebAssembly already (http://caniuse.com/#search=webassembly) . I wonder whether compiling Unity game to WebAssembly is better (more stable) than Unity to ASM.js


There is already a WASM Unity.

http://webassembly.org/demo/


I thought WebAssembly didn't have a garbage collector yet.


Apparently the GC is compiled otherwise you have to manage memory somehow manually...

>> Linking in the runtime adds up to 14kb to a module, but the optimizer is able to eliminate unused runtime code. Once WebAssembly exposes the garbage collector natively, there'll be other options as well.


So what, it just means one needs to ship one with the runtime.

Commodity processors also don't have a GC.


Maybe someday xamarin can use this compiler


I assume it there is no DOM access, right?


Not yet. Once GC is available it should not be far off.


This links to a GitHub organization page, which is spectacularly uninformative.

https://github.com/AssemblyScript/assemblyscript is a better link for this submission, I think. You get a README.md, at least.


Looks like their DNS is fucked up. http://assemblyscript.org/ redirects to their GitHub org, even though there's a website repo in there that claims to be http://assemblyscript.org/.

Edit: apparently their website has no content, just a redirect to GitHub. ¯\_(ツ)_/¯


And if you look at the HTML file in the website repo it is redirecting to GitHub. Not DNS' fault


I can't but think that this is such a "Hype Train" thing.


You should reconsider the name "AssemblyScript" if you want it to catch on.




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

Search: