Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Anything side-effect-free is idempotent too, I suppose



No. A function which multiplies a number by two is side effect free, but is no idempotent.


I dispute your example. If you call f(2) and it always returns 4, it's idempotent and side-effect-free. If you call f() and it returns 4, then 8, etc, it is neither.


From wikipedia:

"A unary operation f, that is, a map from some set S into itself, is called idempotent if, for all x in S, f(f(x)) = f(x)."


Instead of checking wikipedia for a general definition of idempotency, check the RFC for the definition that applies to HTTP

9.1.2 Idempotent Methods

   Methods can also have the property of "idempotence" in that (aside
   from error or expiration issues) the side-effects of N > 0 identical
   requests is the same as for a single request.


Yes, in mathematics, not programming. And a function that doubles a number isn't idempotent even by that definition.


Of course a doubling function is not idempotent!

I think the confusion arises because side-effectful functions can be considered as having type

    f :: (RealWorld, OtherArgs) -> (RealWorld, OtherOutputs)
and so for a garage door toggle you have something like

    t :: RealWorld -> RealWorld
where the new state is the old one with the door opened/closed as appropriate.

Now the idempotence condition becomes:

    t(t(world)) == t(world)
but clearly

       t(t(doorOpenWorld)
    =  t(doorClosedWorld)
    =  doorOpenWorld
    != t(doorOpenWorld)
    =  doorclosedWorld
so this is where the notion comes from. If you abuse notation and just say a function of no arguments can be idempotent then you'll get confusion like this.


But `GET(GET(x))` doesn't make sense, in general (and if it did, then you would not expect it to be idempotent), so clearly idempotency in this context is meant to mean side-effect free. They should probably just say side-effect free, though, to avoid the confusion.


It's possible to be idempotent without being side-effect free. If you PUT some record, for example, then that operation _will_ have side effects (modifying the record). If you then PUT that same data again, the result will be the same (it's idempotent).


that’s not a side effect. in common usage, a side effect is an extra action, not the desired action itself. if you PUT some record, and some other record or state changes, that’s a side effect.


I don't disagree with common usage, but common usage is not what's being discussed here.

It is a side effect in programming usage (not just HTTP).

Something is side-effect-free if and only if the only result of it running is that you get an answer. If you ignore the answer, then you cannot tell you ran the function/method/call/whatever. PUT is not side-effect-free.

That said, side-effect-free-ness is an incomplete paraphrasing of the HTTP spec (RFC7231); you'll notice that the only mentions of the phrase "side effect" are giving examples of legal side effects.


I suppose logging is a side effect and that makes practically everything technically non-idempotent (though on purpose).


I think because in math you don’t ever have side effects you usually use composition where in programming you usually use a sequence. So to change that function in to how people would implement it means rearranging the internal stuff and then it probably wouldn’t be idempotent be either definition.


But not the reverse. If you are side effect free you must be idempotent.


"Idempotent" is one of those overloaded terms...


I think that is considered idempotent in the REST-sense of the word: you can multiply a number by two as many times as you like, the result will be the same (and no state is mutated).

I looked it up, apparently there's a formal definition "denoting an element of a set which is unchanged in value when multiplied or otherwise operated on by itself", which does not seem to describe the REST usage very well, though.


The typical operation applied to sets of functions is composition, so idempotency of a function f is the condition that f(f(x)) = f(x) for all x in the domain of f. I don't think that applies meaningfully to GET.


It does apply to HTTP idempotency. `x` is the state of the server. `f` is the change to the state of the server that ensues when one makes such-and-such an HTTP call. So taking PUT as an example, `x` is the state before the PUT, `f(x)` is the state after one PUT, and `f(f(x))` is the state after that single PUT is sent twice. Of course in a RFC7231-compliant server, `f(x) = f(f(x))`. Taking GET (or any other nullipotent method) as an example, we also see that in a RFC7231-compliant server, `x = f(x) = f(f(x))`.


Ah yeah that makes sense.


Technically speaking, idempotency as defined by RFC7231 only requires f(x) = f(f(x)).


Yes, and nullipotency requires x = f(x) = f(f(x)), and four of the methods defined in RFC7231 are expected to be nullipotent, otherwise known as "safe". The point of mentioning that is to highlight the relationship between idempotence and nullipotence.


Except if the domain is zero.


Or even a slightly more exotic case, such as Z mod 2 (a single binary digit)




Consider applying for YC's Fall 2025 batch! Applications are open till Aug 4

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

Search: