Is it wrong to call Julia interpreted?

which sweeping statements did you have in mind?

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.

Good note. I will update this.

edit: updated

1 Like

Also note that this package code is compiled to machine code, not bytecode.

1 Like

In my mind, a JIT-compiler is a popular strategy for implementing interpreted languages.

Apparently this mental model is not shared by anyone else in the Julia community.

I don’t think that’s a Julia community thing – pretty much everyone seems to agree “JIT != interpreted”

2 Likes

If you read the answers, you will see that some of them share my view.

edit: but certainly not all

Even “native assembly” is interpreted, by your CPU. If we want to get pedantic about it, EVERY programming language is interpreted :wink:

3 Likes

But not before being “compiled” to microcode, of course. :rofl:

@ninjaaron what is the interpreted vs. compiled line to you?

an interpreter runs code from source and a compiler converts source code into another form (often but not always machine instructions).

A compiler may be part of an interpreter in this paradigm

The meaningful distinction for me is interpretation vs. AOT static compilation. This is primarily a distinction in workflow and doesn’t tell anything about runtime behavior. Java does AOT static compilation, but the runtime behavior is similar to V8 or any other tracing JIT. Julia is (according to my mental model) interpreted, but the runtime behavior and compilation strategy is more similar to C++ and mainly relies on generating specialized code paths using type inference.

Even this distinction is fuzzy in some cases, since there is often caching of generated code, but if the cache invalidated when the source code changes, it more or less preserves the “interpreted workflow”.

There’s a distinction between interpreted and interactive. Julia is interactive and can parse compile and run new source code statements. But when most people say interpreted they mean there is some interpreter which is operating on the source code without generating new machine code. That’s not what Julia does.

Yes. Someone else has pointed out that, according the definition you presented—which seems to be the predominate definition in this community—there are no major programming languages which are interpreted anymore.

To me, it’s meaningful that you hand source code (in files or interactively) directly to the julia executable to be executed, but I guess this is not related to “interpretation” for most people here.

Ah, man! Beat me to it!

Dang it I had a draft going but was logged out by some maintenance…

Anyway, the thing I was going to say was that the distinction between interactive and interpreted has a long history of confusing people. Even in the 80’s and 90’s when almost all compiled languages were ahead of time static compilation (Fortran, C, Pascal, Modula etc) there was Common Lisp, which was fully interactive, but there were multiple compiled implementations. CMUCL for example had an interpreter which it would use to improve interactivity, but the compiler would kick in and it was ultimately very fast. I worked at a financial data processing company where they had a C program that took 8 hours to process 8 hrs of ticker feed (in 1999 or so) and would occasionally crash with typical C memory management corner cases etc (which was obviously pretty bad as we had one chance to re-run it overnight or be a day behind the curve). I implemented a program that took the same input and had the same output, in CMUCL, and after profiling and tuning it, it would process 8hrs of ticker feed in about 15 mins. It was definitely not interpreted. But, at the same time, it was fully interactive in that I could debug individual functions, and do Julia style bottom up development.

The thing was, other than Common Lisp, there were very few interactive languages which were compiled. So people confused “interpreted” and “interactive” because for most cases it was a distinction without a difference.

9 Likes

An argument against the “interpreted” label for Julia is that it only ever looks at the source/lowered code when it first encounters a method signature (or after that method has changed – only with Revise.jl?). It then compiles this to machine code and caches it. In that sense, JIT seems a more suitable label (in my layperson judgement).

@ninjaaron I think the main source of confusion is that you don’t distinguish the processing of bytecode from the processing of machine code. It’s actually the main point!

CPython is interpreted because it never makes a machine code version from the source code. Instead it interprets the bytecode.

C# and Java are not interpreted because they translate (just in time but it doesn’t matter) the source code to a machine code version, which is then executed.

With an interpreter, the work of bytecode interpretation will happen all over again when the same function is called again. With a JIT like C# or Julia, you actually have a machine code representation of the whole function, which can be executed directly by the CPU (edit: that’s basically the point made by @mikmoore ).

2 Likes

There is a very simple experiment you can do.

Find libjulia-codegen.so.1.9 and rename or temporarily relocate it. Likewise for libLLVM-14jl.so for good measure. These are usually in the lib/julia of a Julia install. I would just add .bak to the names. You might be able to do this more simply with the --compile=none command line option, but renaming the shared libraries will remove all doubt.

This will not tell you what is usually compiled or not, but it will demonstrate what can be done without a compiler on hand. This is partly possible because a considerable amount of code is compiled ahead-of-time.

Matlab is typically referred to as interpreted, despite also using a JIT compiler.

And what is wrong with just calling Julia an interpreted JIT compiled language?

1 Like

It’s not wrong that Julia is also interpreted, if you do:

julia --compile=no

The term “JIT complier”, i.e. compiler, should tell you it’s well compiled, not interpreted, usually considered opposites. But as brought up, a language is neither, just the implementaion, and Julia allows either, or in fact both.

It helps to know about: julia --help-hidden

then see:

–compile={yes*|no|all|min}
Enable or disable JIT compiler, or request exhaustive or minimal compilation

I used to often to --compile=min, since --compile=no was broken (and may still be). You would think “minimal compilation” would actually be none, and I think that’s true, both use the interpreter.

With packages precompiled by now, this option is getting less important (to know about). But not while this is the global option, there’s may be a local option for packages to choose this (though I likely misremember, I likely mixed up with the following) and optimization level. I’m not sure if any packages opt into the interpreter, it seems rather extreme, but opting into -O1 (or -O0, more extreme, seems not needed) has been helpful. E.g. Plots did that. Jeff made it happen, I believe the first package to do this 3 years ago, and I copies/suggested same for other packages:

That option (also @max_methods?) is I think likely getting less useful over time, i.e. with 1.9+ packages are precompiled to native code.

2 Likes

Folks can have strong opinions about terminologies and technical definitions. Julia can live in some gray areas that don’t quite fit some terms precisely.

This reminds me of the old homoiconicity and dependent types debates. Sometimes it’s easier to just not use a (potentially overloaded) descriptor and just describe the relevant behaviors instead.

11 Likes