> I should have used "side-effect-free" instead of "idempotent" in my tweets
The HTTP term is "safe method". Although you weren't even wrong because section 4.2.2 of RFC7231 (i.e. HTTP) defines all safe methods, including GET, as idempotent.
I think they use this language because nothing is truly side-effect free. In fact GETs can have side-effects, the most obvious of which is writing the fact of it to a logfile, and that's the most harmless side-effect of all, right until you run out of disk space.
'Side-effect free' means that doing it once, twice or n >= 3 times (with same parameters) yields the same result, i.e. what it returns doesn't depend on any remote state that is altered by the call itself.
However, an idempotent HTTP call is certainly not a pure function which some people seem to be mixing up. Pure functions don't work with I/O.
REST is bit more specific and explicitly requires GET to be nullipotent which really means "effect free" - it just reads and doesn't alter the state on the remote system at all.
Side-effects like log files, rate-limiting, etc. will always exist, but they do belong to a different 'layer', so to speak. That is, these should be unobservable side-effects (also think about minuscule effects on the power grid, the fact that a request might write something to an ARP-cache, etc. - they all happen at different layers, so the quantum world state keeps changing, but that's not what this is about). Whether an X-Request-Count header violates the requirements or not depends on interpretation. From the garage door perspective, I wouldn't care...
When discussing HTTP behaviours I think it’s easiest to stick to the definitions of these terms given in the HTTP standard. Anything else is fruitless bikeshedding.
IMO "side-effect free" is always a statement constrained by the operating level of abstraction. Logging is not an effect at the level of the application, but rather some subset of it's context (system, db).
I love that term and am going to use it as much as possible
EDIT: it's actually his address, I thought it was just a coincidence but you can the house on Street View... I removed the actual name as doxxing isn't great, sorry.
Every time you write some code you need to remember removing before commit, surround it with a comment containing "NOCOMMIT". With this script as a pre-commit hook, git will echo an error message and fail.
E.g.:
print("debug: ", myval)
becomes:
print("debug: ", myval) # NOCOMMIT
I end up relying on this every day I program. Can't go back.
Thanks! I'm not sure how easy it would be to put the git hook on all my machines though? I have a collection of laptops (and one desktop) that I work on and I often don't use the same machine for a few weeks :-/
I ended up using a "env.h" file... is there a C-equivalent of the PHP (?) .env file?
Thank you! I use 'git add -p' all the time, but didn't know the trick with commit. I am a sucker for nice commits so I will check every commit's diff multiple times. When I don't, I usually end up including pieces of code which is not ready yet, which is meant for debugging,...
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.
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.
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 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.
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))`.
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.
https://github.com/wpearse/wemos-d1-garage-door-wifi
I'll get around to fixing it later this week.
Also, an apology: I should have used "side-effect-free" instead of "idempotent" in my tweets.