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

Apple Intel laptop + a butterfly keyboard was the absolute gutter tier experience. Not only it was slow and ran hot, but after a few months a random key would get stuck and stop working.

Also touch bar, also was all USB-C at a time when there was 0 adoption (2016). I went out of my way to buy a 2015 model instead, held up for 10 years.

I was gifted a Touch Bar and bought an M1 air when they came out. It was a night a day difference. Fan speed and throttling killed the experience and Touch Bar was not good.

I agree that sucked, and I fixed a few of them myself instead of sending to Apple. Got quite good at it.

I think the laptop hardware pre Apple M chips was just terrible and has pretty much stayed that way. There’s a reason why Apple moved away from Intel.

Before M chips an Apple Intel laptop was just a shiny wrapper for a PC laptop experience: fans turn on to full blast all the time, battery lasts <3 hours under any regular usage beyond just browsing (say having an IDE open, and frequently switching between apps). Laptop would get hot to the point where you need padding if you keep it on a lap so you’re not boiling yourself. Made for a good leg warmer during the winter though haha.

With an Apple M4 laptop, the only time I’ve heard the fan turn on is when I almost 100% filled the memory with some local LLM model. I can’t recall any other times. Battery life is finally as advertised, can last many hours, laptop is consistently fast, never gets hot and any CPU throttling is not perceptible under medium to high CPU usage.


^^^ This.

What can the Erlang / Golang runtimes do that the JVM can’t?

Thousands of share-nothing actors (fibers / green-threads) with first-class support for communication between them, for a start. Erlang/Elixir -- immutability as well.

"As a rule of thumb, if your application never has 10,000 virtual threads or more, it is unlikely to benefit from virtual threads."

https://docs.oracle.com/en/java/javase/21/core/virtual-threa...


BEAM threads are kinda magicsauce tho, instructions have a cost and after a certain cost total (quantums) the scheduler can divert to another virt thread to guarantee forward progress. Also the immutability rules etc make it easier to optimize this switching.

Eh, reduction counting isn't magic. Golang manages similar preemption semantics without counting that many operations (some tight loops do have barriers inserted every so often, but that's the exception and not the rule). And reduction counting has some serious costs! It slows the runtime down a shitload (and the BEAM is already in the bottom half of interpreted language runtimes by speed) and makes lots of JIT-flavored runtime optimizations slower or harder to implement.

I like immutability too; I wish Java and Golang did more of it. It costs a lot in terms of unexpected copies in the BEAM though, there's less copy-elision optimization than you'd think. That especially bites if you're doing a ton of message passing, because of how process heaps are implemented and how garbage collection (traditional or ETS/ThreadProgress-based) works.

I think what I want is something like Golang but with goroutine-based ownership semantics (or Rust with the Go runtime and goroutines): en excellent scheduler for extremely light-weight green threads, no refcounting or reduction counting, and all the clever optimizations around channel sending and copy elision--but no ability to use a value after it's sent to a channel, and only channel-based access to shared global state. That'd get most of the benefits of process-local heaps but without the (copying, cache/memory fragmentation) drawbacks.


These are all true and I have recognized those as innate limitations of the BEAM VM. For now I am OK with those but I am already skirting at the limit and I am starting to want to jump to Golang and Rust again.

Obviously. But it's really nice to have the option, and none of us knows the future. I've been bitten by those "0.1% chance" things much more times than I would be not-embarrassed to admit, and I know I a not alone.

I believe the point they were making is you can have millions of virtual threads on the JVM no problem. Your information on the JVM is outdated.

Good, thanks for the grounding. I'll have to reevaluate at one point then.

As I just posted in another comment (https://news.ycombinator.com/item?id=48384622), I'd probably drop Erlang/Elixir due to difficulties of employment and contracting -- if the more popular languages get those STM / share-nothing runtimes.


What kind of software actually requires this? Honest question. Anything I can think of would probably be written by C++ devs

"requires" is of course subjective, there are always multiple ways to do something. But sometimes it is convenient to model a system as concurrent execution streams, for example: multiple sessions (servers), multiple entities (games, robotics), multiple in-flight transactions (any kind of i/o or concurrent compute). Agreed these are often C++ use-cases but there are obvious benefits to using Erlang or other virtual machines: memory safety, isolation, fault tolerance.

Web / API services during bursts. Or just when you _really_ don't want to scale horizontally.

Elixir / Golang can do this very well. And they do. I have supervised, led and authored such projects that are in production to this day.

Rust too but it's lower-level and you kind of have to hand-roll OTP which of course will always fail.


from experience, during bursts it's never actual web/api server that is bogged down, it's the downstream io bottlenecks.

if your accepting layer is abstracted away and implemented correctly, there is very little performance difference between different concurrency approaches and all you're exposed to as developer is implementation of your handler functions.


Not the case; good abstractions are valuable, but the performance differences between runtimes are very real.

Take the example of some simple HTTP<->blob store service gets slammed with millions of requests when someone using the API does a backfill via some framework on their end that aggressively scales request volume up and out.

Something like, say, async Python/starlette with a coroutine per request is gonna perform slightly worse than Erlang, which in turn is gonna perform much worse than Go.

You're right that those differences are sometimes marginal when the latency of whatever IO the backend's doing dominates the equation. However, in my experience huge volume surges show issues with the runtime (the thing managing/launching multiplexed request handler routines) or the ecosystem (the backend IO libraries' ability to work with the runtime's IO multiplexing and make things like request coalescing easy or automatic) more often than you'd think.

It really takes surprisingly little volume to cripple a return-hello-world Phoenix app that indirects the "hello world" behind way too much middleware and message passing; it takes even less to kick over, say, a Gunicorn instance returning "hello world" at the bottom of the Django middleware stack. Golang with Gin, on the other hand, is surprisingly hard to cripple in the same way. And I say that as someone who likes Elixir and Python a lot more than I like Go!


Thank you. As a guy who made a career out of Elixir (and begins to regret it recently but oh well) I agree that Elixir's throughput is not amazing. However, it can get very far and we should always optimize for the most common usages.

I've personally rewritten one hobby and one professional projects from Elixir to Golang and loved the result; as you said, extremely difficult to bring down a Golang service to its knees.

One clarification: Phoenix server behind Caddy/nginx fairs better btw. But, details. Your point stands.

I am yet to see a Rust web/API service I wrote to _ever_ buckle under pressure and just crash. It was either an application bug (like the famous Cloudflare's `.unwrap()` error from the last weeks/months) or the Linux OOM killer. Literally never crashed. But I did witness it brutally murder a MySQL cluster because it couldn't serve it fast enough. That was both fun and terrifying to watch on the dashboards.


> I did witness it brutally murder a MySQL cluster because it couldn't serve it fast enough. That was both fun and terrifying to watch on the dashboards.

Haha yep. In my experience, everyone running CGI/process-per-request application servers is bullish on switching to a concurrent or cooperative runtime...until they realize they just removed the primary ratelimiter on downstream DB/service accesses.

The converse war stories are also amusing: people rewrite their whole app in a concurrent/asynchronous framework and nothing changes, because the DB driver is still farming out all queries to a tiny fixed-size threadpool of connections that was the bottleneck all along.


Oh yeah, definitely. If your DB server (or any storage backend) cannot have like 200+ connections alive at all times then it's absolutely pointless rewriting your app in Elixir or Golang. You'll just serve DB timeouts in your responses.

> You're right that those differences are sometimes marginal when the latency of whatever IO the backend's doing dominates the equation. However, in my experience huge volume surges show issues with the runtime (the thing managing/launching multiplexed request handler routines) or the ecosystem (the backend IO libraries' ability to work with the runtime's IO multiplexing and make things like request coalescing easy or automatic) more often than you'd think.

fair enough, although at this point we start talking about LB in front of the thing, consumption mechanics, autoscaling signals

i will still maintain that my simple advice for a dev worrying about scale, is that they should focus their efforts on ensuring downstream IO doesn't get overwhelmed (db read replicas, caching, etc) before optimizing runtime performance or autoscaling out unnecessarily.


> focus their efforts on ensuring downstream IO doesn't get overwhelmed (db read replicas, caching, etc) before optimizing runtime performance or autoscaling out unnecessarily.

All good advice, but the choice of runtime can affect the point at which autoscaling and load balancing even need to enter the conversation at all. Optimizing, say, a mostly in-memory cache service and writing it in Golang may yield results like "we can run a single instance of this and serve three orders of magnitude of business growth; slap it behind a DNSRR or a k8s NodePort for update/replacement/fast failover if it crashes, no complex load balancer needed", where writing the same thing in, say, PHP might require discussing orchestration/load balancing/memory/worker process recycling/autoscaling early on in the service's lifetime. Being able to skip those conversations (entirely or for a long time) is a very significant business benefit.


(Upvoted for a really relevant and valuable refinement to the thread.)

Admittedly that layer is almost always abstracted i.e. AWS / GCP and various other smaller hosted solutions that handle a good chunk of load balancing for us. In that landscape BEAM VM's strengths shine even brighter. I've seen firsthand that you can in fact bring a BEAM VM to its knees if you expose it just like that to the net. It's not pretty. Golang fares a touch better and Rust seems almost immune (provided one does not screw up their caching layer and don't do elementary N+1 query mistakes).


>share-nothing actors

although this is a deliberate choice rather than some accidental defect. Clojure went with STM as its concurrency model, if you're not buying into that and you want an Actor-centric language it's not the right choice to begin with.


STM is seldom used in modern Clojure projects, it is certainly not the dominant model. Most projects I am aware of use a few or even exactly one atoms with immutable data structures.

Virtual threads can do that too.

Low memory usage.

Yes, he’s throwing himself. Aikido is often practiced solely as a non-competitive art.

If you want to see what competitive throws/takedowns with a kimono/gi look like against live resistance, watch Judo. Example https://youtu.be/fLD87nqwp3Y

For the same but without kimono, watch Greco-Roman. Example https://youtu.be/4Xc-wxNSsTk).


A reminder that both things can be true at the same time:

1. Trump is a bad president

2. The Islamic Republic of Iran should not be allowed to have nuclear weapons


> The Islamic Republic of Iran should not be allowed to have nuclear weapons

Neither should Israel, right ... right?


The US Navy has quite a few more tricks up its sleeve apart from aircraft carriers. Just one publicly known that immediately comes to mind: amphibious assault ships, which can launch/land F35s.

[0] https://en.wikipedia.org/wiki/USS_Tripoli_(LHA-7) [1] https://www.youtube.com/watch?v=JCMSKTxgQI4


>>> SpaceX is an amazing success story

100%, and something that is underappreciated and often taken for granted nowadays, especially on our little forum here.

>>> It would benefit even better by having many SpaceXs around.

That made me chuckle, sounded to me a bit like "our house would benefit from having a few cats around". Perhaps the reason why there aren't too many SpaceX-like companies around is that it's truly among the hardest companies to ever create.


If we're going to do public/private cooperation, we still need the whole competition thing.

If we don't have it, either we're subject to monopoly, or just a State owned company, at which point, why not just cut out the middlemen and go full Nationalized?


Boeing and others do complete in that area.


I’ve rented many different brands and the BMW interface is by far the best and quite consistent across generations. It hasn’t changed all that much since early 2000s. What exactly do you think was “user-hostile”? If you want to see bad UI/UX, try a Range Rover. Unfortunately all brands collectively (even BMW) have taken a step back with the latest generation of cars and the touch-screen-all-the-things craze.


Exactly. Unfortunately, it seems like the ship has sailed towards exploitation of the current local maximum (I got GPUs and Terawatts, let’s go!) instead of looking for something better.


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

Search: