It takes a less efficient but more general approach than type-based dispatch; I find it more useful, at least in a language like arc. An older (incompatible, unfortunately; I may fix that at some point, but I'm unconvinced that labels weren't a good feature) and somewhat modified version of it is on anarki at lib/extend.arc (http://github.com/nex3/arc/blob/master/lib/extend.arc).
Say, have you ever used labels? When I wrote my first version, I said, "ah, labels, good idea, I'll put them in". Then after using it for months I noticed that I wasn't ever using the label. So I took it out on my next iteration.
I have used them. Mostly I used them for debugging, rewriting, "code sketching" as it were. Without them, extending or reextending a function at the REPL is just annoying; if you ever make a mistake in the test function you have to reload the original function. I suppose it might make sense to have two macros - extend and extendl, maybe - one which doesn't take a label, and one which does.
Undo & reextend could easily be implemented on top of labeled extend - just store the label last used when extending a given function in a table, along with whatever information is needed to undo that extension, and have an unlabeled extension macro that uses a gensym as the label. That way we get labeled & unlabeled extend with undo & replacement.
In the Arc server, I moved creating the request object out of 'respond (http://awwx.ws/srv-misc), so that 'respond is now being passed the request object and does the usual Arc srv action to respond to a request: look to see if there is a defop etc. defined for the request path.
Now I can extend respond to implement my own ways of responding to requests: I can easily have my own way of choosing which action to take (I can have http://myserver.com/1234 display the "1234" item page, for example), or implement my own kinds of defop's.