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

You may not have intended it this way, but your top paragraph could easily be repurposed as a talking point for the current administration. What does the I in ICC stand for?

If that's a talking point it's a stupid one. The Rome Statutes are only valid in territories that have agreed to be bound by them.

It isn't bound, Hamas didn't agree to be bound by ICC.

And the local drug dealer says he's a sovcit but is still somehow in jail. What's your point?

But the equivalent don't hold there is no one enforcing ICC warrants in Gaza and Yahya Sinwar wasn't in jail.

Game programmers have long been the producers of the most impressive applied computer science.

The film Shrek 3 (2007) took 20 million CPU hours of render time. Games push 60 frames a second. For a visual comparison, check Call of Duty world at war (2008).

Also compare to browsers, which can sometimes scroll smoothly through some styled rectangles and text, and consume gigabytes of ram if you have a few tabs open.

Games have directional sound effects and soundtracks. Don't need 800 Spotify engineers to pull that off.

Multiplayer games solve crazy distributed system problems, making it feel like 'now' when players shoot each other, even with historical latencies of 100-200ms.

AI (in terms of LLMs) seems to be a continuation of that. You used to be able to play 7 AIs on 1998 hardware, at a distinctly "non-beginner level".


Game developers cheat like there's no tomorrow, though. In the videogame 3D graphics space, the old mantra was, "if it looks right, it's right".

That barrel you shoot, is really half a barrel when you're up close, a flat rectangle when you're far, a point-with-mass + a vector for purposes of physics, and not even there for purposes of AI because pathfinding uses a precomputed graph of nodes that's carefully aligned with the map so you don't notice the enemies can noclip through everything other than floors and walls. Etc.

And yes, many games would have scripted enemies or other events come out at you so you don't linger in particular areas too long, lest you spot some of the shortcuts they made.

I grew up wanting to make games, spent my teenage years in hobbyist gamedev communities, and to date, this remains to me the most enjoyable and pure form of exercising software development skills.


An immutable object is a special kind of mutated object, which when mutated does what exactly?

To clarify, It looks like Haskell got better string types around 20 years ago.


Yes. Agreed. Did you intend to respond to someone else?

Nah. It involves multiple passes and setting the answer to the wrong value before (hopefully) setting it to the right value.

Plus it forces you out of whatever lazy/streaming paradigm you had going on. If your foldr produces a list, downstream can start consuming it in constant memory as long as you let it do its thing.


fold kinda does too, for setting the first combined value that you are assembling, and thus on an empty list you end up with that wrong value, same as the for loop

No, the sum of the first ten natural numbers is always 55. It is not "initialised" to some other number beforehand.

japgolly’s signature for reduce above is slightly wrong, it should be `[A] -> ((A,A) -> A) -> Maybe A`.

I.e. there is no initial value to pass in, but the result is an Optional to handle the empty iterator case. That’s how rust does it, for example:

https://doc.rust-lang.org/std/iter/trait.Iterator.html#metho...


If your data should not be successfully folded if it's empty, you should've already parsed it as an Optional nonEmptyList instead of letting illegal states fly around for a while in your application.

Yeah that's good application design, but those concerns aren't so relevant to the person writing the standard library for a language. You can certainly include a specialized version of reduce for nonEmptyLists which just returns A, but that doesn't change the fact that you have to return an Optional for a normal possibly-empty iterator if you want your reduce function to be non-partial.

It's pairwise, not global reasoning.

The accumulator is global state. If you're folding from list<int> to int you're right that it's (usually) effectively a pairwise operation on ints. If the fold is something like list<foo> -> tree<bar> then you have to reason about each intermediate (tree<bar>, foo) -> tree<bar>, i.e. how global state should evolve over time with each update.

I don't think I can recall a time where I routed-around-the-damage on the basis of a particular typed exception.

As soon as you consider retrying a network failure, you immediately need to start thinking about distributed systems failures, idempotency, and all that good stuff.

As soon as you start thinking about the above, it becomes immediately obvious that low-level calls should not be able to decide to re-run themselves.


>I don't think I can recall a time...

I appreciate that there is a _ton_ of different experiences out there when it comes to solving problems, but I _have_ encountered exactly the case I was describing, which is what led me to my original question. Isn't the fact that it was a checked exception that led you to "consider retrying a network failure, you immediately need to start thinking about distributed systems failures, idempotency, and all that good stuff" worth it as opposed to an unchecked exception you may not realize is being thrown?


The standard library writers can go first.

Same rationale as flow valuing. Some people like values being reassigned, and some people like types being reassigned.

You might be reading too much into the union example. The checker just doesn't know if the middle block ran, so maybe it remained an int, or maybe it became a string.


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

Search: