Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
AssemblyScript: A variant of TypeScript targeting WebAssembly (assemblyscript.org)
174 points by washclothjr on Dec 19, 2020 | hide | past | favorite | 54 comments


FYI, AssemblyScript is a TypeScript variant targeted to WASM. If someone would ask why you want to use another JS to use WASM, it is not a scripting language. AssemblyScript produces WASM binaries with minial runtimes so its WASM binary size is very small, even smaller than C outputs (with Emscripten) most of times.

So if you want to write a low-level WASM code in WebAssembly text format (WAT), it is probably a good idea to use AssemblyScript instead.


So we're on our way to finish the re-creation of Java, by unifying the JavaScript and foreign code into a single bytecode format.

Honestly I'm all for it, and wouldn't change much since most JavaScript written today goes through compilation anyway (TypeScript and/or Babel). Only executing bytecode and taking out JavaScript parsers/interpreters would simplify browser implementations too. Just... what a roundabout trip it has been.


I suppose it is, but Java applets never took off because they were horrible. Half the time they wouldn't work, and when they did they never felt like they were part of a page, and generally felt bloated and slow. Much more like a bad version of Flash than something that felt like part of a page.


This implementation detail issue could be solved by integrating graalvm in the browser and with the DOM


I seem to remember that they eventually fixed the problem with slow startup for applets but it was long after people had stopped using them.

Let’s not forget that when applets were a thing Java was a proprietary, although liberally licensed, from Sun Microsystems and the only JVM available was though them. I don’t even know what the status of it is to this day even though there are far more options than there were then.

I didn’t touch Java for years because it was risky to invest time and energy into a language were the owner, Sun and now Oracle, could just yank it or start charging for the JDK at any time. It only became safe when it was successful enough that it became unlikely that thy would do something like that and there started to be viable alternatives. It’s easy to forget that Java had a huge cloud over its head foe many years.


There are plenty of languages other than this AssemblyScript that compile to Webassembly whereas only Java code compiled to Java bytecode. It's no more another Java than another C or Lua or any other language that just happens compiles to a binary or bytecode.


A lot of languages compile to java bytecode.

https://en.m.wikipedia.org/wiki/List_of_JVM_languages


Fair enough. How many of those languages are just considered reinventions of Java?


There's an entire list of existing languages that compile to the jvm. A small sample:

COBOL Common Lisp Haskell JavaScript

Most of the languages are not similar to Java.


Scala is definitely NOT Java


No, but he's arguing that Scala compiles to Java bytecode


By "Java" I meant the runtime, apologies.


How lucky the young must be, to not hear of Java nor JRE.


There are far more languages that compile to Java bytecode then to javascript or Webassembly and it has been a thing for far longer. The Java virtual machine has a good jit-compiler(at least for java but often for other languages too) and a good garbage collector. It offers access to many useful libraries especially for desktop guis so its long been a target. Most popular languages targeting java include groovy, scala, clojure, Kotlin. Also Jruby is a fairly popular alternative ruby implementation on top of the JVM

You're probably thinking of something like cpythons bytecode which is unstable internal only thing (breaking compatibility with minor python versions). Java bytecode has to be stable since it had to be shared by multiple jvm implementations. And even then a famous ruby hacker made a ruby-to-python-bytecode-compiler(now probably broken by version changes).

https://news.ycombinator.com/item?id=2321204


> There are far more languages that compile to Java bytecode then to javascript or Webassembly

No. There are far more languages that compile to Wasm.


AssemblyScript is a tiny subset of TypeScript; it's probably better to describe it as a C-like compiled language that borrows syntax from TypeScript.


Not only syntax, but also standard library, ecosystem and etc. You could easily transpile AssemblyScript project to JavaScript via tsc if use portable glue code. From C it I guess it borrows AOT compilation, ability to use low-level intrinsics and more granular and sound types. Btw many people still thought AS has manual memory management, but it's not true. By default it use hybrid ARC and GC approach called PureRC: https://github.com/dcodeIO/purerc/blob/master/papers/Bacon03...


You can easily transpile any C-syntax subset into C, if you use the right libraries. Same with Python, or Java, or MIT Scratch, or any other language I can think of.


that description should be on their front page; it communicates the concept more clearly than "A language made for WebAssembly" IMO


This looks great. I’ve been playing a lot with WASM lately (working on a tiny frontend MP4/H264 encoder[1]) and using huge programming tool chains like C/C++ or Rust is not that appealing for building small WASM/web-centric modules. AssemblyScript on the other hand seems very web-first.

[1] https://github.com/mattdesl/mp4-h264


I'm curious how this works in terms of interoperability with Javascript but I couldn't understand that from reading their website. Does anyone here know how the interop works, by any chance?

* Can JS functions call Assemblyscript functions? * Can AssemblyScript functions call JS functions? * Can Assemblyscript manipulate Javascript objects? Or is the communication restricted to low-level types such as integers, WASM byte arrays, and so forth?


You're right WebAssembly hasn't provide seamless interop for compound objects. AS expose special utility called loader: https://www.assemblyscript.org/loader.html#usage

There are also exists other projects which simplify this: https://github.com/torch2424/as-bind


Thanks, but the WASM ecosystem is a bit foreign to me so some of what you said went right over my head. Would it be correct to say that:

1. AssemblyScript functions can be exposed to Javascript via the loader utility. If the arguments are primitive types then calling them is straightforward. Complex types like strings and arrays must be converted between the JS version of the type and the AS version of the type.

2. AssemblyScript code cannot call Javascript functions or directly manipulate Javascript objects. However, Javascript objects and functions can be passed around as an opaque anyref.


Yes, indeed. All points are valid.

Opaque anyref (externref) or reference-types WebAssembly proposal not yet in all browsers, but after it interop will become much easier. At least you don't need glue code for JS side any more.


Thanks again. Much appreciated.


I'm really really happy to see where this project is at now.

I had seen it a while ago when it was still very early and the amount of work that has been done is phenomenal.

I think the documentation and examples are also very polished and make me really want to start using this.

Congrats to the developers, I wish I could upvote this more!


I've been trying to use the AssemblyScript compiler in a Rust project compiled with MSVC. So far, my best solution is calling QuickJS[0] on the command line. Is there any obvious solution I'm missing? Perhaps NectarJS[1]?

[0]: https://bellard.org/quickjs/

[1]: https://nectar-lang.com/


I don't have the answer, but I'm really curious what you're building.


Just a small education platform that'll likely never see the light of day. AssemblyScript is a simple enough language that non-programmers should be able to use and understand it, and it compiles to WASM (which runs sandboxed) so it's reasonably safe to throw around. I'm using it to describe the educational resources (basically, interactive / generalised flashcards).


Sounds cool!

I guess AssemblyScript isn't self-hosted (yet)? Seems like your life might be easier if you could compile the compiler to WASM.

Would a JavaScript interpreter be too slow for your use case? I can find a few of those written in Rust (e.g. https://github.com/boa-dev/boa), although some look abandoned and others seem incomplete.


A JavaScript interpreter would be brilliant, but I can't find a complete one written in Rust. NectarJS (mentioned upstream) seems to compile to WASM (by embedding a JavaScript runtime environment), so I'll probably use that for prototyping.


Can someone explain why I would want Web Assembly versus just writing in another language?

Serious question: I feel like I am missing the use case for something like this - is it primarily useful for multi-tenant scenarios where you want to sandbox the workload or ??


Webasm is something you compile to, not write in. It can be run in a web browser at near native speeds. I don't understand the rest of your question or what your question marks allude to.


So is the use case that I want to write code for the Browser but in an alternative language (say, in Rust)?


It's great if you're already using TypeScript for the server and browser (non-WebAssembly) parts of your system. That way you can harmoniously share some of the same code and data structures.


It can be used when you just want native, low-level WASM features. It is often better when you don't want complex WASM interoperability interfaces of other languages. This help your code keep clean.

Its minimal runtime can be run outside of browser easily. Even Rust requires complex interfaces, requires big runtime binaries to run on WASM, and it sometimes is not portable that it can run only on browsers.


There’s another post on the front page right now about how Shopify uses wasm outside of the browser: https://news.ycombinator.com/item?id=25476605


Great dev story about using AssemblyScript in production: https://engineering.q42.nl/webassembly


> It's not quite a subset, not quite a superset, but rather a variant.

So it sounds like it's not aligned-enough to take advantage of TS's expansive ecosystem? It's more just "a high-level language designed for WASM, with syntactic decisions familiar to people who know TS but which don't actually make it compatible". That's a much less compelling proposition


TS seems like a great choice syntactically for WASM because it’s familiar to developers who are writing WASM, ie frontend programmers. Compared to rust WASM, this seems to be much better for on boarding.

However, because it’s not actually compiling to JavaScript like typescript is normally, this means there must be quirks and differences that must be understood to solve harder problems. Depending on how friendly the compiler is, this can be very painful or intuitive.

I’m guessing it’s infeasible to compile TS to WASM since they’re targeting very different outputs - a ahead of time, dynamic weakly typed scripting language can’t possibly be compatible with an ahead of time, strongly typed, binary output.

And if someone tells you it is, I suspect they’re doing a lot of magic that’s hiding problems that only become obvious after writing nontrivial programs.


I think the developer base still remains to be seen. As long as WebAssembly doesn't provide significant speedups over tuned JS, it seems likely we'll continue to mostly see it used for porting code from platforms and languages that don't natively target the web.


WebAssembly still not reaching their full potential in browsers. For example: https://bugs.chromium.org/p/v8/issues/detail?id=11085&q=comp...

On Firefix and Safari we have the same missing optimizations. Basically wasm in all browsers reuse the same codegen from JS. But this will improved in the future.

Also, don't forget about SIMD, multi-threading with stared buffers and atomics and multi-values, a lot of special instructions like popcnt, ctz, clz, rotl/rotr and etc which not supported by JS and usually emulate not in the best way that complicates or make impossible to optimize this by the JS compiler.

In some points JS is really fast, so much that it is not inferior, for example, to the C language with the LLVM compiler without vectorization (-O2). Obviously WebAssembly can't outperform JS in such cases.


Here a great example of how SIMD brings WebAssembly closer to native speed:

https://medium.com/@robaboukhalil/webassembly-and-simd-7a7da...


> Definitely not a TypeScript to WebAssembly compiler


AssemblyScript is a great idea, and has some excellent people working on it. I posted about this earlier, and Aaron Turner replied. His "wasmboy" Gameboy emulator is a perfect example of just what AssemblyScript is good for, and he gave an interesting talk about it too.

https://news.ycombinator.com/item?id=20079367

DonHopkins on June 3, 2019 | parent | favorite | on: Compiling C to WebAssembly Without Emscripten

Anybody used or have opinions about AssemblyScript? https://github.com/AssemblyScript/assemblyscript

>AssemblyScript compiles strictly typed TypeScript (basically JavaScript with types) to WebAssembly using Binaryen. It generates lean and mean WebAssembly modules while being just an npm install away.

https://dev.to/jtenner/an-assemblyscript-primer-for-typescri...

Here's a great example of a project that uses it:

https://github.com/torch2424/wasmboy

>Gameboy Emulator Library written in Web Assembly using AssemblyScript, Debugger/Shell in Preact

Here's an excellent talk about wasmboy by the author, Aaron Turner -- he's done some really outstanding work:

https://www.youtube.com/watch?v=ZlL1nduatZQ

Since you can compile AssemblyScript into JavaScript with the TypeScript compiler as well as into WebAssembly, you can compare the speed of JavaScript -vs- WebAssembly on the same source code. Aaron did some interesting benchmarks using wasmboy, in the great tradition of using GameBoy emulators to benchmark JavaScript engines:

https://medium.com/@torch2424/webassembly-is-fast-a-real-wor...

Aaron Turner posted this useful link to a good AssemblyScript example a while ago: https://news.ycombinator.com/threads?id=torch2424

torch2424 7 months ago | unvote | parent [-] | on: Walt: JavaScript-like syntax for WebAssembly

I help out every once and a while on the AssemblyScript team with like issues, docs, and things. And made wasmboy, which uses AssemblyScript:

https://github.com/torch2424/wasmBoy

But that being said, usually when people are interested in the language, we usually direct them to the "n-body" example: https://github.com/AssemblyScript/assemblyscript/blob/master... . Which kind of looks more typescript-y :)

Also, just to stay on topic, I think walt is awesome. Stoked to see so many projects coming up with a "Wasm for JS devs" approach/story.

torch2424 on June 3, 2019 [–]

Hello!

Aaron Turner here, thank you for all the kind words! :) Yes I did all those things, and stoked to see people excited about it!

Definitely feel free to reach out anytime about AssemblyScript or WasmBoy. Would love to chat with you / anyone interested.

We also have a slack channel you can reach out and get invited to (see the wiki sidebar): https://github.com/AssemblyScript/assemblyscript/wiki

Thanks again!


A function that calculates Fibonacci is used as an example. Just a reminder that if you want to calculate the nth Fibonacci number you can use Binet's formula.

https://mathworld.wolfram.com/BinetsFibonacciNumberFormula.h...


The caveat is that computing this formula with enough precision to get the correct result needs as many steps as the recursive algorithm.


If I implement this with floating point numbers, will I get the correct integer value?


In general, no.


I haven't played with assemblyscript, but just read today that it doesn't support closures. So no javascript good parts in assemblyscript yet?


This is a temporary limitation which mean you can't capture free vars from outer scope (except global scope). One of the main goal of AS is performance but closure elimination required some extra efforts like Middle IR, eta/beta-reductions, lambda lifting / dropping. Without all of this closures will produce significant overhead. So at first need to implement all this things


To confirm, existing TS modules won't work hence there is a tiny ecosystem for this language, right?


I miss writing crankshaftscript


Must have a bent Johnson Rod




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

Search: