Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Declaring design pattern in a Macro in Clojure

One of the virtues of Lisp is Macros. I have been reading a lot that in Java you write design patterns again and again. Not in Lisp/Clojure.
In Lisp/Clojure you’d declare the pattern in a macro and you’d only have to write the actual code.

Ok, nice and dandy but seeing is believing.

Would you please provide me (or refer me) an example with code -preferably Clojure- about how to declare a design pattern in a Macro?

like image 485
Chiron Avatar asked May 08 '26 22:05

Chiron


2 Answers

Most of the existing design patterns originated and makes sense only in the Object Oriented world. As soon as you step into functional programming, and maybe especially Lisp dialects such as Clojure, your need for design patters gets smaller and smaller. There's an intresting discussion about design patterns and FP here.

On the other hand, macros are not intended to encapsulate design patterns, but rather extend the language with constructs that are more handy to solve the problem at hand. Take the with-open macro: calling it a design pattern to invoke close on a resource seems simply wrong.

Patterns exist in the FP world as well, but as you don't have objects anymore their main focus is on algorithms. Good examples of "patterns" for FP languages are monads and zippers.

Warning: it might take time to grok those concepts, but it's definitely worth to understand every bit of them.

like image 119
skuro Avatar answered May 11 '26 15:05

skuro


Example of a typical macro usage to implement a design pattern would be the "Decorator" pattern applied to an existing function.

; a simple function
(defn square [x] (* x x))

; a macro to "decorate" a function with a debug output println
(defmacro with-debug-output [f] 
  `(fn [& args#] 
     (let [result# (apply ~f args#)]
       (println (str "Debug-output: " result#))
       result#)))


; call the straight function
(square 16)
=> 256

; call the decorated function
((with-debug-output square) 16)
Debug-output: 256
=> 256

Note: you don't really need a macro to do this, you could also do it with a higher order function.

like image 34
mikera Avatar answered May 11 '26 14:05

mikera



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!