
Nectar: A Native JavaScript Compiler Inspired by Crystal Lang and Nim Lang - seraum
http://blog.seraum.com/nectar-a-native-cross-platform-javascript-ecmascript-compiler-inspired-by-crystal-lang-and-nim-lang
======
pbiggar
I wrote a PhD on this topic ([https://paulbiggar.com/research/#phd-
dissertation;](https://paulbiggar.com/research/#phd-dissertation;) for PHP,
though solving different challenged than you'd have to for JS). I also worked
on Firefox's JS engine.

I'd be extremely (and pleasantly!) surprised if this turns out to be real. It
is very common for people to compile a subset of the language and achieve
great speedups, only to discover it doesn't scale to the full generality of
the language. That would be my guess for what's happening here.

Best of luck to the Nectar team, looking forward to seeing what you've got. If
this works as you say it does, you'll have built something incredible!

~~~
gravypod
I'm having a hard time understanding what your PhD is about. Could you clarify
in layman's terms?

~~~
pbiggar
Sure. Basically, a bunch of scripting languages (Ruby, PHP, Python, a few
others) share the same properties, that make them hard to compile:

\- they're not really specified anywhere

\- they use `eval` and similar dynamic constructs

\- they allow you to mutate your data in weird ways (in particular, you can
change variables dynamically by knowing the name of the variable, aka
"variable variables").

I looked at how to solve these problems in PHP by embedding the PHP
interpreter into the compiler as well as into the compiled program. Then I
looked at how to do alias analysis in PHP - alias analysis is a type of static
analysis to figure out which names in the program point to the same value.
This had been done before for a subset of PHP but not for the full generality
of the language, in particular dealing with variable variables.

~~~
vjeux
FYI, both PHP and JavaScript do have a specification.

PHP Specification: [https://github.com/php/php-
langspec/blob/master/spec/00-spec...](https://github.com/php/php-
langspec/blob/master/spec/00-specification-for-php.md)

JavaScript Specification: [http://www.ecma-
international.org/publications/files/ECMA-ST...](http://www.ecma-
international.org/publications/files/ECMA-ST/Ecma-262.pdf)

~~~
pbiggar
JS does - I didnt focus on JS.

PHP has an unofficial spec now but didn't then. Here's what I wrote about it
when it came out: [https://circleci.com/blog/critiquing-facebooks-new-php-
spec/](https://circleci.com/blog/critiquing-facebooks-new-php-spec/)

------
munificent
Some of the world's greatest minds have been spending decades making
JavaScript go fast inside VMs where the JIT can take advantage of profile
information gathered at runtime.

Getting even remotely comparable performance in an ahead-of-time
compiler—without spending eons waiting for complex whole program analysis—is,
as far as I know, an unsolved problem for real-world programs. I'd like to see
what "really, really fast" means for this compiler.

~~~
AshleysBrain
Seconded. An "offline" compiler can't use things like the type information
gathered at runtime. So I'd expect this to actually be slower than JITs.
Benchmarks should be provided before making performance claims!

~~~
CalChris
Why then don't people write in Java for performance? HotSpot has this runtime
information. It runs OK (GCCish) for code that gets past the JIT threshold and
dog slow otherwise. Hell, Java 9 is offering AOT.

JITs have been around for 30+ years and they're umm OK. As in not magical.

~~~
rictic
The things that make Java slow compared to C++ aren't in the compiler so much
as in the language. In a sentence, Java made tradeoffs for productivity and
simplicity that in C++ went in favor of performance and power.

~~~
CalChris
Well, back in the day, the Sun people were crowing that HotSpot would be
faster than C++.

------
andars
Something is fishy. Author claims 10x "faster" than Node, which seems to imply
that they are beating V8. I find this highly unlikely given how fantastically
resistant JS is to AOT optimisation and how many talented engineer-years have
been put into the development of V8. I am very interested in seeing some
numbers and hearing about the techniques employed.

------
dingdingdang
Great project, let's see a repository sooner rather than later. Also, at least
basic benchmarking and information on the compiler backend would be great,
LLVM or something else? How does the compilation work commandline wise
(personally like the Crystal approach, i.e. easy fast compile & run as if
interpreted and then allow extra compiler flags to facilitate optimized
compilation for distribution). Also, what about I/O file system access and
parallelization of tasks CPU wise?

~~~
seraum
We will write a post with benchmarks, specs etc soon.

~~~
NonEUCitizen
how about an executable that others can independently test?

------
bastawhiz
I'd be more interested in seeing them start from fully annotated TypeScript
and working backward. It'll almost certainly be the case that native
compilation of plain old JS is going to be slower than interpreted and JITed
code, just because you have to hardwire in all of the type checks in places
where you're not certain of what might get passed in. All of the fun fiddly
things that modern JS engines do, like creating hidden classes, are somewhat
impossible. You can't deopt unsuccessful optimizations, so everything has to
be provably safe at compilation time. JIT compilers have the benefit of being
able to run type checks and rewrite their generated code to be less optimized
(at runtime). You can't really do that with a static binary. At least with TS,
you can (probably) generate some fairly clean native code from the get-go
without having to worry about things falling apart in an edge case.

~~~
rmrfrmrf
That's been done already: it's called C#.

------
rubiquity
How is this inspired by Crystal and Nim? I don't see anything in the post
indicating their influence.

~~~
mutagen
I'm guessing it is the compilation of dynamic languages to machine code.

~~~
seraum
To machine code, and more : llvm, wasm, asm.js ...

~~~
dualogy
> _and more : llvm, wasm, asm.js ..._

Neat for sure, but not a lot of stuff you can "usefully" do in asm.js in terms
of end-user-facing "RIA", you have numbers, byte arrays, function calls,
numeric operators, primops keywords. (Hell of a way to go type-safe: eliminate
all types but numbers and byte-arrays! ;) No JS-native/runtime-own strings, no
DOM, no built-in objects (window etc), hard to impractical to try to do other
record/object handling. Wrap all interaction with stuff you don't get in
asm.js in exports and "foreign"s. (OK fair game for code generation but still
what a mess and constant switches between the asmjs context and the normal
interpreted context aren't free either --- the bulk of "RIA" logic seems to be
string/list ops, DOM/window interop, basic cheap control flow.) All the funky
emscripten stuff that works in asm.js just also-compiles-and-then-uses the
original memory/byte-based logic for these (records, lists, strings, objects
etc) of the source's native runtime/compiler/libs.

As for wasm, seems to aim to mostly follow in the above footsteps "at first"
(read, the next half decade at best, realistically...)

(But yeah, asm.js is of course still neat for overwhelmingly-numerical high
load computations (game-playing / media-editing stuff etc comes to mind) as
well as showcasing/proof-of-concepting both older C / OpenGL games and newer
3D engine demos..)

------
gogodancer
About V8 JavaScript: "Slow, because compared to C, Crystal or Go, it's slow."

In my experience writing real world server programs, Node.js is faster than Go
in many cases. Part of this is a lack of Go library maturity, but it's also
due to the fact that V8 optimizes code at runtime based on how it's being
used. This project seems to come from a naive, "interpreted slow, compiled
fast" view of the world, leading to false assumptions like Go is going to be
automatically faster than Node.js because Go is AOT compiled and Node is JIT
compiled.

~~~
geocar
I can't speak to Go or Crystal. V8 performs well on microbenchmarks, but very
poorly with a sustained high volume of input due to GC pressure. I've used
node.js in such an application and "version 2" was written in another language
because of the GC pauses.

~~~
gogodancer
So what was the language C, C++, Rust?

~~~
geocar
KDB, although I'm experimenting with Erlang for some things and it seems
sufficient.

~~~
danielearwicker
Odd. Erlang uses GC.

~~~
geocar
Yes, but many small heaps means small GC pauses. It's not as
deterministically/fast as reference counting (KDB) but it's close.

------
placebo
I'd be interested in knowing what parts of the language it doesn't support and
the estimated timeline for implementing them (as in soon, not soon, probably
never). In any case it looks very interesting and should make quite a splash
if it can deliver. Gotta love HN - always a new and interesting surprise :-)

------
tjallingt
Fair warning: I don't know much about compilers.

Maybe it's an idea to make this a native Typescript compiler as it will profit
much more from being compiled than pure JavaScript will?

This way it would probably still be possible to compile pure JavaScript but
providing type information would allow the compiler to apply many more
optimisations.

If I'm not mistaken V8 already does something similar to this with WASM (and I
think asm.js).

~~~
markonen
Here's a TypeScript to C89 transpiler:

[https://github.com/andrei-markeev/ts2c](https://github.com/andrei-
markeev/ts2c)

Very early, but the author seems to be actively working on it.

~~~
finchisko
thank you

------
spraak
I finally understand what 'hand wavy' means after reading this post. Not much
of substance here.

If you want to take advantage of Go's speed alongside JS, check out
[https://github.com/ry/v8worker](https://github.com/ry/v8worker)

~~~
dom96
> I finally understand what 'hand wavy' means after reading this post. Not
> much of substance here.

Indeed, this blog post is very vague and offers no solid evidence that this
project even exists. I was very sceptical of it from the beginning and I'm
surprised it was voted up so much. I guess generating hype is easy when
JavaScript is involved.

------
zem
given the effort put into compiling other languages to javascript, i wonder if
this could be the basis for easy cross-compilation of those languages. (i'm
thinking mostly of ocaml, but lots of other languages could potentially
benefit from the native compilation too, clojurescript-to-native, for
instance.)

~~~
masukomi
Clojurescript-to-native was my first thought too. I think where it will break
down is the threading model though. Crystal, for example, threw Ruby's
threading model out the window, went with channels, and is now working on an
implementation of parallelism. Native JS is a great idea, but we've got to get
these languages leveraging the CPUs they're on if we really want fast native
code.

------
gravypod
I'd love to see the output of the compiler. What assembly it generates with
some standard functions (Fib, fac, tree generation, tree traversal, etc). I've
wanted something like this for some time.

If anyone knows how and can make this happen I'd like to see this on some
godbolt-esq site.

~~~
seraum
We are making a godbolt-esq site for Nectar, coming soon :)

~~~
gravypod
If the output comes out nice and the argument passing semantics is sensable
I'll try and rewrite my OS kernel in this. I want to do it in JS or something
similar as it would be a great teaching tool to students as the language is
very simple and they need no other testing utilites then their web browser.

------
91bananas
Link to the actual project?

~~~
seraum
The website project is in active development, coming soon

~~~
gravypod
Source code? Is it on github? Can you provide some example binaries?

------
jiyinyiyong
I would like to hear comments on SoundScript. Heard Google was trying to speed
up JavaScript by creating a high performace subset of it, and it's very
related to type inference. But no more updates.

[http://www.2ality.com/2015/02/soundscript.html](http://www.2ality.com/2015/02/soundscript.html)

[https://github.com/v8/v8/wiki/Experiments%20with%20Strengthe...](https://github.com/v8/v8/wiki/Experiments%20with%20Strengthening%20JavaScript)

------
crudbug
I think the definitively typed [0] can be leveraged here for AOT compilation.

Looking forward to more details.

[https://github.com/DefinitelyTyped/DefinitelyTyped](https://github.com/DefinitelyTyped/DefinitelyTyped)

------
neilsimp1
This is really neat. I can see JS compiling to WASM as a gret way to get early
adopters.

~~~
seraum
Yes, it's one of our goals

~~~
ilaksh
Just to double check, when you or anyone else involved initiated this project,
were you aware that JavaScript IS in fact now compiled to optimized native
code at runtime (i.e. JIT compiled)? I am asking because several years ago
that wasn't the case, and many people still to this day refer to JavaScript as
an interpreted language, when that generally isn't so anymore.

------
tannhaeuser
Super exciting.

How does it compare to EncloseJS and nexe (which grab V8's unoptimized
compiled machine code)?

What does it target (ES3 CP, ES 5, ES 6)?

Does it require/support async server-side apps?

Does it have http, http/2 or other IP protocols?

Can it compile regexpes to native code like V8?

------
MikeHolman
The only way I can imagine this is faster than Node is on run-once code, where
you are comparing against interpreter or baseline JIT.

------
brian_herman
Cool!

