MichaelDrogalis / dire

Erlang-style supervisor error handling for Clojure
483 stars 19 forks source link

Passing functions as well as symbols to with-* functions? #20

Open dparis opened 10 years ago

dparis commented 10 years ago

Any interest in being able to do the following?

(defn foo [a] true)

(with-handler! foo  ;;  <---   Note the ability to pass a function instead of a var
  Throwable
  (fn [e & args] ...))

It'd be an easy change to make, and I could do it in a way that would preserve existing behavior. If you think it'd be too confusing, or are just opposed stylistically, I'm fine to leave things as they are.

MichaelDrogalis commented 10 years ago

How're you able to pull it off? I couldn't make it happen when I implemented it because it would lose the metadata from the var-root.

dparis commented 10 years ago

(var ...), yo. Check out the documentation: http://clojure.org/special_forms#var

The symbol must resolve to a var, and the Var object itself (not its value) is returned. The reader macro #'x expands to (var x).

So if your with-* functions expect to be called with some kind of #'fn-symbol as the task-var arg, that should be the same as calling it with (var fn-symbol). At that point, just add a little method indirection to pass task-var into a converter, say, (task-arg->var) and that should do it. The converter can just pass through args which are already vars, so it shouldn't affect existing behavior.

If I've missed some subtlety here, please let me know, since I'm not very familiar with the intricacies of Clojures metadata handling. Otherwise, should be a straightforward change.

MichaelDrogalis commented 10 years ago

Clojure's metadata is extremely tricky to get right when you're passing a var between functions. The var call (I think) won't resolve inside the function because AFAIK the scope will be lost. Give it a try though.

dparis commented 10 years ago

Ah, good call! I think there might be a way around that using the intern built-in, but I'll have to poke around for it. I should have guessed there'd be more to it, since it hadn't been done yet and seemed like such low-hanging fruit. :grin:

MichaelDrogalis commented 10 years ago

Give it a shot. I wouldn't mind making that change for 1.0.0, but it's not easy (perhaps not possible either).

dparis commented 10 years ago

Alright, I'll probably keep this one on the back-burner for now then. Something to fiddle with in my free (ha!) time.