{ANN} defun: A beautiful macro to define clojure functions with pattern match.

1,329 views
Skip to first unread message

dennis zhuang

unread,
Sep 14, 2014, 2:47:28 AM9/14/14
to Clojure

Hi , i am pleased to introduce defun: a beautiful macro to define clojure functions with pattern match.

Some examples:

(defun say-hi
  ([:dennis] "Hi,good morning, dennis.")
  ([:catty] "Hi, catty, what time is it?")
  ([:green] "Hi,green, what a good day!")
  ([other] (str "Say hi to " other)))

(say-hi :dennis)
;;  "Hi,good morning, dennis."
(say-hi :catty)
;;  "Hi, catty, what time is it?"
(say-hi :green)
;;  "Hi,green, what a good day!"
(say-hi "someone")
;;  "Say hi to someone"

Recursive function? It's all right:

(defun count-down
  ([0] (println "Reach zero!"))
  ([n] (println n)
     (recur (dec n))))
(defun fib
    ([0] 0)
    ([1] 1)
    ([n] (+ (fib (- n 1)) (fib (- n 2)))))


Guard functions? it's all right:

(defun valid-geopoint?
    ([(_ :guard #(and (> % -180) (< % 180)))
      (_ :guard #(and (> % -90) (< % 90)))] true)
    ([_ _] false))

(valid-geopoint? 30 30)
;; true
(valid-geopoint? -181 30)
;; false

It's really cool,all the magic are from core.match, much more details please see 


--
庄晓丹
Email:        killm...@gmail.com xzh...@avos.com
Site:           http://fnil.net
Twitter:      @killme2008


dennis zhuang

unread,
Sep 14, 2014, 5:58:25 AM9/14/14
to Clojure
Released 0.1.0-RC,  defun collect :arglists metadata, another recursive function example:

 (defun accum
      ([0 ret] ret)
      ([n ret] (recur (dec n) (+ n ret)))
      ([n] (recur n 0)))

     (accum 100) ;; the result is 5050
Message has been deleted

Herwig Hochleitner

unread,
Sep 14, 2014, 12:15:36 PM9/14/14
to clo...@googlegroups.com
Hi Dennis,

marrying core.match to defn is a pretty neat idea. Thanks for releasing it!

I see that you actually extended defn in that you made it possible to recur between different arities.
Can you give a quick rundown on how you made that work? Are the arities still separate IFn arities? Does it still run in constant stack space?

kind regards

PS @adrian: If you feel like "Friendly advice" ing someone, why not do so in a private email?

dennis zhuang

unread,
Sep 14, 2014, 12:26:41 PM9/14/14
to Clojure
Hi Herwig

Actually,defun just define a variadic arguments function,so it doesn't have different arities. And when using defun macro ,it walk through the body forms, find 'recur'  forms and replace them with (recur (vector ...arguments)) instead.

A macroexpand-1 result of accum:


(macroexpand-1 
  '(defun accum
      ([0 ret] ret)
      ([n ret] (recur (dec n) (+ n ret)))
      ([n] (recur n 0))))
=>

(clojure.core/defn
 accum
 {:arglists '([0 ret] [n ret] [n])}
 [& args__4602__auto__]
 (clojure.core.match/match
  [(clojure.core/vec args__4602__auto__)]
  [[0 ret]]
  (do ret)
  [[n ret]]
  (do (recur (vector (dec n) (+ n ret))))
  [[n]]
  (do (recur (vector n 0)))))

--
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/d/optout.

dennis zhuang

unread,
Sep 14, 2014, 12:32:57 PM9/14/14
to Clojure
And of course ,it still run in constant stack space just like normal recur form.

P.S. I think adrian's advice is good, please forgive my poor english,and i changes the description to ' a macro to define clojure functions with pattern match just like erlang or elixir.

adrian...@mail.yu.edu

unread,
Sep 14, 2014, 12:36:01 PM9/14/14
to clo...@googlegroups.com
Criticism accepted Herwig. I apologize for not doing so initially. 

Bozhidar Batsov

unread,
Sep 14, 2014, 2:06:01 PM9/14/14
to clo...@googlegroups.com, dennis zhuang
Cool idea! I really wish something similar was available out-of-the-box - perhaps it makes sense to include such a macro in core.match itself as some point?

Cheers, 
Bozhidar

Henrik Eneroth

unread,
Sep 14, 2014, 3:07:42 PM9/14/14
to clo...@googlegroups.com
For all the good qualities of the Clojure group, it can sometimes produce a bit of a harsh tone. Don't let that get you down though, it's great that you're building stuff and showing it off!

As far as defun goes, it looks interesting. The out-of-the-box pattern matching was one of the things I enjoyed with ML. It's usually a quite tidy way to handle the termination conditions of recursions. It's less useful in Clojure, since we're more or less confined to loop and recur, but I still like the looks of this.

Max Gonzih

unread,
Sep 21, 2014, 5:13:26 AM9/21/14
to clo...@googlegroups.com
Amazing! Would love to have something like that in clojure.core.


On Sunday, September 14, 2014 8:47:28 AM UTC+2, dennis wrote:

killm...@gmail.com

unread,
Sep 21, 2014, 11:57:00 AM9/21/14
to clo...@googlegroups.com
I am glad it's helpful.I am using defun to write transform functions for instaparse in a DSL parser,it's really good at it.I am not sure if i can create a pull request to core.match.

发自我的 iPad

Devin Walters

unread,
Sep 23, 2014, 12:44:26 AM9/23/14
to clo...@googlegroups.com
I didn't read it that way.

On Sep 14, 2014, at 7:45 AM, adrian...@mail.yu.edu wrote:

Friendly advice: when you describe anything you create with adjectives like beautiful, it comes off as unnecessarily arrogant to native English speakers.

Adrian

J David Eisenberg

unread,
Sep 23, 2014, 8:20:43 PM9/23/14
to clo...@googlegroups.com


On Saturday, September 13, 2014 11:47:28 PM UTC-7, dennis wrote:

Hi , i am pleased to introduce defun: a beautiful macro to define clojure functions with pattern match.

[snip]

This is totally wonderful. Elegant, and useful.

Jacob Goodson

unread,
Sep 24, 2014, 11:03:15 PM9/24/14
to clo...@googlegroups.com
I did this same thing and called it defmatch.  You can use vinyasa to inject functions into core through leiningen.  I did that and it allowed me to have defmatch anywhere I wanted to have it.  Anyway, I guess someone else had this idea lol =P.

Ivan L

unread,
Sep 25, 2014, 1:09:03 PM9/25/14
to clo...@googlegroups.com
Is this clojurescript ready?  This looks amazing, I would also love to have it in core.


On Sunday, September 14, 2014 2:47:28 AM UTC-4, dennis wrote:

Andre Richards

unread,
Sep 26, 2014, 1:42:37 AM9/26/14
to clo...@googlegroups.com
Don't think Rich Hickey is a fan of pattern matching, which is probably why it is not in core to begin with.

If you watch his "Simple made easy" talk, pattern matching is one of the items listed under Complexity Toolkit, with this description: "Complects multiple who/what pairs".

I'm not sure where core.match is positioned - might have a better change to get added there?

dennis zhuang

unread,
Sep 26, 2014, 7:00:04 AM9/26/14
to Clojure
I will add supporting for clojurescript this weekend.Thanks for your suggestion.

--
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/d/optout.

Mars0i

unread,
Oct 10, 2014, 6:01:13 PM10/10/14
to clo...@googlegroups.com
I think it is a beautiful macro.

Max Gonzih

unread,
Oct 23, 2014, 8:59:28 AM10/23/14
to clo...@googlegroups.com
Are there any updates on clojurescript support?

Jay Porcasi

unread,
May 26, 2015, 1:13:27 AM5/26/15
to clo...@googlegroups.com
hi Dennis
wow... that's beyond beautiful, it's awesome
this makes Clojure even more 'Haskell-ish', which is a good thing in my opinion
thanks for sharing this gem with the world
Jay

Daniel Szmulewicz

unread,
May 28, 2015, 12:40:33 AM5/28/15
to clo...@googlegroups.com
A very instructional presentation about pattern matching in general and defun in particular was given by Sean Johnson at Clojure West.


Recommended watching. 
Reply all
Reply to author
Forward
0 new messages