
Rust: The New LLVM - wcrichton
http://notes.willcrichton.net/rust-the-new-llvm/
======
trishume
Counterpoints as someone considering writing a language that targets LLVM, and
as someone who has used Rust a bunch:

\- Your compile times will be a lot slower than they would otherwise be. This
is a big one for me.

\- If your type system is materially different than Rust's, you don't gain any
benefits since you have to write your own type checker anyways.

\- LLVM is designed to be easy to machine generate, including having a library
API for generating code. Rust doesn't yet.

\- You can't necessarily re-use Cargo if your language requires type info to
link that wouldn't be in the Rust source files generated.

\- If you have semantic differences in memory model you'll need to give up the
advantage of Rust's safety by having your code generate unsafe pointers, for
example if you want to have shared mutability in a single-threaded context,
which Rust doesn't handle nicely.

\- If you do re-use Rust's type checker the error messages you get out will be
terrible and point into generated Rust code.

\- Debug info and debugging get even harder.

\- If you want Rust interoperability you have to replicate Rust's enormous
type system in your language's FFI, which is hard if you also have your own
type checker, see above.

Basically it is a good idea, if your language has semantics and type system
very close to Rust.

A much better idea IMO is to target LLVM and then write an LLVM plugin that
can link to Golang object files and generate Golang struct metadata. Golang's
FFI and type system are much much simpler and more likely to be able to graft
onto new languages. Also Go's library ecosystem is larger.

~~~
wcrichton
Thanks for the good counterpoints. Some thoughts:

\- When you say "materially different," how different are we talking? I'll
admit that if you want to implement Haskell (or anything with HKT) that it's a
long shot, but if you want to implement Javascript, it shouldn't be that hard,
yes?

\- Can you give an example of when you need type info to link?

\- RE: debug info and error messages, do you disagree with what's written in
the post? I agree this is an issue, but it doesn't seem unsolvable.

Generally, I guess I don't see how most languages have semantics terribly
different from Rust. You don't need unsafe pointers for shared mutability with
a single thread because you can use a RefCell (see: my language linked in the
post). In my experience, most type systems for general-purpose languages have
roughly the same feature set as Rust.

I buy that implementing a language completely different from Rust in
semantics/types makes Rust not a good target, but for most languages we use
nowadays, isn't that not the case?

~~~
panic
How will you implement exceptions?

~~~
Manishearth
catch_unwind, probably? Its not supposed to be used for exceptions and if you
try to use it for them there are some barriers in the way. But these are not
fundamental barriers and can be solved through codegen, which is how the
language is planning to work anyway.

------
azakai
> This is part of the inspiration for LLVM, or Low Level Virtual Machine,
> which is a kind of "abstract assembly" that looks vaguely like machine code
> but is platform-independent.

LLVM is not platform-independent.

LLVM IR has baked-in constants, ABI details, and other platform-specific
things. The "LLVM IR is a compiler IR" post has a good summary,

[http://comments.gmane.org/gmane.comp.compilers.llvm.devel/43...](http://comments.gmane.org/gmane.comp.compilers.llvm.devel/43769)

One result of that is that the following quote is not true:

> a compiler writer can target LLVM and then have his language work across
> platforms (e.g. on Linux, Mac, and Windows machines)

Actually a compiler must generate _different_ LLVM IR for each platform.

It is true that LLVM does abstract some or even most things away - CPU
architecture is (mostly) handled for you, for example, which is what the
author mentions - but many important things aren't.

> as well as with other languages that use LLVM

You'll still need to make sure to use the right ABIs for those languages.

In fact, LLVM has somewhat poor abstraction for the C ABI, in that it exists
in clang and not in LLVM, as a result, Rust has had to duplicate a bunch of
that code. This point actually supports the author's position - targeting Rust
would actually be a more portable target than LLVM!

Overall, it might make sense to compile to Rust. But probably to Rust MIR, the
IR they are developing. MIR needs to mature and stabilize, but there are
already signs of an ecosystem starting to form around it. It's interesting
speculation, but it would be exciting to see Rust MIR be "the new LLVM."

~~~
ZenoArrow
Reading the article, I get the impression that the VM part of the LLVM name is
causing some confusion.

For all those reading this that may have thought LLVM acts like a low-level
version of something like the JVM (as the name suggests, I got caught out with
this before too), it's not the case. LLVM is a compiler framework, the main
output of which isn't bytecode for a VM but is rather machine code for the
platform you're running on. There is no performance overhead from running
LLVM-generated code because LLVM is not part of the final runtime.

~~~
groovy2shoes
LLVM _is_ a virtual machine, though, even in the sense that the Java VM or the
Lua VM are virtual machines! Virtual machines (a.k.a. abstract machines,
though technically virtual machines are a subset of the abstract machines) are
simply computers that are implemented in software. When you target the LLVM,
you _do_ generate bitcode in much the same way you'd generate bitcode for the
JVM (though the bitcode itself is very different).

What makes the LLVM low-level, compared to the JVM or the LVM for example, is
that it doesn't offer the same level of abstraction that they do. For example,
the JVM abstracts not only the machine, but also the operating system, the
program linker/loader, and even some devices, etc. On the other hand, the LLVM
essentially abstracts the CPU's instruction set, and that's about it. This is
why even when generating LLVM bitcode rather than native code, you still need
to worry about things like ABI, naming conventions, system calls, etc. --
because those things are separate from the physical machine's ISA.

However, just like with physical machines, I'd wager that it'd be possible to
implement those abstractions _on top_ of the LLVM, though it's likely easier
and more efficient to just have a retargetable code generator.

Note that the LLVM can also operate as a JIT VM much like Java's HotSpot VM or
LuaJIT's VM, and in such a mode the differences are less obvious from the
outside. Similarly, both Java _and_ Lua can be compiled to native code (in
fact, in order for JIT to work, this _must_ be the case), but going a step
further, they can be compiled AOT. In a sort of "middle-ground", they can be
compiled to their respective bitcode, and then further compiled into native
code -- precisely the way the LLVM tends to operate.

The idea goes way back. There are plenty of examples throughout history of
compilers targeting virtual (abstract) machines, and it offers several
advantages. Portability is the one everyone talks about, but there can also be
advantages for code density and compiler complexity, among others. For
example, the ANSI/ISO/IEC standard for the C programming language defines the
semantics of C in terms of the operation of an abstract machine. A handy way
to specify the operational semantics of a language! [EDIT: In fact, the
original purpose of abstract machines was for this kind of formal
specification of semantics; it was nearly a decade before people realized the
other advantages of AMs when used as an abstraction in programs themselves.]

See also: Landin's SECD machine, BCPL (O-code), UCSD Pascal (P-code), (O)Caml
(CAM - categorical abstract machine), the G-machine, and many more.

~~~
kibwen
I think this is a bit too keen to hew to the textbook definition of "virtual
machine". In modern industry practice a "virtual machine" tends to imply "we
wrote an interpreter, and to run your program you execute this interpreter and
feed it your program".

In the interest of being precise, I'd rather call LLVM an "abstract" machine,
in the same vein as the C abstract machine defined by the C language
specification
([https://blogs.msdn.microsoft.com/larryosterman/2007/05/16/th...](https://blogs.msdn.microsoft.com/larryosterman/2007/05/16/the-
c-abstract-machine/)).

~~~
groovy2shoes
> _I think this is a bit too keen to hew to the textbook definition of
> "virtual machine"._

That's interesting to me because I haven't ever read any textbook on virtual
machines. If you could recommend one, I'd be very interested (especially if it
covers designing an ISA that's a good fit for your language, which seems like
a dark art to me; I've seen plenty of examples but no design docs or notes
whatsoever).

> _In modern industry practice a "virtual machine" tends to imply "we wrote an
> interpreter, and to run your program you execute this interpreter and feed
> it your program"._

My experience has been exactly the opposite: people have a preference for the
word interpreter. When they've written an interpreter, they call it an
interpreter. When they've written a virtual machine, it's _still_ often called
an interpreter. For example, you rarely hear talk of the Python VM, Lua VM,
Scheme VM, Lisp VM, etc. the way you hear talk about the JVM. I normally hear
"the Python interpreter" or "the Lua interpreter", etc. I sometimes even hear
these sorts of VMs referred to as bitcode or bytecode interpreters.

> _In the interest of being precise, I 'd rather call LLVM an "abstract"
> machine, in the same vein as the C abstract machine defined by the C
> language specification_

I'd normally be with you on that one, but I referred to it as a virtual
machine here for two reasons: 1) I most often hear the terms "virtual machine"
and "abstract machine" used interchangeably, and 2) the LLVM -- Low-Level
Virtual Machine -- is called a virtual machine by its creators. All in all,
the distinction between the two isn't a large one, and only rarely an
important one, so I thought it best in this case to avoid causing any more
confusion than I already felt I might :)

(As an aside, I think a big problem with the computation science field -- both
in academia and in industry, though perhaps more pronounced in industry -- is
the sheer lack of (and sometimes even disdain for!) precision in our jargon.
Abstract vs. virtual machines is, of course, a topical example, but _many_
others come to mind: parser, DSL, interface, object, message, native,
relational, lightweight, functional, and many more. Of particular annoyance to
me is the cloud of meanings surrounding the word "type" and its variations,
along with a great deal of modifiers typically used alongside it ("strong",
"weak", etc.). It's enough to drive the more formal/rigorous/pedantic of us
batshit, myself included.)

------
kibwen
As a long-time Rust guy, this article makes little sense to me. It is surely
possible for any language to target Rust, but unless the semantics of that
language are an unusually close match to Rust's then you're going to have to
pull off some gymnastics. LLVM IR is actually designed to be a decent
compilation target for a wider variety of languages (though I wish there was
more documentation on what is and is not UB), but even LLVM IR is going to
start looking like a poor choice of a target the farther your language is from
C++.

~~~
wcrichton
Can you give an example of when language semantics are so different from Rust
that it would be difficult to do this kind of thing? When I wrote this
article, I was thinking major languages: Javascript, Java, Matlab, etc. and to
my mind they all are suitable for compiling to Rust. Granted, I don't know the
Java specification or its internals, I'm not claiming right now that
everything specified by the JVM can definitely get ported to Rust, but moreso
the general ideas behind the languages.

~~~
mike_hearn
Rust has a unique design that would be rather difficult to map other languages
efficiently to, unless you simply used it as as complicated assembly language,
in which case why not just use LLVM?

Most obviously you cannot map Javascript or Java methods or variables directly
to Rust because these languages don't have anything like the borrow checker.
You could come up with a way to work around that, but then why target Rust at
all?

I think there's a deeper problem with your proposal though, which is - why? I
know you try and answer that in the article but I found it unconvincing. The
JVM was explicitly designed to solve the problem you're trying to solve, as
you clearly know, so a good starting point would be to much more thoroughly
analyse why you aren't satisfied with it.

You say you have to "shoulder the runtime overhead of a garbage collector" but
then name lots of languages you want to compile to Rust, all of which assume
and require the presence of a garbage collector. Then later you talk about
needing a good GC written in Rust. Well ... why? If you're gonna have to
provide a GC anyway for practically every modern language, then the runtime
overhead of this will be paid no matter what.

Having studied the JVM quite extensively, I don't see much in it that's
obviously wrong or could be done wildly better, but I see a lot that's done
right. If you re-walk that path, you will probably end up reinventing the
wheel.

~~~
solidsnack9000
> Rust has a unique design that would be rather difficult to map other
> languages efficiently to...

With regards to efficiency, a "unique design" is of little direct consequence;
we are always mapping from one very different language to another, since
assembly bears ultimately little resemblance to Java or Ruby or Haskell.

A language can be a bad compile target but that has more to do with runtime
restrictions. For example, it's hard to build command line tools that start
quickly if you target the JVM. Compacting GC can make interop with other
languages hard (since objects get moved around). But Rust doesn't come with
abstractions or an execution model that are any more heavy weight than C++
(which is no way a bad language for implementing interpreters or compilers,
and has even served as a compile target on occasion); in fact it is a more
conservative extension of C than C++ is.

Rust does impose a burden that is kind of like saying, your
compiler/interpreter has to pass Valgrind+Coverity; but this is perhaps more
of a help than a hindrance -- and it doesn't limit the kind of language you
can write.

~~~
pjmlp
> For example, it's hard to build command line tools that start quickly if you
> target the JVM.

Only for those that don't know what they are doing.

There are plenty of JDKs that AOT compile to native code.

~~~
solidsnack9000
Okay, so how do I do this? Because if I write a simple Scala program that
prints "Hello World" it can take like three seconds to start.

~~~
premium-concern
I think that's pretty much untrue.

That program is 0.x seconds on Scala-JVM and 0.0x seconds on Scala-Native.

~~~
solidsnack9000
Well, Scala-Native should of course be much faster.

The last time I looked at this was a awhile back; maybe it was 0.3 seconds and
I misremembered it.

------
Animats
This guy wants to use Rust as a target language for a compiler. He likes that
Rust doesn't have too much run-time machinery, such as a GC or a JVM. OK,
fine. Compilers have been written to target C for similar reasons.

Then he wants a "battle hardened GC", a JVM, access to the internal syntax
tree of the compiler, and enough dynamism to allow an interpretive
environment. What? Those are all features that Rust deliberately doesn't have.
Adding them would drastically change the language and add considerable
complexity. They would not contribute to Rust's main goal - provide something
in which to write reliable production software.

From the feature list this guy is asking for, what he really wants is
Microsoft's ".NET" system. That has all the run-time stuff he wants, and
multiple compilers compile to it.

~~~
Manishearth
The point, which he outlines in the post, is to be able to mix high level
programming with lower level languages. This is already a common pattern in
the industry where you write your application in python/ruby and speed up the
tight loops with C/C++/Rust. The lingua franca of the interop is C. Which
means that the boundary between the two is very stark and unsafe. You can't
use advanced typesystems or seamlessly share datatypes. I'm working on
something similar these days (C++ and Rust though, no high level language).
You lose all template/generics info at the C bindings boundary. Bindgen
programs let you get it back to some degree, but forcing monomorphization/etc
are all not easy problems to solve without making the compilers talk to each
other (also not easy to do).

Will's idea seems to be to use Rust as a target for a high level GCd language,
which can then (mostly) seamlessly interop with "pure" Rust code, and the
interop won't have an unsafe boundary.

~~~
pjmlp
You should check how COM and now WinRT (aka 2nd coming of COM+ Runtime) work.

You get an OO ABI, with support for generics and OS level interoperability and
reference counting as the GC algorithm.

Yes, using COM from C is a pain, but it was never intended to be used as such,
rather C++, VB, Delphi and any other Windows language able to speak COM.

~~~
Manishearth
Yeah, I'm aware :) I don't like it as much but that's because I've always
ended in situations where I need to bind via a C API, which isn't COM's fault.

------
tathougies
Haskell functions (pure or with side effects) simply cannot be made into
anything resembling standard Rust types due to the presence of laziness.

This post oversimplifies the problem of language interoperability. Interop is
not limited because of lack of a common target. Every platform/OS combination
has a well-defined ABI. Most languages have facilities to use functions that
conform to this ABI and most can also export functions which use the ABI. The
choice of LLVM has nothing to do with it -- LLVM simply uses the ABI. The fact
that many compilers use LLVM is not because a hand-rolled solution couldn't
implement this ABI, but rather because LLVM is easy to use.

~~~
wcrichton
I don't believe interop is that simple, though. If you want, for example, PHP
to interact with Python, you can't just go to the ABI level. You need code to
define the translation between objects of one type in PHP to another type in
Python. ABI-level compatibility is good for really low level stuff, but for
everything else it just doesn't work.

As for Haskell, I agree that it doesn't fit into this language vision. Both
its lazy semantics and type system would be difficult to fit into the model I
suggest.

------
dbcurtis
Debug information, anyone? The author ignores the need for passing line
numbers and storage symbols through some sort of debug dictionary.

The kindest thing I can say about this article is "simplistic".

~~~
erickt
Rust Core Team member here. I actually wrote up an RFC [1] that proposes
adding JavaScript-like source map support to Rust, in order to improve our
plugins-in-stable-code supports. Odds are we are going to reject it for now
since I think we found a simpler way to achieve our goals, but we are
certainly not opposed to adding support for it if there's demand.

[1]: [https://github.com/rust-lang/rfcs/pull/1573](https://github.com/rust-
lang/rfcs/pull/1573)

~~~
dbcurtis
I only had time to give your link a quick skim, but I'm impressed that the
Rust team is actually thinking about how to pass debug information through
from "Rust-front" tools.

The #line directive in C is limited, at best. Debugging flex/lex/yacc/bison,
for instance, is sketchy at best. But of course line numbers are only part of
the problem. If someone really wants to create Spiffy New Language as a Rust-
front, then SNL structures/objects/collections/whoozits will want to pass
symbolic information to the debugger so that users can explore their data
structures using meaningful names.

And even so, this assumes that with debug symbols on, you can turn
optimization off. Debugging optimized code gets wacky very fast because
associating line numbers to source is not always possible any more, and gives
non-intuitive results due to code motion and inlining even when it is
possible. (You haven't lived until you've seen gdb's source line pointer jump
around like a weasel on crack due to code re-arrangement.)

At Rust's current level of maturity, I suspect there are bigger fish to fry
than passing debug info from Rust-fronts, so rejecting ambitious debug symbol
machinery is probably the right strategic decision for the time being.

------
zodiac
> If you compile to Python, well, your program will probably run pretty slowly
> and you lose any static typing guarantees.

What? The static typing guarantees should be checked (statically!) by the
compiler, so the choice of language you emit doesn't need to affect what kind
of type system you can design your input language to accept.

------
webkike
This sounds like it is written by a person with little experience with
compilers. The reason you compile to SSA is because it's easy to perform
optimizations on. At some point you compile Rust to LLVM.

~~~
wcrichton
Yes, and Rust does the hard work of turning your code into SSA and activating
all those optimizations. Why should we have to recreate all the effort of the
Rust compiler devs?

And please refrain from ad hominem. It adds little to the conversation.

~~~
webkike
As others have pointed out, the difference is a sacrifice in compilation time
to more quickly implement a langauge very semantically similar to rust. If
it's not super similar to rust, you are simply jumping through more hoops than
it is worth. Yes, LLVM IR is a pretty decent compilation target. And honestly,
having costly abstractions provided to you would probably encourage you to
generate poorer code. But I digress.

------
ridiculous_fish
Here's a weird bit of C++ code:

    
    
        std::vector<int> foo = ...;
        for (iter = foo.begin(); iter != foo.end(); ++iter) {
            *iter += 1;
            foo[0] += *iter;
        }
    

A naive translation to Rust would run afoul of the borrow checker. If we are
to compile C++ to Rust, how are we to address this? Should we simply generate
unsafe Rust?

~~~
hellofunk
What do you consider weird about this code? This is fairly straightforward
C++, as far as syntax and language use. Do you mean the logic of what it is
doing seems weird to you?

~~~
ridiculous_fish
Yes, it's just accomplishing something weird. And it's straightforward C++ (as
you say) that uses multiple mutable references to a single object. Of course
Rust forbids this.

How would one transpile this code to Rust? Or is the idea that every language
ought to have Rust-style semantics? If so, it's hard to reconcile that with
"Rust is the new LLVM," since LLVM does not demand such strict semantics.

------
wilonth
Such a bad idea, fanboyism is too strong here, Rust is one of the slowest
languages to compile, and incremental compilation isn't even available yet.
Your new language's compilation will take pretty much forever.

~~~
wcrichton
Is your main objection just compilation times? I agree that's a trouble point,
although I don't believe it will never get fixed. Incremental compilation is
just around the corner!

I assure you that this post is thought out past the point of just "fanboyism."
Have some faith :-)

------
andreaferretti
In fact, as a compilation target, one wants a language with a lax semantics,
not a strict one. This is (one of the reasons) why so many languages compile
to C, instead of - say - to C++.

Consider this fact for example: many languages make use of objects allocated
on the heap in a way that prevents to know statically when they are to be
disposed; then a GC takes care of that dinamically. How are they going to give
Rust the necessary information to track lifetimes, when the information is not
there to start with? Of course, one can just write a GC in Rust, but how is
this an improvement with respect to a GC written in C?

Also - what about typed languages - such as Go - that do not have generics?
These are not going to map well to the Rust type system. Or what about lazy
languages? Or languages that save the stack on the heap to implement call/cc?

In short, whenever the semantics is different enough, you will not be able to
map to idiomatic Rust constructs, and in fact if you don't want to pay the
cost of interpretation, you will probably map to unsafe constructs most of the
time.

~~~
Manishearth
Rust most probably will be getting hooks that make it possible to safely
integrate efficient GCs. Writing a safe nonconservative GC for rust has
already been done, and once these hooks are in place it should be possible to
write a _good_ GC. Though for a codegenned language on top of rust you may not
need these hooks.

[https://github.com/mystor/rust-callcc](https://github.com/mystor/rust-callcc)
is callcc for Rust. Technically abuses a feature for a purpose it was
explicitly not intended for, but meh :)

callcc and gc are usually not useful operations in rust. That doesn't mean
that its not possible to implement them. The implementation might be annoying
to use, but of you are codegenning to rust this doesn't matter.

Yes, some semantics won't copy over. I feel like most would though. Those that
don't can often be emulated at the lower level with enough codegen.

~~~
andreaferretti
It's not that writing a GC is impossible - of course it is doable. The issue
is that objects written in this hypothetical language will always make use of
the GC because they do not have lifetime information in the first place. So
the question arises naturally: why bother compiling to Rust if you have to
avoid the borrow checker anyway?

~~~
Manishearth
The reason I gave in
[https://news.ycombinator.com/item?id=12148269](https://news.ycombinator.com/item?id=12148269)
applies here too. Clean interop. The ability to freely use a GCd language and
smoothly transition to Rust when necessary.

And Rust-as-a-target doesn't necessarily mean you're doing it for the borrow
checker. It could also be the typesystem (with the perf and safety of lower
level code as a unique bonus). Yes, other, better, typesystems exist, but
nobody's saying that Rust is the only language you can do this with :)

~~~
andreaferretti
How is Rust type system helpful? If the codegen produces valid Rust, the Rust
type system will not give errors. If it doesn't, I'd say it is a bug of the
higher level language - and at best the user is going to see a type error of
Rust, while working in X, which is not the best user experience.

Really, these kind of checks belong to the frontend.

~~~
Manishearth
No, I mean if you want your higher level language to have a typesystem similar
to that of Rust. As I mentioned in the other comment, interop between high
level and low level languages usually happens through the medium of C, in
which all type information is lost. If your higher level language is compiling
to Rust, you can easily add Rusty typesystem features with seamless interop.

I'm not saying Rust's compile errors should ever be shown to the user. I don't
think that's what the OP is suggesting either. If rustc errors you should emit
an internal compiler error, because your higher level compiler should be
producing valid rust code.

------
sid-kap
Minor nit: GHC has a LLVM backend (in addition to an assembly backend and a C
backend), but the assembly backend is the most commonly used.

(The LLVM backend is known to produce better-optimized code, but the compile
times are slower.)

------
nickpsecurity
I'd rather see things compile to typed ASM or something. SPARK + Rust if we're
talking intermediate language so we get SPARK's static benefits on some code
with Rust's on other code.

~~~
favorited
Then you'd probably want LLVM IR (or an equivalent). It was literally designed
to be a hardware-agnostic strongly-typed SSA assembly.

And/or you could do what Rust and Swift are doing (with MIR and SIL,
respectively), and define your own ASM-like language between your parsed AST
and LLVM IR. That way you can do high-level optimizations, static analysis,
etc. before you drop too far down and lose much context.

~~~
nickpsecurity
LLVM folks told me it has issues that stem from fact it was created originally
for C/C++ and x86. I'd think something more like TALC or, as you said,
strongly-typed SSA that was language and HW neutral. Plenty of research on
such stuff though.

------
programminggeek
How long till someone writes "Javascript: The New LLVM" or even better
"Javascript: The New Rust"?

~~~
nhaliday
Speaking of which, [https://www.destroyallsoftware.com/talks/the-birth-and-
death...](https://www.destroyallsoftware.com/talks/the-birth-and-death-of-
javascript)

~~~
programminggeek
Great talk, Gary is a cool dude.

------
__s
llvm has alloca. llvm has computed goto. Saying safe-Rust can generate
arbitrary "safe" LLVM is a bold statement

As an aside it may be interesting if this could be "Target MIR", but that's a
future prospect

~~~
wcrichton
Rust doesn't generate arbitrary LLVM, but to my knowledge it does generate
LLVM that is memory safe. That's the whole point of the borrow checker.

------
erlend_sh
> To my knowledge, Lia is the first major language that actually compiles
> directly to Rust.

You might be interested in checking out Dyon

[https://github.com/PistonDevelopers/dyon](https://github.com/PistonDevelopers/dyon)

------
jeffdavis
Really creative ideas in here. Others have raised a lot of good questions, but
it seems like an interesting area to explore, anyway.

------
vanderZwan
Once static compilation gets off the ground, I wonder if Julia isn't an easier
target for "high level LLVM". The whole language is built to be extensible,
and people are already using it in comparable ways.

APL implementation:

[https://www.youtube.com/watch?v=XVv1GipR5yU](https://www.youtube.com/watch?v=XVv1GipR5yU)

As a code generator for the Go assembler:

[https://www.youtube.com/watch?v=02NkiDoRDCU](https://www.youtube.com/watch?v=02NkiDoRDCU)

------
solidsnack9000
Rust does offer some type features that could make language interop a lot
better while not really imposing too much on the way other languages work.
Traits in particular provide a way to model polymorphism that is compatible
with subtypting but doesn't require it.

------
bogomipz
Can someone explain this:

"Second, LLVM is a simpler language to target than traditional assembly
languages—it has nice features like infinite registers and recently support
for stack frames."

Aren't stack frames a basic component of any run time? How was support for
those only recently added? Maybe I am not fully understanding the context. I
looked at this docs but it didn't clear it up for me.

------
bogomipz
"CPUs are basically assembly interpreters, and that's the most fundamental
unit of execution that we can target"

I'm not trying to nitpick here but CPUs are interpreters of binary words. I
think that sentence might be misleading to someone.

------
sitkack
For all the corner case clarences out there, this is some forward thinking
stuff that you should grok before you turn it down.

------
ilaksh
Web assembly is the new LLVM.

~~~
ridiculous_fish
Doesn't web assembly put most responsibility for optimizations on the thing
emitting it? That's a big difference from LLVM.

~~~
flamedoge
webassembly is just a binary IL spec

~~~
ridiculous_fish
I don't know much about it. Is it like Java bytecode, where the runtime is
expected to do substantial optimization? Or is it more like traditional
assembly where the optimizations are expected to have already been done?

~~~
btrask
If you're still curious, I dug this up:
[https://news.ycombinator.com/item?id=9734842](https://news.ycombinator.com/item?id=9734842)

It sounds like WebAssembly is in a weird position, where it can be
(relatively) directly translated to machine code, or more heavily optimized to
support dynamic languages.

