Graydon’s outlook here is really impressive.
He kicked off an incredibly influential project, then didn’t block other people from evolving it in a direction that wasn’t his original vision, and can talk about it so sensibly. Clearly he’s attached to some aspects of his initial vision (and he does sometimes argue that specific Rust features were mistakes/shouldn’t be adopted), but recognizes that actually existing Rust fills an important niche, that it probably couldn’t have filled while following his initial vision.
So many tech luminaries would be writing bitter posts about how much better everything would be if the project had just listened to them. Or they never would’ve stepped down in the first place, and the project would’ve stalled.
Yes definitely … and I was thinking about this a little more: What do Graydon-Rust and Rust-2023 actually have in common? The only things I can think of are:
Almost everything else seems different?
That’s like EVERYTHING in a language !!! What did I miss?
It’s a bit shocking that it even worked, and ended up where it is today … it’s so wildly different.
It seems like Mozilla got together a bunch of talented language and compiler engineers around Graydon’s side project, and then produced something completely different.
As an aside, has anyone rendered the early doc links from this post (and published them)?
OTOH the initial assessment why Rust was needed was spot on, so I think it accomplished the goal, even if via different path.
Yeah definitely, looking over it, I would add these stable design points
swap[T]()
syntaxSo in those senses it’s the same, but it still surprises me how different it turned out!
(Also fun to see the stack iterators and actors, re-reading that deck)
That’s a really neat artifact!
I had exactly the same thought while reading this. The other thought I had was that I would have very much preferred many of the ideas he suspects the reader would not. In many cases the choices he would have made perfectly match my retroactive wishes after having used rust for a while.
I can’t think of an example of a tech luminary who would be bitter. it might be i’m super skeptical about what constitutes a luminary, though.
I think this is a huge misread of Torvalds
He’s infamous for some abusive rants, but they’re all directed at Linux contributors, and not at people working on other open source projects, or their work
To me it’s not a coincidence that he created what’s arguably the most collaborative open source project of all time, and he gets emotional about what is let into the codebase.
It’s basically because of the large scope and highly collaborative nature of the project – that’s the only “control” he has
Most maintainers would try to review all patches, and they would drown in it, and lose contributors, and the project would end up smaller. But he doesn’t, so he fishes out “smells” and then blows up when he sees something he doesn’t like
I’m not defending it (I certainly wouldn’t want to work in that environment). But I’m saying it’s not coming from a petty or jealous place
And TBH the rants generally seem like they have a reasonable technical justification, and there could be something to learn. He just chose to make it profane and abusive so everybody remembers it … kind of a shitty tactic, but there’s a method to the madness
He’s infamous for some abusive rants, but they’re all directed at Linux contributors, and not at people working on other open source projects, or their work
The first Linus rant that comes to mind is the one where glibc replaced memcpy with one that complied with the spec and was faster, but broke programs that expected memcpy to me have like me move. So I’m going to have to disagree with this as a statement of fact.
Sure, but I’d say Torvalds is angry because he has “skin in the game” … Not because he’s a petty or jealous person.
I mean Graydon quit and Torvalds didn’t until recently, and Linux is much bigger than Rust – it’s inherently a stressful position
I’ve corresponded with him directly many years ago, and he’s a very clear and effective communicator, always interested in the best solutions.
It’s unfortunate that he got what he wanted – people remember the 1% of his extreme anger – but 99% of the time he’s helpful and effective.
(And not to say I don’t have any technical problems with what they’re doing. Lots of Linux and git are simply incoherent. But I regard that as a side effect of scale. It’s literally parallel development where people don’t think about what others are doing. The contrast is something like https://www.oilshell.org/ where I try to keep the whole language in my head, and make it globally coherent, and it doesn’t scale development-wise. I think that’s mostly OK for what we’re doing, but it’s a tradeoff, and could be better.)
That particular change broke the closed source Flash player plugin, which basically broke the Web back then. Have to agree with Linus there.
Yeah, because that’s what he said about git after giving up his primary developer status to Junio C. Hamano? Oh, wait… https://www.linuxfoundation.org/blog/blog/10-years-of-git-an-interview-with-git-creator-linus-torvalds
Has it lived up to your expectations? How is it working today in your estimation? Are there any limitations?
Torvalds: I’m very happy with git. It works remarkably well for the kernel and is still meeting all my expectations.
It’s certainly an unusual stance, but I don’t know if it led to the best outcome vs. being BDFL and making Rust a better language.
Better for what and along what axis is the question.
The vision the community (and probably mozilla) latched on is clearly very different than Graydon’s, but is it worse for it? Would the world be better off with an other efficient-ish applications language, and more importantly still without any sort of viable replacement or competitor to C++?
The performance aspect seems like the most important difference to me, and could be a deal breaker for many use cases. Wasn’t Go designed as a replacement for C++ though?
Kinda but not.
It was designed as a replacement for some C++ uses at the upper edge (or is it bottom?): network services, daemons some CLI. But it never aimed to broadly replace C++ itself in the niches were it’s solid. Rather to take the space where C++ and scripting languages would meet.
This is basically a carbon copy of Rust’s Option.
For C++ programmers this is new, for those who moved on to Rust this is daily business for many years already. I wonder how long it takes the C++ committee to adopt the rest of the Rust interface. Maybe another 5-10 years, with compilers supporting the new features trickling down to the industry in 15 years? While it is encouraging that C++ is being modernized, the fact that the real innovation happens in Rust cannot be overlooked (and yes, I am aware that Rust’s Option
is inspired by Haskell’s Maybe
type [1] and other, older functional programming concepts, but the difference here is that Rust does not insist on functional purity and makes these concepts easy to understand and usable in low-level contexts like OS and real-time programs).
[1] https://notes.iveselov.info/programming/cheatsheet-rust-option-vs-haskell-maybe
It is not! It doesn’t have niche optimisations and layout guarantees that could make it zero-cost without size overhead.
But most importantly Rust’s Option
is safe from easy-to-hit UB, but std::optional
isn’t. C++ has chosen dereference to be quietly UB instead of guaranteeing abort.
Even this article has potential for UB:
if (!p->has_pepperoni)
p->has_pepperoni = true;
p->
is UB if the optional doesn’t have a value.
I find this design decision flabbergasting — I know it’s for speed and consistency with all the other unsafe dereferences, but modern C++ was supposed to stop doing this reckless stuff. They’ve been so close to creating a safe abstraction, and chose to make yet another fancy nullable pointer instead.
I fully agree with you, but I assumed that easy-to-hit UB is already implied when we are talking about C++, which is why I didn’t mention it. However, I have to admit, while I was skimming the article, I didn’t notice the potential UB in the examples that was pointed out by @snej and you.
It’s not surprising that a language created 10 years ago would adopt these features more quickly than one created 40 years ago. As for the features themselves, they’re hardly novel, as you point out. And they can be implemented in a couple of lines of code apiece in C++ (I’ve done it.)
and_then
, or_else
and map
interface [2].std::optional
was introduced in C++17 [3].std::optional
is extended by the three most obvious, simple functions imaginableI don’t know the full story of why it took so long. And I’m not blaming any individual here - I know how hard it is to negotiate interfaces and standards in a committee. But it is clear that the C++ committee is dysfunctional in many ways. It seems to me that the language, more than ever, lacks a clear vision and that the committee has inscrutable priorities.
[1] https://blog.rust-lang.org/2015/05/15/Rust-1.0.html
I’m very happy Cargo has switched to the new registry protocol. The original git-clone-everything protocol did not scale well, and Cargo managed to switch away from it before it became a major bottleneck. Crisis averted!
The title is exaggerated. These I/O abstractions are stateful, and mutation of the state requires &mut
. The fact that these traits aren’t ideal for a special case of in-memory random access doesn’t make them dangerous.
I remain utterly baffled by people’s capacity for self-deception when it comes to LLMs.
You can literally go and chat to one right now and get it to, often within minutes, spit out nonsense. Often well-written but subtle nonsense, but nonsense nonetheless.
Which makes sense, given the algorithm explicitly tries to generate text which probabilistically sounds like a correct answer.
This odd assumption that somehow, via magic, this technology will do all of the things it fails to do now (despite its underlying algorithm being literally incapable of doing so) seems to be what’s driving this.
The excitement is based on the self-perpetuating idea of what it could be + a snazzy demo. And isn’t that a description of every bit of vapourware out there?
I don’t mean to be disrespectful, but I do find this LLM craze a good litmus test of AI ‘experts’. Those who back the knowingly false nonsense spoken about LLMs expose themselves as either liars, incompetent, or in the most charitable interpretation, wishful thinkers.
Unfortunately I think ML as a field has a lot of bullshit and people twiddling knobs with no understanding of what underlies what they do, despite calling themselves ‘data scientists’. It’s been a huge turn off for me from when ‘big data’ proponents first claimed ridiculous things that don’t seem to have panned out. Plus ca change.
This is not to say that it isn’t useful for anything, it’ll be very useful for spam, fraud, copyright theft (which is a lot of what it actually does anyway), and in the nicer realms perhaps automation of the most rote, pattern-based non-novel activities out there.
For things which have precise requirements and are trivially novel, it is worse than useless, it is actively harmful.
Obviously you can come up with 100 examples of ‘this time it feels different’ things that were meant to change the world but people forget so quickly… equally so with this when chat gpt + friends fail to fulfill the nonsense claimed for them (but do succeed at those things they are good at). People will just act as if they only meant the latter all along…
Have you compared levels of nonsense between generations of GPT? GPT-2 would fall for all silly questions like “who’s the king of the USA?”, but GPT-3 catches many of them. GPT-3 will happily hallucinate and give vague answers about anything you ask it, but GPT-4 less so. It’s not perfect, but it is going in the right direction, and there is real tangible progress. What makes you believe that it won’t improve further?
I’m expecting some performance plateaus to show up sooner or later as a result of it getting progressively harder to source training data that didn’t itself come out of an earlier version of ChatGPT.
A lot of complex tasks reach plateaus where techniques that work moderately well simply don’t improve. For example:
If you want to predict the weather in a temperate climate, you can get around 60% accuracy by predicting the same as yesterday. You can also get similar accuracy by predicting the same as this day last year. You can then build statistical models on top that try to exclude outliers. No matter how complex these models are, you don’t get to 70% accuracy. To get to 80-90% accuracy, you need to do fluid dynamics modelling of the atmosphere.
If you want to translate natural language and you have a dictionary of words, you can do a reasonable job (at least within a language family) translating them independently. You get a big improvement moving to translating bigrams (pairs of words) and trigrams. Above that, you get little improvement.
Dall-E and Stable Diffusion both also got a lot of hype, but they still get fingers wrong. Worse, at least Stable Diffusion is massively racist. Yesterday, my partner used it to generate an image to accompany a blog post. The prompt asked for a student sitting an exam with a robot looking over their shoulder. The first picture was okay (except or some weirdness around the eyes) but about two thirds of them had an Indian person instead of a robot, no matter how we tweaked the prompts. Now, hopefully, that’s because there are a lot of Indian students photographed at robotics competitions and it doesn’t know which of the features in the image is the student and which the robot, but it could equally be racism in the training data. Either problem can be solved only with better-labelled data and that’s expensive.
I can’t think of a single probabilistic process that doesn’t show massive wins early on and then plateau. LLMs will definitely hit that, the only question is how close we are to that point.
LLMs are simply not capable of inferring results from insufficient data, they’re essentially running statistics on words in a corpus with zero understanding of what is being discussed.
The idea that a technique that literally CANNOT do what people claim of it will one day evolve into being able to do them SOMEHOW is my whole objection.
Case in point is tesla’s FSD. Trivially novel tasks are not suited to such techniques nor could they ever be. That’s not to say they’re not useful for some things.
Tesla’s FSD is a fraud, not LLM.
Notion of AI “understanding” anything is irrelevant. It’s philosophical distraction and a tangential argument about semantics. It’s not falsifiable — an AI can conquer the universe, and you can always say it merely executed a universe-conquering algorithm without truly understanding what it did.
So I still think we are on track to make an algorithm that can execute almost any text-based task as well or better than a human. The algorithm won’t have a clue that it exists, beyond parroting how humans refer to it. It won’t understand that it is beating humans at intellectual tasks. Humans will continue to change the definition of AI to make these achievements not count as intelligence.
I never said LLM was a fraud? I said it can’t do what people claim of it because it cannot handle novel input.
When I say ‘understanding’ I mean it modelling reality e.g. understanding physics for a physics question, understanding logic for a logic question etc. That you think that is ‘philosophical’ is umm… ok.
The issue is that when past data is sparse (trivially the case for many realms, e.g. driving, hence why I mention it) and you have literally no realistic model for inference, but rather some unknowable process based on what is perceived to sound like a correct answer, you are going to get eloquent sounding nonsense.
Nobody here nor anywhere else anywhere that I’ve read (and I have read fairly widely) who is promoting what you are promoting here has explained how this can be overcome.
I think there’s a reason for that and the fact you quite literally ignored the first paragraph in the parent post encourages my belief in that.
I think you are far and away too pessimistic about this tech. Instead of approaching LLMs as another tool for translating natural language to computing actions you’re attacking the hype around it. Of course there’s hype, it’s new and cool. That doesn’t matter. There are two important factors about LLMs that matter to me personally:
LLMs feel about as important as databases to me right now but they’re newer, different and not as explored so I could be wrong.
To those people who upvoted OP: have you tried, like really tried to utilize gpt-4 or gpt-3-turbo or any local models to process naturally posed questions and requests into reasonable commands and formatted api responses? That’s one of the powers this stuff grants you. You write a few sloppy sentences about what you want, add preprocessing and extra prompting in the back then with the support of systems that read from the generated output you’re able to use that for good enough end user responses.
And if they don’t like the first gen, generate it again.
It’s just another tool that you should vet for your work. It may require more effort than you want to put in in order to make it useful for your domain but other people have different reqs.
LLMs feel about as important as databases to me right now but they’re newer, different and not as explored so I could be wrong.
I think that’s a great analogy. In particular:
‘To those people who upvoted OP’ or, like, OP himself perhaps? Slightly rude there. Yes I have, thanks. But do go on assuming I haven’t used this technology, as I am sure that is far more convenient.
‘Instead of approaching LLMs as another tool for translating natural language to computing actions you’re attacking the hype around it.’
OK, replace ‘LLM’ with eliza. Do you see the issue?
The problem is whether the technique is capable of doing what is claimed of it. No amount of ‘it’s getting better!’ or digs at me can get around the fact that LLMs are simply not capable of solving trivially novel problems (again, I see all these people criticising me have totally ignored that, very telling).
You can’t correctly infer a model from which to make a determination with sparse data to do so using LLMs, it’s literally impossible.
I find the database analogy utterly bizarre. Databases are precise and follow set rules which you can assess and find out in detail exactly what they do.
LLMs infer things from data sets and by their nature have not one inkling about what they speak.
And again as I’ve said, I’m sure they will be useful for some things. They just won’t be replacing programmers or radiologists or magically changing the nature of knowledge work. My objection is firmly directed at the CLAIMS made for it.
I find the database analogy utterly bizarre. Databases are precise and follow set rules which you can assess and find out in detail exactly what they do.
I use databases for storing and querying data; I’ve seen ChatGPT used for spitballing ideas and napkin calcs for cargo laden airships with accurate formulas and usage of those formulas.
From your previous post:
This is not to say that it isn’t useful for anything, it’ll be very useful for spam, fraud, copyright theft (which is a lot of what it actually does anyway), and in the nicer realms perhaps automation of the most rote, pattern-based non-novel activities out there.
It’s not just spam. It’s idea and lead generation at the very least. https:// rentry airships_gpt_full
But do go on assuming I haven’t used this technology, as I am sure that is far more convenient.
It just feels like you used for a bit then concluded that it was and forever will be a toy. I might be wrong in that assumption. Sorry for making it if it’s wrong.
I use databases for storing and querying data; I’ve seen ChatGPT used for spitballing ideas and napkin calcs for cargo laden airships with accurate formulas and usage of those formulas.
OK so databases are used for spitballing ideas? I mean… no? My point is comparing them to databases (rigid, specific, understandable method for obtaining data, you can even run PLAN commands) is bizarre as LLMs are the precise opposite.
It’s not just spam. It’s idea and lead generation at the very least.
Yes perhaps I was a bit mean there, sorry. I definitely do think there are uses for it, people keep missing that I say that though, perhaps because I was a wee bit too spicy in that OP. I have used it for idea generation myself!
It just feels like you used for a bit then concluded that it was and forever will be a toy. I might be wrong in that assumption. Sorry for making it if it’s wrong.
Nope, as I’ve said over and over again, my objection is based on the nature of LLMs - they’ve been around for a while and I seriously doubt many were claiming they can do what people now claim they can do.
The fundamental issue is that they cannot deal with novel input. They essentially perform a clever pattern match to their giant corpus, algortihmically determining what sounds like a correct answer to a query.
Where data is sparse in that corpus, it has no model of reality to refer to to determine what is a sensible answer or not. It maintains the ‘what sounds like the right answer’ and thus defaults to eloquent nonsense. This is not something that can be fixed iteratively, it’s a limitation of the technique.
There are some fields (driving is a good example) where there is infinite, trivial novelty (complicated junction, ok now it’s snowing, ok now there’s glare, ok now it’s icy ok now there’s fog ok now there’s 3 vehicles doing complicated manouvers with 1 obscured, ok etc. etc.).
My issue is not with LLMs, it’s with people claiming they can do things they very obviously cannot not or that ‘trust me bro’ it’ll iterate to these magical things in the future.
This perception is pushed by people who stand to make literal $bns from this. perhaps $100’s of bns or more + endless ML folks who, I am a little cynical as to how well they understand the fundamentals of what they do shall we say who are equally benefiting from the gravy train. That combined with a number of people who kid themselves and those honestly confused or who don’t understand the technique + fanboys and we see why this hype cycle is what it is.
I can’t stand lies, I can’t stand liars, it’s that simple for me.
This is not to say that it isn’t useful for anything, it’ll be very useful for spam, fraud, copyright theft (which is a lot of what it actually does anyway), and in the nicer realms perhaps automation of the most rote, pattern-based non-novel activities out there.
This is overly dismissive. I use ChatGPT and CoPilot a lot during the day, because it makes me more productive and I can assure you I am not a spammer or a fraudster.
Claiming that LLM’s are useless because they can produce nonsense is like saying that autocomplete is useless because sometimes the option you want isn’t listed in the pulldown. Clearly the world has a different opinion on that.
As for progress, I am not an expert, but so far each generation of GPT has shown remarkable steps forward. If it suddenly stops with GPT4 I am ok with that, because I can already put it to good use.
You intentionally ignored the second part of the sentence there. But again, people prefer to ignore that because it’s much more exciting to imagine that LLMs can do things LLMs can’t do.
I never claimed ‘LLMs are useless because they can produce nonsense’. I think it’s quite telling that critics have to misrepresent these things. And ‘the world’ had a different opinion on crypto from me. It also a different opinion on evolution by natural selection. I’ll leave you to fill in the gaps as to why that’s a bad analogy.
If you’re happy using copilot to essentially plagiarise other people’s code without license where, again, due to the literal nature of how LLMs work, subtle errors that you might miss creep in then fine. Personally I would consider this to be ‘worse than useless’.
It’s a shame that the paper decided to open with cheap shots and stir needless controversy. The problems it describes are real. The C ABI boundary is unchecked and wildly unsafe, and the glue FFI language they propose could make it safer.
The motivating example in the introduction is interesting:
#[no_mangle]
pub extern "C"
fn add_twice(a: &mut i32, b: &i32) {
*a += *b;
*a += *b;
}
I didn’t know this was valid. I guess I assumed that pointer arguments in extern functions always had to be raw pointers? It seems like the semantics guaranteed by &
and &mut
could never be correct when passing pointers from C.
calling, say, add_twice(&bar, &bar) from C results in undefined behavior
Rust gives ABI layout guarantees for a few types. For example extern fn free_t(_: Option<Box<T>>){}
is a valid useful implementation taking a nullable pointer and freeing it.
But it’s caller’s responsibility to pass valid data. Rust enforces this on its side, but C can’t.
and freeing it.
Tangent, but note that assuming you care about portability and haven’t done things like setup custom allocators, you should only free something allocated by Rust like this, not something allocated in C with malloc. Freeing rust-allocated pointers in C or C allocated pointers in rust is a way to get undefined behaviour.
FreeBSD’s tar supports --zstd
and --lz4
[1], both of which are great for when you want fast compression and decompression. 55% compression seems pretty low from gzip, that’s about what I get on random data with zstd and lz4 with settings where I/O remains the bottleneck.
I haven’t used gzip for a long time. Where I care about compression ratio at the expense of everything else, bzip2 and then xz displaced gzip. Where I want compression without impacting throughput, lz4 took over. These days, zstd has a great range of options and gives a better compression-ratio:speed tradeoff than gzip for everything I’ve tested.
[1] The article mentions that GNU tar supports external tools, the nice thing about the built-in support is that tar x
on FreeBSD detects all of these compression headers and does the right thing, without needing to pass z
, Z
, J
, and so on when decompressing.
Shouldn’t be, I got it from a reputable source.
Really the only advantage of tgz is compatibility, only bz2 comes close and it’s slow. So tgz exists only for slinging, especially many small files as the “solid” compression will be advantageous compared to zip files (the other ubiquitous format, even more so as AFAIK Windows still does not have built-in explorer support for tgz).
it’d be cool if more gnu userland tools started supporting libarchive. it’s made things so much easier to work with on the bsd side: https://libarchive.org/
Or if Linux distros would just ship bsdtar instead of GNU tar by default. It’s far more pleasant to use and one of the things that keeps annoying me when I’m in a Linux terminal.
bsdtar (libarchive) is a dependency of pacman, so we ship it by default in Arch. I agree with you that it is far more pleasant to use!
Funny enough, Microsoft announced today that they are adding support for tar, gz, etc. through libarchive
. Wouldn’t have believed this was ever going to happen 10 years ago!
It’s really not clear from that article whether this is support built into Explorer (the UI). They’ve been shipping some sort of tar for a while in the terminal.
Who wouldn’t have believed this? Anybody who didn’t read the Halloween Documents in the 1990’s.
Embrace, Extend, Extinguish.
Disclaimer […] These audits should not be construed as reflecting material safety or security properties of Rust crates.
How should they be construed?
Also, “just because we’ve audited these against our threat model that doesn’t mean they’re suitable for your threat model”.
Disclaimer: I work adjacent to some of the people working on this but this is me opining in ignorance.
I’d love to see multiple organizations publishing audits like these so other consumers can get a sense of the state of things in aggregate.
I’d love to see multiple organizations publishing audits like these so other consumers can get a sense of the state of things in aggregate.
Looking at the cargo-vet
documentation, I see https://mozilla.github.io/cargo-vet/importing-audits.html#the-registry.
ADTs (enums with data) work really well in Rust, and it’s a widely-applicable feature that could easily work in other languages. I’m surprised other languages haven’t added them yet.
I think everyone actually have added an equivalent already
Haskell is in the same boat as C# — pattern matching without exhaustiveness
GHC has it under -fwarn-incomplete-patterns
which is part of -W
, so it’s hardly the same boat as C#.
Reasonably, Go programmers are likely to insist that the memory allocated from Go be released automatically. Thankfully, Go has a mechanism for this purpose. You put the C data in a Go structure which is subject to automatic garbage collection. Then you tie the instances of this structure to a “finalizer” function which will be called before the Go structures is garbage collected.
The author misunderstands finalizers: they’re not guaranteed to be called before a value is GC’d.
The finalizer is scheduled to run at some arbitrary time after the program can no longer reach the object to which obj points. There is no guarantee that finalizers will run before a program exits
A finalizer is guaranteed to be called before its object is GC’d, if the object is GC’d. What that statement means is that the process may exit before GC runs or before GC collects that object. (Otherwise the process would be required to run a full collection before calling exit, which is pointless for anything but finalizes.)
Quite often this doesn’t matter because the resource being cleaned up by the finalizer is already cleaned up by the process exit, such as a heap block or file handle.
The key point, which is largely omitted in the docs but which is why the docs are slightly confusing, is that object deallocation is not observable in the abstract machine. Once an object is unreachable then you have no way of referring to it. If it does not have a finaliser then, at some point, as an implementation detail, the runtime may reuse its memory. Because this operation is invisible in the abstract machine (by design, it simplifies a lot of things), it doesn’t make sense to say that a finaliser runs between the object becoming unreachable and behind deallocated: the second event is not observable and is not guaranteed to happen (it’s valid to just leak unreachable objects as long as doing so doesn’t crash the program and that’s the best strategy for a lot of short-lived programs).
From an implementation perspective, the finaliser is called before the object is deallocated by the GC, but the docs try to avoid leaking the implementation into the language definition.
Agreed. I think the only guarantee is that
As far as I understand, there is no guarantee that any finalizer(s) attached to a value will be executed before that value is GC’d by the runtime. I’m happy to be corrected, if you can point me to something that suggests otherwise!
edit: The ultimate tl;dr here is that finalizers != destructors
edit 2: I think I might be confusing the discussion. A finalizer will indeed be executed before its corresponding value is GC’d (in a certain sense) — but the point I’m trying to make (very ineffectively) is that there is no guarantee as to when a value is actually GC’d in that sense, and so applications can’t treat finalizers as anything other than best-effort optimizations.
I mean, we can look up how this stuff works.
Unless you suspect that the documentation is flat out wrong, I’m not sure why you’d read the code instead? :)
The author misunderstands finalizers: they’re not guaranteed to be called before a value is GC’d.
I’m finding the use of “guaranteed” to be difficult here. I think it is guaranteed with caveat. If the finalizer goroutine completes, then the finalizer did run before the memory was freed by the GC. (same source, first paragraph)
There is no guarantee that finalizers will run before a program exits
That seems like a disclaimer for a different case that exit/abort/crash doesn’t run them, but this doesn’t mean they won’t (eventually) run in a continuously running program.
Even in languages with deterministic destruction (C++, Rust) destructors aren’t guaranteed to run before program exits, because anything can call exit or quit the main thread without giving other threads a chance to unwind.
My understanding is that when a finalizer is executed is fundamentally non-deterministic. It is guaranteed to not execute before a value is GC’d, but it is not guaranteed to execute after a value is GC’d.
edit: I am not expressing my point effectively; see this comment.
This is not how I understand the docs. The logic is that if a value is GCed, it will definitely run the finalizer associated with it. There are just many caveats/quirks/footguns that may indefinitely delay or prevent a value from being GCed.
This sounds a bit like how “drop” isn’t guaranteed to be run in Rust but you can, outside of for safety reasons, pretty much assume that it does. GC languages tend to have even more issues with this because when a value is free’d is not deterministic and, for any implementation, there may be a number of reasons why a value may not ever be collected.
I’m surprised that drop
isn’t guaranteed to run, I always assumed that types that implement Drop
are treated as linear. Do you happen to know of any situations where it might not run?
If there’s a cycle, or mem::forget.
https://cglab.ca/~abeinges/blah/everyone-peaches/
This whole “you can’t assume drop
will run to uphold safety invariants” came to a head with the leakpocalypse and the “Pre Pooping Your Pants” post (now Pre Pitting Your Peaches).
Nobody who says C/C++ thinks they’re the same language. They’re just talking about properties these both languages share, which the smart pointers and templates and RAII and exceptions and iterators and all these other features and modern patterns of the totally different language with different paradigms still haven’t managed to meaningfully change.
“/” is short for “yes I know you have vectors, but []
is still not bounds checked and .at()
is only used for well-actually, and CMake is just as annoying for both languages”.
Nobody who says C/C++ thinks they’re the same language.
e.g. HR often use it as a just another keyword without knowing anything at all about it. Some contemporary managers or architects use it as a pejorative shortcut for something „obsolete“ and „legacy“ while they are reinventing the wheel, unix, rediscovering old patterns or models and repeating old errors.
At least in the job descriptions it would be useful to specify, whether they do a) just C, b) mostly C++, c) something like 50:50 mix of both or d) this is just another irrelevant technology mentioned in the job description.
Yeah. Given that recruiters still can’t tell Java from JS I didn’t even think to count them.
I assume TFA meant contexts like articles and comments from programmers.
Rust - love it. So safe and blazingly fast, in particular compilation.
In particular I like to have so many dependencies: https://github.com/orhun/rustypaste/blob/master/Cargo.lock Feels cozy.
https://github.com/orhun/rustypaste/blob/master/Cargo.toml#L26
It doesn’t seem unreasonable. A web server. TLS. Globs, regex, date/time processing.
Note that Rust libraries are typically split into tiny components, so transitively there’s many of them, e.g. cookie parser is a crate instead of being copy pasted code in a web server monolith. It actually helps code reuse.
Complaints about number of deps to me sound like “I can’t eat a pizza cut into 12 slices, that’s too many slices! Cut it in four instead!”
This is a pitfall of looking at the Cargo.lock
. axum
is not used in this project. It’s not even compiled. It’s there, because it’s part of a disabled optional feature of shuttle-common
that supports multiple back-ends.
It seems both are used:
21:53:15|~/tmp/rustypaste|master✓
λ cargo b -q -F shuttle
21:53:55|~/tmp/rustypaste|master✓
λ nm target/debug/rustypaste | rg actix | wc -l
4008
21:54:04|~/tmp/rustypaste|master✓
λ nm target/debug/rustypaste | rg axum | wc -l
286
I’m looking at the latest commit (f20e2d8d), and I’m not seeing axum
it either cargo tree
or cargo build
output. Maybe those symbols are from some panicking placeholders that just print “axum is disabled?”
22:13:31|~/tmp/rustypaste|master✓
λ git rev-parse HEAD
f20e2d8d12ceecf65ac60a0acb4b59277b148fac
22:13:36|~/tmp/rustypaste|master✓
λ cargo tree -F shuttle -i axum
axum v0.6.18
├── shuttle-common v0.16.2
│ ├── shuttle-proto v0.16.0
│ │ └── shuttle-runtime v0.16.0
│ │ ├── rustypaste v0.9.0 (/home/matklad/tmp/rustypaste)
│ │ └── shuttle-actix-web v0.16.0
│ │ └── rustypaste v0.9.0 (/home/matklad/tmp/rustypaste)
│ ├── shuttle-runtime v0.16.0 (*)
│ └── shuttle-service v0.16.0
│ ├── shuttle-runtime v0.16.0 (*)
│ └── shuttle-static-folder v0.16.0
│ └── rustypaste v0.9.0 (/home/matklad/tmp/rustypaste)
└── tonic v0.8.3
├── opentelemetry-otlp v0.11.0
│ └── shuttle-common v0.16.2 (*)
├── opentelemetry-proto v0.1.0
│ └── opentelemetry-otlp v0.11.0 (*)
├── shuttle-proto v0.16.0 (*)
└── shuttle-runtime v0.16.0 (*)
The number of transitive dependencies is quite important when you consider the attack vectors of a rogue library. To take you analogy back, each slice is cooked by a different chef. Each has a chance to be poisoned, and you eat all the pizza.
Here’s the list of chefs (and their subordinates) you need to trust:
$ cargo tree --format "{r}" | grep -o "https://github\.com/.*"|cut -d" " -f1|sort -u|cut -d/ -f4|sort -u
abonander
actix
alexcrichton
Alexhuszagh
allan2
allenap
Amanieu
bancek
bitflags
bluss
bojand
briansmith
BurntSushi
bytecodealliance
Canop
carllerche
chyh1990
contain-rs
cryptocorrosion
ctz
cuviper
deprecrated
dguo
dimbleby
djc
dropbox
dtolnay
fizyk20
francesca64
Frommi
Geal
gyscos
hannobraun
hsivonen
hyperium
indiv0
inotify-rs
jean-airoldie
JelteF
jonas-schievink
kennytm
Kimundi
Lokathor
magiclen
Manishearth
marshallpierce
matklad
mehcode
mitsuhiko
mvdnes
notify-rs
nox
orhun
paholg
pyfisch
rust-cli
RustCrypto
rust-itertools
rust-lang
rust-lang-nursery
rustls
rust-random
rutrum
seanmonstar
serde-rs
SergioBenitez
servo
smol-rs
Soveu
srijs
Stebalien
sunfishcode
taiki-e
tailhook
TedDriggs
time-rs
tkaitchuck
tokio-rs
toml-rs
unicode-rs
vorner
You can be absolutely certain that one of such organizations/users is at reach to be exploited by a malicious state actor.
That is true, but you have to consider what are the alternatives. Usually it’s either write the whole thing yourself from scratch, which is highly impractical for most projects, or use dependencies from your OS’s package manager.
Do you know how many maintainers an average distro has? I don’t think any distro does vetting that could catch a state actor. And even good maintainers can’t do much beyond just “LGTM” the tons of code they pull in. And you usually don’t get fewer transitive dependencies, it’s just that package managers using precompiled binaries are worse at showing you the full tree.
In the end transitive dependencies are a form of a web-of-trust, so it’s not a big set of random people. If you’re really at risk of state attacks, you need to review every line of code you use. Rust has cargo-vet and cargo-crev for these.
You’re usually better off using the stdlib, and then implementing pieces of what you need. Really the only thing you should ever pull in is a cryptography and hardware abstraction library.
“Web-of-trust” only works where entities are verified in real life, like what GPG does. This is not a web of trust package systems have… it’s a web of “hopefully Im too small to matter to be attacked”.
It doesn’t seem unreasonable. A web server. TLS. Globs, regex, date/time processing.
That by itself isn’t, but you need to look at the actual crates.
Many crates are way too bloated, with unnecessary dependencies, and they’re being pulled in by other crates without concern for efficiency.
It’s a cultural problem. Why is everyone pulling in serde
, when nanoserde
already covers 90% of use cases? Answer: laziness.
Why is everyone pulling in
serde
, whennanoserde
already covers 90% of use cases? Answer: laziness.
I’m uncomfortable nowadays with large crate dependency graphs, but I think this is a poor example with an overconfidently uncharitable conclusion.
nanoserde
may suffice for an application that works only with the few, concrete serialization formats supported by nanoserde
, but serde
, as a generic infrastructure for supporting all formats, seems more useful for a library.
I’m sure many crates have dependencies that could be switched out to reduce bloat, but one would need to remove the heavier dependency from the entire graph, which, for a crate with a large dependency graph, may be difficult for such a standard choice as serde
. If one doesn’t, then using an uncommon choice like nanoserde
could worsen the bloat.
Attribution to laziness is itself a lazy explanation.
So you use less known, less supported, worse documented, less interoperable library, wrangle with your whole dependency tree to avoid pulling in serde anyway, write more glue code, and you save a couple of KB from your executable? So lazy.
The problem with bloated dependencies isn’t executable size, it’s compile times.
there isn’t even a practical difference in dependencies.
There’s a big difference. Serde pulls in syn, pro_macro2 and quote. That alone bumps up my clean compile times by 15-20 seconds.
All the points you mentioned are valid, but I doubt that the majority of library authors actually make an informed choice about their dependencies, evaluated alternatives, and measured their compilation times.
Most people follow the herd, and pull in serde, clap, actix without doing their research on alternatives. This is a textbook definition of laziness.
It’s your assumption that compile times matter more than run-time performance, file size, development time, functionality, or reliability. This is not universal, and people who don’t have the same values as you aren’t necessarily lazy.
Just to avoid some misunderstanding here: I’m not calling everyone who uses serde lazy. Obviously there are good reason to use that crate. It’s awesome. I also don’t believe that compile times matter more than the other things you mentioned.
My point is that many, many library authors pull in large dependencies for no net benefit. Compile times are one of the most noticeable examples, because they directly impede my productivity.
I’m talking about cases where they use maybe 1-2% of functionality of the crate. Cases where picking a lighter dependency increases runtime performance, without being brittle or poorly documented. This is what I’m referring to.
I think the way you’ve presented this situation is a false dichotomy, where picking the “standard choice” gives you all these other benefits.
GradIEEEnt half decent was one of the most insane experiments I’ve seen!
Every entry by tom7 is fantastic.
I keep wondering how a programming language can make an IO bound application blazingly fast by implementing in Rust (assuming you have asyncio and threading support in existing implementation).
Then, you have this gang wanting to write Python FFI to an underlying C library in Rust and promising performance improvements…
Fighting this myth occupies part of my day at work as a principal.
I get a lot of perf gains at my company rewriting components or applications in Rust, but it’s usually replacing Java which doesn’t really have a good async story save for Netty, Node.js, or Python which wasn’t using asyncio. We have some Python applications using asyncio and I must confess to being unimpressed.
e.g. I replaced a library built on an HTTP client used in Node.js (this was async I/O) with a native Rust library that exposed a NodeJS API via FFI. The Rust library emitted data using a Kafka Producer client instead of HTTP. Tail and median response latencies, reliability, overall efficiency all greatly improved. A big differentiator is that I’m not just able to do the work faster (parallelization, concurrency), I’m able to do more with less (efficiency).
Another example: I have an application that processes a Kafka data stream that decompresses to about 5.5 GB/second. The Java applications consuming this same exact topic have, 64, 128, or 256 instances, each an individual server deployment w/ a whole JVM. The 128 instance deployment has 1,100 cores and 2.5 TB of RAM allocated.
I’m processing that in Rust doing very similar work with about 5 seconds of consumer lag with 10 instances, ~65-75 CPU cores utilized during peak throughput and 100 cores allocated. 7.8 GB - 8 GB RAM utilized, 15 gigabytes allocated. The Java applications were written by some of the best backend developers at my (not small) company.
Another example: rewrote a relatively low-level library function that looks up IP addresses. Node.js version took double-digit microseconds, the Rust and Java versions I wrote both benchmarked at ~130-150 nanoseconds. I’m not even sure how to write an efficient bitwise prefix trie representation in NodeJS, but if such a library exists for Node, I couldn’t find it. I’d probably just reuse the Rust library in a Node app. This library function gets invoked trillions of times per day at my company, this isn’t small potatoes.
I have many examples for this because much of my work has been upgrading/replacing unreliable and inefficient systems and libraries the last few years. It’s not a panacea, you have to measure and you have to understand how things work well enough to accurately judge where wins can be obtained. I don’t think it being non-trivial justifies prejudicially ripping out a chunk of your engineering decision tree.
Your job as a principal is not only to be Dr. No but also to equip people to accurately judge, test, and evaluate engineering outcomes themselves and w/ minimum time staked.
There definitely are a lot of valid use cases where you can get visible performance gains. I guess it will mostly be when you move some implementation from byte code (virtual machine) based languages to natively compiled languages.
I am particularly wary of using Rust as a Python FFI to call into an underlying C library when there are decent tooling to use Python CFFI to call into C library without the intermediary Rust bindings.
It’s not a panacea
Yes, you need a good reason to rewrite something.
you have to measure and you have to understand how things work well enough to accurately judge where wins can be obtained.
This is the key, fully agree.
Your job as a principal is not only to be Dr. No but also to equip people to accurately judge, test, and evaluate engineering outcomes themselves and w/ minimum time staked.
Not being a luddite here trying push back anything Rust. When there is proposal, I would like to see data driven approach (prototype & measure).
I guess it will be mostly be when you move some implementation from byte code (virtual machine) based languages to natively compiled languages.
That’s part of it but not even most of it. There are natively compiled languages out there like GHC Haskell, Golang, and OCaml that can’t get super close to what i can do in Rust. I say this as someone well known for teaching and using Haskell professionally. The bitwise prefix trie in Java and Rust being the exact same in a benchmark is one exception but that isn’t a compiled language, not that I think it really matters here.
On the side of GC, tail latencies, etc. Discord’s blog post here is good: https://discord.com/blog/why-discord-is-switching-from-go-to-rust
For efficiency/CPU usage, https://andre.arko.net/2018/10/25/parsing-logs-230x-faster-with-rust/
IME benchmarks like the programming language shootout understate and minimize the differences and typical outcomes I see when I make changes to an existing production application.
I am particularly wary of using Rust as a Python FFI to call into an underlying C library when there are decent tooling to use Python CFFI to call into C library without the intermediary Rust bindings.
If that makes sense for your application that’s great but it usually doesn’t shake out as nicely as you’d hope for. It’s not enough to have librdkafka
bindings, you need something to manage the producer in a thread-safe manner, do some data processing and serialization before sending it over the wire, etc. etc. etc. It’s faster and more reliable if that I just do that in Rust.
Speaking as someone who patched librdkafka recently I am pretty sure I could make a faster Kafka Consumer in and of itself in pure Rust and leverage that to make the aforementioned application processing 5.5 GB/second more efficient.
You’d be surprised how often you don’t want the limitations of Python’s runtime, GC, and inefficiency. There are a number of things I can do more efficiently and safely with Rust bindings to librdkafka
than you could with Python C FFI talking to librdkafka directly. For one thing, I can read and share data with C safely and without copying. e.g. https://docs.rs/rdkafka/latest/rdkafka/message/struct.BorrowedMessage.html
I leverage BorrowedMessage
in the aforementioned application that processes 5-12 gigabytes / second in real-time.
Further, in Rust I have things like tokio, async
/await
, etc. I can do things with ease that would be tremendous work to make bug-free in C and be virtually unmaintainable for most working programmers.
Rust isn’t adding any overhead in your alternative. It’s logic that would end up living in either Python (slow, untyped) or C (unsafe, error prone) anyhow. The FFI between C and Rust isn’t like Python and C.
All that aside, not much of my Rust work involves wrapping a C library in the sense you mean unless you’re counting glibc or something. The Kafka clients are the main thing for me there. The native Rust libraries are often better when they have everything you need.
I’m not trying to personify the Rust Evangelism Strike Force here, it’s just that it felt like you were judging from experience in industry that didn’t include exposure to the kinds of applications and workloads I deal with.
In the era of SSDs and multi-gigabit connections I/O bound isn’t what it used to be. You can get accidentally CPU-bound on silly things, especially if you use a high level web framework.
True, we saw this happen in NFS over NVMe. Saturating the available network became the new challenge in the NFS server implementation.
FreeBSD’s GEOM stack hit a lot of this a decade or so ago. It was beautifully designed with clean message-passing abstractions between layers. They added some overhead but with 10ms disk response times the latency was in the noise. NVRAM-based storage suddenly turned them into bottlenecks and there was a load of work done to allow a single thread to do synchronous calls through the stack.
Almost every nontrivial C extension out there has threading bugs that are currently impossible to hit because of the GIL. It will take an enormous amount of effort to make all the old C code thread safe. That means in practice you may not be able to use a lot of useful libraries that rely on C code in a multithreaded python interpreter.
Sure, but this is how we make progress with software:
When I introduced Sidekiq to the Ruby community, there were still lots of gems with threading issues, including Rails itself. Now the ecosystem is thread-safe as Sidekiq usage grew and folks fixed the threading issues. It just takes a few years.
Data races are famously non-deterministic. Your tests will likely pass and you will still release a heisenbug into the wild.
I hate to be that guy who suggests rewriting in rust, but I came to this thread to lament the fact that my current favourite pastime (writing python modules in rust for the enormous performance boost) would be going away.
Maybe though… it wouldn’t be a bad idea?
A lot of these extensions are wrappers for third-party libraries, so what you’d be doing really is rewriting the third-party library and committing to maintain it forever.
Also, it’s not always only C – if you think you can build a better BLAS/LAPACK implementation (required for NumPy) than the current Fortran versions, you’re welcome to try it. But I think there’s a reason why Fortran continues to be the base for that stuff, and it’s not “because they hate Rust”.
A Rust adapter-wrapper from Python to some Rust and some C is still a totally valid pattern where you don’t rewrite the whole stack, but you add some correctness (say parsing, state machines, thorny inplace processing). It can be a spectrum.
A lot of these extensions are wrappers for third-party libraries, so what you’d be doing really is rewriting the third-party library and committing to maintain it forever.
I don’t mean to be glib, but isn’t that a bit of an entitled attitude that places an unfair burden on open-source maintainers? I see no reason that they shouldn’t commit to only maintain it as long as its useful for them. If someone else finds it useful, then they can either pay for support or maintain it themselves.
That’s assuming the Python API even makes that possible. For example the buffers API allows python side to cause data races and Rust can’t prevent that: https://alexgaynor.net/2022/oct/23/buffers-on-the-edge/
Parallelism is not the same as a speed-up. If a task takes 100 CPU seconds with Python, 10 threads/processes with full parallelism means 10 seconds to get a result, and those cores can’t be used for other things. The Rust equivalent might only take 1 CPU second on a single core. In some situations parallelism is good enough, but optimization tends to be much more valuable if you can manage it.
(Longer discussion: https://pythonspeed.com/articles/do-you-need-cluster-or-multiprocessing/)
Rust has a very strong unique ownership model. Python allows arbitrary aliasing. Two Python threads can share any objects that are returned from Rust. I think the only solution to this is to make everything that is exposed to Python adopt the Sync
trait. Anything in Rust that is mutable and Sync
is unsafe
. The simplest way of doing that mostly correctly is to expose Sync
proxies that acquire a lock before calling into the real Rust objects (Rust has some nice lock guard types for doing this, so the unsafe
bit is in the standard library). It’s not clear to me that this would end up being easier than exposing C/C++ things.
Rust’s concurrency benefits rely on the Rust type system. When you are interoperating with code that has weaker constraints then there are lots of places for bugs to sneak in.
Rust Python: https://github.com/RustPython/RustPython
Unless the C code is doing stuff like using OS-level resources assuming there’s only one instance of it running (which is ekhm anyway because there can be multiple CPython processes,) it’s still going to run under GIL within the subinterpreter.
The haiku at the end has the wrong syllable count. LLMs cannot count syllables or letters in words reliably. I have been informed that this is an artifact of the tokenization process.
I think LLMs are neat, but a lot of “this time is different” just assumes that the current progress will continue. Maybe? I don’t have a prediction one way or the other. But I will say that at the current level of technology, if you lose your job, it was a bullshit job.
It is indeed an open question whether the recent LLM progress was just a fluke, and it’s already approaching the ceiling, or is it just a baby step in a whole new field. For now, it seems like it’s the latter. GPT 2 -> 3 -> 4 were noticeable improvements, and there’s no sign of them stopping. We still have possibility of both developing more powerful hardware and throwing more data at them, as well as continued advancement in reducing model sizes and improving training. We’re also at inflection point where LLMs are useful for preparing and cleaning training data for themselves.
if you lose your job, it was a bullshit job.
That’s meaningless. There was a time when being a messenger was an important job. There was a time when being a watchmaker was a proper craft.
Is programmer a bullshit job? Lawyer? Pharmacist? Psychotherapist? Is Prompt Engineer a serious job?
I mean “Bullshit Job” in the sense of the kind of job in David Graeber’s book of the same name and I mean if you lose your job to an LLM with the capabilities it has in May 2023. There are lots of jobs today that are made more efficient by an LLM, but if it can be made so efficient that it can be eliminated entirely, I don’t think the job needed to be done in the first place. I dunno, maybe some companies can go from having three people in marketing down to two, but I can’t think of anyone at my small company who we could eliminate today with an LLM. Everybody does a lot of different small things, and getting faster in one area just means we can do something else with the left over time.
One of my grandfathers was a traveling salesman, and part of his job was adding up the numbers for his sales. The adding part was made obsolete by Lotus 123, and travel part is being obviated by Zoom. I’m not totally sure, but I think his old job doesn’t exist anymore because the company went broke due to globalization.But now I have a job that didn’t exist then. I don’t think it makes sense to worry about technological unemployment. People have enough to do to keep us all busy!
As I recall, Graeber deliberately defines a bullshit job as one that the person doing it thinks is bullshit. If you start defining other people’s jobs for them then that’s not quite what he was saying, besides being ruder and perhaps patronising.
Ironically, I think many of Graeber’s bullshit jobs are fairly safe from AI: a lot of them are the kind where the employer wants warm bodies.
I remember I was visiting San Francisco when I read Bullshit Jobs and the neighborhood I was visiting had little advertising banners for the neighborhood itself up on the lamp posts with a hashtag on them. (I can’t find a picture of it on my phone, but it was something dumb like “#feelmore in Filmore!”) I remember thinking that it was clearly a bullshit job to have to think up the hashtag for the campaign, because there was no way any human being would ever bother to tweet the hashtag or search for it. I bet you could get an LLM to spit out hashtags for a neighborhood very quickly.
I think you’re stretching David Graeber’s Bullshit Job definition. We have obviously useful value-producing creative and intellectual jobs threatened by AI. Not just data entry assistants to middle-managers for regional branch compliance advisory departments, but doctors, graphic artists, and programmers that until recently were thought irreplaceable. I do expect that for now many will keep jobs to supervise AI and have things to do thanks to Jevon’s paradox, but if we get closer to AGI, it will turn things upside down.
We still have possibility of … throwing more data at them
Do we? What data have they not used that they could? I find it hard to believe that a company with such enormous financial resources would not already have, to all intents and purposes, exhausted all possible training data.
We’re also at inflection point where LLMs are useful for preparing and cleaning training data for themselves.
Are we? How do we know that? Has it happened? Can you give a reference?
I think there are some realistic jobs that could feel threatened. GPT-3 may not be great at spitting out correct python code (in my experience), but it has been exceptional when I ask it for very formulaic stuff. I’d expect copy writers, maybe people dreaming up marketing campaigns, legal interns typing up form letters, and anything that plays into its strength of “Make up something that sounds reasonable” should be concerned.
That said, I believe this will then add jobs onto people checking the output, doing editing, and the like. Similarly, for the image generating AIs, I could see smart artists adding a “Artisanal computer graphics made by a human” sticker onto their work and charging more as the flood of AI-generated fluff starts floating around.
LLMs will likely impact jobs that today are needed, but that doesn’t mean the job isn’t valuable to someone today.
I say this entrenched in the “ChatGPT couldn’t spit out a single working program for me” camp, seeing AI as an assistant, not a replacement, in any field that requires correctness (such as compiling code).
It’s very interesting that Apple’s thumbing its nose at Google by including in Safari the JPEG XL format which Google removed from Chromium.
Firefox might be convinced to add it now that WebKit has, as their position up till now was “neutral”.
Firefox’s more detailed position has been along the lines of “we’ve added it behind a flag in nightly but we’re not rushing to roll it out because it’s not clear that it’s a winner and it kinda sucks that no memory-safe decoder exists yet”. Hm, I wonder what Apple is doing for the decoder – probably just libjxl sandboxed like other codecs?
Even if Mozilla is scared to add its flag to even work in beta branches, we have a consolation in Librewolf (and other forks) allowing users to enable JPEG XL it without needing to running nightly specifically.
From Chromium behind a flag, with a flagged-feature deadline that was extended a couple of times without activity in between. So where’s the ecosystem enthusiasm?
Had Chromium simply enabled the feature, people would be screaming murder on how Google unilaterally defines what enters “the web platform”, and how that was only done to complicate matters for new implementations by adding features upon feature with the sole purpose to build a moat.
JPEG XL was a collaboration between a lot of different parties to be something without royalties, efficient, open source, and could losslessly compress the beloved JPEG. In asking for this flag to be added back you had team members from GIMP and Krita fighting alongside Adobe and Instagram–
.jxl
is closer to universally liked than hated/lukewarm. Compare that to WebP which was Google’s creation and was foisted upon the net while having serious flaws vs. JPEG.I wonder if that’s just for the web, or will they eventually move away from HEIC? Getting rid of HEIC would be a huge win for royalty-free codecs.
I don’t think they’re going to go away from HEIC. It is the “raw” format of the iPhone camera now. The new Safari also added it as a supported image format.
Well, DNG is the raw format of the iPhone camera ;-) HEIC is arguably the “native” format, though, yes.
I think quite a few cameras are using it now too.