[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)