[HN Gopher] More Control with Idempotency
___________________________________________________________________
More Control with Idempotency
Author : charlieirish
Score : 62 points
Date : 2022-04-14 14:20 UTC (1 days ago)
(HTM) web link (buttondown.email)
(TXT) w3m dump (buttondown.email)
| Twisol wrote:
| > A program is idempotent if when we run the program multiple
| times (on the same input), it will have the same effect as if we
| run it only once.
|
| Determinism/purity could be defined the same way; the difference
| hinges on your interpretation of "run the program multiple times
| on the same input". That is, if you run `f(x)` and then `f(x)`
| again (on the same input, see!), you ought to get the same
| result. Given the spotlight pure functions have received for the
| last N years, maybe this distinction is worth making explicitly?
|
| The "on the same input" part is, I think, what puts it
| uncomfortably close to determinism. Hmm...
|
| > How I like to think about idempotence is that we have some
| desired state (the input), and then we have an actual state and
| the purpose of the program is to bring the actual state to the
| desired state.
|
| This is a lovely way to look at it!
| lmkg wrote:
| Idempotence is usually used when talking about effectful code.
| Modeling the state as part of the input/output seems to run
| counter to that purpose, because that's how you create a pure
| model of an effectful program. It's useful to talk about
| idempotence when running the function _zero_ times is different
| than running it _once_ , which is hard to do in that framing.
| As you say, "on the same input" is difficult to reconcile if
| the state is part of the input.
|
| If we consider the state to be part of the input, then it's
| easier to say that when f(x) = y, then f(y) = y as well. In
| other words, f(f(x)) = f(x). Which, as it just so happens, is
| literally the mathematical definition of idempotence which the
| programming concept is based on.
|
| In any case, this still gets to the same overall conclusion:
| the point is to arrive _at_ a specific destination, not to move
| _towards_ it. That shift of perspective is helpful in framing
| problems towards an idempotent solution.
| Twisol wrote:
| > Idempotence is usually used when talking about effectful
| code.
|
| Agreed! The idempotent operation _acts on_ some state; how
| that state is modeled is an independent concern.
|
| > In other words, f(f(x)) = f(x). Which, as it just so
| happens, is literally the mathematical definition of
| idempotence which the programming concept is based on.
|
| That's the one I like the most, because I try to concentrate
| impurity to a small region of the overall program. In a
| language like Haskell, in some ways your hand is forced! But,
| as you say, it's biased toward a particular way of modeling
| state and effects.
|
| My point is, if a program is said to be idempotent if running
| it multiple times on the same input produces the same output,
| then you exclude the Haskell approach to idempotence. Half
| the point of `f(f(x)) = f(x)` is that the input f(x) is
| typically not the same input as x itself!
| jimminy wrote:
| It's not really uncomfortably close to determinism, it is
| baseline deterministic which is necessary for the verification.
| The powerful part of idempotence is that it's deterministic + a
| verified assurance "as if we run it only once."
|
| Deterministic (but not idempotent): send_message(id=1, body)
| without verifying the state of id, could result in the message
| being received multiple times.
|
| Idempotent: send_message(id=1, body) would verify that the id
| token hadn't been consumed, before acting, thus only allowing
| the message to be sent one time.
| Twisol wrote:
| In your second example, if you run `send_message(id=1, body)`
| once and then run `send_message(id=1, body)` again, it
| behaves differently the second time than the first time,
| despite receiving the same input. So `send_message` is
| idempotent, but its behavior is not determined by its inputs
| (i.e. it is not pure).
|
| If you imagine the hidden state that `send_message` reads and
| writes to be part of the input, then when you run it the
| second time, its inputs have changed. So it wouldn't be
| correct to say you're running it multiple times "on the same
| input".
|
| These details are not obvious from the given definition, and
| that's why I say it's uncomfortably close to purity.
| Idempotence is very much _not_ about purity (though you can
| have both), and that 's why I like the author's goal-oriented
| explanation better: it makes the role of state very explicit.
| jimminy wrote:
| Yeah, my example was bad. I was more trying to point out
| that determinism of the intrinsic action is a pre-condition
| to the idempotency, in order to make and verify the
| assurance required.
|
| You could easily split the deterministic action, and
| comparison/verification against existing state into two
| different Pure functions. Being able to perform the
| verification separately is valuable for addressing the "at
| most once", "at least once", and "exactly once" assurance
| described in another comment in this the thread.
|
| I was casually opening my scope up to the outer state, in
| the example, to express the "assurance" portion of the
| definition. But you're correct, it's an erroneous example
| that doesn't pass the more rigorous definition of Pure
| Determinism, when applied the local scope of the function.
| spyspy wrote:
| Idempotency is something I think about constantly. It's part of
| my Optimize For Sleep(r) development philosophy. You have to
| assume that 1) your program can and will fail at any arbitrary
| point during execution and 2) the caller of your code will retry
| it with reckless abandon every time it fails (or even if it
| doesn't). I know this because I am often on both sides of my own
| code, the writer and the caller. Managing state to avoid side
| effects takes a lot of mental effort and devs often get
| complacent or rush through it, but eventually it is going to burn
| you.
| Fire-Dragon-DoL wrote:
| What program was used for the diagrams?
| jugjug wrote:
| OP here. I draw them on a tablet. For more, see
| https://marcel.is/drawings-first-steps/
| [deleted]
| catlifeonmars wrote:
| Idempotence is a very useful property to have in a distributed
| system. This is because most distributed systems are (by
| definition) not atomic wrt state transitions. For example, it is
| not cheap to guarantee exactly once delivery over an event bus.
| If you can build in idempotence, your gonna have a _much_ easier
| time adapting to changing business requirements
| CraigJPerry wrote:
| Idemopotency is up there with immutability, queues & purity for
| making the life of the software architect bearable.
|
| This article glances off a really interesting related problem -
| the choice between "at most once", "at least once" and "exactly
| once" events.
|
| If the process is due to send an alert mail, but the process (or
| the server or whatever) dies just after the mail is sent but
| before the status is updated in the system's state.
| prlyons wrote:
| FYI I cannot reach the URL linked.
| [deleted]
___________________________________________________________________
(page generated 2022-04-15 23:01 UTC)