1,276 karma · joined June 15, 2013
GraalVM is excellent technology, but when it comes to targeting Wasm, I believe the core language compilers will always have an edge.
Scala.js has the fastest implementation of 64-bit integers on the JavaScript engine. The implementations cannot be understood unless you actually prove them correct. IMO that's one of the best reasons to invest in the formal proof of a program fragment.
[1] https://lampwww.epfl.ch/~doeraene/thesis/doeraene-thesis-201... section 4.4.2, page 114.
So it's possible.
> It's not really a compiler, but a transpiler to WAT.
That's still a compiler. What do you think many languages' early compilers were doing when they compiled to C source code? Heck, what do you think early C compilers were doing when they were compiling to .s files, before feeding them into assemblers?
These are all the same technology. We write compilers, with all the same skills, methodologies, practices. It doesn't matter the format that we output.
Here is a public gist with the `Result` data structure, as well a good portion of the file handling all the game mechanics, which should show it gets used. https://gist.github.com/sjrd/34fe234d1b6232cf42ffda5d23292d3...
https://github.com/sjrd/barrage/blob/main/src/main/scala/be/...
We do this in our regular job. It makes sense to me to demonstrate this process to students.
None of us knows everything there is to know about a language and its libraries. Heck, I'm part of the language development team of a language and I have to look things up about it.
For those interested in more details, we published a paper about it in OOPSLA'16 [1].
So no, we're still a long way from the abstractions of a JVM, even taking the component model into account.
It's a good step in the direction of better interoperability between languages, though, don't get me wrong.
The fundamental difference is that the JVM bytecode has an object model. When they talk to each other, Java, Scala and Kotlin do so at the abstraction level of the JVM object model. You can directly call methods between them because virtual dispatch of methods is a concept with semantics in the bytecode.
There's no such thing in Wasm, even with the GC extension. You get structs and arrays, but nothing like methods. If you want virtual dispatch, you encode it yourself using your own design of virtual method tables. That means Java, Scala and Kotlin, despite all having their Wasm GC backend at this point, cannot call each other's methods in Wasm.
It's one thing I keep using from Belgian French despite having lived in Switzerland for over a decade, because it's objectively better.
(Swiss French has the objectively better names for 70-80-90, though. No quatre-vingt-dix BS like on France. :-p)
No, French doesn't have spelling for the name of letters.
(I'm a native French speaker.)
And Scala.js has shipped it. [1] Although technically experimental, it has no known bugs and it has full support of things like manipulating DOM objects from Scala.js-on-Wasm code.
[1] https://www.scala-js.org/news/2024/09/28/announcing-scalajs-...
The reluctance of the authors is due to backward compatibility with sandboxed "secure" JavaScript (SES). That said, every other language in existence that has immutable structs and records allows to put arbitrary values in them.
So it's at a standstill, unfortunately.
Then that main reason has a number of declinations, like no JavaScript `new`, no field selection, etc. But you can work around all these things with similar "calling convention conversions".
That's the only question I got wrong because it did not make any sense to me.
I also wrote a "toy" (read: for school) dialect of Scala compiling to Oz and therefore turning every local variable or field into what Scala calls a Future, for free. Performance was abysmal, though! But in terms of language idioms, it was quite nice.
---
Unrelated: about Wasm, none of what it does is new, obviously. What's interesting about it is that
a) browser vendors agree to do it together, and
b) the design grows to accommodate many source languages. This used not to be the case but the eventual arrival of WasmGC significantly redistributed the cards of the game.
Relevant background here: I'm the author of the Scala to JavaScript compiler, and now co-author of the Scala to Wasm compiler.
> If MULTILINE mode is not activated, the regular expression ^ ignores line terminators and only matches at the beginning of the entire input sequence. The regular expression $ matches at the end of the entire input sequence, but also matches just before the last line terminator if this is not followed by any other input character. Other line terminators are ignored, including the last one if it is followed by other input characters.
Looks like I have some code to fix.
[1] https://docs.oracle.com/en%2Fjava%2Fjavase%2F21%2Fdocs%2Fapi...
I wrote a compiler from Java regex to JavaScript RegExp, in which you'll find that particular compilation scheme [1].
Edit: also quoting from [2]:
> By default, the regular expressions ^ and $ ignore line terminators and only match at the beginning and the end, respectively, of the entire input sequence. If MULTILINE mode is activated then ^ matches at the beginning of input and after any line terminator except at the end of input. When in MULTILINE mode $ matches just before a line terminator or the end of the input sequence.
[1] https://github.com/scala-js/scala-js/blob/eb160f1ef113794999...
[2] https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pa...