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.