They're just a convenience. You can specify a place where, if there is a function to call, you call it. You "hook" into certain pieces of code. news.arc uses them all over the place, like in the last line of
(def edit-page (user i)
(let here (edit-url i)
(shortpage user nil nil "Edit" here
(tab (display-item nil i user here)
(display-item-text i user))
(br2)
(vars-form user
((fieldfn* i!type) user i)
(fn (name val)
(unless (ignore-edit user i name val)
(when (and (is name 'dead) val (no i!dead))
(log-kill i user))
(= (i name) val)))
(fn () (if (admin user) (pushnew 'locked i!keys))
(save-item i)
(metastory&adjust-rank i)
(wipe (comment-cache* i!id))
(edit-page user i)))
(hook 'edit user i))))
I've not read news.arc thoroughly, so I don't know if this example actually works 100%, but humor me: Say at one point you need to diagnose a problem with edit-page, so you (defhook edit ...) to log the user on each call. After finding the problem, you need to change how edits work, so you (defhook edit ...) again to render an alert message that lets users know how editing has changed. But you don't want that message up forever, so after a week you (defhook edit (user i) nil).