Not right now as packages, larger communities etc need to be developed. But long term solutions the potential is obvious. A friendly, powerful and high performance dynamic language ought to have a very broad appeal.
Not right now as packages, larger communities etc need to be developed. But long term solutions the potential is obvious. A friendly, powerful and high performance dynamic language ought to have a very broad appeal.
And now Julia has competition from Mojo. Mojo makes some compromises for backward compatibility with the Python world, but it's really solving the problems that hurt AI most. And the folks behind Mojo have a lot of real-world experience migrating a community from one language to another.
I think Julia will remain a niche language, confined to science and statistical computing outside of mainstream data science and machine learning.
Isn't this a bit premature? Mojo doesn't tangibly exist for most people (we can't run it ourselves), and I am unaware of any ML/ AI applications built with Mojo.
If they successfully import Pythons libraries without a bunch of wrapping, its userbase will likely follow.
It was faster than Python and easy to do paralleization like go. But it’s not quite fully baked yet.
You know that the entire blogpost you're ostensibly commenting under is about how the JIT overhead has been greatly reduced via more static AOT compilation, right?
Python is not compiled and start & load pandas (which is comparable to the libraries loaded in the article) in ~0.4" on my computer, and that's a notoriously slow language.
If I were to use e.g. Rust with polars, load time would be virtually none. And when I have to process ~50k different datasets, I can't afford 0.85" per file, which would translate to ~11 hours of overhead.
No it's not, because I will not architecture my whole pipeline & program around Julia inability to start in maybe a second in a year or 1.7" now, I will just use another language.
Hello C, C++ and Fortran.
Because you're compiling...
And if you need to do the same in Julia, you should also pre-compile or some other method like https://github.com/dmolina/DaemonMode.jl (their demo shows loading a database, with subsequent loads after the first one taking roughly ~0.2% of the first)
But 1.7 seconds at first startup isn't even enough time to articulate a serious thought, much less write any good code.
I struggle to believe it's a dent in anyones workflow.
> I struggle to believe it's a dent in anyones workflow.
This is exactly what I dislike in the Julia community, the ‶if I don't have this issue, then the ones meeting it are holding it wrong″ attitude.
If Mojo finds it groove and can convince people that static typing is a price to pay for performance I think Julia will have to adopt some sort of a pure AOT compilation mode and forgo the Dynamism that keeps that Just- portion lying around which does seem like an issue for DS/ML folks.
>and you can't quickly run a script
What is wrong with the following to run a script?
$ julia myscript.jl
If you have specific needs that demand, after hitting return, the few seconds of delay for the vast majority of scripts is an issue, you can pre-compile it ahead of time or simply use something like https://github.com/dmolina/DaemonMode.jl
Julia has issues as with all languages but "not being able to quickly run a script" is by far one of the easiest to work around.
> and you can't quickly run a script or REPL for development.
REPL- I disagree. Of course you can - that's how many of use Julia.
> And now Julia has competition from Mojo.
...maybe. The code-samples we've seen from Mojo look very similar to Python, obviously. And that is specifically why a lot of poeple love Julia.
The problems people are more and more interested in (machine learning, etc) are at their base mathematical problems. These languages are all tools to translate mathematics into computer instructions. The code should then ideally look as close to that math as possible. Spamming np.linalg, sp.sparse, and so forth over and over again is just ugly, and the entire Python workflow overly encourages object oriented design for concepts that are mathematically functions. And, well, should be functions. If you're working in these or related fields at all and write any code with Julia, it's hard to not fall in love.
Mojo may make Python faster. But it will still be, roughly, Python.
And considering that the Python 2 -> Python 3 transition has still not completed, I think it's premature to conclude Mojo's python upgrades will get anywhere.
But I don't think either of those are given. Projects with huge potential have unfortunately failed for "trivial" reasons like personpower, funding, approachability, etc. that have nothing to do with underlying technical merit. (edit: but, to be clear, I don't think at this point Julia can exactly "fail", that seems pretty implausible; it will definitely have a strong presence in the MATLAB-ish niche, in the sciences and in engineering. The uncertainty is about more general purpose, popular usage).
I love Julia and would love to see it succeed, but at this point in time its future is still uncertain. (And it's also unclear what if any the effect of LLM code generators is going to be - are they going to reinforce the current popular languages since those are the ones they're good at? Or are they actually going to make less popular languages more approachable, as they grow to learn to generate code in them too?)
There is an (admittedly niche) use-case where Julia would be almost incapable to work, as compared to other interpreted languages like for example Lua or Perl. Making a "busybox" style executable that replaces all coreutils (cat, ls, head, tail, wc, sort, uniq, tr, cp, df, echo, printf, ...) with simple Julia implementations. The slow startup-time for each Julia instance would make most shell scripts unbearably sluggish.
I agree that Python would be an equally bad choice for that, but at least it should be slightly faster.
Regarding "serious" uses of Julia, especially in numerical mathematics, I find some basic things still lacking. For example a complete base package for sparse matrices, including kronecker products etc. Octave/Matlab have the "kron" function in the base language. In Julia, should I use things with dubious names like LuxurySparse or what?
I wonder if DaemonMode (https://github.com/dmolina/DaemonMode.jl) is the right approach for this, having each of those tools' functionality loaded in the server process, and calling out to them from a client when a tool is invoked.
> a complete base package for sparse matrices, including kronecker products etc.
SparseArrays is a standard library package for sparse matrices and arrays. kron is in the LinearAlgebra standard library. So you can just do
using LinearAlgebra
using SparseArrays
and then do any kron product you want, whether sparse matrices with other sparse matrices, or dense ones, or any other array type.Thanks! Will try it with the new release. Last time I tried, apparently it converted the sparse matrix to dense before calling kron, and (expectedly) it failed due to memory error. For example, try to compute the adjacency matrix of a grid graph of size 1000x1000. It is the kronecker product of two tridiagonal matrices of that size. It only has four million non-zero entries, which are instantaneous to compute, but if you want to store all the zeros you'll need a few terabites of RAM.
I'm sorry, but I can't really let you say that.
I like Julia, it has many nice features, but it still IMHO exhibits a lot of reasons not to use it, all of which I stumbled upon while using it to develop non-trivial pieces of software in bioinformatics.
- parallelism is very confusing, very easy to break, and not very efficient when it works;
- cold-boot time is prohibitive;
- the ecosystem is brittle, and very much underdocumented;
- the dispatch mechanism is both a blessing and a curse;
- the stdlib should include some way of encoding errors, otherwise everyone cook their own stuff in their corner (should I raise an exception? Return -1, or maybe null? Or a Union?);
- not being able to redefine types in REPL is a PITA for REPL-driven development;
- debugging cross-packages bugs with multi-dispatch in time-consuming;
- the stdlib doc website is *excruciatingly* slow;
- memory consumption is hard to control;
- iterators are weird (i.e. eager and hardly composable), and either pipe should be a part of the language or they should be chainable, map(f, filter(g, sort(h, [...]map(t, xs)))) leads to unreadable & uneditable mess;
- performances do not follow what was promised (*C-like order of magnitude*), unless maybe you're (a) a Julia god or (b) only using numeric computations.
Now none of these flaws are intrinsic, and I very much hope that all these edges will be polished in the coming times. But as a ‶grunt on the field″, it is exasperating to see the core Julia community just telling you that you're holding it wrong and that all is best in the best of worlds.1.GPT-4 and co are really, really good at python, and will write 90% of boilerplate for you. That makes a python dev way more productive than the Julia one. There is way, way less data on Julia, so the ceiling for AI assisted Julia is way lower.
2.Data science is not just running fancy statistical functions. Its also API calls to like 10 services. You can setup a PDF->OCR->GPT processed text->Send to vector database with a few API calls in python. There's a python package for everything, and everything put into one script.
3.Did you know everyone using stable diffusion (millions), has to install pytorch and like 50 packages in python? Now 95% will just use auto-installers. But the remainder 5%, will be exposed to python, and forced to learn it if they want to use AI art professionally (scripting) or do further development in it. When you see hordes of nerds desperately learning python to generate waifu pictures on google collab notebooks, you know a language will be dominant for decades to come.
I agree with 3, but it’s also an argument for Mojo, if it delivers on its promises.
A brave decision from the authors though, I imagine they would have got less flak matching the more popular 0-index languages.
Possibly, though those of us already in the space would have found it a (slightly) less pleasant language then.
I mean, computing mean - split range, get result per split and combine it back, and so on and so forth
I've always found 0-indexing mildly unpleasant too, even though C was the language I learnt programming with, and felt like I found home when I came across 1-indexed languages.
But I already know from real life that if there's maintanence in blocks 5 to 15, that's eleven blocks under maintanence. With half-open ranges, it once again introduces confusion and makes things unintuitive.
We can each find countless examples where each style comes out better, for eg `1:N` most often expresses the intent better than `range(N+1)`. I find people who prefer half-open ranges to be weird and incomprehensible, you probably find my preferences the same, I just don't like the categorical statement often made in this regard that one is inherently and universally superior to the other.
In Python, C/C++ and its descendant
[0...N)=[0...N/2)+[N/2...N)
Isn't that just n-1:-1:0 in Julia?
Was this sarcasm?
It's like the whitespace in Python debate that everyone gave up because the language got so popular that people stopped caring.
I thought the same thing about Python's indenting originally (and still do). But the ecosystem was enough to overcome it for me eventually.
You cannot do easily [0...N) = [0...N/2) + [N/2...N)
But really, these discussions are funny to me - each side pretending their convention is how God intended indexing to be done. You see it's naturally composable because N/2 shows up twice, which is really the perfect amount of times to show up, and as you recall I just defined composable in that way (not to mention it matches the fact that N/2 occurs twice in [0, N)!)
In Python (C, C++ with whole STL) you could split in the middle, or at any M
[0...N)=[0...M)+[M...N)
You could split it k times at any boundaries, still
[0...N)=[0...M1)+...+[Mk...N)
Another important thing is that number of elements to process is exactly the difference between last and first index of the range
And in Julia, it’s
length(a:b)
which also works with non-unit step sizes like length(a:x:b)
The intent of these expressions seems clearer than the intent of `b-a` and `ceiling((b-a)/x)` with your proposed approach in a zero-indexed language.I'm not quite sure that this is the case enough to say "typically". In terms of undergraduate exposure to math, I think more people have taken Calculus (or Analysis) than Linear Algebra, and I think Calculus textbooks tend to index from 0 while Linear Algebra textbooks tend to index from 1.
Assuming that arrays start at 1 is a source of occasional bugs in public packages. The existence of OffsetArrays means that arrays can start at any index (so for people who get nauseated by 1-based arrays, you can change it).
Instead, write "for i in eachindex(arr)".
In fact, Julia’s array syntax means you can loop over and manipulate arrays without using indexes much of the time, so don’t even need to know how they’re based.
Most modern languages have a «foreach» operator or its functional equivalent as a collection item generator. «foreach elem in my_collection {}» also has a clearly defined semantics: «process everything». The code is cleaner, concise and a bit shorter and reduces the cognitive overload. And since many languages now support lambdas, the code can quickly and error free be converted into a staged data processing pipeline without the use of temporary variables that serve no purpose, e.g. «foreach elem in my_collection.filter (_ -> _.my_selection_criteria ("42"); ) { do_something (elem); }». Whether the collection is indexed from 0 or from 1 becomes irrelevant.
I use ABS, Perl, PHP or Nim for most of that stuff but am always looking for new ones to try. (Preferably single binary these days since I have to migrate systems from time to time)
Sidenote - MIT's Introduction to Computational Thinking is a pretty decent course.
That's my interpretation, I'd be curious what Julia folks who actually know what they're talking about think of it.
It's also 1-indexed.
I just think it's neat, but it's never solved a meaningful problem for me. My data gets filtered and well-structured upstream of my analysis, so python+pandas is perfect. Visualization tools aren't better in Julia than JS or Python. Really crunchy simulations tend to be written in C or C++.
This is a strength, as the only thing you have to do to get the performance of fully compiled code (modulo things like GC and bounds checking) is make sure your functions are “type stable”, i.e., their type information can be determined statically. (In fact, in Julia you get better performance by writing more, smaller functions because you'll have more regions within which the types are statically inferrable.) But it's also a weakness because the first time you start up a REPL and call a bunch of functions, each of those functions has to be compiled from scratch, which takes a long time (google “Julia time to first plot”).
Julia has other niceties such as very flexible math (promotion between every pair of numeric types) and a lisp-like macro system with homoiconic code, which make writing numerical code and scientific algorithms highly ergonomic.
But also to further clarify on this, the context of the article is that Julia 1.9 makes it so that for code in packages, the package authors can set up a "call a bunch of functions" section in the package itself, and the compiled results of those calls will be stored as native code. So anything from those parts will have much lower "time to first X".
Of course, Fortran and Matlab had heard of each other. How could they not have, given so many mutual friends? Many of those friends thought that they should meet up. Some even thought they would hit it off. But the common view was that they would dislike each other. Elderly Fortran, who thought deeply before even considering to act on something, didn't see much to gain in meeting Matlab. And Matlab, long the darling of the just-go-for-it crowd, was by now middle-aged, and saw little benefit in dating at all.
But on day, as the joke goes, they both walked into the same bar. Fortran ambled in slowly carrying a musty book and exuding an air of superiority. Matlab arrived a bit later and, busy chatting on the phone, did not even notice Fortran sitting alone in the shadows. But after a while, Matlab did notice a flickering over in that dark corner of the bar. It was a candle. Intrigued, Matlab strode towards the light in the darkness.
Fortran, as always, was deep in thought. Buried in the book, sure, but more than that. Fortran had been thinking about this thing for several weeks. And not just thinking with a single mind, like others in the bar, but at this point with ten thousand minds. The idea was only now just starting to take shape, with these many minds and these many hours.
Now, Matlab was no fool. Matlab could recognize brilliance when it was sitting right there, with the candle, the book and the furrowed brow. The rest of the bar faded away. The music, gone. The conversations, the laughter, the flirting, the clinking of glasses -- all gone. For Matlab had realized something: Fortran was sexy as hell.
So Matlab sat down. And Fortran, to the astonishment of anyone who had been around for the past half-century, looked up. Wow. In this light, in this place, at this moment Matlab seemed like an angel descended from heaven.
They said very few words. And the words didn't really even matter much. It was the tone of voice that mattered. The pauses. The crinkling around the eyes. After a while, Matlab's hand reached for Fortran's. And that was the start of something new. Something neither expected. Something their friends could not have imagined, let alone hoped for.
NEXT: PART 2, JULIA IS CONCEIVED.
There are no reasons to not use it if you like gesturing from a distance
>weak typing despite having multiple dispatch
I'm struggling to understand, do you mean that it doesn't have type safety? Could you explain a bit?
1-based indexing - I don't care about...
the "no DL libraries" and the community effects around having weight portability is significant I think. I need to spend more time with Transformers.jl.
I thought more or less the same. Sometimes people think strong typing is type safety. Weak/strong typing is a very confusing concept now, I think dynamic / static is a much clearer division.
Personally I have had a lot of value using the Julia type system for runtime inference in programs, I love it!
`A = [ x for x in range(10) if not isprime(x) ]`
In Julia, you'd instead write:
`A = [ x for x in 0:10 if !isprime(x) ]`
It feels like as if having an infix operator for not is redundant - why add a separate & distinct symbol when it means the exact same thing?
There's also the experience of writing iterables/generators, where in Julia you have to subtype the very specific Base.iterate function, but in Python you can just append the magical `yield` to your function.
Overall in Julia I feel like there is less 'magic', but with the added benefit of having a very clear picture of what's happening.