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

For folks who have never seen it, these are the referenced Top Gear segments:

- part 1: https://youtu.be/xnWKz7Cthkk

- part 2: https://youtu.be/xnWKz7Cthkk

- part 3: https://youtu.be/kFnVZXQD5_k


Second link is wrong (links to part 1 again). Corrected: https://youtu.be/xTPnIpjodA8

We’re in very nitpicky terminology weeds here (and I’m not the person you’re replying to), but my understanding is “commutative” is specifically about reordering operands of one binary op (4+3 == 3+4), while “associative” is about reordering a longer chain of the same operation (1+2+3 == 1+3+2).

Edit: Wikipedia actually says associativity is definitionally about changing parens[0]. Mostly amounts to the same thing for standard arithmetic operators, but it’s an interesting distinction.

[0]: https://en.wikipedia.org/wiki/Associative_property


It is not a nit it is fundamental, a•b•c is associativity, specifically operator associativity.

Rounding and eventual underflow in IEEE means an expression X•Y for any algebraic operation • produces, if finite, a result (X•Y)·( 1 + ß ) + µ where |µ| cannot exceed half the smallest gap between numbers in the destination’s format, and |ß| < 2^-N , and ß·µ = 0 . ( µ ≠ 0 only when Underflow occurs.)

And yes that is a binary relation only

a•b•c is really (a•b)•c assuming left operator associativity, one of the properties that IEEE doesn't have.


If a therapist helped 99/100 patients but tacitly encouraged the 100th to commit suicide* they would still lose their license.

* ignoring the case of ethical assisted suicide for reasons of terminal illness and such, which doesn’t seem relevant to the case discussed here.


What kind of mobile functionality were you looking for? The (unofficial) iOS app is pretty good IMHO and integrates with iOS’s OS-level password filling, and also supports the pass-otp plugin’s format for 2fa codes if you use that plugin. There was a decent Android client I used a while back as well, though I don’t recall the name.

[1]: https://apps.apple.com/us/app/pass-password-store/id12058205...


Not the parent, but dwindling yubikey support (for gpg key storage) is an issue, had to pull out a legacy version on Android for it to keep working (they changed the underlying crypto library and lost the support there)

No ipad version I've found supports yubikey either


18 days is how long the first human-to-human heart transplant recipient lived post-op. The more recent first pig heart recipient made it two months.


And keep in mind people who get these organs are very very ill


> Adding non-primitive props you get passed into your component to internal dependency arrays is rarely right, because this component has no control over the referential stability of those props.

I think this is wrong? If you memoize a callback with useCallback and that callback uses something from props without putting it in the dependency array, and then the props change & the callback runs, the callback will use the original/stale value from the props and that's almost certainly a bug.

They might be trying to say you just shouldn't use useCallback in that situation, but at best it's very confusingly written there because it sure sounds like it's saying using useCallback but omitting a dependency is acceptable.

IMHO useCallback is still a good idea in those situations presuming you care about the potential needless re-renders (which for a lot of smaller apps probably aren't really a perf issue, so maybe you don't). If component A renders component B and does not memoize its own callback that it passes to B as a prop, that is A's problem, not B's. Memoization is easy to get wrong by forgetting to memoize one spot which cascades downwards like the screenshots example, but that doesn't mean memoization is never helpful or components shouldn't do their best to optimize for performance.


In my experience you're correct yeah - 95% of the time if you use it it should be included in the dependency array, and any edge cases where that's not true you should endeavour to understand and document. There's a 'react-hooks/exhaustive-deps' eslint rule for exactly this purpose.


author here , sorry for the confusion. I did not mean to imply that leaving out the prop from useCallback is better - you _always_ have to adhere to the exhaustive-deps lint rule to avoid stale closures (I have a separate blog post on this topic).

What I meant is that the API design of B, where the hook only works as intended if the consumer A memoizes the input props, is not ideal because A has no way of knowing that they have to memoize it unless they look at the implementation or it’s clearly documented (which it rarely is). It’s not A’s problem because B could’ve used the latest ref pattern (or, in the future, useEffectEvent) to work without passing that burden onto its consumers.


> > Adding non-primitive props you get passed into your component to internal dependency arrays is rarely right, because this component has no control over the referential stability of those props.

> I think this is wrong? If you memoize a callback with useCallback and that callback uses something from props without putting it in the dependency array, and then the props change & the callback runs, the callback will use the original/stale value from the props and that's almost certainly a bug.

The problem is up a level in the tree, not in the component being defined. See the following code block, where they show how the OhNo component is used - the prop is always different.


The parent is the source of truth for the children nodes. Which means don't send anything down that you don't intend to be stable. As the children will (and should) treat it as gospel. That also means that the root component is god for the whole view.

Most source of bugs happens when people ignore this simple fact. Input start from the root and get transformed along the way. Each node can bring things from external, but it should be treated careful as the children down won't care. It's all props to them.

Which also means don't create new objects out of the blue to pass down. When you need to do so, memoize. As the only reason you need to do so is because you want:

- to join two or more props or local state variables

- or to transform the value of a prop or a local state variable (in an immutable fashion, as it should be).

- or both.


You're making the same argument as the author. As they said, the only two solutions are:

1. Enforce that you're always memoizing everywhere always

2. Memoize every new function and object (and array) and pray everyone else does too

#1 is pretty miserable, #2 is almost always guaranteed to fail.

The mismatch is that you need stable props from the bottom up, and you enforce stable props from the top down. Any oversight in between (even indirectly, like in a hook or external module) creates a bug that appears silently and regresses performance.


The only solution is to have everyone have discipline and respect the convention of React.

> you need stable props from the bottom up, and you enforce stable props from the top down.

You don't need stable props from the bottom up. Component will always react to props change and will returns a new Tree. The function for that are going to be run multiple times and you're not supposed to control when it does. So the answer is to treat everything that comes from the parent as the gospel truth. And any local transformations should be done outside of function calls.

#1 is not needed. Memoization concerns is always local to the component, as long as you ensure that the props you're sending down is referentially stable, you're golden.

#2 is not needed. Again your only concern is the current component. Whatever everyone does elsewhere is their bad practices. Maybe they will cast your carefully constructed type into any or try/catch your thougthful designed errors into oblivion along the way too. The only thing you can do is correct them in PR reviews or fix the code when you happen upon it.


> You don't need stable props from the bottom up. Component will always react to props change and will returns a new Tree.

This is strictly false, because of effects. The bottom of your tree consumes props and triggers events. The author has plenty of examples of this, and even calls out useEventEffect as being helpful.

> The only solution is to have everyone have discipline and respect the convention of React.

The article specifically goes out of its way to show that mistakes still happen and linters aren't capable of solving this alone.

> as long as you ensure that the props you're sending down is referentially stable, you're golden

This is literally the point. You can't. As the component, you're powerless to ensure this. And components that use your component can't even be sure, because referential stability doesn't only require your code to be correct, but every third party library as well.


I think one of the most awkward things about React (stemming from its virtue of being just a JavaScript library, as opposed to a framework with some custom DSL that could handle memoization behind the scenes) is that it has to be stated explicitly that non-primitive props should be memoized. React makes it way too easy to pass someProp={[1, 2, 3]}, yet to me it is always a caller’s bug.


Hence react compiler


Does it automatically memo non-primitives?


IIRC that's the idea


The “stolen” one is a 1991 model according to the article, so not that new (just kept in immaculate condition as the photos show, I was surprised when I saw it was a ‘91), and only 6 years between the two vehicles involved. Given those ages, it’s not shocking Mercedes was using the same key patterns.


In fact other German cars are susceptible to this too. Famously VW uses so few combinations on their keys that it's actually not at all unlikely your key will work with another random VW of the same vintage.


I look forward to the Matt Levine's section on this in tomorrow's Money Stuff.



I'm very reminded of this Money Stuff: https://www.bloomberg.com/opinion/articles/2024-04-18/jane-s...

Probably unrelated, no mention of Millennium.



I can think of multiple “corner stores” that are the only business within a single-family home residential area within a few minutes drive of the house I grew up in in suburban NY. I’m pretty sure they all got grandfathered in and would not be permitted as new construction with the zoning, but they’ve all been in business since before I was born and are still going. These are mostly neighborhoods without sidewalks, and the stores have parking for only a handful of cars.

You’re right that “most” houses can’t be within walking distance of a corner store outside cities, but my anecdata experience is those residential communities can definitely support those businesses. They might require a short drive, but they’re still a lot closer than the shopping center, and a mix of “ran out of one thing”, deli/breakfast sandwiches, and beer keeps them in business.


I suspect many of them are grandfathered in economically too - they are not generating enough income to support starting a new one, but the family has had it for years and never ran the numbers to see just how badly they are doing. (or maybe they only work so long as the equipment doesn't break)


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

Search: