Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Wait, how is that a thing? I'm a pure JS developer (for now) but I don't understand how something framed on desktop OSs could compile to JS, a browser language. Does it compile to Node maybe? Which version of JS?

EDIT: I'm googling now to learn more but I'm not asking to challenge anybody, I'm asking because probably you guys know more than me and I wanna know how this works.



There's no intrinsic property of “desktop” languages preventing them targeting “browser” languages. Any Turing-complete language can be compiled to and from any other.

And you don't even need to go down to that level of abstraction for Java-to-JavaScript, the two share many commonalities. Java classes can become JavaScript objects, Java methods can become JavaScript functions, Java exceptions can become JavaScript exceptions, and so on.

There's some things you can't directly translate (64-bit integer math, for instance), but these can be emulated.

As for “desktop” OS facilities, the browser may not be able to provide all of these, but whatever you need can be substituted (file access can be replaced with e.g. localStorage) or worked around.


So I don't know much about Java, but I was under the impression that it compiles to a binary fie (like C), and thus could do things that directly affect the hardware like malloc. How would Javascript handle something like that? I'm not aware of Javascript being able to perform these kinds of tasks. I guess they just have workarounds, like what you're saying for file access?


It's java source to javascript source compilation(/translation/transpilation), so you only need to follow the semantics of the language, not the actual implementation.

As a simple example, if you create an array of numbers in Java, you don't need to worry about how the memory for that is allocated as long as you get an array of numbers in javascript.

The difficulties are more in how you get around where the two languages differ widely and making sure you match the semantics (often subtle) of the source language without tanking performance in the target language.

For that example of a numeric array, Java has very different expectations when it comes to bounds checking and exactly what numeric type is in there, for instance, and that has to be enforced by the code you generate if you are going to have any sort of sanity while authoring in the source language.


>...so you only need to follow the semantics of the language, not the actual implementation.

Wouldn't you need to follow the syntax and not the semantics? Aren't the semantics what the syntax is abstracting? (I'm genuinely curious, not trying to flame.)


Not OP, but I'm pretty sure you care more about the semantics here.

The syntax is really just one way to express an intention. What you care about are the intensions--the meanings. That's exactly what the semantics are. For example, the semantics of this statement in Java

    int foo = 1 / 0;
are very different from the semantics of this statement in JavaScript:

    var foo = 1 / 0;
even though the two are syntactically rather similar.

(In the former, Java will throw an ArithmeticException, whereas in JavaScript it will return Infinity.)

So you want to ensure that your translation is meaning preserving, that is, that the source code and the generated code are semantically the same.


In this case it doesn't apply, but Emscripten actually compiles LLVM assembly to JavaScript. The way they deal with malloc is by implement it in JS, that is, instead of calling the kernel malloc(), you're just calling a JS function that expands an array of bytes (specifically: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...)


What do you mean by 'affecting hardware'?

Compiling is separate from linking. In C, a simple program calling malloc() and nothing else will include malloc.h. That results in a lot of definitions being brought in, but no implementations. Compiling will produce an object file. Again, no implementations for malloc(), it's an empty address waiting to be filled in. When you link, it all comes together, assuming the linker can find an implementation for malloc() (and there can be many implementations).

So compiling is rather straightforward. The harder part is automatic linking -- anything Java-specific that doesn't directly exist in JS (like long ints -- https://github.com/dcodeIO/long.js), or any calls to some library that also doesn't have a direct equivalent (like, say, some Swing draw commands), will have errors at link time. You can resolve that by creating an interface-equivalent version in JS and telling the linker about it, or you can go all the way to emulating a CPU and other hardware for an OS: https://win95.ajf.me/


It compiles the Java source, not the Java bytecode, but even if it did....

Take your malloc example, you can compile a C program that uses malloc to JS, you just have write a malloc in JS that will behave the way you expect it to.

C gets compiled to assembly, assembly to machine code.

Their compiler just takes Java source and emits JS source instead of JVM bytecode.


> do things that directly affect the hardware like malloc

All your code affects the hardware in the sense of read/write RAM and run on CPUs. C and malloc has fewer layers than JS and new, but they're similar.


I mean, ultimately all a compiler really does is take one symbol stream as input, apply some rules and produce another symbol stream as output.

There's a series of steps to make this happen, but as long as the input can be represented in the output, this should always be possible. JavaScript is Turing Complete.

http://steve-yegge.blogspot.com/2007/06/rich-programmer-food...


Node is JS. And JS isn't a browser language. And similar things like Scala.js [1] have been quite popular for quite a while.

https://www.scala-js.org/


> but I don't understand how something framed on desktop OSs could compile to JS, a browser language

GWT compiles Java to JS. If the Closure Compiler is mostly Java code, you only need to implement a few native code things (like replace file loading with just giving it source code as strings) in JS to do a cross compile to javascript.



You're going to bust an internal organ when you check out Emscripten. :-)




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

Search: