# Is it wrong to call Julia interpreted?

**URL:** https://discourse.julialang.org/t/is-it-wrong-to-call-julia-interpreted/104296
**Category:** General Usage
**Created:** [September 27, 2023, 7:36am UTC](https://discourse.julialang.org/t/is-it-wrong-to-call-julia-interpreted/104296 "2023-09-27T07:36:02Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![ninjaaron](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ninjaaron/32/6392_2.png) [@ninjaaron](https://discourse.julialang.org/u/ninjaaron)
#### Post date: [September 27, 2023, 7:36am UTC](https://discourse.julialang.org/t/is-it-wrong-to-call-julia-interpreted/104296/1 "2023-09-27T07:36:02Z")

</div>

@sdanisch and I are having it out in a GitHub issue about whether or not it is correct to call Julia an interpreted language. [Julia is not an interpreted Language · Issue #7 · ninjaaron/administrative-scripting-with-julia · GitHub](https://github.com/ninjaaron/administrative-scripting-with-julia/issues/7)

His contention (and I hope he will correct me if I misrepresent his position) is that Julia has a compiler and most code is compiled to machine instructions at runtime. Therefore, it is misleading and actually incorrect to call Julia interpreted.

My contention is that Julia has an interpreter, this interpreter is running in every Julia process, and that numerous other implementations of interpreted languages use JIT compilers to produce machine code at runtime (albeit not as extensively or to as great an effect)

I’m interested to hear what other Julia users and especially language maintainers think about this topic.

---

<div class="post-metadata">

### Author: ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)
#### Post date: [September 27, 2023, 8:11am UTC](https://discourse.julialang.org/t/is-it-wrong-to-call-julia-interpreted/104296/2 "2023-09-27T08:11:37Z")

</div>

> [@ninjaaron](#):
>
> albeit not as extensively or to as great an effect

I think this is key to why people classify languages with both compilation and interpretation as one or the other. Your argument that Python is interpreted but has compiling implementations muddles the question; it’s not really the _language_ but the _implementation_ that can be classified as one or the other. PyPy JIT-compiles to machine code, CPython interprets compiled bytecode. The Numba package can be used with CPython to incorporate limited JIT compilation into an otherwise interpreted implementation. Julia’s (only?) implementation is compiled by that logic, no question; the compiler is what runs our code, and unlike in CPython, the interpreter has a minor role.

Your opinion that interactivity is a property of interpreted languages is not common, they’re considered orthogonal concepts, even if correlated. You could change CPython to a non-interactive yet interpreted implementation, just take away the REPL and force people to run scripts in the terminal.

---

<div class="post-metadata">

### Author: ![oxinabox](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oxinabox/32/206603_2.png) [@oxinabox](https://discourse.julialang.org/u/oxinabox)
#### Post date: [September 27, 2023, 8:37am UTC](https://discourse.julialang.org/t/is-it-wrong-to-call-julia-interpreted/104296/3 "2023-09-27T08:37:33Z")

</div>

Practically speaking, julia is a compiled language because its performance characteristics match that of a compiled language.  
Albeit a very late one, with a very fast compiler (at least compared to say a C++ compiler).  
The time before you can start running julia code is nontrivial, you need to wait for it to compile before it can be run.  
Once it runs its really fast – julia has an optimizing compiler, it rewrites your code to be semantically identical but faster, including e.g. deleting code that has no user visible effects beyound taking time to run (a lot of compilers don’t do this, and no interpreters do this).

Less pratically speaking, I have heard it said that the julia compiler runs an bstract interpretation of the source code, which happens to output compiled code as a side effect.  
Which is catchy but idk that it is _that_ meaningful.

---

<div class="post-metadata">

### Author: ![ninjaaron](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ninjaaron/32/6392_2.png) [@ninjaaron](https://discourse.julialang.org/u/ninjaaron)
#### Post date: [September 27, 2023, 8:38am UTC](https://discourse.julialang.org/t/is-it-wrong-to-call-julia-interpreted/104296/4 "2023-09-27T08:38:43Z")

</div>

> [@Benny](#):
>
> Julia’s (only?) implementation is compiled by that logic, no question; the compiler is what runs our code, and unlike in CPython, the interpreter has a minor role.

Julia’s only implementation is also interpreted. These two things are not mutually exclusive.

(also, in the name of pedantry—we’re all nerds here—I want to point out that compilers don’t run code at all, but this is not really your point, I understand)

---

<div class="post-metadata">

### Author: ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)
#### Post date: [September 27, 2023, 8:41am UTC](https://discourse.julialang.org/t/is-it-wrong-to-call-julia-interpreted/104296/5 "2023-09-27T08:41:33Z")

</div>

> [@ninjaaron](#):
>
> Julia’s only implementation is also interpreted.

CPython is also compiled, but nobody calls it a compiled implementation or even compiled-then-interpreted. It’s a misleading classification, nothing we can really do about it, but it does have a logic to it that puts Julia in the compiled camp.

---

<div class="post-metadata">

### Author: ![ninjaaron](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ninjaaron/32/6392_2.png) [@ninjaaron](https://discourse.julialang.org/u/ninjaaron)
#### Post date: [September 27, 2023, 8:46am UTC](https://discourse.julialang.org/t/is-it-wrong-to-call-julia-interpreted/104296/6 "2023-09-27T08:46:28Z")

</div>

> The time before you can start running julia code is nontrivial, you need to wait for it to compile before it can be run.

`--compile=min` can be used to avoid this startup time because it uses the interpreter more extensively. You don’t _need_ to wait for the Julia compiler. You just get more optimized code if you do, so it’s the default.

> deleting code that has no user visible effects beyound taking time to run (a lot of compilers don’t do this, and no interpreters do this).

Some interpreters actually do do this. Specifically, this is a feature of Python 3.12 which they call “tier 2 optimization”. It does inlining and eliminates redundant bytecode, among other things.

---

<div class="post-metadata">

### Author: ![jar1](https://avatars.discourse-cdn.com/v4/letter/j/c0e974/32.png) [@jar1](https://discourse.julialang.org/u/jar1)
#### Post date: [September 27, 2023, 8:50am UTC](https://discourse.julialang.org/t/is-it-wrong-to-call-julia-interpreted/104296/7 "2023-09-27T08:50:25Z")

</div>

In a normal program with definitions and a single top-level call what actually gets interpreted?

---

<div class="post-metadata">

### Author: ![ninjaaron](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ninjaaron/32/6392_2.png) [@ninjaaron](https://discourse.julialang.org/u/ninjaaron)
#### Post date: [September 27, 2023, 8:58am UTC](https://discourse.julialang.org/t/is-it-wrong-to-call-julia-interpreted/104296/8 "2023-09-27T08:58:06Z")

</div>

[This bit on Julia’s execution model](https://docs.julialang.org/en/v1/devdocs/eval/#Julia-Execution) indicates that some code is indeed interpreted on every run. Specifically, all top-level statements.

“heuristics” are used to decide if other bits of code are interpreted or compiled. The code is [here](https://github.com/JuliaLang/julia/blob/master/src/toplevel.c)

---

<div class="post-metadata">

### Author: ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)
#### Post date: [September 27, 2023, 8:58am UTC](https://discourse.julialang.org/t/is-it-wrong-to-call-julia-interpreted/104296/9 "2023-09-27T08:58:09Z")

</div>

> [@ninjaaron](#):
>
> Specifically, this is a feature of Python 3.12 which they call “tier 2 optimization”. It does inlining and eliminates redundant bytecode, among other things.

Is this correct? For one, 3.12 is not out yet, and for another, tier 2 optimization is said to be planned for [3.13](https://github.com/faster-cpython/ideas/blob/main/3.13/README.md). I also haven’t heard of generalized inlining happening in CPython, in fact [this PEP from this year](https://peps.python.org/pep-0709/) outright states it’s “near-impossible” in the general case where functions can be changed (and Python doesn’t do method invalidations like Julia). I have observed CPython doing limited constant folding and dead code elimination when compiling to bytecode.

> [@ninjaaron](#):
>
> Specifically, all top-level statements.

Sure, but even there the calls are invoking compiled code, so the interpreter does very little.

---

<div class="post-metadata">

### Author: ![ninjaaron](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ninjaaron/32/6392_2.png) [@ninjaaron](https://discourse.julialang.org/u/ninjaaron)
#### Post date: [September 27, 2023, 9:05am UTC](https://discourse.julialang.org/t/is-it-wrong-to-call-julia-interpreted/104296/10 "2023-09-27T09:05:54Z")

</div>

Release candidates are out, so the interpreter at least exists. It may be that I said too much about tier 2 optimizations being in 3.12. This was my impression from my reading, but it may be that I misunderstood. In any case, as you said, some dead code elimination is already in Python.

As far as I understand, there are some runtime checks to make sure the code is on the “happy path” and it uses the inlined code if it is. It’s the normal kind of stuff that every tracing JIT does, just without the JIT.

_edit: I check some docs and I was definitely wrong about tier 2 optimizations in 3.12. There were some other optimizations slated for 3.12 which would eliminate some redundant bytecode, but it appears these were also postponed. Most of the improvements this time were around the object representation._

---

<div class="post-metadata">

### Author: ![sdanisch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sdanisch/32/1406_2.png) [@sdanisch](https://discourse.julialang.org/u/sdanisch)
#### Post date: [September 27, 2023, 9:22am UTC](https://discourse.julialang.org/t/is-it-wrong-to-call-julia-interpreted/104296/11 "2023-09-27T09:22:07Z")

</div>

> “heuristics” are used to decide if other bits of code are interpreted or compiled. The code is [here](https://github.com/JuliaLang/julia/blob/master/src/toplevel.c)

This is how most JIT compilers work:

 ![image](https://global.discourse-cdn.com/julialang/original/3X/3/9/3950a7b1d94a1908b4c52e20fdfdb26c69a97ff4.png)

> **[Just-in-time compilation](https://en.wikipedia.org/wiki/Just-in-time_compilation)**
>
> In computing, just-in-time (JIT) compilation (also dynamic translation or run-time compilations) is compilation (of computer code) during execution of a program (at run time) rather than before execution. This may consist of source code translation but is more commonly bytecode translation to machine code, which is then executed directly. A system implementing a JIT compiler typically continuously analyses the code being executed and identifies parts of the code where the speedup gained fro JIT c...

Still, JIT is its own category of how to run code, and not just “another interpreter”.

And compared to other JIT languages, Julia has a particularly simple interpreter with a much simpler heuristic, which is used much less then in other JIT languages (which is sadly also the reason, that we have those horrible compile time latency problems).

Because of that, I’d categorize Julia much closer to a compiled language than most other JIT compiled languages - and therefore even further from any interpreted language.

---

<div class="post-metadata">

### Author: ![ninjaaron](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ninjaaron/32/6392_2.png) [@ninjaaron](https://discourse.julialang.org/u/ninjaaron)
#### Post date: [September 27, 2023, 9:49am UTC](https://discourse.julialang.org/t/is-it-wrong-to-call-julia-interpreted/104296/12 "2023-09-27T09:49:40Z")

</div>

The actual heuristics Julia uses are also very different from other JITs. I don’t think Julia does profiling, but someone can correct me if I’m wrong. My understanding was that it was more about inference and inferability (sounds like a title for a Jane Austen novel…), but it’s been a while since I kept up with the specifics of the Julia compiler. My understanding, in any event, is that this snippet from wikipedia is not true for Julia.

---

<div class="post-metadata">

### Author: ![ShalokShalom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/shalokshalom/32/52462_2.png) [@ShalokShalom](https://discourse.julialang.org/u/ShalokShalom)
#### Post date: [September 27, 2023, 9:57am UTC](https://discourse.julialang.org/t/is-it-wrong-to-call-julia-interpreted/104296/13 "2023-09-27T09:57:04Z")

</div>

Strictly speaking:

The last remaining regular programming language that did what was commonly known as interpreting code, was Ruby 1.8.

Other languages, that still do that, are not considered regular programming languages.  
Bash, is an example.

That is, _line by line_ interpreting.

All modern languages do some form of compilation.  
The degree, to which they do that, differs.

Still, a lot of people use the term interpreting for anything, that doesn’t compile directly to machine code.

---

<div class="post-metadata">

### Author: ![Raf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raf/32/3383_2.png) [@Raf](https://discourse.julialang.org/u/Raf)
#### Post date: [September 27, 2023, 10:20am UTC](https://discourse.julialang.org/t/is-it-wrong-to-call-julia-interpreted/104296/14 "2023-09-27T10:20:50Z")

</div>

Julia doesn’t use many JIT heuristics, it mostly just compiles what it parses.

We have to manually call `Base.invokelatest` to _stop_ julia from trying to compile through code, say in an expensive to compile but rarely-used branch.

Yes, branches deep in your call stack that will not be used are usually _still compiled_ unless the compiler can prove from the types that they are not used. Its pretty far from being interpreted.

---

<div class="post-metadata">

### Author: ![tecosaur](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tecosaur/32/23206_2.png) [@tecosaur](https://discourse.julialang.org/u/tecosaur)
#### Post date: [September 27, 2023, 10:58am UTC](https://discourse.julialang.org/t/is-it-wrong-to-call-julia-interpreted/104296/15 "2023-09-27T10:58:42Z")

</div>

```julia
julia> @code_native 1 + 1
	.text
	.file	"+"
	.globl	"julia_+_143" # -- Begin function julia_+_143
	.p2align	4, 0x90
	.type	"julia_+_143",@function
"julia_+_143": # @"julia_+_143"
; ┌ @ int.jl:87 within `+`
# %bb.0: # %top
	push	rbp
	mov	rbp, rsp
	lea	rax, [rdi + rsi]
	pop	rbp
	ret
.Lfunc_end0:
	.size	"julia_+_143", .Lfunc_end0-"julia_+_143"
; └
                                        # -- End function
	.section	".note.GNU-stack","",@progbits

```

Ah yes, the good 'ol Julia interpreter.

---

<div class="post-metadata">

### Author: ![ninjaaron](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ninjaaron/32/6392_2.png) [@ninjaaron](https://discourse.julialang.org/u/ninjaaron)
#### Post date: [September 27, 2023, 11:02am UTC](https://discourse.julialang.org/t/is-it-wrong-to-call-julia-interpreted/104296/16 "2023-09-27T11:02:29Z")

</div>

I guess the mental disconnect for me is that everyone is going to great lengths to demonstrate that Julia is compiled when I’m not denying that.

Its execution model involves an interpreter and a compiler. It is interpreted and compiled. These things can coexist in my mind. Why am I wrong?

---

<div class="post-metadata">

### Author: ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)
#### Post date: [September 27, 2023, 11:05am UTC](https://discourse.julialang.org/t/is-it-wrong-to-call-julia-interpreted/104296/17 "2023-09-27T11:05:10Z")

</div>

> [@ninjaaron](#):
>
> Its execution model involves an interpreter and a compiler. It is interpreted and compiled. These things can coexist in my mind. Why am I wrong?

then don’t call Julia interpreted? Say it’s JIT-ed is perfectly fine and just leave it at that

---

<div class="post-metadata">

### Author: ![tecosaur](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tecosaur/32/23206_2.png) [@tecosaur](https://discourse.julialang.org/u/tecosaur)
#### Post date: [September 27, 2023, 11:07am UTC](https://discourse.julialang.org/t/is-it-wrong-to-call-julia-interpreted/104296/18 "2023-09-27T11:07:31Z")

</div>

Because the vast, vast majority of Julia code is executed via LLVM compilation. The interpreter as I understand it is a shim to make bootstrapping easier and slightly reduce some of the JIT tradeoffs — not a major feature of the language design.

At a glance, I must admit this looks like you’ve seized upon a relatively minor detail and are using it to make much more sweeping statements than are actually supported.

The core devs have previously described Julia as a “Just ahead of time” compiled language for good reason.

---

<div class="post-metadata">

### Author: ![sdanisch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sdanisch/32/1406_2.png) [@sdanisch](https://discourse.julialang.org/u/sdanisch)
#### Post date: [September 27, 2023, 11:08am UTC](https://discourse.julialang.org/t/is-it-wrong-to-call-julia-interpreted/104296/19 "2023-09-27T11:08:24Z")

</div>

> Its execution model involves an interpreter and a compiler.

Because that’s pretty close to the definition of a JIT compiled language, which is it’s own execution category - which behaves significantly differently from an interpreted language…  
So anyone hearing “interpreted” won’t think of “ah yes, a JIT compiled language”, so people will attribute the wrong attributes to Julia if you call it interpreted (E.g. no compile times, slow performance, which just doesn’t fit Julia).

_edit_:  
You are correct, that the precise categorization is pretty hard to nail down because of all those subtleties involved, but calling it interpreted without mentioning Julia’s JIT is just misleading.

---

<div class="post-metadata">

### Author: ![tecosaur](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tecosaur/32/23206_2.png) [@tecosaur](https://discourse.julialang.org/u/tecosaur)
#### Post date: [September 27, 2023, 11:10am UTC](https://discourse.julialang.org/t/is-it-wrong-to-call-julia-interpreted/104296/20 "2023-09-27T11:10:27Z")

</div>

Something else I notice in the github repo, you say

> it compiles to LLVM bytecode at runtime

it’s probably worth stating that with the changes in the last few Julia releases, most package code is actually compiled earlier. That’s the whole reason why we’ve now go `.so` files as well as `.ji` now.

[Next page](https://discourse.julialang.org/t/is-it-wrong-to-call-julia-interpreted/104296.md?page=2)
