
Musings on AOT, JIT and Language Design - ingve
http://pointersgonewild.com/2015/11/28/musings-on-aot-jit-and-language-design/
======
StefanKarpinski
Between this post and others like it [1], Maxime Chevalier-Boisvert's ideas
sound like they're evolving towards something very much like Julia [2], a
dynamic language carefully designed to make ahead-of-time data-flow-based type
analysis easy. This analysis allows Julia to achieve performance comparable to
C and Fortran. Much of the design involves selecting which aspects of
traditional unrestricted dynamism can be given up without compromising
usability. For example, function bindings are constant by default, which
allows type inference to know with certainty which function object is being
called in most function calls. Similarly, since much of the difficulty in
optimizing dynamic languages comes from trying to guess the types in
arrays/structures/objects, Julia allows programmers to specify these, thereby
eliminating this difficulty entirely. More information about Julia's design
and implementation can be found here [3].

[1] [http://pointersgonewild.com/2012/11/09/static-vs-dynamic-
why...](http://pointersgonewild.com/2012/11/09/static-vs-dynamic-why-not-
both/)

[2] [http://julialang.org/](http://julialang.org/)

[3] [http://arxiv.org/abs/1209.5145](http://arxiv.org/abs/1209.5145)

------
pcwalton
Don't compile to C. It's very difficult to avoid undefined behavior, you won't
be able to modify the compiler backend (and you will want to as you start
optimizing), you can't add new language intrinsics, good GC is pretty much
incompatible with that, and precise control over debug info is impossible.
Compile to LLVM IR and/or GCC IR instead.

~~~
tachyonbeam
Do you know if you can compile to a text form of the LLVM IR? Also wondering
how you'd interface with a GC if you did that.

~~~
pcwalton
Yeah, you can compile to LLVM IR in assembly format and then run the result
through llc. But you will pay in compilation time for this due to the
serialization and deserialization steps, so I can't see a situation in which
it'd be worth it to do so.

The LLVM GC interface is controlled through intrinsics, so you can access it
through the human-readable IR representation just as you can with the API.

~~~
andrewchambers
> so I can't see a situation in which it'd be worth it to do so.

The obvious one is not having a giant build time dependency that might change
and be at different versions on different platforms. The text interface is far
more stable.

The problem I had with doing this is how picky llvm is when it comes to
ordering your temporary registers.

~~~
Gankro
As far as I've seen, the text interface is _radically_ more unstable. Like
when they recently striped types from pointers, I was like "oh no that sounds
like it'll be a lot of work to upgrade to", and all the backend peeps seemed
to think it wasn't a big deal because LLVM's API handled it. Particularly when
you factor in that any breakage in the direct LLVM API can often be resolved
by looking at what Clang did when it upgraded.

~~~
andrewchambers
That is a shame then.

------
RyanZAG
Honestly if you're going to take a step back and consider those things, why
not also consider that we already have so many programming languages that it's
almost impossible to get to a deep level of understanding of all of them.

Obviously if you enjoy making languages then you should do so - and in that
case, noticing that your dynamic un-toolable language won't get wide scale
adoption shouldn't matter. It's already a guarantee it won't get that wide
scale adoption. Either make your un-toolable language because you enjoy making
them, or contribute your efforts to an already popular language that you
enjoy. There are tons of interesting problems and huge areas for improvements
in every single language.

Don't make a new language for the goal of gaining widescale adoption.

~~~
hyperpape
This won't be good advice until it's been at least 20 years since any
mainstream language was born. Today, you can point to Go, Rust, and Clojure as
counterexamples within the past decade (and if there's a new mainstream
language born last year, we probably won't know for 5-10 years).

I suspect what you're trying to say is "don't expect to succeed." That's true
--most people will fail, but we should all hope people continue trying, unless
we're satisfied with what we have. I'm not satisfied, and I think progress
will require new languages, not just improving the ones we have.

Some things require that a lot of people try and fail. Language design is one
of them.

~~~
tachyonbeam
I think he's also saying "do it for fun, not for success, have fun doing it",
which is good advice IMO.

~~~
hyperpape
"and in that case, noticing that your dynamic un-toolable language won't get
wide scale adoption shouldn't matter."

That's what I'm reacting to, and I still disagree. People should have an eye
on what getting traction would require, even if only a tiny fraction of
language designers can make it.

~~~
RyanZAG
The problem is that a static easily tooled language is not going to be as good
as the dynamic un-toolable one without massive tooling support specifically
for that language's features. Creating those tools is not the job of a lone
developer. The cost is immense. The language first has to achieve popularity
to receive the tooling, or be heavily backed by a large tooling capable
company (eg, Google, Jetbrains, Microsoft). So far, the only recent languages
to receive the kind of required static tooling are from those 3 companies.
Also note that the language did not come first in those cases - the
requirement for the language came first, and a language was made to fit what
was needed.

However even more importantly - if you're going to create a language, it needs
to be the ultimate language in your own eyes. You can't leave off novel
features that you have experience in because it doesn't have mass appeal or
has tooling issues. You need to create the best language you possibly can if
you want to compete with others trying to create the best language.
Hamstringing your enjoyment of the language by going in a direction you don't
like because it has more apparently mass market appeal isn't any more likely
to be successful, and it certainly isn't going to be enjoyable enough for you
to slog through the tiny complexities.

While there is a tiny chance that your language becomes the next big thing, it
probably won't. That means you need to make the language you want to make and
hope it succeeds, not make the language that 'will succeed' but you don't want
to make.

~~~
hyperpape
Your point about support is well taken, but while Rust is being supported by
Firefox, it was Graydon Hoare's side project for 3 years. It is at least
possible for an individual to run with an idea for a static language and get
community or corporate support, even if it is tremendously difficult. And I
don't know if you can say that the language sprang from the requirement. It
did, so far as a lot of people have had longstanding dissatisfaction with C++,
but I'm not sure Mozilla originally was looking for a replacement (ditto for
Google and Go--though lessons learned there may not apply to people who aren't
Rob Pike...).

I agree with you so far as it can't be a language you don't want to make. I
don't think this article describes that, but a more modest set of constraints.
Elsewhere, the author mentions Julia as a positive inspiration.

I think the idea of compromise depends on the idea you're trying to bring into
the world. You can't compromise your core idea, but you can compromise on
other things. I guess I'm making assumptions about what the author is
compromising that I'm not entitled to. Perhaps you know that I'm wrong.

------
DasIch
The real problem isn't dynamic vs. static and how it affects tools. The
problem is that programming languages are made by language designers, when
what we would really need are programming experience designers.

We need people that look at the experience of programming as a whole, writing,
editing, debugging, profiling, testing, analysis and packaging. People that
take all of that into consideration and design languages within that context
and under the constraints that imposes.

If you only see yourself as a language designer and ignore the wider context,
your language will fail.

~~~
mafribe
What makes you think language designers have no experience of programming?
Rest assured that the Simon Peyton Joneses and Martin Odersky's of this world
have been doing a lot of programming in their time.

To be sure, they do program applications that are quite different from what
'bread-and-butter' programmers do, and that might influence their taste in
programming language features.

~~~
lotyrin
I don't think the hypothesis is that language designers have no experience
programming, I think it's quite the opposite, that they have experience with
poorly designed languages and tools, and perpetuate a sort of stockholm
syndrome for the current state of what it means to be a developer.

We need languages designed to be used by future generations of programmers in
a world where usability and tools come first. The "Manipulate symbols in this
arcane syntax and hit F5/Run until it does what you want" experience is
fundamentally at fault. Sure we have debuggers and IDEs, but they're more or
less tacked on top of core flaws, things that allow for whitespace formatting
debates or semicolon religion. My IDE and my VCS should just edit and encode
the AST of my language. The compiler and IDE should share the exact same code
for indexing and finding symbols in that AST -- the language acting as a
library to the IDE so new releases with new features are automatically
understood instead of lots of duplicated language for
highlighting/completing/searching every language for every IDE. These are just
a couple examples of the ways we're currently living in a state of sin.

~~~
DasIch
Indeed. It's beyond my understanding how one could even consider not providing
a public API to the parser, when one develops an interpreter or a compiler.
Given all the complexity of such programs, this is trivial.

The standard library of a language should provide access to the parser, so
that developers can easily create tools for the language they're using.

~~~
NhanH
You just sang the song of Lisp programmers all over the worlds.

~~~
DasIch
In Lisp basically everyone starts to develop their own languages. Given that
most people can barely get a reasonable API together that's just a bad idea.

~~~
NhanH
No disagreement here. I was just pointing out that what the GP wanted already
exists in the form of Lisp (with different flavors of macro being different
"API" to the parser, so to speak).

------
nickpsecurity
I remember reading papers around a decade ago that combined AOT and JIT
advantages by profiling that fed back into an AOT compiler. Even JIT's local
optimizations can happen by sending an AST to a client to AOT compile and then
run, optionally with a profile to further direct optimization. These kinds of
methods, minus profile, were done with agent-oriented tech in 90's and in
Juice project that used compiled, Oberon AST's to replace JavaScript.

Most of what we're doing isn't about what's technically the best so much as
what was and is popular. That's for backward compatibility, integration,
network, and marketing benefits. A clean slate attempt at profiling-guided AOT
compilation, at server or binary, could probably match or do a lot better than
most modern stuff.

------
oillio
Dynamic features in a language make tools impossible because communication is
expected to be one way. The interaction between languages and their tools
currently have a rigid design that is shared by almost every modern language.

I would love to see a language that breaks this mold. Where the language and
the tools are intimately coupled, or at least had a more complex API. Why
aren't the concepts of the convention over configuration movement being pushed
further, into the developer workflow and the language itself.

What if unit tests exercising your code was expected, because this is what
drives code completion.

How about a community that won't accept a new library as being complete until
it hooks into the standardized tools to support its custom macros.

I'd love to see what could happen if we question our basic assumptions of the
roles between language, tool, and programmer. What could we do differently if
a program was stored as pure AST, instead of a text file, for instance?

------
sklogic
> _the design of my ultra-dynamic language would make it near-impossible to
> have much tool support_

Dynamic, run-time reflection - yes, it is very harmful indeed. But dynamically
extensible parser per se is not an obstacle for tooling.

> _If you can hijack the parsing of a program while it’s being parsed, and
> alter the parser using custom code you wrote, then good luck running any
> kind of static analysis. It’s just not going to work._

It works. Easily. No problem at all. As long as you can clearly separate
compilation time and runtime.

I could easily make any dynamically introduced syntax extension to play well
with an IDE without any user effort. Autocompletion, semantic highlighting,
type balloons, autoindentation - all the usual IDE stuff.

> _Rest assured though, this language will be dynamically typed ;)_

This is a big mistake. Dynamic typing breaks tooling, not an extensible
syntax.

~~~
aidenn0
Smalltalk and Lisp have each had some of the best tooling around and they are
both dynamically typed.

~~~
sklogic
Yes. But both failed to deliver the autocompletion the spoiled kids expect
these days.

And Lisp is far less dynamic than Smalltalk and the modern lesser toys like
Python.

See in ACL2 how a fully static typing can be added on top without a
significant change in semantics.

------
cottonseed
I think static vs dynamic and JIT vs AOT compilers are orthogonal concerns.
JIT is alive and well in the JVM and a lot of effort is being put into JIT
compilers for JavaScript. And you can certainly write an AOT for dynamic
languages which attempts analysis to reduce the cost of dynamic features (type
inference, vtable specialization and the like).

------
ilaksh
If you are interested in languages that compile to C take a look at Nim.

If I were doing a new language I would compile to web assembly.

------
jack9
You can tool for anything. It's a matter of tool coverage. If there are things
that circumvent the tooling, that doesn't diminish the tool. It will tend to
push programmers not to use those features though (see Aspect Oriented Java
for the first few years).

