It is true that $defer is better for delays than setTimeout when in an angular app but I suspect that coli was just using it to simulate an asynch call to something outside angular in which case there would be no setTimeout but it appears that we still need the $apply.
By the way in your fiddle Thomas you put that you are delaying for 100ms to allow the scope change to come into affect. This is not how angular works. There is no other thread that will kick in and notice the scope change if you just wait for a bit. What is actually happening is that by calling $defer(...,300) you are actually triggering a $apply, which in turn triggers a $digest which catches the scope changes. This can be done simply with a $apply if you know you are outside angular and you don't need a delay. If you are not sure if you are in an angular $apply call already then you can use $defer without a time-out value, which effectively triggers a new $apply loop immediately after this call has completed.