Clojure Macro Challenges #1

Sunday, February 12, 2012 8:54 PM

This is a bunch of ideas for macros that I know I’m never going to get around to implementing, but I would find insanely useful if anyone else did.

Magic Partial

Partial in Clojure works, but it’s slow.  You can tell this by the number of times you see functions that return other functions, rather than applying partial.  What you really want is to declare a function once and get the partials declared for you.  e.g.

(defn-partial wrap-authenticated [handler request]
    (handler (assoc request :user (get-user request)))

gets rewritten as

(defn wrap-authenticated
   ([handler request] (handler (assoc request :user (get-user request))
   ([handler] (fn [request] (handler (assoc request :user (get-user request))))

A better solution would be, of course, to fix the performance of partial, but that’s a lot harder.

There’s a harder version of this: to evaluate the function up to the point it needs the unprovided parameters.  But just the basic version would be a performance win.

Generators

C# implements generators like those in Python.  However, it’s worth noting that the feature is entirely supported by the compiler, there’s no MSIL level implementation.  The function gets written as a state machine.  To go purely functional, you’d probably want to do it by constructing a sequence of (value, continuation) pairs and then calling (map first coll) on that.  Obviously, you’d want to support all Clojure special forms.

Await

Await is a new feature of C#, but that’s no reason Clojure can’t have it.  It’s already been done for CoffeeScript.  If you really want to be flash, implement generators and await using the same code.

Technorati Tags: ,,,,
Comments
Gravatar
# Await through a monad
Posted by Jiří Maršík on 2/13/2012 12:32 AM
Since the async and await keywords in C# are based on F#'s Async workflows and since "workflow" is just F# lingo for monad, it should be possible to honor the old adage "use macros only when a function won't do" and implement this functionality via a monad in Clojure.

Sounds like a nice little project if somebody hasn't done it already.
Gravatar
# re: Clojure Macro Challenges #1
Posted by Julian on 2/13/2012 10:40 PM
I'll admit to not really understanding monads, but as I understand it, there are basically two parts, "turn into monad" and "turn back out". You could probably create def-monad, which did some standard things in transforming standard clojure syntax to a monad, and the def-generator and def-async construct the monad and then resolve it back out. Hopefully with excellent performance... :)

But as I say, I don't really understand monads. I understand that they're powerful, but I don't really understand how to use them or the performance implications of using them.
Something to add?

Talking sense? Talking rubbish? Something I'm missing? Let me know!

Fields denoted with a "*" are required.

 (will not be displayed)

 
Please add 2 and 3 and type the answer here:

Preview Your Comment