Hacker News new | comments | ask | show | jobs | submit login

The writer really likes the word "idempotent".

And uses it incorrectly. Idempotence is when f(f(x)) == f(x). React views take some props and/or state and return a component, so applying the view to its output would just give an error.

I think the word he's looking for is "pure".

EDIT: I was wrong - apparently "idempotent" can also describe a consistent relationship between the input and some state. In that sense, it's actually a very good description of how the input to a React view affects the DOM.

Well, even in Wikipedia, the definition is quoted as being different for CS vs the unary operation you describe.

"In computer science, the term idempotent is used more comprehensively to describe an operation that will produce the same results if executed once or multiple times."

Which is more that f(x) == f(x) == f(x) for the state affected by f.

They are analogous if you represent side effects like this:

    new_state = f(old_state, x)
then an idempotent operation is

    f(f(state, x), x) == f(state, x)
In the context of drawing windows:

    draw(draw(fbuf, wnd, x, y), wnd, x, y) == draw(fbuf, wnd, x, y)
but this is of course false if you allow alpha channel transparency...

Thank you for pointing this out, I was not aware that the word could be used this way. They are really quite different concepts.

I'm not sure that they are. You just need to model the concept of state as the function's input/output, as functional programmers are eager to do :)

If we start in state x, then apply operation f, the resulting state is f(x). If we apply operation f again, we'll be in state f(f(x)). If f is idempotent, then state f(x) and state f(f(x)) are identical.

He is not using it incorrectly:


React views are idempotent. They are not necessarily pure (though they can be).

Don't they have to be pure in order to be idempotent? If you might get a different virtual DOM even when props/state are unchanged (not pure), then re-rendering the component might update the DOM even when props/state are unchanged (not idempotent).

It makes sense that idempotent can have both definitions.

Mathematical functions can't have side effects so they have the "normal" definition of f(f(x))=f(x).

In computer science, with side effects, since state can change, the passage of time could be though of as similar to composition f(x) ... f(x) ~= (f o f)(x) = f(f(x)). This is the line of thinking that gets to monads where successive calls would in fact be f(f(x)) (or f(x).f())

Am I understanding idempotence/side effects/monads right?

Rendering a React component satisfies the f(f(x)) definition, too! We just need to consider the component's props/state to be constant, which is the scenario that the article describes.

In general, the act of rendering a React component is a function from (component props, component state, DOM state) to DOM state. But, when the component's props/state are considered constant, the rendering process is simply a function from DOM state to DOM state.

This is an idempotent function over DOM state if and only if the React component's render method always returns the same virtual DOM tree — that is, iff the React component's render method is pure. In that scenario, the internal React renderer will perform the diff, discover that the physical DOM state matches the returned virtual DOM tree, and leave the physical DOM state unchanged.

Turns out, saying that the render process is idempotent is exactly equivalent to saying that the component's render method is pure! Cool!


From Wikipedia, which agrees with you...

> A unary operation (or function) is idempotent if, whenever it is applied twice to any value, it gives the same result as if it were applied once; i.e., ƒ(ƒ(x)) ≡ ƒ(x). For example, the absolute value function, where abs(abs(x)) ≡ abs(x).

So is f(x) = x + 1 idempotent?

Under this part: "whenever it is applied twice to any value, it gives the same result as if it were applied once" it would appear so. f(2) = 3 f(2) still = 3.

But under this part: "ƒ(ƒ(x)) ≡ ƒ(x)"

f(f(x)) == f(f(2)) == f(3) = 4

Where'd I go wrong?

When they say "applied twice", they're not talking about two independent applications to the same initial value. (That's a test for functional purity, not idempotence.)

Instead, they're referring to the following sequence of actions:

1. Update the value x according to the operation f.

2. Update the value x according to the operation f.

Understood; thanks.

I just realized I've been using the wrong definition of "idempotence" for years...

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