How an MIT research project became the Julia programming language
news.mit.edu
news.mit.edu
There's lots to like, but I think the thing I love most about it and find it so interesting is that it's almost uniquely good at taking a piece of code and transforming it's meaning in various ways, and has so many tools for doing so. There's
* Multiple dispatch allowing very flexible writing of generic code, and multiple dispatch isn't some tacked on, opt-in extra. Every function in the language is overloadable, and there's no performance penalty for using multiple dispatch
* Parametric typing allows for a huge amount of abstraction over common 'base' types
* Lispy macros let you do metaprogramming that changes the meaning of a piece of syntax
* Generated functions let you intervene at compile time and lets you essentially take over the compilation pipeline and customize the code generation for any given input type signature
* The abstract interpreter interface which lets one essentially take over the compiler and customize your code generation and analysis passes to your heart's content. This is used for instance to support GPUs and automatic differentiation as package offerings.It's a shame. So hard to recommend it to anyone outside of an academic environment.
If you reach into unstable language internals, yes there is a lot of churn. If you use public language interfaces, the language has been extremely stable for a long time.
The ecosystem quality and quantity depends a lot on what you're trying to do. If you're far away from numerics, then yeah, you will struggle a lot more. E.g. I wouldn't want to do web-dev in julia, but if your software product involves needing to solve an ODE, or a lot of linear algebra, I wouldn't want to be anywhere else.
The ode stuff is cool, but when we reached for it none of the demos ran on recent versions. It was almost like the groups working on it either intentionally made it so you couldn't keep up with them or that again everything was built on a bed of sand.
I agree writing linear algebra in Julia is clean. That said, the cost for adding a few "." Chars or calling a library in any other language far outweighed the costs for trying to buy into the language itself.
I didn't even know you could do web dev in Julia. I don't want to know what that looks like.
That certainly has not been my experience with the language since 1.0
> weird issues with basic transitive dependencies breaking after a minor version bump to the language.
Not sure what exactly this is referring to, but I suspect it was some bugs that happened when some stdlib packages were taken out of the sysimage and started being treated more like regular packages which are pre-installed.
For a couple minor versions, if you instantiated an manifest from a previous version that used some stdlibs, it could error out. That was indeed unfortunate and IMO should not have been released as such, but it's since been fixed.
I will point out though that officially, you are not supposed to use the same manifest across versions.
> didn't even know you could do web dev in Julia. I don't want to know what that looks like.
There's actually some rather cool stuff happening in that space, but yeah it's early days.
It's really not early days. The language is about 15 years old. That excuse gets really tired.
It's crazy to me how every person posting positively about Julia has the same tactics. They don't change year after year. They try to draw people in only to find it's a Trainwreck or a waste of time.
I just hope my comments save a start up a few million dollars or a curious hobbyist 5 months of their free time.
The manifest thing is a good example of a hard situation. You have a file format that's not designed to be portable across versions, but the usage pattern around it heavily encourages that, so of course it gets used across versions and bad stuff happens. I'm sure theres also some other examples like this one can pull up.
Of course there's cases where we should be doing better. I'm just also saying that this isn't the only experience out there, and the negative experience you're reporting isn't my experience.
> It's really not early days. The language is about 15 years old. That excuse gets really tired.
Please don't twist my words. I was responding to what you said about webdev, and I said there was some interesting things happening in that space, but still early days. I was explicitly referring to the webdev ecosystem being immature, not the language.
I think things have come down to a much more reasonable place though now.
It is a lot of fun to start from an empty file, add maybe an import LinearAlgebra, and develop things like a convolutional neural network or a Markov-chain Monte Carlo algorithm completely from scratch. And then it is very rewarding to have such a program be fast enough (looking at Python here) to train on the MNIST dataset or find reasonable estimates for critical exponents.
I am not sure there are languages better suited than Julia for these kind of things.
https://raw.githubusercontent.com/mech-lang/mech/codex/taich...
Compared against Taichi, Halide, Futhark, Rust', Lua, LuaJIT, Numpy and pure scalar Python. Julia holds up great it can run basically as fast as you'd like! (These are not apples-to-apples comparisons, picture this as a basket of fruit)
'The Mech results should be understood to be a lower bound on how Rust would perform.
I added PyPy and Mojo.
PyPy performs valiantly compared to Cpython -- even better than LuaJIT. I'm sure someone skilled at writing it could do an even better job.
I measured 3 Mojo implementations. The first is a dynamic implementation, it performs like a typical dynamic language. Then when you use Mojo's SIMD intrinsics you can get compiled-tier performance in line with Futhark, Julia, Rust etc.
Then if you use their Max toolchain you can compile Mojo directly to Metal, with performance at the top of the stack (for the amount of money Qualcomm paid they'd better be there!).
The Rust / Mech version was rewritten to put it back on top, but the unchecked test is about equal. Basically if a toolchain can emit direct Metal code there's nothing preventing equal performance it seems, so the magic is in the compiler. Although there is some abstraction overhead depending on how you get there e.g. going wgpu->Metal has a penalty over going directly to Metal.
The big disclaimer again is that all of these measurements should be taken as lower bounds for one algorithm on one machine. I'm sure expert performance engineers could do better.
(I last tried Julia a few years ago; perhaps this has been improved since?)
The pre-compiled binary outputs are much smaller, and load a lot faster. =3
On the flip side, the rise of agentic coding means that the library/batteries mismatch against python will largely stop mattering. It should be very easy to have an agent implement large libraries -- especially if they can be just a translation from one language to another (esp. one with with better primitives!)
https://docs.julialang.org/en/v1.13-dev/manual/workflow-tips...
https://www.youtube.com/watch?v=kc9HwsxE1OY
The biggest drawback of the language in my view is that Julia is an LLVM toolchain "pretending" to be an interpreted language (it is, technically), this often leaks as very slow first execution latency (and almost forces you to keep the interpreter open instead of just calling it on the file you're editing).
There's some exciting work that was presented in Juliacon 2026 though on an upcoming tiered JIT and this should reduce latency a lot, as you suggest.
It's kinda one of those mid-hanging fruits that has been known about for a long time, but not seriously tackled till now.
Julia seems to sit in this area between Matlab and Fortran where I can’t ever find a reason to learn it instead of just using one of the other two. But people seem to love it (and the GPGPU support sounds like it is good?) so I should probably just make up a reason.
I'm sure there are lots of smart people who found that the language didn't suit their needs. there are also lots of smart people who love using Julia. both things can be true at the same time.
There are some real issues in the ecosystem. Specifically there is a high proportion of “gradware” because much like other scientific languages there is a high proportion of graduate students doing their projects and then moving on.
The language also encourages relying on packages which can break. But juliaup makes this easy enough to solve by downgrading.
It’s true that MIT and a few other organizations have more influence than others simply because they employ more developers with time/scope to work on the language. Just like every programming language.
But this becomes less true all the time. And most of the direction that is “paid for” is an unadulterated good: JuliaC ahead of time compilation has been requested for over a decade and has made enormous progress.
I think you misunderstood my sentiment. That's okay. In a few years you'll probably be where I am now. Setting a reminder for 2 years.
When the criticisms relate to correctness bugs, I don't think 'try it out and see how you like it' is sufficient. I might love the syntax and the design and so on, but that doesn't tell me whether I'm going to run into serious bugs some time in the future.
It got a little long and meandered a bit, but I think there's some good, nuanced discussion there.
> I think there’s also a mindset split, some people just like to have things more strict and avoid bugs by having their compiler proof everything, and others like more freedom and are fine with occasional mishaps.
> Just for the fun of it, I put claude on Python, and it also found some eye watering correctness issues (to be fair, I haven’t taken the time to verify and judge them, but it seems like that’s a similar situation for the Julia version)
I say "self-soothe" because if the intention were to better understand the correctness situation, presumably one would at least want to evaluate the output before declaring it "eye watering". And then even if the output was real, it would be better to report it to the affected Python projects instead of using it as an excuse to downplay problems in Julia.
But most of the supposed "bugs" seem like totally fine/reasonable behaviors to me, often for clearly nonsensical inputs. Seriously, `np.array([1, 'two', 3.0])`? That's not a bug, the behavior is clearly documented on numpy.org, but really no matter what Python does with that, it's not comparable to issues like `prod([Int8(100), Int8(100)]) != prod((Int8(100), Int8(100)))` from that post about Julia. Which again the linked Discourse post downplays as "freedom and occasional mishaps".
1. random.choices(['a','b','c'], weights=[-1,5,1], k=10000)
Negative weight on 'a' silently shifts
Python docs say, "Weights are assumed to be non-negative and finite." Garbage in, garbage out. 2. random.choices(['a','b','c'], cum_weights=[5,2,7], k=10000)
Non-monotone cum_weights makes 'b' unselectable.
...Those weights aren't cumulative, which the docs say they should be. Again, garbage in, garbage out. 3. statistics.fmean([1,2,3], weights=[-1,1,1])
“Mean” of three values in [1,3] returns 4 — outside the convex hull.
This is just straight-up mathematically correct behavior. It preserves linearity. It fits the commonly accepted definition of weighted mean as `(w1*x1+w2*x2...)/(w1+w2...)`.The LLM fabricated a fake/idiosyncratic definition of weighted mean in order to claim it's a bug, because it was instructed to come up with bugs.
4. json.dumps({1: 'a', '1': 'b'})
Produces invalid JSON with duplicate keys; round-trip silently drops one entry.
Again, documented behavior/GIGO. Docs say, "loads(dumps(x)) != x if x has non-string keys." 5. urlparse('http://example.com/?').geturl()
Trailing ? (empty query) and # (empty fragment) silently stripped
This is literally just what geturl() is supposed to do. It's the whole point. Docs say "empty parameters, queries, and fragment identifiers will be removed". The LLM is claiming that geturl()'s primary intended purpose is a bug.So all of these "eye watering correctness issues" so far seem to be either (1) straight-up correct, or (2) doing things Python explicitly tell you not to do. Same deal with the Numpy "bugs", AFAICT, as I touched on in my previous comment.
In fact, I would venture that we all know those Python bugs are fake, but (unfortunately) the Julia ones aren't. Because the Julia bugs mentioned by Yuri were reported to the Julia bug tracker, and eventually fixed. Whereas if you really thought these are real bugs in Python, then (IMO) you should be reporting them to the Python tracker, not getting mad at me for doubting them.
Moreover, even if they were real bugs in Python (which they aren't), bugs existing in Python still wouldn't change the situation for Julia. The Discourse user who posted it still admitted that they didn't even take the time to verify them.
Surely you must realize how bad it makes Julia look, when its users fling LLM slop to attack Python in response to Julia's issues being brought up? A constructive project should instead talk about what's been done and planned to improve Julia's situation, not tell lies to drag Python down. I liked Julia when I tried it! The JIT plus multiple dispatch is so unique. But this so isn't the way.
>>> x = [2*53, 2*53 + 2]
>>> statistics.covariance(x, x) 4.0
>>> statistics.variance(x) 2
```
python has plenty of bugs like these too. is this example also "LLM slop" ? I think it's frankly delusional to somehow believe that these issues are unique to Julia.
exactly. and the same is true for many of the bugs that have been presented as indictments of Julia. but when the same is said of those, the community is called "defensive." so it's a lose-lose.
What's been presented as an indictment of Julia (in Yuri's own post and after) is the fact that members of the Julia community have vocally downplayed problems and played the victim when quality concerns have been raised, as I think you're doing. Do you want to convince everybody you've "won" "a lose-lose"? Or do you want to write correct programs?
I like Julia, the language and the tech. I really hope this hostile attitude towards criticism and growth fades eventually, because I'd like to be able to use and trust it at some point.
> If anyone really believes the Python bugs are real, they should report it to Python
I have reported several bugs, both to Python and to Julia.
I'm not going to engage further in this thread, but if you want to continue discussion I'd be happy to chat somewhere else that's a little less clunky
I wouldn't say this is true really. Julia does have some unique properties which cause these issues other languages just sidestep. The dynamic dispatch system is really magical when it works, but it's the source of much of the consternation you see here in this thread, and the reason it persists despite individual bugs being fixed. The problem is the "bugs" in this case aren't really as such; they're not wrong code, they are violations of silent contracts.
The whole magic of dynamic dispatch is you write Library A and Type B, and they "just work" together without having to know about one another. This is of course very powerful and so people have been very enthusiastic when wielding it.
But with great power comes great responsibility; when using libraries and types that weren't meant to work together, one of those types might violate a silent contract in the library. This would be fine if the error could be caught at compile time, but it happens in the form of numerical correctness issues, so they don't even present as actual errors.
The most obvious example of this is where Julia allows for arbitrary arrays and two things expecting different bases come into contact. This is something that's just not possible in other languages, so they're not exposed to this class of bugs.
So maybe you can harden and make explicit some of these contracts, or put up warning signs, or add some lints, and thus "fix bugs"; but they keep coming back because the dynamic dispatch system assures it due to the combinatorial explosion of interactions it incurs. I'm very interested in how Julia will solve this issue going forward.
> “With Dyad 3.0, you can upload data and design documents and the system will design an entire aircraft for you,” Shah says
Some languages are less permissive, and have a culture of searching harder for corner cases and dealing with them than others, that is true. I would expect to find less cases like this in Rust, but more cases like this in Python.
Julia is an extremely flexible and permissive language, which means that generic code needs to be written carefully and contracts between interfaces need to be thought through.
When you combine funky package types like OffsetArrays with functions from a package where the authors didn't think about OffsetArrays, bad things can happen. Those things were then reported and the community has learned a lot about how to deal with those sorts of things.
I'm sure an AI agent can crawl through and find a new big list of weird bugs in julia, but that's true even of a language like Rust.
My expectation is that when I think I've found a bug in the programming language implementation I'm using, it's actually me that's mistaken (or at least that language lawyers consider me to be mistaken). Hearing about someone who has encountered multiple bugs (in regular use, rather than running a fuzzer or being directly involved in implementing the language) makes me very wary.
Which, apparently, sat in the standard library for almost four years after it was introduced before it was fixed. [1]
Even if there was some merit to your argument, I would still find the attitude disqualifying. While it may be technically true that all programming languages have bugs, software and software communities for numerical computing should take responsibility and treat those bugs seriously, not downplay them by pointing to the fact that other software probably has bugs too.
FWIW I don't have a horse in this race. I've used both before, and I currently make money using neither. I liked Julia. I find that article concerning. And I find the attempts by Julia users to discredit that article in this thread, without addressing its substance, even more concerning and disappointing.
Well, bugs can be fixed. But ideally not by a culture that dismisses them as inevitable or unimportant.
[0] https://github.com/JuliaLang/julia/issues/39183
[1] https://github.com/JuliaLang/julia/blob/26f2333686ce90331548...
Scanning the language it doesn't strike me at all as "simple."
https://juliahep.github.io/Hands-on-Julia-for-particle-physi...
BASIC "made simple things easy, and hard things impossible..."
Julia is the first language I've seen in years that implicitly abstracts parallelism cleanly. =3
What do you mean by “implicitly”? A single dot is short but not implicit.
I also do not see https://docs.julialang.org/en/v1/manual/parallel-computing/ s mention that such map calls (can) run on multiple threads.
https://cuda.juliagpu.org/stable/tutorials/introduction/
But I agree the shared memory Distributed Computing part of Julia still needs a lot of work. Spawning binary image instances over ssh is too fragile. =3
I agree the change is simple, and didn’t question that; I questioned the “implicitly” in the claim
> Julia is the first language I've seen in years that implicitly abstracts parallelism cleanly.
(Aside: I think scala does this even nicer. There, adding `.par` can make code run multi-threaded. See https://docs.scala-lang.org/overviews/parallel-collections/o...)
I hope one day Julia does a cleaner version of Scala or Erlang/Elixir OTP languages. Clustering on OTP was certainly an area even seasoned gray beards tried to avoid. =3
Which, for anyone who doesn’t know Matlab, is the solve operator; it calls out to a big algorithm that chooses an appropriate solver given the operands, reducing large programs down to a single line.
I still like Julia more, as it is fun. =3
Secret mode: ./julia —-lisp
From my experience, grad students use Julia when their PI thinks a new programming language will help differentiate their next NSF proposal among vast funding requests.
imo this isn't really a good summary. Julia is one of the 3 languages to have done an exascale HPC run https://arxiv.org/pdf/2309.10292v1 (Fortran and C are the other 2). Some parts of the compiler are written in c++ (the llvm interface), but doing codegen with llvm is much more similar to C/Rust/Fortran than R/Matlab
https://docs.sciml.ai/ModelingToolkit/stable/tutorials/nonli...
If you've used something like SciPy or symbolic Matlab or Maxima or whatever, it always feels like I'm very carefully converting the equations I've scribbled down on paper into code and always a little nervous that I've accidentally split one variable into two names or used the wrong equality operator and am going to end up hating life, or accidentally assigned x = sp.Symbol("y") somewhere.
The Julia version is just plain beautiful. There's no ceremony other than the three @parameters, @variables, @mtkcompile macros. It lives in its own little world where you don't have to constantly watch your back to make sure you haven't duplicated a symbol somewhere.
When I first read about Julia, I was really amazed - especially the type system with its multiple dispatching and not automatically converting between types (e.g., between integers and floats). Though, I do not know, how Julia is today.
Today, I use Python instead of Octave (or Julia) - just because it has a large ecosystem and is widely adopted. An additional advantage is that Python has much better OOP features than Octave had back then.
However, I wished Julia had the status that Python has today.
Some of the lower-level APIs like those for concurrency were quite poorly thought out though, at least when I last used Julia. Condition variables don't have equivalent of pthread_timed_wait. Condition variables and channels APIs are not well integrated, design wise. I found so many such issues that it convinced me Julia wasn't general purpose enough. It felt like the features were a bit half-baked and had been hacked together by someone who knew their value but lacked the deep experience/knowledge to pull them all together into a single cohesive vision. Same issues as python, POSIX, etc.
If you are an EE that wants to remain employed... than make sure you have documented hours with C/C++, Verilog on Zynq, and ladder logic for Rockwell automation products.
Best of luck =3
Zynq is super cool and strongly agree that it’s worth looking into, although starting with just a naked little FPGA board might be more approachable. On the other hand, if you’re sufficiently capable with both embedded Linux and Verilog to successfully implement a piece of hardware in the PL and build a driver and userspace for it in the PS, you’re definitely miles ahead of most candidates.
TI/Octavo chips with the PRUs are kind of similar; not that they’re asynchronous logic like the Zynq PL is, but they’re similarly powerful as far as doing hard real-time deterministic jobs driven by an attached Linux core.
https://www.analog.com/en/resources/evaluation-hardware-and-...
> I’ve never touched ladder logic
Depends what kind of work you do, as product development is different from factory journeyman. I don't see a chaotic market supporting many domestic product development projects for the next 2 years. =3
I started using python for various engineering analysis problems around 2001 and I loved it for how fast (due to minimal boilerplate and automatic memory management) I could code up some thought relative to using C or Java. I could tackle problems in ways I just wouldn't have tried otherwise because I couldn't afford the longer time to write it in other languages. However, for problems which needed speed, of course it bogged down.
I started using Julia for ODE stuff in 2018 or 2019 and was thrilled with the speed and conciseness. As others have said, it looks much more like math and a lot of better design choices were made.
Python obviously has a much larger ecosystem and probably always will, and it will remain a safe choice, but you don't set yourself apart by doing the same thing as everyone else.
That rules it out to become a successor to Python. It sounds reasonable until you start interacting with other libraries.
I do know the attemp to justify it for Lua and I don't buy it.
It is better than your code, which is probably a low bar.
why so rude and adversarial, especially when so misinformed? AI code is better than 95% of engineers at this point.
I have yet to hear a good argument for why the answer to "How do I get the third element of this array?" should be `arr[2]`
> Both R and Julia have their core functions written in C++. Absolutely nothing new.
What on earth are you talking about? This is at least a novel claim. Some deep parts of julia's compiler are written in C++ but that's about it. Nearly everything in the language is written in julia itself.
The only significant foreign codebases in the language are
* LLVM
* OpenBLAS
* LibUV
all of which are extremely reasonable foreign things for a language to use (though we are gradually moving more and more of these things to the julia side)Ask a carpenter.
To get to the third pigeonhole in a racked series of one foot per pigeonhole unit you literally offset two feet from the origin.
In C (of course), arr[2] works as well as does 2[arr] as both are literally just syntactic sugar for arr+2
ie. The third pigeon hole begins after passing two whole pigeonholes.
I mean, that's an important low-level detail to know when you're working with assembly or doing pointer math, but it is not something that necessarily needs to be polluting the semantics of a high level language.
I find it much easier to think in terms of v[i] is the i-th element of my vector.
These sorts of things just feel like mental gymnastics people perform to post-hoc justify language quirks.
> but why are you trying to think about a list of elements in terms of offsets from the origin
I don't try to think about them in this way - I do and have always thought about them in this way - in software terms for 50 years, in real world cut, saw, and hammer ways for over 60.
> I find it much easier to think in terms of ...
Which is the crux of the issue really, that's how you think.
> v[i] is the i-th element of my vector.
I think of V as the start of a row of elements.
V+0 is equivalent to V and naturally the start of the first element.
V+1 is the start of the row, plus one - the literal start of the second element.
I've always thought of V[i] as offsets, "jump overs" if you will.
It comes naturally for many that have worked with their hands on physical objects and worked with tape measures.
> but it is not something that necessarily needs to be polluting the semantics of a high level language.
Either way of thinking works - I spent decades going back and forth from Fortran to C, and people are free to make their high level languages however they wish - it's trivial to move from one to the other.
There are even some funky (or eyeball gouging) tricks done to preamble a data run with meta data, leading to V[-1] indexing being commonplace (in some domains)
I don't see a good argument though, I just see adaption to a quirky convention.
> Either way of thinking works - I spent decades going back and forth from Fortran to C, and people are free to make their high level languages however they wish - it's trivial to move from one to the other.
Here I agree. I have no real problem using a 0-based indexed language, I adapt to it quickly (or as you mention a -1 indexed language. Julia itself actually stores type-level metadata at the -1 index of a pointer to a mutable struct)
I just dislike when people try and turn every conversation about julia into "oh it's 1-based indexed so that disqualifies it", and act like 0-based indexing is some god-given most natural way to do all indexing.
Of course you do - you very likely didn't start programming in assembler.
You literally asked "How do I get to .." implying you wanting street instructions, distances, etc.
In assembler the third element begins literally and straightforwardly at the address base plus two (element widths).
That's not "a quirky adaption" is it? It's a dull pragmatic address of the start of the third element - the answer to the question you posed.
> Of course you do - you very likely didn't start programming in assembler.
I did not, and I do not think that conventions from assembler should influence basic ergnonomic design decisions of modern high-level langauges.
Indexes start at 1, offsets start at 0.
And offsets are the measurements that get you to an element - the question was explicitly phrased as "how do I get to" ...
Of course their sponsors demand it. So it is in the same place as Ruby: interesting but out of the question.