HNHacker News
TopNewBestAskShowJobs

sjrd

1,276 karma · joined June 15, 2013

Compiler Engineer, Scala Center, EPFL. I develop Scala.js https://www.scala-js.org/
submissionscomments
sjrd··on EU to ban carry-on baggage fees
Good. Now do the same for the volatility of train ticket prices, please? If you want people not to destroy the planet, make sure they can afford the more ecological routes.
sjrd··on Most ints are not floats
Float to double conversion is safe. The thing that's not safe in your example is to write `0.3f` (or `0.3d`) in the first place. The conversions from decimal to float or double is unsafe (inexact) and gives different results from floats than for doubles. But the conversion of float to double, in itself, is always exact.
sjrd··on Most ints are not floats
Always... except when you're actually writing floating point operations. If I'm implementing `sqrt`, I'd better make sure the result is exactly the expected one. Epsilon is 0 in all my unit tests. ;)
sjrd··on Most ints are not floats
Signed ints are also the integers mod 2^n. The beauty of modular arithmetics is that it's all equivalent. At least for all the operations that work in modular arithmetics in the first place. They just have different canonical representatives for their respective equivalence classes, which are used for the operations that don't work in modular arithmetics (like divisions, comparisons or conversions to string with a sign character).
sjrd··on Running Clojure in WASM with GraalVM
The trick is to call the latter GCC. Much less confusing. ;-)
sjrd··on Running Clojure in WASM with GraalVM
It's acceptable. Meanwhile 5.6MB of Wasm is about the size of the entire test suite of Scala.js. :-p

GraalVM is excellent technology, but when it comes to targeting Wasm, I believe the core language compilers will always have an edge.

sjrd··on Stuffed-Na(a)N: stuff your NaNs
The spec mandates normalization of NaNs in ArrayBuffers. If other engines do not normalize, I believe it's a bug in those engines!
sjrd··on Long division verified via Hoare logic
We actually proved correctness of the fast Long division of Scala.js using similar reasoning. [1] We had mechanical proofs for the other operations, but the solver couldn't handle division. The interplay between bit vector semantics and floating point semantics was too much for it to bear.

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.

sjrd··on Translating 10M lines of Java to Kotlin
Scala solves the primitives-in-generics, and it significantly improves on the array-hates-generics.

So it's possible.

sjrd··on MoonBit compiler is available on GitHub
(I don't work on Moonbit, but I am a compiler engineer.)

> 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.

sjrd··on Boardgame.io: an engine for creating turn-based games using JavaScript
Oh shoot, yes. I have imitation copies of the original game graphics in there, and so I can't make it public without violating copyright of their assets. :-(

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...

sjrd··on Boardgame.io: an engine for creating turn-based games using JavaScript
The way I did this was to design a more-or-less monadic container `Result<A>` for all my game logic functions. It batches a sequence of animation steps with a result. It can also model error conditions (like not having enough resources for example). I can then instantiate it any concrete result type, such as a full game state or just the result of individual computations. It was very nice to concisely write complicated game logic with animations while retaining the happy path.

https://github.com/sjrd/barrage/blob/main/src/main/scala/be/...

sjrd··on Principles of Educational Programming Language Design
Huh? I teach a first year programming course. I often reply to questions with "let's see if the compiler lets us do that" or "let's quickly search how to do that".

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.

sjrd··on Rust’s Incremental Compiler Architecture
The Scala.js compiler toolchain has been using similar techniques since 2015 by default. It features parallel and incremental whole-program optimizations, so it is also used for release builds. In fact it's so fast we run most advanced optimizations in development builds as well.

For those interested in more details, we published a paper about it in OOPSLA'16 [1].

[1] https://dl.acm.org/doi/10.1145/2983990.2984013

sjrd··on Spin 3.0 – open-source tooling for building and running WASM apps
Even the component model has nothing to say about the concept of methods. All you have are top-level functions with immutable arguments and immutable results. You can't hold on to an instance of an object created by the other language. You could hold an integer handle, but then you don't get garbage collection across the two languages.

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.

sjrd··on Spin 3.0 – open-source tooling for building and running WASM apps
I develop the Scala-to-Wasm compiler, and also maintain the JVM backend of Scala. I can tell you that Wasm is very different from JVM bytecode.

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.

sjrd··on What has case distinction but is neither uppercase nor lowercase?
And it's so convenient, too! No letter thus requires several syllables to be pronounced.

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)

sjrd··on What has case distinction but is neither uppercase nor lowercase?
> Is there are proper French spelling for that pronunciation? Like how h is aitch in English.

No, French doesn't have spelling for the name of letters.

(I'm a native French speaker.)

sjrd··on Should JavaScript be split into two languages?
> Projects like Hoot (Scheme) and Kotlin port are already demoing such things.

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-...

sjrd··on Proposal: JavaScript Structs
I've been following that proposal closely, and even (unsuccessfully) tried to contribute suggestions to it. I think what's killing it is that the authors of the proposal won't accept arbitrary values as fields of R/T, but all the potential users are saying that they won't use R/T if they can't put arbitrary values in them.

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.

sjrd··on Compilation of JavaScript to WASM, Part 2: Ahead-of-Time vs. JIT
It's a bit between the two, really. There are typically still JavaScript helpers in the middle, but not for the reason most people think. The remaining reason is that Wasm cannot perform JavaScript method calls (with a receiver object). It can only perform function calls (without receiver). So you need JavaScript helpers in the middle to translate between a calling convention that doesn't use `this`, only regular parameters, to another convention where one of those parameters becomes the receiver of a method call.

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".

sjrd··on Show HN: Are You Smarter Than a 5th Grader?
The correct answer to that question would be the Logarithm. 32 can be divided 5 times by 2 before it becomes 1 and you can't divided it anymore. I think the phrasing of the question is incorrect.

That's the only question I got wrong because it did not make any sense to me.

sjrd··on Writing a Rust compiler in C
This is what we did for Mozart/Oz [1]. We have a compiler for "proto-Oz" written in Scala. We use it to compile the real compiler, which is written in Oz. Since the Scala compiler produces inefficient code, we then recompile the real compiler with itself. This way we finally have an efficient real compiler producing good code. This is all part of the standard build of the language.

[1] https://github.com/mozart/mozart2

sjrd··on How to Know When It's Time to Go
It's not every day that we see Oz mentioned here! I was very involved in writing the Mozart/Oz 2.0 VM.

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.

sjrd··on A long list of (advanced) JavaScript questions, and their explanations
I sampled about 20 questions and got them all right. I guess it helps to be author of a compile-to-JavaScript language. That gives way more knowledge about the tricky spec corner cases. Knowing these things is less useful for a JavaScript practitioner.
sjrd··on AI copilots are changing how coding is taught
IMO most proposed changes to teaching using AI are misguided. My philosophy regarding AI copilots and teaching is: as calculators are for those who already know how to compute, so are AI copilots for those who can already develop software. They are tools to leverage when you know the craft, to accelerate. They are not there to do what you don't understand.
sjrd··on The dangers of single line regular expressions
OK it seems they changed the doc since. In the docs for JDK 21 we read instead [1]:

> 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...

sjrd··on The dangers of single line regular expressions
`$` does mean end of input in Java, unless you explicitly ask for multiline mode. In the latter case it means `(?=$|\n)` if also in Unix-lines mode, and the horrible `(?=$|(?<!\r)\n|[\r\u0085\u2028\u2029])` otherwise.

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...

sjrd··on CS 6120: Advanced Compilers: The Self-Guided Online Course
I disagree. The landscape has significantly evolved into incremental compilation techniques in the past decade. While theoretical developments are mostly confined into parsers, practical implementations do it across the entire pipeline, all the way to whole-program optimizations and code generation.
sjrd··on Show HN: Boardzilla, a framework for making web-based board games
This looks very interesting. One question: would I be able to develop a game using my favorite compile-to-JS language? Or would the game infrastructure force me to use TypeScript?
← PreviousPage 2 of 10Next →