Hacker Newsnew | past | comments | ask | show | jobs | submit | more pornel's commentslogin

Threads don't support cancellation in any reasonable way. Cancellation is immensely useful for networked applications and for GUIs.

Threads make it difficult to fully use CPU and network, without over-subscribing either one. If you start handing off tasks between threadpools, you're on the path to reimplementing futures (or you work on callbacks/events, which make the code fragmented, and which async/await was meant to be a syntax sugar for).

The alternative for cancellation and timeouts requires weaving a Context object like golang does, and then having issues with leaf code naively calling functions that don't obey the Context properly, which is only marginally better than pains with non-async functions in async code.


Everything you're describing goes back to problems with thread APIs. I agree that threads as implemented are very coarse grained and limited. What I dislike is the idea of inflicting an explosion of cognitive load onto the programmer to manually manage things instead of thinking about how to implement a better kind of thread.

The latter is what Go did. I'm not a giant Go fan but not having async is far and away the best thing about the language and makes up for almost all its other faults.

Anything the language makes the programmer think about detracts from the programmer's ability to think about the actual problem they are solving.

BTW Rust is still superior to C++ and I use it, so I am not dissing Rust too badly. The async cancer is found across the entire ecosystem, not just Rust, so my comment was more against async programming in general as opposed to getting threading right. If we could get threading right we would massively simplify all programming everywhere.

Ultimately it boils down to the fact that it's 2024 and we still run everything on 1970s operating systems.


I don't get how can you think Golang does it better.

Its async is not easily composable. Anything beyond async 101 becomes a tangled web of DIY goroutines, wait groups, channels, callbacks, special empty signal channels for selects, and the Context objects which need careful management to be shared but not shared too much to cancel and time out right parts at the right time.

And then all of that has to be thread-safe, even though golang built-in types aren't. You need to pay sync overhead even for I/O-bound workloads or thread-per-core designs, because you don't control the fat runtime, and some of your green threads may be real.


I suspect that most the hate for Rust's async is from overuse of tokio's multi-threaded spawn(), as if it was the `go` of goroutines.

Tokio's mt spawn adds burdensome Send and 'static requirements, and often gives too fine granularity, especially if the tasks still need to return results to their caller.

spawn() is often replaceable with join_all and streams. These allow same-thread temporary data, and are runtime-agnostic.

The other self-inflicted pain is stubborn avoidance of boxed futures. Every escaping pointer in golang is heap allocated, and nearly everything goes through interfaces. If you allow Box and dyn that often in Rust, you can skip a lot of the type system and lifetime complexity too.


Pin is a state rather than a property of the data itself.

This has a very nice effect of allowing merging and inlining of Futures before they're executed.

It's similar to how Rust does immutability — there's no immutable memory, only immutable references.


Rust is already popular and old enough to have terrible Enterprise Rust code bases.

There are a few things working in Rust's favor:

* unsafe code is used to build safe abstractions around it, so most users don't have to write unsafe code themselves. It is easy to forbid use of unsafe blocks in your own codebase. You can flag unsafe code during code reviews, and have a policy who is allowed to write unsafe code.

* Rust leans on open-source dependencies a lot. Commonly used libraries are decent, since the community can band together to improve or replace them. This makes Rust applications mostly "glue" code, where there's less room to mess up in novel ways.

* the language allows defining strict library APIs which are harder to misuse. There's Clippy checking for common mistakes and sloppy code.

Rust already assumes that it will be written by less than prefect programmers.


The examples of dithering that look low-contrast and overly bright are due to incorrect gamma.

The diffusion algorithms don't inherently make images brighter. They require working in the right color space, linear light in this case.

This color space error is less visible when dithering to many colors, because the difference between the most similar color and dithered color is small, so the (incorrectly) diffused error is small. But dithering to 1 bit is the worst case.


Passing Acid3 is a nice milestone, but realistically that's a 16-year-old test without modern performance requirements. $1 million is wild for an open-source hobby project, but sadly it doesn't buy many person-years at competitive salaries.

For Google and Apple browsers are loss leaders for their bigger business, so they have infinitely deep pockets to play Fire and Motion[1] with each other by adding more and more stuff to the platform, and setting higher and higher performance and security/privacy goals. Once you implement the first 90%, there's the harder second 90% to implement, and the goal keeps moving. And that's before you even have to waste time fighting bug-compatibility caused by the Chromium monoculture and Google's "oopses" serving non-broken code only to Chrome.

[1]: https://www.joelonsoftware.com/2002/01/06/fire-and-motion/


it seems to me that, if we could clearly define and document a useful subset of browser features, and start targeting that, it would help tremendously with long term viability and sustainability of hobbyist browser implementations. maybe starting with what dillo supports today?


That’s terrible for developers though. It’s already a moving target and having several moving targets to pick from doesn’t sound fun


Sounds more like the subset would be a static target that you could confidently assume that works.

Which is sort of what I expected from AMP and Gemini.


How could it be a static target though? That doesn't seem practical.


if it is a strict subset, why is that harder?


There's over a decade of real-world data available from Tesla and Leaf, and the batteries are very long-lived: they degrade about 1%-2% per year with a good battery management system, and around 3% per year with Leaf's weaksauce one.

Additionally, batteries are getting cheaper and more energy dense, so when it's time to replace them, you'll probably get an upgrade for cheaper. Leaf started with 24kWh batteries, and now you get 40kWh for the same price, and a 64kWh upgrade option.

People often extrapolate from their experience with cell phone batteries, but these "lithium" and those "lithium" batteries are very different. There are different chemistries, different conditioning with active cooling/heating, different rates of discharge, and a big difference in redundancy when you have 1 cell vs 7000 of them.


I've had e208 from on.to. It's a lovely nimble city car.

The downside is that it charges at 60-80kW, and it's not especially efficient car either. Purely from BEV perspective it's a low-end performance for a mid-range price.

I've heard that e3008 is better, but the first gen EV powertrains from Stellantis just weren't good.

ID.3 is a bit better with charging speed, and Hyundai/Kia's e-GMP platform runs circles around them with 2-3x faster charging for not much more money.


Not especially efficient? Hmm, I'd noticed that range per kWh varies a lot but not checked in detail. That's disappointing.

The Ioniq series look amazing and are very popular, but are significantly larger cars (disadvantage for me, maybe advantage for others).

Edit: on.to? oh.no more like:

> "On 11 September 2023 Jonathan Lees and Gavin Maher of Teneo Financial Advisory Limited were appointed as Joint Administrators of Onto Holdings Limited. On the same date, Gavin Maher and Ian Wormleighton were also appointed as Joint Administrators over Onto Tech 1 Limited, Onto Tech 2 Limited, Onto Tech 3 Limited and Onto Tech 4 Limited, each a subsidiary of Onto Holdings Limited (together "the Companies"). "

:(


It does vary a lot. In city it's easily 4mi/kWh or more. But I remember being pissed at Stellantis when in cold rain on highway the efficiency dropped to 1.7mi/kWh, and the range estimate was still calculated based on the marketing number, going down by 2 miles for every 1 mile driven (it was a version without a heat pump).

Ioniq's worst case is better than this (~2.1 in bad weather, 3.1-3.3 at highway speeds in good conditions), and it displays accurate range based on real usage. Ioniq is indeed a bit too fat for UK's parking spaces.

on.to was great. I think they took advantage of tax breaks when leasing for a business, and during lockdowns they couldn't buy new cars fast enough.


BTW, if you want something for road trips, check out Bjorn Nyland's data:

https://docs.google.com/spreadsheets/d/1V6ucyFGKWuSQzvI8lMzv...


Charging has gotten pretty decent in the last couple of years.

I used to be annoyed that signs for highway services don't show which ones have chargers, but they've fixed that by installing chargers at every one of them (at least along my routes).

It's even better in western Europe, where Ionity and Fastned have a pretty dense coverage of 300kW chargers.

I've been road tripping around the UK and Europe for the last three summers, and it's been easy peasy.

Hyundai has a universal charging card that works with the majority of minor crappy charging networks, which solves the pain of having to install seventeen different charging apps.


The whole paying for charging thing needs to die a painful and fiery death. I have a universal (money) charging card in my wallet - it was issued by my bank. There should be nothing else required to pay for charging a car up.

Same with parking. Most car parks around here accept only coins (and I stopped carrying coins about 5 years ago) or pay-by-phone, which always charges more than the advertised parking price and is usually conveniently located in a mobile phone dead spot. Parking meters used to accept contactless card payments - what gives?


>It's even better in western Europe

Where? Because here in Austria public EV charging infrastructure is next to non existent.

Ironically it's best in Vienna where car ownership is lowest due to excellent public transportation but next to no existing in the other smaller cities where car ownership is highest.

It's bonkers.


I have first hand good experience from France, Belgium, Netherlands, and Germany. I've also driven across Poland, and that was where I had to start planning charging, rather than just go wherever, which is why I say west Europe, not just EU.

Austria looks less dense than Germany and Switzerland, but still good – DC fast chargers along highways, and over 100 fast chargers in Vienna.

Austrian Alps have poorer coverage, but that's not surprising — there aren't many roads there either, but still there are enough chargers to cross them in an EV, so at least as a tourist I don't think I'd have major difficulty.

https://abetterrouteplanner.com/


To be fair Benelux and the Nordics are far ahead in terms of EV infrastructure that the rest of "western Europe" whatever that term means if it's geographical, political or economicall.

And what's the point of highly dense cities like Vienna having much better EV charging infrastructure, when most of the people there usually use the excellent public transportation so car ownership is low anyway. EV infrastructure Investments should happen precisely in the places with lesser density where cars are a necessity but those are the ones with the lest EV infrastructure precisely as you pointed out.


Rust's async is in some places more difficult to use, because Rust is obsessed with avoiding allocations and dynamic dispatch.

Languages like C# and JS allocate a new object for every Promise and every listener. Rust bends backwards to avoid that, and make inlined strongly typed state machines instead. It creates limitations where you wouldn't expect, e.g. recursive calls need special handling, and abstract interfaces don't fully support async.

As for supporting both, it's just inconvenient to do, because many small syntactic and semantic differences mean it's hard to automate and cumbersome to maintain.


Not every await and new task produces an allocation in C#: ValueTask only allocates a state machine box if it yields asynchronously, plain task objects are pooled for common values and state machine box itself can also be pooled for frequently called methods (is opt-in), for example socket.SendAsync does not allocate thanks to this.

This will change further as "Runtime Handled Tasks" implementation comes along which will replace Roslyn-generated explicit state-machine code with runtime-provided suspension mechanism which will only yield/suspend the execution at true yield points, with further improvements to how the captured state that needs to persist across them is stored.


From what I've asked people, the complaints fall mainly into two categories:

* familiarity and aesthetics. Rust uses fewer round () parens, and more <> and {}. This makes it look alien, and people say it's unreadable when they don't immediately recognize the language constructs they know.

* misattributing difficulty of learning Rust concepts like lifetimes and generics to their syntax. People say they want less syntax, but they mean they don't want to explicitly specify things like ownership and trait bounds.


Consider applying for YC's Winter 2026 batch! Applications are open till Nov 10

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: