A macro for writing defn-like macros?

166 views
Skip to first unread message

Mark

unread,
Sep 3, 2013, 12:01:46 PM9/3/13
to clo...@googlegroups.com
I find the vast majority of the time I'm tempted to write a macro (yeah, yeah, I know the first rule of macro club), is to defn-like things.  Writing a defn-like macro to handle all the stuff defn does is pretty tough so I end up writing a barebones thing that doesn't support doc-string, doesn't support multiple arities, and doesn't support metadata.  I'm wondering, has anyone written a defdefnmacro macro?

Ben Mabey

unread,
Sep 3, 2013, 12:23:35 PM9/3/13
to clo...@googlegroups.com
On 9/3/13 10:01 AM, Mark wrote:
I find the vast majority of the time I'm tempted to write a macro (yeah, yeah, I know the first rule of macro club), is to defn-like things.  Writing a defn-like macro to handle all the stuff defn does is pretty tough so I end up writing a barebones thing that doesn't support doc-string, doesn't support multiple arities, and doesn't support metadata.  I'm wondering, has anyone written a defdefnmacro macro?


Clojure's tools.macros has a helper function for such macros called name-with-attributes:

https://github.com/clojure/tools.macro/blob/master/src/main/clojure/clojure/tools/macro.clj#L275-L298

HTH,
Ben

Ben Wolfson

unread,
Sep 3, 2013, 12:23:33 PM9/3/13
to clo...@googlegroups.com


On Tue, Sep 3, 2013 at 9:01 AM, Mark <markad...@gmail.com> wrote:
I find the vast majority of the time I'm tempted to write a macro (yeah, yeah, I know the first rule of macro club), is to defn-like things.  Writing a defn-like macro to handle all the stuff defn does is pretty tough so I end up writing a barebones thing that doesn't support doc-string, doesn't support multiple arities, and doesn't support metadata.  I'm wondering, has anyone written a defdefnmacro macro?

--
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@googlegroups.com
Note that posts from new members are moderated - please be patient with your first post.
To unsubscribe from this group, send email to
clojure+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google Groups "Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.



--
Ben Wolfson
"Human kind has used its intelligence to vary the flavour of drinks, which may be sweet, aromatic, fermented or spirit-based. ... Family and social life also offer numerous other occasions to consume drinks for pleasure." [Larousse, "Drink" entry]

Ben Wolfson

unread,
Sep 3, 2013, 12:27:18 PM9/3/13
to clo...@googlegroups.com

Alex Baranosky

unread,
Sep 3, 2013, 1:51:50 PM9/3/13
to clo...@googlegroups.com


On Tue, Sep 3, 2013 at 9:01 AM, Mark <markad...@gmail.com> wrote:
I find the vast majority of the time I'm tempted to write a macro (yeah, yeah, I know the first rule of macro club), is to defn-like things.  Writing a defn-like macro to handle all the stuff defn does is pretty tough so I end up writing a barebones thing that doesn't support doc-string, doesn't support multiple arities, and doesn't support metadata.  I'm wondering, has anyone written a defdefnmacro macro?

--

Jim - FooBar();

unread,
Sep 3, 2013, 2:08:12 PM9/3/13
to clo...@googlegroups.com
I've been staring at this function for 20 minutes now (name-with-attributes)...I must be totally stupid but even though I 've understood what it does I can't figure out how to use it. Does anyone have an example usage? Let's suppose I want to define a DEFN macro that behaves exactly like defn...how would that go? I'm struggling to find examples of this on the web. I had previously resorted to my own solution but this certainly looks nicer...


thanks in advance :)

Jim

Konrad Hinsen

unread,
Sep 3, 2013, 3:49:32 PM9/3/13
to clo...@googlegroups.com
--On 3 septembre 2013 19:08:12 +0100 "Jim - FooBar();"
<jimpi...@gmail.com> wrote:

> understood what it does I can't figure out how to use it. Does anyone
> have an example usage? Let's suppose I want to define a DEFN macro that
> behaves exactly like defn...how would that go? I'm struggling to find

The general pattern is:

(defmacro defn [name & args]
(let [[name args] (name-with-attributes name args)]
... use name and args as if nothing has happened... )

For a real-life application see


https://github.com/clojure/algo.monads/blob/master/src/main/clojure/clojure/algo/monads.clj#L196

Konrad.

Jim - FooBar();

unread,
Sep 3, 2013, 4:12:10 PM9/3/13
to clo...@googlegroups.com
Yes! I eventually figured it out...thanks Konrad :)

Jim

Phillip Lord

unread,
Sep 6, 2013, 10:17:26 AM9/6/13
to clo...@googlegroups.com
For this, I just use defn. For example, this macro is like defn, but
also takes a function as the second argument. It composes the body with
function.

(defmacro defnwithfn [name function & body]
`(let [vr# (defn ~name ~@body)]
(alter-var-root
vr#
(fn [f#]
(fn ~name [& args#]
(apply ~function f# args#))))
vr#))

Basically, you let defn do the work, then fiddle with it after.

Phil

Mark Addleman

unread,
Sep 6, 2013, 12:22:12 PM9/6/13
to clo...@googlegroups.com
That's cool.  Thanks!


--
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@googlegroups.com
Note that posts from new members are moderated - please be patient with your first post.
To unsubscribe from this group, send email to
clojure+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to a topic in the Google Groups "Clojure" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojure/fu3-n_iFLuk/unsubscribe.
To unsubscribe from this group and all its topics, send an email to clojure+u...@googlegroups.com.

For more options, visit https://groups.google.com/groups/opt_out.



--
\
Reply all
Reply to author
Forward
0 new messages