I am thinking about learning Clojure, but coming from the c-syntax based (java, php, c#) world of imperative languages that's going to be a challenge, so one naturally asks oneself, is it really worth it? And while such question statement can be very subjective and hard to manage, there is one specific trait of Clojure (and more generally, the lisps) that I keep reading about, that is supposed to make it the most flexipowerful language ever: the macros.
Do you have any good examples of macro usage in Clojure, for purposes which in other mainstream languages (consider any of C++, PHP, Perl, Python, Groovy/Java, C#, JavaScript) would require much less elegant solutions/a lot of unnecessary abstraction/hacks/etc.
Clojure has a programmatic macro system which allows the compiler to be extended by user code. Macros can be used to define syntactic constructs which would require primitives or built-in support in other languages. Many core constructs of Clojure are not, in fact, primitives, but are normal macros.
Clojure is a good choice for a wide variety of projects. You can use it from social networking industry to Big Data solutions. Initially, Clojure language was targeted for working with JVM. So, the most popular modern Clojure implementation uses the Java Virtual Machine.
I find macros pretty useful for defining new language features. In most languages you would need to wait for a new release of the language to get new syntax - in Lisp you can just extend the core language with macros and add the features yourself.
For example, Clojure doesn't have a imperative C-style for(i=0 ;i<10; i++)
loop but you can easily add one with a macro:
(defmacro for-loop [[sym init check change :as params] & steps] (cond (not (vector? params)) (throw (Error. "Binding form must be a vector for for-loop")) (not= 4 (count params)) (throw (Error. "Binding form must have exactly 4 arguments in for-loop")) :default `(loop [~sym ~init value# nil] (if ~check (let [new-value# (do ~@steps)] (recur ~change new-value#)) value#))))
Usage as follows:
(for-loop [i 0, (< i 10), (inc i)] (println i))
Whether it is a good idea to add an imperative loop to a functional language is a debate we should probably avoid here :-)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With