If you need to deal with matrices Julia's built-in support for that kind of stuff is the best out of any language I've ever seen (and I've tried dozens of different languages). It's like having first-class numpy arrays without installing any third party packages, and the syntax is even more convenient than Python. The standard library is reasonably comprehensive (not quite as big as in Python or Ruby or Go, but it's usually more well-designed).
It is also an excellent language for messing about because the language and especially the REPL have tons of quality-of-life features. I often use it when I want to do something interactively (eg. inspect a data set, draw a graph, or figure out what's going on with an Unicode string, or debug some bitwise trickery).
What Julia is not great at is things where you need minimal overhead. It is performant for serious number crunching like simulations or machine learning tasks, but the runtime is quite heavy for simple scripting and command-line tools (where the JIT doesn't really get a chance to kick in).
Go is a total non-starter, it's not interactive at all. The competitors are things like Matlab, Mathematica, R or Python (with the right math libs). If you're weird you could use something like Haskell, APL or Lisp in this role, but you'd pay a hefty price in available libs.
In what situations would a non-interactive language be a non-starter? I have never felt that I missed having a REPL when coding C++ or Rust. The only reason it is even useful in python is that the type info is laughably bad, so you need to poke things interactivly to figure out what shape of data you should even expect.
(I'll take strong static typing every day, it is so much better.)
REPLs/notebooks are really nice in situations where you don't know what you want ahead of time and are throwing away 90% of the code you write, such as trying to find better numerical algorithms to accomplish some goal, exploring poorly documented APIs (most of them), making a lot of plots for investigating, or working a bunch with matrices and Dataframes (where current static typing systems don't really offer much.)
Yeah, this is a entirely different domain than what I work in (hard real-time embedded and hard real-time Linux).
Though poorly documented APIs exist everywhere, but they are not something you can rely on anyway: if it isn't documented the behaviour can change without it being a breaking change. It would be irresponsible to (intentionally) depend on undocumented behaviour. Rather you should seek to get whatever it is documented. Otherwise there is a big risk that your code will break some years down the line when someone tries to upgrade a dependency. Most software I deal with is long-lived. There is code I wrote 15 years ago that is still in production and where the code base is still evolving, and I see no reason why that wouldn't be true in another 15 years as well.
At least you should write tests to cover any dependencies on undocumented behaviour. (You do have comprehensive tests right?)
People working with math or stats are often in an explorative mode, testing different things, applying different transforms to the data, plotting variables or doing one-off calculations. You need some form of interactive session for that to be feasible, whether it is a REPL or a notebook. There actually is a C++ REPL just for this use case from CERN, because they have a ton of HEP C++ code that they want to use interactively.
On top of what others have said: In many situations the alternative to Julia isn't Go but C++ (or maybe Rust though its library support is lacking). E.g. if you are writing high-ish* performance algorithmic code that should also run on GPU. Julia also heavily prioritizes composability of libraries. And though that can be a source of bugs at times, there are things we are doing in Julia with one or two PhD students that would be practically impossible (as in require an order of magnitude more implementation work) in any other language.
My two cents: while Julia is arguably more complex than Go, it's type system and especially its data types (N-dimensional arrays, ...) make it way more suited anything that needs to process complex data, or do anything that's even closely related to geometry. `.|>` is wonderful and makes functional-like code easier, and that's just the tip of the iceberg, macros are also beautiful and absurdly useful. Also LLVM more often than not generates faster code than the Go backend, albeit the slowdown at startup in Julia programs is often a dealbreaker for small scripts and iteration in my experience
Also, the REPL. Julia's REPL is vastly better than any other language REPL, by far. Python's is good but Julia is way better, even as a calculator for instance, it has fractions and it is more suited for maths
Yeah, Julia's REPL deserves special attention as it allows to do the package management (by pressing "]"), look for the functions help ("?") and do shell operations (";") without leaving it.
We use Julia at our quant fund. We looked into it and several other alternatives 5 years ago as a more performant replacement for numpy/scipy/etc., and Go was one of the alternatives we considered, along with things like numba and writing C extensions.
Julia won for a very simple reason: we tried porting one of our major pipelines in several languages, and the Julia version was both the fastest to port and the most performant afterwards. Plus, Julia code is very easy to read/write for researchers who don't necessarily have a SWE background, while Go or C++ are not.
We started using Julia in the Research Infrastructure team, but other teams ended up adopting it voluntarily because they saw the performance gains.
Correct, but I would add: Julia is better than Python+NumPy/SciPy when you need extreme speed in custom logic that can’t be easily vectorized. As Julia is JIT-compiled, if your code calls most of the functions just once it won’t provide a big advantage, as the time spent compiling functions can be significant (e.g., if you use some library heavily based on macros).
To produce plots out of data files, Python and R are probably the best solutions.
Disagree on the last statement. Makie is tremendously superior to matplotlib. I love ggplot but it is slow, as all of R is. And my work isn’t so heavy on statistics anyway.
Makie has the best API I’ve seen (mostly matlab / matplotlib inspired), the easiest layout engine, the best system for live interactive plots (Observables are amazing), and the best performance for large data and exploration. It’s just a phenomenal visualization library for anything I do. I suggest everyone to give it a try.
Matlab is the only one that comes close, but it has its own pros and cons. I could write about the topic in detail, as I’ve spent a lot of time trying almost everything that exists across the major languages.
I love Makie but for investigating our datasets Python is overall superior (I am not familiar enough with R), despite Julia having the superior Array Syntax and Makie having the better API. This is simply because of the brilliant library support available in scikit learn and the whole compilation overhead/TTFX issue. For these workflows it's a huge issue that restarting your interactive session takes minutes instead of seconds.
I recently used Makie to create an interactive tool for inspecting nodes of a search graph (dragging, hiding, expanding edges, custom graph layout), with floating windows of data and buttons. Yes, it's great for interactive plots (you can keep using the REPL to manipulate the plot, no freezing), yes Observables and GridLayout are great, and I was very impressed with Makie's plotting abilities from making the basics easy to the extremely advanced, but no, it was the wrong tool. Makie doesn't really do floating windows (subplots), and I had to jump through hoops to create my own float system which uses GridLayout for the GUI widgets inside them. I did get it to all work nearly flawlessly in the end, but I should probably have used a Julia imGUI wrapper instead: near instant start time!
Yes. And I did port my GUI layer to CimGui.jl. The rest of it is pretty intertwined with Makie, didn't do that yet. The Makie version does look better than ImGui though.
I tried some Julia plotting libraries a few years ago and they had apis that were bad for interactively creating plots as well as often being buggy. I don’t have performance problems with ggplot so that’s what I tend to lean to. Matplotlib being bad isn’t much of a problem anymore as LLMs can translate from ggplot to matplotlib for you.
And I would further add: In addition to performance, Julia's language and semantics are much more ergonomic and natural for mathematical and algorithmic code. Even linear algebra in Python is syntactically painful. (Yes, they added the "@" operator for matmul, but this is still true).
As long as someone else does the porting and maintains the compatability between both subecosystems of thoose who prefer using Jax and thoose who prefer depending on the NumPy. Also not having zero overhead structs that one can in an array handicaps types of performance codes one can write.
It is highly interactive and dynamic, yet performant. And it is not only about scientific computing, for almost any application can take advantage of interactive, modifiable system, where you can explore your state at any point. In others, more static langs good debuggers help with this to lesser or larger extend, but it is not the same from my experience.
So better question is: in which circumstances would you choose Julia over more mainstream-y alternative like Clojure? And here scientific and numerical angle comes to play.
At the same time I think Julia is failed attempt, with unsolvable problems, but it is a different topic.
To replace uses where you would use Matlab or R probably. I prefer Julia over Matlab or R. So data science. For production code however, it's not great since it has no static typing. Imagine having your production code crash mid-execution with the error "Function foo not found". Only dynamic languages can do that to you.
I broadly agree that it can be hard to nail down Julia's behaviour but it does have static typing and I think it is more subtle. Function arguments and variables can be concrete types e.g. if you were implementing an approximation for sin, you could restrict arguments to Float32 if you knew it was only suitably accurate for that type.
> it does have static typing and I think it is more subtle.
Yes sure Julia isn't fully dynamically typed, but that doesn't change the fact that it isn't fully static typed. If it was, it should be pretty easy to create static binaries and find bugs like "func not defined" at compilation time.
While others have mentioned plenty of reasons, for this particular case I want to highlight 3 things:
1. Julia has great tooling for operations research/linear programming. JuMP provides an standardise interface to interact with solvers (e.g., Gurobi, CPLEX) via wrapper libraries.
2. I like its overall ergonomics. It is fast enough that a programmer might not need to use a compiled language for performance. The type system allows for multiple dispatch. And the syntax is more approachable than say Python for matrix algebra.
3. I would say the performance is overstated by the community but out of the box it is good enough to avoid languages like C/C++ to build solutions. The two-language problem in academia is real, and Julia helps to reduce that gap somewhat in certain fields.
A very minor nit: Julia is a compiled language, but it has an unusual model where it compiles functions the first time they're used. This is why highly-optimized Julia can have pretty extreme performance.
> I would say the performance is overstated by the community but out of the box it is good enough to avoid languages like C/C++ to build solutions.
For about a year we had a 2-hour problem in our hiring pipeline where the main goal was to write the fastest code possible to do a task, and the best 2 solutions were in Julia. C++ was a close third, and Rust after that.
It was roughly "given this dataset with 100 time series, write code to calculate these statistics as performantly as possible. Make one single-threaded version and one using 4 cores."
The C++ versions were around ~250 lines long, and the developers generally only had time to try one approach. While the Julia versions were around ~80 lines long, and the developers had time to try several approaches. I'm sure the best theoretically possible C++ version is faster than the best Julia version, but given that we're always working with time constraints, the performance per developer hour in Julia tends to be really good in my experience.
Julia is not an alternative to Go. It is the alternative to Python (slow) and to C++ (hard and complex). Go is fast and simple but doesn't have abstractions to create complex code required by math libraries.
Julia collapses entire programming paradigms into single character syntax, and often will transparently handle clean parallelism or cluster instance batching.
Judging by Julia's Discourse, compiling actual production Julia code into a standalone binary is highly nontrivial and ordinary users don't really know how and why to do this.
I shared this article internally and my peers were impressed about how similar it is to our final implementation. (It differs in the fact that we use Redis as queue.)
On one hand, I love the possibility of having millions of albums at your disposal via streaming services. On the other hand, I hate having to type or click to select them (voice recognition just doesn't work).
I am forced to use a MacBook M4 at work but I have and love my Framework 13 Intel.
Battery management is superior in MacOS but I can leave my Framework suspended for more than at least a week (I never measured how long it can stay like this).
I run vanilla Ubuntu with TLP, though, which might be the trick.
TLP is definitely the trick. TLP makes a huge difference in improving battery life while on suspend in Linux - especially since laptop makers stopped supporting S3 sleep.
For all those hating the Twitter link, it's a practical way to convert traffic and likes. It doesn't have to be your favourite tool, it serves his purpose.
I wasn't aware about how bad the situation was for devices, in general, about privacy until I installed a Pi-Hole in a Raspberry and used it as DNS service at home.
It's really surprising the amount of data that tries to leave the premises, and this just the one that I block with a mid-range security ban list.
I work daily with PHP and honestly nearly all my code I write is synchronous.
The shared-nothing architecture of PHP makes that really a non-issue for me. Requests never share any state with each other. Something like RabbitMQ can handle communication between systems.
That's in no way lightweight though, and most languages can easily do the same. Just launch multiple instances/VMs/processes. That's having multiple separate OS processes, each having everything that is needed to run PHP, and having no way to communicate with each other, other than what you implement. No channels, no task distribution, no queue on which to sync and take tasks from, no signaling of all processes being done and then accumulating the results. That is why you then need something like RabbitMQ or other things, and it does not mitigate the heaviness of the approach.
It is kinda funny, that you mention RabbitMQ, which is written in Erlang, which is famous for its lightweight processes. But also compare the approach with thread pools built into the standard libraries in other languages. And even many of those are heavy weight compared to Erlang's lightweight processes.
PHP's approach is simple though, and in my experience that simplicity pays off when you do start scaling the systems.
In other systems once you get beyond a single machine you need that external communication mechanism anyway, and now you have multiple classes of comms which introduces bugs and complexity and performance cliffs.
In PHP you just throw another server at it, it'll act the same as if you just added another process. Nice linear scaling and simple to understand architectures.
The shared-nothing architecture is great for some scenarios.
Long running processes and async I/O are a great tool to have though. They are present in PHP for almost two decades now, and despite having many incarnations (select(), libevent, etc) and even frameworks (amp, reactphp, etc) the knowledge is highly transferrable between them if you understand the fundamentals.
Don't worry, we're not comparing languages here. You are free to chose the language and community that fits best to your approach to software development.
It's better to build your app in e.g. PHP, prove its worth, then identify the bottlenecks, THEN determine if you need multi-threading. And if so, determine if PHP would be the best language for it or if you'd be better off going for a different language - one with parallelism / multithreading built into its core architecture.
The first logical step after PHP is NodeJS, which has the fast iteration cycles of PHP without the low-level memory management or the enterprisey application server headaches of other languages, AND it has the advantages of a persistent service without needing to worry too much about parallelism because it's still single process.
But if you still need more performance you have a few options. But if you're at that point, you're already lucky. Most people wish they needed the performance or throughput of a language/environment like Go.
By this logic, it seems like it would make more sense to just start with Node rather than PHP for the prototype and save the potential rewrite. Node does seem more popular than PHP nowadays to me as an outsider to both, so maybe that's exactly what did happen.
> Most people wish they needed the performance or throughput of a language/environment like Go.
Most people do need the performance and throughput offered by modern languages like Go, though. Time to market is the most important consideration for most. Maybe at Facebook scale you can spend eons crafting perfection in a slow-to-develop language/ecosystem like PHP or NodeJS, but most people have to get something out the door ASAP.
I still have flashbacks from working with the pthreads extension, which caused extremely hard to debug, non-reproducible segfaults sometimes; I realise Joe has probably started from scratch and improved a lot on that (and I know he's a generally awesome guy), but without a properly financed maintainer team to support him, I'm not sure I want to take that risk again before parallel has gained some maturity.
But why pick PHP then? Why not use nodejs or similar where the language, application stack and the community is already in agreement on the execution model.
I don’t use php but it’s extremely popular around the world. There’s also Laravel which seems a lot more productive than anything in js for full stack dev.
reply