[HN Gopher] Julia 1.9.0 lives up to its promise
       ___________________________________________________________________
        
       Julia 1.9.0 lives up to its promise
        
       Author : leephillips
       Score  : 82 points
       Date   : 2023-05-13 18:46 UTC (4 hours ago)
        
 (HTM) web link (bkamins.github.io)
 (TXT) w3m dump (bkamins.github.io)
        
       | socialdemocrat wrote:
       | People are increasingly running out of reasons to not use Julia.
       | It really is the future for data science and machine learning. No
       | let me correct that. It really could replace anything R, Python,
       | Perl, Ruby etc is used for today.
       | 
       | 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.
        
         | alwaysbeconsing wrote:
         | I'm not a math or data scientist so personally when I touch
         | Python or Ruby it's for a system scripting, small CLI tool use
         | case. Would you say Julia fills that corner as well?
        
           | sundarurfriend wrote:
           | I'm curious about this too. The latest 1.9 changes make it so
           | that package precompilations are stored and reused, so the
           | actual workflow will have to be to generate a package (which
           | Julia has tools for), and have the script be just a tiny
           | driver that calls into the package. With that workflow, what
           | kind of latency can we expect? And how consistent would that
           | be?
        
           | currymj wrote:
           | you can do it but it's not great. there's no batteries-
           | included standard argparse library and even with the new
           | improvements, there is still some noticeable overhead of a
           | few seconds for some scripts i've written.
        
         | mxkopy wrote:
         | Julia:Python::RISC:CISC imo. The first example that comes to
         | mind is that in Python, you'd write:
         | 
         | `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.
        
         | cwp wrote:
         | I think Julia really dropped the ball on the execution model.
         | Just-ahead-of-time compilation ends up being the worst of both
         | worlds - you can't compile a small fast binary for deployment,
         | and you can't quickly run a script or REPL for development. It
         | turns out that this really matters for adoption.
         | 
         | 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.
        
           | adgjlsfhk1 wrote:
           | IMO Mojo isn't competing with Julia. It's competing with
           | Rust. Manual memory management, you have to type annotate
           | every variable (if you want good performance), and no
           | overloading doesn't seem to me like a language aimed in the
           | same area as Julia.
        
           | pjmlp wrote:
           | Right now, Mojo is as successful as Swift for Tensoflow.
        
           | ivirshup wrote:
           | > it's really solving the problems that hurt AI most
           | 
           | 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.
        
             | garbagecoder wrote:
             | I have tried it. Iirc, the company developed it, or its
             | compiler, specifically for ML/"""AI""".
             | 
             | 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.
        
         | enriquto wrote:
         | > It really could replace anything R, Python, Perl, Ruby etc is
         | used for today.
         | 
         | 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?
        
           | sundarurfriend wrote:
           | > Making a "busybox" style executable that replaces all
           | coreutils
           | 
           | 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.
        
             | enriquto wrote:
             | > and then do any kron product you want, whether sparse
             | matrices with other sparse matrices
             | 
             | 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.
        
               | adgjlsfhk1 wrote:
               | that definitely sounds like a bug. if it still is like
               | that, please file an issue :)
        
         | sundarurfriend wrote:
         | You're not technically wrong, in that Julia has the _potential_
         | to replace all of those languages. And _if_ it could attract
         | large communities, an amazing interoperating coherent package
         | ecosystem could develop there that 's much less of a pain to
         | use than most current systems.
         | 
         | 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?)
        
         | jimsimmons wrote:
         | No classes, weak typing despite having multiple dispatch,
         | 1-based indexing, no real DL libraries with comparable baseline
         | to pytorch/weight portability
         | 
         | There are no reasons to not use it if you like gesturing from a
         | distance
        
           | sgt101 wrote:
           | No classes - thank the lord. This was a 30 year experiment
           | that failed. Parametric polymorphism is the way and the
           | light.
           | 
           | >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.
        
         | barrenko wrote:
         | Still trying to wrap my head around what is Julia exactly.
         | 
         | Sidenote - MIT's Introduction to Computational Thinking is a
         | pretty decent course.
        
           | bobbylarrybobby wrote:
           | Julia is a language that you write more or less like python,
           | but in cases where python would chase a million pointers to
           | figure out what the type of a variable is, get an instance
           | variable, call a method, etc, Julia (if written correctly)
           | does just in time compilation. The first time it has to call
           | a function on a combination of types it hasn't seen before,
           | it compiles the function for those specific types (into LLVM
           | IR, and then native code) and stores the compiled code so
           | that subsequent dispatches of that function with those types
           | are instantaneous, calling directly into the compiled code.
           | You do not need to add type annotations for this to happen;
           | at runtime, Julia checks the types of variables (which may
           | have even been determined when the function was compiled,
           | eliding the runtime check, if it was used in a context where
           | the types were statically known; see below) to determine
           | which version of a function to call.
           | 
           | 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.
        
             | sundarurfriend wrote:
             | > 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").
             | 
             | 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".
        
           | Iwan-Zotow wrote:
           | modern day fortran
        
           | sundarurfriend wrote:
           | An attempt at an easy-to-use dynamic language which tries to
           | compile things early as much as possible via aggressive type
           | inference (helped by the type system's design and multiple
           | dispatch), so that you don't leave performance on the table
           | where it's possible to have it, while also having the
           | flexibility of dynamism where you need it.
           | 
           | That's my interpretation, I'd be curious what Julia folks who
           | actually know what they're talking about think of it.
        
           | MengerSponge wrote:
           | Matlab that compiles to LLVM. It's fast, pretty easy to
           | write, and surprisingly expressive.
           | 
           | 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++.
        
         | anonylizard wrote:
         | This kind of thinking is very old school. Its 2023 now.
         | 
         | 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.
        
           | garbagecoder wrote:
           | GPT-4 seems best at C#. Scary good. Hmmm.
           | 
           | I agree with 3, but it's also an argument for Mojo, if it
           | delivers on its promises.
        
           | jimsimmons wrote:
           | Proto AGI GPT4 can't faithfully translate Python to Julia?!
        
         | packetlost wrote:
         | Having 1-indexed arrays is unforgivable.
        
           | huijzer wrote:
           | Okay. I'll bite. Why?
        
             | gcmrtc wrote:
             | This is the opinion of Dykstra:
             | https://www.cs.utexas.edu/users/EWD/ewd08xx/EWD831.PDF
        
               | Iwan-Zotow wrote:
               | sure, [0...N) ranges are composable, to be short
        
             | xedrac wrote:
             | I used Julia for a project back in 2016, and had the same
             | adverse reaction to 1-based indexing. It's the same reason
             | I have a hard time with Lua. Why? I suppose it's all rather
             | superficial, but it's one of those things that just grates
             | on me and I'll avoid it if I can. I'm not sure there's a
             | logical explanation, but I've found the sentiment to be
             | rather common among developers.
        
               | sweezyjeezy wrote:
               | Same, but probably it's more of a familiarity bias rather
               | than a logical one. I think there is a strong argument to
               | index from 1 as is done in MATLAB, R etc. since it
               | matches the way most people refer and think about lists
               | in reality.
               | 
               | A brave decision from the authors though, I imagine they
               | would have got less flak matching the more popular
               | 0-index languages.
        
               | sundarurfriend wrote:
               | > I think 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.
        
           | upbeat_general wrote:
           | Agreed.
           | 
           | I thought the same thing about Python's indenting originally
           | (and still do). But the ecosystem was enough to overcome it
           | for me eventually.
        
           | leephillips wrote:
           | Yes, that's probably why Fortran was never used seriously.
        
           | bobbylarrybobby wrote:
           | Not just that, but ranges are inclusive on both ends.
        
             | webshit2 wrote:
             | Little do Julia fans know they're missing out on gems like
             | range(n - 1, -1, -1).
        
             | sundarurfriend wrote:
             | Ha, I was thinking of replying to your parent comment,
             | "Half-open ranges are such an unpleasant thing as to be
             | unforgivable to me. Different subjective preferences."
             | 
             | 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.
        
               | bobbylarrybobby wrote:
               | With half open ranges, the length of the range is the end
               | minus the beginning, which is nice. It's also much more
               | simpler to write an empty half inclusive range. For
               | instance if left=right then left..right would be the
               | empty range. Whereas in Julia I'd need... left:(right-1)?
               | But is 1:0 the empty range or the right-to-left inclusive
               | range [1,0]? Very confusing and hard to work with all
               | around.
        
               | sundarurfriend wrote:
               | > With half open ranges, the length of the range is the
               | end minus the beginning, which is nice.
               | 
               | 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.
        
               | bobbylarrybobby wrote:
               | Yes, range(n+1) is bad. I hate python as well. You want
               | something like Rust's m..n _and_ m..=n to have the
               | choice. Anyway, if you have half open ranges, it 's
               | trivial to get a closed range (add one to the right
               | endpoint), but going the other direction is not so
               | simple.
        
               | Iwan-Zotow wrote:
               | Julia ranges are not composable, period
               | 
               | In Python, C/C++ and its descendant
               | 
               | [0...N)=[0...N/2)+[N/2...N)
        
           | pjmlp wrote:
           | Plenty of languages have it, so what, it is too much to ask
           | for in skillets?
        
             | Iwan-Zotow wrote:
             | Julia ranges are not composable, that's it
             | 
             | You cannot do easily [0...N) = [0...N/2) + [N/2...N)
        
               | webshit2 wrote:
               | Idk typing +1 seems easy enough... 1:N == union(1:(N/2),
               | (N/2+1):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)!)
        
               | Iwan-Zotow wrote:
               | In python this is natural way to do ranges, and in Julia
               | you have to remember this pesky +1
               | 
               | 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
               | 
               | https://www.cs.utexas.edu/users/EWD/ewd08xx/EWD831.PDF
        
           | goatlover wrote:
           | This again. Fortran, Cobol, Smalltalk, R, Matlab, APL,
           | Wofram, Lua. Its primary use is scientific computing.
           | 
           | It's like the whitespace in Python debate that everyone gave
           | up because the language got so popular that people stopped
           | caring.
        
           | Rarebox wrote:
           | It's jarring initially, but becomes natural very quickly.
           | Writing loops like "for i in 1:length(arr) ... end" is pretty
           | neat compared to C++ or even python. Plus in math sequences
           | typically start at index 1.
        
             | threatofrain wrote:
             | > Plus in math sequences typically start at index 1.
             | 
             | 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.
        
             | leephillips wrote:
             | You should never write loops that way, at least in code
             | you're going to share (assuming that you're going to have
             | some arr[i] in the loop body).
             | 
             | 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.
        
       | [deleted]
        
       | sundarurfriend wrote:
       | > groupby by two columns is not very common, so DataFrames.jl
       | decided to leave it out from precompilation. For this reason when
       | you run groupby(flights, [:origin, :dest]) native code for such a
       | scenario is not cached. This is indeed a hard design decision for
       | package maintainers. You could add more and more precompilation
       | statements to improve the coverage of cached native code, but it
       | also costs as it would impact: package installation time and
       | package load time.
       | 
       | How feasible is it to let the users provide their own
       | precompilation code? If I know that two-column groupbys are
       | important to me (or some other operation that takes tens of
       | seconds), it would be nice to be able to pay the one time
       | precompilation cost for them to have much better TTFX later.
        
         | celrod wrote:
         | One approach you could try now is creating StartUp packages:
         | https://julialang.github.io/PrecompileTools.jl/stable/#Tutor...
        
           | sundarurfriend wrote:
           | Thank you. Tim Holy linked to the same in a previous thread
           | (https://news.ycombinator.com/item?id=35885133), but I
           | couldn't understand the context in which I'd want to use it
           | when I looked at it then. Now I understand the idea of
           | Startup packages much better.
        
       ___________________________________________________________________
       (page generated 2023-05-13 23:01 UTC)