5 ms·
> being forced to have only one choice (Javascript) When it comes to JS, you already have a gazillion prettier and more enthralling languages to choose from th
by dualogy 9y ago
> being forced to have only one choice (Javascript)
When it comes to JS, you already have a gazillion prettier and more enthralling languages to choose from that transpile neatly to JS. Are {{TypeScript/Flow/ReasonML/PureScript/Elm/CoffeeScript/Haxe/Haste/GHCJS/Fay/Fable/WebSharper/Scala.js/GorillaScript/Roy/Idris/etc}} really not enough choice? While wasm is still busy being hatched and birthed, JS has already long become "the web's choice compilation target".
That's not to say that projects compiling to wasm aren't worthwhile of course :D but I observed that the precursor "asm.js" paradigm didn't get widely adopted even though browsers already do optimize-for/precompile it. Unless the whole "EcmaScript + Browser APIs" (dom/xhr/string/array/etcpp) are readily-available from within wasm by default without bridging (ie "the modern web client runtime" exposed fully within wasm -- in a prim-op/pointer fashion I guess), I remain mildly skeptical that it'll take off as "a full JS replacement" rather than remain a pluggable niche component for specialized high-perf computations and such..
- justinpombrio 9y ago> that transpile neatly to JS As a PL researcher, I can assure you that there is nothing "neat" about transpiling to JS. JS is an awful compilation target.
- dualogy 9y agoHow so? Interested in your elaboration. I would have surmised it'd be very smooth and fun to target, given all the freedoms it gives you (free-form records, dynamically-sized arrays, no types). All the things that are "foot guns" when hand-writing it, should make codegen-ing it a lot easier. Because when a code-gen "shoots yourself in the foot", one can just fix the transpiler once instead of one's individual JS code-base(s) time-and-again
- TazeTSchnitzel 9y agoFor one thing, JS has no unstructured control-flow. So your compilation process involves breaking down ifs, loops and so on into branches, then… trying to messily reconstruct them.
- dualogy 9y agoWell, ouch, a transpiler writer has to code up a bit of boilerplate, most of it just once early on in the project's life-time.. "too bad"! IMHO reconstructing stuff may be a somewhat tricky challenge, but there's no intrinsic need for it to be "messy" regardless of the target language? I must be missing something here still.. =) I'm doing transpilation to Go right now, so often I think "much of this would have been much simpler to get done if I transpiled instead to an anything-goes scripting language". (Reason of course being I want to emit idiomatic human-written-like code, and working with mostly-incomplete type information coming in, still reconstruct types rather than pass-and-return-typeless-boxed-values-around messily.) A lot of this is pretty "messy" right now, but I place all of the blame for that on me (guess I prefer rodeo-ing into it rather than "sitting down and writing a formal paper on it first"), neither the target or source language.
- TazeTSchnitzel 9y ago> there's no intrinsic need for it to be "messy" regardless of the target language The generated code with “re”constructed control flow is going to be a mess and you can't really help it. Worst-case it'll be a `while(1) { switch(i) {` type of thing.
- deleted 9y ago[deleted]
- DiThi 9y agoUnstructured control flow is easily emulated with switch statements. In fact it's what emscripten did long before asm.js was made, IIRC.
- TazeTSchnitzel 9y agoEmscripten has a specially-designed algorithm called relooper for reconstructing control flow (there’s a paper on it!). Switch statements are its last resort.
- 9y ago
- justinpombrio 9y ago> free-form records, dynamically-sized arrays, no types AFAIK, free form records and lack of types do not an easier compilation target make. It's pretty easy to compile an untyped language to a typed language. > How so? - There are a ton of implicit casts that are almost certainly not what you want. So, for example, if you're going to use addition in the compiled code, it's a 10-step process [1, section 12.8.3.1], and you should be careful not to trigger the 9 steps that do things other than addition. - There is, last I heard, no way to determine the size of the stack. - No integers. - Say you have a demo page for some language, and someone using the page writes an infinite loop. Don't want the page to crash? Welcome to advanced compilation techniques like CPS transformations and trampolining. Overall, JS has a ~850 page spec, and any part of the language you target for which you don't fully understand the spec is a potential bug. Instead, you want your target language to be dumb, tiny, and explicit. [1] http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf http://www.ecma-international.org/publications/files/ECMA-ST... Disclaimer: I have done research on JS, but I do not study or develop compilers.
- DiThi 9y ago> There are a ton of implicit casts Very easy to avoid if you're compiling a statically typed language to JS. > No integers Not in the JS specification (outside typed arrays), but every JS JIT works in a way you can actually declare variables as 32 bit signed integers, and made its way into the asm.js specification. They are declared like this: var a = value|0; Where the |0 is a no-op so not actually done, just a type hint. If what worries you is precision and not performance, doubles allow 53 bit integers (not counting sign bit) with full precision. > Say you have a demo page for some language, and someone using the page writes an infinite loop. Don't want the page to crash? Welcome to advanced compilation techniques like CPS transformations and trampolining. Or just use a web worker, which you can terminate if you haven't heard back in a while (pun intended). > and any part of the language you target for which you don't fully understand the spec is a potential bug It heavily depends on what type of language you do. If your compiler tracks the types and doesn't mix them, edge cases are much, much easier to avoid. Source: I did make a compiler for my own language that targeted JS.
- 9y ago
- hermanradtke 9y agoInteresting you say that. The creator of elm said he compiles to JS because it is so easy.
- sjrd 9y agoAs a PL researcher, I disagree with you. JS is a much neater target to compile to than Assembly, for example.
- bad_user 9y ago> enthralling languages to choose from that transpile neatly to JS I wish people would stop using "transpiling". This "to transpile" verb happened in order to inform that a language such as CoffeeScript compiles without information loss to JavaScript -- i.e. they are at the same abstraction level, CoffeeScript being just syntactic sugar. But when it comes to other languages, like Haskell, Idris, PureScript, Scala, Clojure, those languages are not at the same abstraction level and you lose information by compiling to JS. And we have had a perfectly adequate term for naming tools that transform one programming language into another – to compile.
- shakna 9y agoTranspile comes from transcompile, (nicely defined as source-to-source compiling), which refers to a subset of compiling. It's a perfectly valid term from the 80s. (I've answered this so many times, I don't care to look through my history for the sources. Feel free to.) You're fine to get upset when people say transpiling isn't compiling. But getting upset that people use a more specific term than you are, is verging on the overly-pedantic, and isn't going to win you any friends on the other side of the fence.
- bad_user 9y agoI’m not getting upset when people are more specific, I’m getting upset when they are wrong. Check the output of languages like Scala.js and ClojureScript sometimes. The JavaScript those produce can no longer be classified as “source” ;-) For these languages the generated JS is not higher level or more readable than JVM or CLR bytecode.
- shakna 9y agoThe first transcompiler produced optimised AIX assembly code from C. By your measure, that wouldn't be considered source code. The original meaning was somewhere along the lines of "not assembled bytecode". Why the new term then? Compiling was commonly thought of as including what we now refer to as the assembling step. They wanted to point out they weren't doing that. Editable code, non-hex code, non-binary code, etc. was thought of as source code. This stuff isn't worth getting upset over. Defining terms to have reasonable conversations has always been difficult. Here, if you see compiler or transpiler, you understand a transformative process is happening, and so does everyone else. Accusing someone of misusing a term that can mean different things to people from different backgrounds, or being "wrong", is just going to isolate you from being able to speak reasonably to them. Our language evolves. A word from nearly thirty years ago is coming into common usage, which means that it's definition will likely change. It might become even become more specific. Most programmers using transcompilers today, don't have thirty years of experience behind them, but they will shape the usage. You can find a middle-ground with them... Or convince them your experience isn't worth listening to.
- vog 9y agoThose mentioned languages were designed to compile to JS. In addition, there are general purpose languages that compile pretty well to JS: * OCaml (js_of_ocaml, bucklescript) * Haskell * etc. Those have the advantage that they have a mature ecosystem of libraries, and have very good compilers to native code on server side as well.
- flavio81 9y ago>more enthralling languages to choose from that transpile neatly to JS Many of those languages you listed (for example, TypeScript) run slowly compared to plain Javascript. Transpiling to js is not an easy task and I don't think one can claim it can be done in a "neat" way; see for example the paper that Emscripten authors wrote regarding that topic. Why should I accept a performance penalty if I write in TypeScript, being so similar to JS? TypeScript is js with typing support. In the outside world (outside of the js ecosystem), if you have a dynamically typed language and you add type annotations to it, performance gets boosted dramatically, 3x to even 10x speed (practical example: Lisp). Not in the case of Typescript. It goes slower than js. Why? Because transpiling to js isn't so nice. Those langs, compiled to Webassembly, should work much faster, and many will outperform Javascript substantially. Even in simple stuff: Javascript only has floating point numbers. There is a lot of computationally intensive code that will massively outperform the JS equivalent, if implemented using Webassembly using plain integers.
- dualogy 9y ago> Why should I accept a performance penalty if I write in TypeScript, being so similar to JS? TypeScript is js with typing support Indeed you shouldn't. TS set out to be "JS with types, that get checked then ditched". Has it morphed into something more? The above shouldn't be slow to generate. And as for code speed, not much code-gen should be happening in the first place once type info is erased from source as "TS turns into JS". I might not be fully up to speed on TS' latest developments however.