Rust or Nim are really the ideal targets for LLMs and will continue to grow. As LLMs write more code and as humans review less, it will be more important to have confidence that your code doesn't run into a weird one off runtime heisenbug issue.
1,164 karma · joined June 26, 2018
Rust or Nim are really the ideal targets for LLMs and will continue to grow. As LLMs write more code and as humans review less, it will be more important to have confidence that your code doesn't run into a weird one off runtime heisenbug issue.
afaict, for that project they never went through PCI compliance. See original thread for more information: https://news.ycombinator.com/item?id=40228751
They seem to not have a lot of real world experience and/or throw caution to the wind and YOLO through security practices. I'd be weary using any of their products.
Most "data scientist" code is exploratory (it's a prototype or a script for an one-off exploration) in nature. And my main gripe is that making that code production ready and maintainable over a long period of time is so difficult that I would switch to Rust instead. If I were going to switch to Rust, I might as well start with Python.
I largely think multiple dispatch works well in Julia, and it enables writing performant code in an elegant manner. I mostly have smaller gripes about subtyping and the patterns it encourages with multiple dispatch in Julia, and larger gripes about the lack of tooling in Julia.
But multiple dispatch is also a hammer where every problem in Julia looks like a nail. And there isn't enough discussion, official or community driven, that expands on this. In my experience the average developer to Julia tends to reach for multiple dispatch without understanding why, mostly because people keep saying it is the best thing since sliced bread.
wrt to hybrid languages, honestly, I think Python/Cython is extremely underrated. Sure you can design an entirely new language like Mojo or Julia, but imo it offers only incremental value over Python/Cython. I would love to peek into another universe where all that money, time and effort for Mojo and Julia went to Cython instead.
And I personally don't think Python/Rust is as bad. With a little discipline (and some tests), you can ensure your boundary is safe, for you and your team. Rust offers so much value that I would take on the pain of going through FFI. PyO3 simplifies this significantly. The development of `polars` is a good case study for how Rust empowers Python.
I think the Julia community could use some reflection on why it hasn't produced the next `polars`. My personal experience with Julia developers (both in-person and online) is that they often believe multiple dispatch is so compelling that any person that "saw the light" would obviously naturally flock to Julia. Instead, I think the real challenge is meeting users where they are and addressing their needs directly. The fastest way to grow Julia as a language is to tag along Python's success.
Would I prefer a single language that solves all my problems? Yes. But that single language is not Julia, yet, for me.
PS: I really enjoy your blog posts and comments.
To clarify exactly where I'm coming from, I'm going to expand on my thoughts here.
What is Julia's central conceit? It aims to solve "the two language" problem, i.e. the problem where prototyping or rapid development is done in a dynamic and interactive language like Python or MATLAB, and then moved for production to a faster and less flexible language like Rust or C++.
This is exactly what the speaker in the talk addresses. They are still using Julia for prototyping, but their production use of Julia was replaced with Rust. I've heard several more anecdotal stories of the exact same thing occurring. Here's another high profile instance of Julia not making it to production:
https://discourse.julialang.org/t/julia-used-to-prototype-wh...
Julia is failing at its core conceit.
Julia as a community have to start thinking about what makes a language successful in production.
Quote from the talk:
> "(developers) really love writing Rust ... and I get where they are coming from, especially around the tooling."
Julia's tooling is ... just not good. Try working several hundred thousand line project in Julia and it is painful for so many reasons.
If you don't have a REPL open all the time with the state of your program loaded in the REPL and in your head, Julia becomes painful to work in. The language server crashes all the time, completion is slow, linting has so many false positives, TDD is barebones etc. It's far too easy to write type unstable code. And the worst part is you can write code that you think is type stable, but with a minor refactor your performance can just completely tank. Optimizing for maintaining Julia code over a long period of time with a team just feels futile.
That said, is Python perfect? Absolutely not. There's so many things I wish were different.
But Python was designed (or at the very least evolved) to be a glue language. Being able to write user friendly interfaces to performant C or C++ code was the reason the language took off the way it did.
And the Python language keeps evolving to make it easier to write correct Python code. Type hinting is awesome and Python has much better error messages (static and runtime). I'm far more productive prototyping in Python, even if executing code is slower. When I want to make it fast, it is almost trivial to use PyO3 with Rust to make what I want to run fast. Rust is starting to build up packages used for scientific computing. There's also Numba and Cython, which are pretty awesome and have saved me in a pickle.
As a glue language Python is amazing. And jumping into a million line project still feels practical (Julia's `include` feature alone would prevent this from being tenable). The community is growing still, and projects like `uv` and `ty` are only going to make Python proliferate more.
I do think Julia is ideal for an individual researcher, where one person can keep every line of code in their head and for code that is written to be thrown away. But I'm certainly not betting the near future on this language.
In 2020, I thought Julia would be _the_ language to use in 2025. Today I think that won't happen until 2030, if even then. The community is growing too slowly, core packages have extremely few maintainers, and Python and Rust are sucking the air out of the room. This talk at JuliaCon was a good summary of how developers using Rust are so much more productive in Rust than in Julia that they switched away from Julia:
https://www.youtube.com/watch?v=gspuMS1hSQo
Which is pretty telling. It takes a overcoming a certain inertia to move from any language.
Given all that, outside of depending heavily on DifferentialEquations.jl, I don't know why someone would pick Julia over Python + Rust.
Whereas the other around, porting a C++ program to Rust without knowing Rust is challenging initially (to understand the borrow checker) but orders of magnitude easier to maintain.
Couple that with easily being about to `cargo add` dependencies and good language server features, and the developer experience in Rust blows C++ out of the water.
I will grant that change is hard for people. But when working on a team, Rust is such a productivity enhancer that should be a no-brainer for anyone considering this decision.
Julia biggest problem at the moment is growth. Julia has suffered from not having exponential growth, and has either maintained a small linear growth or has fallen in popularity. Search online on YouTube for tutorials, on Twitch for WatchPeopleCode, or on GitHub for benchmarks; and Julia is not even in the room where the conversation is happening - there just isn't any mindshare.
And for good reason. There are so many ergonomic challenges when using Julia in a large codebase and in a large team. Julia has no formal interfaces, LSP suggestions that are often just wrong, and no option types. This just makes writing Julia code a drag. And it makes it quite difficult to advocate to developers experienced with languages that offer these features.
Additionally, the core conceit pushed by Julia advocates is that the language is fast. This is true in controlled benchmarks but in real-world scenarios and in practice it is a real pain to write and maintain code that is fast for high velocity teams because it requires a lot of discipline and a strong understanding of memory allocation and assumptions the Julia can and cannot make. You can write code that is blazingly fast, and then you make a change somewhere else in your program and suddenly your code crawls to a halt. We've had test code that goes from taking 10 minutes to run to over 2 hours because of type instability in a single line of code. Finding this was non-trivial. For reference, if this were uncaught our production version would have gone from 8 hours to 4 days.
The lack of growth really hurts the language. Search for pretty much any topic under the sun and you'll find a Python package and possibly even a Rust crate. In Julia you are usually writing one from scratch. Packages are essential to data processing are contributor strained. If you have a somewhat unpopular open source code code you rely on that doesn't work quite work the way you want it to, you might think I'll just submit a PR but it can languish for months to a year.
The Julia community needs to look at what programming languages are offering that Julia developers want and will benefit from. The software world changing very quickly and Julia needs to change too to keep up.
> <Tag a="b" x={y+z}>{valid JS expression}</Tag> > is > React.createElement(Tag, { a: "b", x: y + z }, [<valid JS expression>])
If you take the main reasons React is criticized and claim it is a feature, surely you have refute the criticism more thoroughly than "This seems so simple, yet do not underestimate it." or "That is powerful. Do not underestimate this."
Modern frameworks (Svelte / Vue / Astro) are about using the platform. They are performant, efficient, easier to read, easier to write, and easier to understand.
I don't see any reason I would pick React for a greenfield project anymore.
I get that if YOU don't want to use a modern framework and want to stick with what you know, sure, by all means, pick React. But writing even a semi complex application in both React and Svelte should make it immediately obvious that React is antiquated, if you give both frameworks a fair shake.
It boggles my mind that engineers and managers that have kids and are working on the YouTube team think this is okay and this is what the future of the platform should look like.
It's the beginning of the end of an era, and I'm immensely sad to see what the internet has become and where it is heading.
Not to pick on any of these projects, but this pattern is way too common to not have a some sugar:
https://github.com/goodlang/good/blob/3780b8d17edf14988777d3...
https://github.com/kubernetes/kubernetes/blob/1020678366f741...
https://github.com/golang/go/blob/6cf6067d4eb20dfb3d31c0a8cc...
I counted the number of lines in my work projects, and I have $WORK projects that are 100k lines of code. Maintaining that in Go would seem like a nightmare to me, but in Rust that is so much nicer. My personal projects range from 10k - 35k and in all of those I much prefer the ones where I'm writing and maintaining Rust vs Go when it comes to similar complexity.
Like take a look at this pattern:
err := db.Get(&latLong, "SELECT lat, long FROM cities WHERE name = $1", name)
if err == nil {
return latLong, nil
}
latLong, err = fetchLatLong(name)
if err != nil {
return nil, err
}
err = insertCity(db, name, *latLong)
if err != nil {
return nil, err
}
Is it really necessary to have the error handling explicit in this case? Go through any of your go code. I find this kind of error handling is 90% of the error handling I write. err := db.Get(&latLong, "SELECT lat, long FROM cities WHERE name = $1", name)
if err == nil {
return latLong, nil
}
latLong, err = fetchLatLong(name)
if err != nil {
return nil, err
}
err = insertCity(db, name, *latLong)
if err != nil {
return nil, err
}
In Rust propagating errors is a lot more succinct and easy to do. It is usually what you want to do as well (you can think of Python and C++ exceptions as essentially propagating errors). The special case can be handled explicitly. In Go, you have to handle everything explicitly, and if you don't you can fail catastrophically.I guess it comes down to what features the language provides that makes it easy to do "the right thing" (where "the right thing" may depend on where your values lie; for example, I value correctness, readability of domain logic, easy debugging etc). And in my opinion, it's easy to do what I consider bad software engineering in languages like Go.
The error handling in Go is SO verbose. When reading my code (or even reviewing other people's code) in order to understand at a high level what is going on, I feel like I'm squinting through a mesh wire window.
Compare this example in Go:
city := c.Query("city")
latlong, err := getLatLong(city)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
weather, err := getWeather(*latlong)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
weatherDisplay, err := extractWeatherData(city, weather)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.HTML(http.StatusOK, "weather.html", weatherDisplay)
To this code in Rust: let lat_long = fetch_lat_long(¶ms.city).await?;
let weather = fetch_weather(lat_long).await?;
let display = WeatherDisplay::new(params.city, weather);
Maybe on first glance the Rust code can seem alien (what is a `?` doing there, what is actually going on with `.await`, etc) but when you are writing a 100k line application in Rust, you learn the patterns and want to be able to see the domain application logic clearly. And yet, there's no hidden errors or exceptions. When this code fails, you will be able to clearly identify what happened and which line the error occurred on.Prototyping even small applications in Go is verbose. And worse still, error prone. It's easy to be lazy and not check for errors and oops 3 months in your code fails catastrophically.
I know a lot of people like Go on here but in my mind Go only makes sense as a replacement for Python (static compilation, better error handling than Python, faster etc). If you don't know exactly what you want to build, maybe it is faster to prototype it in Go? I still would reach for Rust in those instances but that's just me. For large applications there's no question in my mind that Rust is a better choice.
Edit:
people have pointed out that I'm not comparing the same thing, which is true, I apologize for the confusing. But even code where Go propagates the errors, it is much more verbose (and my point still stands)
err := db.Get(&latLong, "SELECT lat, long FROM cities WHERE name = $1", name)
if err == nil {
return latLong, nil
}
latLong, err = fetchLatLong(name)
if err != nil {
return nil, err
}
err = insertCity(db, name, *latLong)
if err != nil {
return nil, err
}
And this is extremely common. More discussion in the thread below.This talk on YouTube seems to suggest that not everything is all hunky dory with Zig as a C/C++ compiler (with reference to libc) but I cannot remember any details since it has been almost a year since the talk was published.
I wonder if things have changed? Does anyone know?
I also think Google's ranking is fair in this case, assuming you want to know most high quality information about "how to iterate through a dictionary". I certainly would prefer this kind of a RealPython article with a table of contents so that I can find exactly what I am looking for.
I do think Google (and the web in general) has started to suck because of SEO spam, and generally agree with the authors premise. Searching for recipes suck, searching for reviews suck, searching for places and events also suck.
I just think this particular instance is a bad example. RealPython values your time, and I wish there were a lot more websites that valued my time too.
If this proposal is accepted, I personally think Zig will drop to the popularity level of Hare or other extremely niche languages. Getting my colleagues to even try Zig out required me sending them articles about how Uber was using it in production. There is no way my colleagues would even have given it a second thought if it didn't have immediate value to their existing projects.
But I get where the proposal is coming from. LLVM compile times can seem awful, and there's lots of neat optimization tricks you could implement with your own byte code. And dealing with bugs in LLVM is basically a no-go, I've seen this happen in the Julia ecosystem as well.
If my recommendations are worth anything, I think Zig should
1. Use a custom bytecode for debug builds - fast build times, fast debug times etc 2. Use LLVM for release builds - fast runtime performance, slow release performance
If they can manage 1.) while still maintaining support for cross compiling C/C++ (just pass that part off to LLVM?) I think that might be the best of all worlds, with the tradeoff that there's additional backend code to maintain.
There are so many comments in that thread advising not to use Google Domains (including my comment).
No metaprogramming in the language meant we had some parts of the code that were written in pascal to generate pascal code before compilation of the main project.
The code was so verbose, and to get the same thing done in alternative languages would have easily been twice as shorter.
Refactoring always took twice as long as I thought it would. Just moving semicolons around was enough to break my concentration when I was in the flow.
I think the kicker was identifiers being case insensitive. That alone would have been enough to drive me crazy. People complain about Nim's case insensitive features a lot, but Nim's implementation is actually good and orders of magnitude better than Pascal's.
Also hiring a good pascal programmer was next to impossible for us at the time.
I don't know why anyone would pick Pascal today over Nim, Zig, Rust, Julia, Go etc.
Any influencer that wants to sell you ads, any organization that benefits from you buying into their product, any scammer that can trick you from parting with your money, all those people are going to want to pay for this and will be rewarded for doing so.
Meanwhile, I struggle to see why the people that generate actual good discourse (imo I guess), the scientists, the engineers, the writers, the thinkers, etc, would ever consider paying for this.
I'm sure there's a massive bot problem but couldn't that have been dealt in different ways? Getting people to pay to boost their tweets as a value add for the subscription really devalues the platform.
I don't understand this complaint? "Named parameters" i.e. keyword arguments in functions work great in Julia!
julia> foo(;x = 1, y = 2, z = 3) = x + y + z
foo (generic function with 1 method)
julia> foo(; z = 4, y = 0)
5
Perhaps the author meant default arguments? julia> foo(x = 1, y = 2, z = 3) = x + y + z
foo (generic function with 3 methods)
julia> foo(3)
8
julia> foo(0, 0, 0)
0
> this flexibility does tend to cause bugs working with other people's code. This is compounded by Julia's pursuit of composability. If you cram your custom data value into someone else's function, and if it seems to be the right shape, it will probably work! Unless it doesn't. In that case you just get silently wrong answers. This is a deal-breaker for a lot of scientific computing people where Julia would otherwise shine.This is almost entirely mitigated by most people using `eachindex` or `axes` or other functions that make the array related code index agnostic. The only reason I say almost entirely is because there's probably some really old code that doesn't work the right way and would silently fail or do the wrong thing if you changed the indexing convention. That said, calling this a "deal-breaker for scientific computing" seems extreme.
> I also find Julia's errors to be fairly obtuse. And I see a lot of them because dynamic typing means the tools can't catch most errors before run-time.
I 100% agree. Julia errors are my biggest gripe with the language at the moment.
> But the big dealbreaker with Julia is it only complies on the fly. That means you can't just hand a compiled executable to someone. You must give them instructions to install Julia and all your dependencies first. That's no good for anything you want to ship like a desktop app or a game. You also don't want Julia on your server recompiling with every web request.
There are packages like PackageCompiler that work pretty well. And I'm positive in the near future (3 years?) we'll have a version of Julia where PackageCompiler will produce small binaries. That said, the convenience of writing in Julia and shipping a precompiled app is pretty awesome, and I personally don't mind it taking more space on disk.
> Like all compiled languages, the development cycle involves a lot of recompiling as you go. For small programs it doesn't matter, but this creeps up as the program grows -- or when you add a heavy dependency, like a plotting library. Julia suffers from this compiled-language drawback, but without the normal advantage of getting a compiled executable you could distribute.
This used to be one of my biggest gripes, but things have gotten a lot better with every version of Julia.
----
My first order approximation when picking a language is this:
1) if I think it'll be easy to write in Python, I should write it in Julia. 2) If I want to ship a precompiled binary that exposes a command line interface, I'll think about using Julia first, and if the size of the binaries are an issue, I might pick Rust.
wrt to Nim, I'm waiting to see how the ORC story shakes out + better documentation about ORC to appear on the scene and for more packages to adopt it. I think Nim currently has too small a community. I've found packages that are commonplace in Rust or Julia are just not even available in Nim. Sometimes a package is 5 years old and hasn't been updated. Yes, it is easy to write interfaces but that requires a lot of work. If it is a project where I'm writing code just by myself, Nim might be a good choice but if I'm working with someone else, having them learn Nim is much harder. The error messages in Nim also need to get better in my opinion.
> You don't have to decide between snake_case or camelCase. You can define your variable either way and both references will work. Ditto for most cases of capitalization. I thought this might be problematic, but in practice it's brilliant. I think that sentiment applies to many of Nim's unexpected design choices.
I personally don't like this at all. Every time I search a nim codebase, I have to use `nimgrep` instead of using `ripgrep`. I have SO many aliases built on top of things like `ripgrep` and `fzf` and none of them are certain to work in `Nim`. It's frustrating that the community is so divided on this, because even though I can see there are benefits to this approach, the benefits pale in comparison to getting user adoption and buy in to use the language.
One of my senior developers on my team agreed to learn Nim in their spare time as a favor to me, to evaluate it for a project at work, and as soon as they came across this "feature" they were so turned off, they wrote the language off as being too weird.
There's a LOT of average programmers out there, and a lot more analysts and data scientists that just want to get shit done, and from personal experience I think it's extremely hard to get adoption for Nim in the scientific community. If 7 out of 10 people have used Python, 4 out of 10 people may have heard of Julia and heard that it's new and modern, but 0 people have even heard of Nim. I've gotten SO many quizzical looks over the years, it is not even funny.
If I wanted to present it you could build a ppt.
And having the source for this un Markdown to use with pandoc is nice.
What I've learnt from the last few years (decade?) is that you can make pretty much any claim on the internet, and you'll find an audience that agrees with that claim. If you dress up your delivery, your persona, your appearance, or even just evoke strong emotions with that claim, it'll amplify that audience. You'll find strong supporters of your claim even when evidence to the contrary is provided to them directly (sunk cost, difficulty in changing opinions because of human psyche etc).
I wonder where the Carl Sagan's and George Carlin's of this generation are. I have a sneaking suspicion that social media just doesn't allow such talent to flourish in today's world. It makes me sad to think about this and it would make me incredibly sad if that were true.
wrt to Lex Fridman, he's a dressed up persona for spouting intelligent sounding thoughts, without any actual meat or gravitas behind them. I personally rank him in the same category as Joe Rogan and any other random interviewer podcaster, who put in low effort to research content but put in a lot of effort to produce large quantities of work.
And with ad-supported social media, quantity over quality seems to be the name of the game.
Hopefully GPT4 will make the Lex Fridman's of the world replaceable more easily? I still don't think we'll get to an era of high quality content by public speakers any time ever.
Channel 5 with Andrew Callaghan are the only interviews (other than maybe some ones on PBS) that I've been able to watch and recommend to peers.
Any interviewers you all like?
https://github.com/jkrumbiegel/ReadableRegex.jl
It is in Julia, but if you have it installed locally it’s just a few taps away. You can even generate the regex, and use that in Python and just add the ReadableRegex in a comment nearby.