{"id":13970,"date":"2013-06-11T22:00:56","date_gmt":"2013-06-11T19:00:56","guid":{"rendered":"http:\/\/www.javacodegeeks.com\/?p=13970"},"modified":"2013-06-11T16:16:17","modified_gmt":"2013-06-11T13:16:17","slug":"clojure-macros-for-beginners","status":"publish","type":"post","link":"https:\/\/www.javacodegeeks.com\/2013\/06\/clojure-macros-for-beginners.html","title":{"rendered":"Clojure macros for beginners"},"content":{"rendered":"<p><a href=\"http:\/\/1.bp.blogspot.com\/-j1P9jtYKKbQ\/UbTyoJNg5EI\/AAAAAAAAAw8\/wa46aI-LOhw\/s1600\/oslo-0.jpg\"><img decoding=\"async\" class=\"alignright\" style=\"border: 0px none;\" alt=\"\" src=\"http:\/\/1.bp.blogspot.com\/-j1P9jtYKKbQ\/UbTyoJNg5EI\/AAAAAAAAAw8\/wa46aI-LOhw\/s200\/oslo-0.jpg\" width=\"200\" height=\"149\" border=\"0\" \/><\/a>This article will guide you step-by-step (or even<br \/>\n<i>character-by-character<\/i>) through the process of writing macros in Clojure. I will focus on fundamental macro characteristics while explaining what happens behind the scenes. Imagine you are about to write an assertions library for Clojure, similar to <a href=\"https:\/\/github.com\/alexruiz\/fest-assert-2.x\/wiki\">FEST Assertions<\/a>, <a href=\"http:\/\/www.scalatest.org\/user_guide\/using_assertions\">ScalaTest assertions<\/a> or <a href=\"http:\/\/hamcrest.org\/\">Hamcrest<\/a>. Of course there are <a href=\"http:\/\/clojure.github.io\/clojure\/clojure.test-api.html\">such existing<\/a> but this is just for educational purposes. What we essentially need first is a <code>assert-equals<\/code> function used like this:<br \/>\n&nbsp;<\/p>\n<pre class=\"brush:java\">(assert-equals\r\n    (count (filter even? primes)) 1)<\/pre>\n<p>Of course this is more than trivial:<\/p>\n<pre class=\"brush:java\">(defn assert-equals [actual expected]\r\n    (when-not (= actual expected)\r\n        (throw\r\n            (AssertionError.\r\n                (str \"Expected \" expected \" but was \" actual)))))<\/pre>\n<p>Quick test with incorrectly defined <code>primes<\/code> vector:<\/p>\n<pre class=\"brush:java\">user=&gt; (def primes [0 2 3 5 7 11])\r\n#'user\/primes\r\nuser=&gt; (assert-equals (count (filter even? primes)) 1)\r\n \r\nAssertionError Expected 1 but was 2<\/pre>\n<p>Cool, but imagine this test failing on CI server or seeing this in your terminal. There is no context, maybe you\u2019ll get test name if you\u2019re lucky. \u201c<code>Expected 1 but was 2<\/code>\u201d tells us nothing about the nature or root cause of the problem. Wouldn\u2019t it be great to see:<\/p>\n<pre class=\"brush:java\">AssertionError Expected '(count (filter even? primes))' to be 1 but was 2<\/pre>\n<p>You see this? Assertion error now gives us full expression that yielded incorrect result. We can see from the very first second what the issue can be. However, there is a problem. Big one. By the time we are throwing <code>AssertionError<\/code>, original expression is lost. We got<br \/>\n<code>actual<\/code> <i>value<\/i> as an argument and we have no idea where did that value came from. It could have been a constant, result of expression like <code>(count (filter even? primes))<\/code> or even a random value. Function arguments are computed eagerly and there is no way to access <i>code<\/i> that produced these arguments.<\/p>\n<h2>Entering macros<\/h2>\n<p>Macros and functions in Clojure are not independent or orthogonal. In fact, they are almost the same:<\/p>\n<ul>\n<li><b>Functions<\/b> execute at <b>run time<\/b>, they take and produce <b>data<\/b> (values). Conceptually one can replace every (pure) function invocation with its value.<\/li>\n<li><b>Macros<\/b> execute at <b>compile time<\/b>, they take and produce <b>code<\/b>. Conceptually one can replace (<i>expand<\/i>) every occurrence of macro with its value.<\/li>\n<\/ul>\n<p>Not that much different? Moreover since Clojure is <a href=\"http:\/\/en.wikipedia.org\/wiki\/Homoiconicity\"><i>homoiconic<\/i><\/a>, Clojure code can be represented as Clojure data structures. In other words both functions and macros accept data, but in case of macros it\u2019s more often to see Clojure source represented using data structures like lists.<\/p>\n<p>What does it all mean and how can it help us? Let\u2019s jump straight into writing our first (incorrect) macro and improve it step-by-step to finally achieve desired result. To keep samples focused I skip throwing an <code>AssertionError<\/code> and leave only equality condition:<\/p>\n<pre class=\"brush:java\">user=&gt; (defmacro assert-equals [actual expected]\r\n            (= expected actual))\r\n#'user\/assert-equals\r\nuser=&gt; (assert-equals 2 2)\r\ntrue\r\n \r\nuser=&gt; (assert-equals 2 3)\r\nfalse<\/pre>\n<p>Works? In fact we are very far from having a correct version:<\/p>\n<pre class=\"brush:java\">user=&gt; (assert-equals (inc 5) 6)\r\nfalse\r\n \r\nuser=&gt; (def x 1)\r\n#'user\/x\r\nuser=&gt; (assert-equals (+ x 2) 3)\r\nfalse<\/pre>\n<p><code>1 + 2<\/code> is definitely equal to <code>3<\/code>, yet it returns false. In order to appreciate this behaviour and call it \u201c <i>feature<\/i>\u201d rather than \u201c <i>bug<\/i>\u201d we must deeply understand what just happened. Remember, macros are executed at compile time, right? And they are almost ordinary functions. So, the compiler executes <code>assert-equals<\/code>. However during compilation it can\u2019t possibly know the values of variables like <code>x<\/code>, therefore it can\u2019t eagerly evaluate macro arguments. We don\u2019t even want that, as you see later.<\/p>\n<p>Instead the compiler passes <b>Clojure code, literally<\/b>. The <code>actual<\/code> parameter is <code>(inc 5)<\/code> &#8211; literally, Clojure list holding two elements: <code>inc<\/code> symbol and <code>5<\/code> number. That\u2019s all there is to it. <code>expected<\/code> is just a number. This means that inside macro we have full access to Clojure source code enclosed by that macro.<div style=\"display:inline-block; margin: 15px 0;\"> <div id=\"adngin-JavaCodeGeeks_incontent_video-0\" style=\"display:inline-block;\"><\/div> <\/div><\/p>\n<p>So maybe you can now guess what happens. Clojure compiler executes macro definition, that is <code>(= expected actual)<\/code>. As far as the compiler is concerned, <code>actual<\/code> is a list <code>(inc 5)<\/code> while <code>expected<\/code> is a number <code>6<\/code>. List can never possibly be equal to a number. Thus macro returns <code>false<\/code>, just like any other function can return it. Later on Clojure compiler replaces <code>(assert-equals (inc 5) 6)<\/code> expression with the outcome of macro, which happens to be\u2026 <code>false<\/code>. We said before that macro should return valid Clojure code (represented using Clojure data structures). <code>false<\/code> <i>is<\/i> valid Clojure code!<\/p>\n<p>Now we know that instead of evaluating <code>(= expected actual)<\/code> by the compiler (after all, we don\u2019t want the compiler to run our assertions, we only want to compile them!) we simply want to return <i>code<\/i> that represents this assertion. It\u2019s not that hard!<\/p>\n<pre class=\"brush:java\">(defmacro assert-equals [actual expected] (list '= expected actual))<\/pre>\n<p>Now our macro returns result of evaluating <code>(list '= expected actual)<\/code> expression. The result happens to be\u2026 <code>(= expected actual)<\/code>. That\u2019s right, it looks like valid Clojure code, again. Extra quote (<code>'=<\/code>) was added so that <code>=<\/code> is interpreted as raw symbol rather than a function reference. Let\u2019s take it for a test drive:<\/p>\n<pre class=\"brush:java\">user=&gt; (assert-equals (inc 5) 6)\r\ntrue\r\nuser=&gt; (macroexpand '(assert-equals (inc 5) 6))\r\n(= 6 (inc 5))<\/pre>\n<p><code>macroexpand<\/code> and <code>macroexpand-1<\/code> are your weapons of choice when debugging macros. Here you see that <code>(assert-equals (inc 5) 6)<\/code> is actually being replaced by <code>(= 6 (inc 5))<\/code>. This process happens at compile time, <b>macros don\u2019t exist at runtime<\/b>. In your compiled code you are left with <code>(= 6 (inc 5))<\/code>. OK, so let\u2019s restore the full functionality of throwing <code>AssertionError<\/code>. As you know by now, our macro should return Clojure code that includes equality check and throwing an exception. This becomes a bit unwieldy:<\/p>\n<pre class=\"brush:java\">(defmacro assert-equals [actual expected]\r\n    (list 'when-not (list '= actual expected)\r\n        (list 'throw\r\n            (list 'AssertionError.\r\n                (list 'str \"Expected \" expected \" but was \" actual)))))<\/pre>\n<p>Notice how every single symbol has to be escaped ( <code>'when-not<\/code>, <code>'throw<\/code>, <code>'AssertionError.<\/code>, \u2026), otherwise compiler will try to evaluate it at compile time. Moreover list in Clojure denotes function call so we must proceed every list literal with <code>(list ...)<\/code> function call. If you are not that familiar with Clojure: <code>(list 1 2)<\/code> returns list of <code>(1 2)<\/code> while <code>(1 2)<\/code> will throw an exception since <code>1<\/code> number is not a function.<\/p>\n<p>Ugly or not, it works:<\/p>\n<pre class=\"brush:java\">user=&gt; (assert-equals (inc 5) 6)\r\nnil\r\nuser=&gt; (assert-equals 5 6)\r\nAssertionError Expected 6 but was 5<\/pre>\n<p>We barely reproduced what original <code>assert-equals<\/code> function was doing and the first commandment of writing macros is: don\u2019t write macros if function is sufficient. But before we go further, let us clean up what we have so far. Typical macro definition consists of lots of Clojure code that has to be escaped and not that much <i>live<\/i> values like <code>actual<\/code> and <code>expected<\/code> in our case. So there is a smart default &#8211; instead of quoting everything except few items, quote everything upfront and selectively <i>unquote<\/i> things. This is called <b>syntax &#8211; quoting<\/b> (using ` character) and unquoting is done via <code>~<\/code> operator. Look carefully: we syntax quote whole result and selectively unquote what was previously not quoted:<\/p>\n<pre class=\"brush:java\">(defmacro assert-equals [actual expected]\r\n    `(when-not (= ~actual ~expected)\r\n        (throw\r\n            (AssertionError.\r\n                (str \"Expected \" ~expected \" but was \" ~actual)))))<\/pre>\n<p>This is equivalent to previous definition but looks much better, almost entirely like valid Clojure code. Let\u2019s employ <code>macroexpand-1<\/code> to see how our macro is expanded during compilation. <code>macroexpand<\/code> would work as well, but since <code>when-not<\/code> is also a macro (!) it would be recursively expanded, cluttering output:<\/p>\n<pre class=\"brush:java\">user=&gt; (macroexpand-1 '(assert-equals (inc 5) 6))\r\n(when-not\r\n    (= (inc 5) 6)\r\n        (throw\r\n            (java.lang.AssertionError.\r\n                (str \"Expected \" 6 \" but was \" (inc 5)))))<\/pre>\n<p>It\u2019s like templating language embedded within that language! Notice how <code>(inc 5)<\/code> piece of code was inserted instead of <code>~actual<\/code> twice. Keep that in mind. Also experiment by removing unquote (<code>~<\/code>) symbol here or there. Use <code>macroexpand-1<\/code> to figure out what is going on. Remember, our ultimate goal was to show <code>actual<\/code> expression in its full glory, not only its value.<\/p>\n<pre class=\"brush:java\">(AssertionError.\r\n   (str \"Expected '???' to be \" ~expected \" but was \" actual-value#))))))<\/pre>\n<p>What should we put in place of <code>???<\/code> to print \u201c <code>(inc 5)<\/code>\u201d <i>string<\/i>. We know that value of <code>actual<\/code> is <i>not<\/i> <code>6<\/code> but a list with two items: <code>(inc 5)<\/code>. Can we somehow quote that list again so that it no longer evaluates at run-time but instead is treated as a data structure? Of course, we know how to quote things!<\/p>\n<pre class=\"brush:java\">(defmacro assert-equals [actual expected]\r\n    `(let [~'actual-value ~actual]\r\n        (when-not (= ~'actual-value ~expected)\r\n            (throw\r\n                (AssertionError.\r\n                   (str \"Expected '\" '~actual \"' to be \" ~expected \" but was \" ~'actual-value))))))<\/pre>\n<p><code>'~actual<\/code>, oh dear! <i>quote unquote actual<\/i>. This translates to <code>'(inc 5)<\/code>. And that\u2019s it! Look how descriptive assertion error messages are:<\/p>\n<pre class=\"brush:java\">user=&gt; (assert-equals (inc 5) 5)\r\nAssertionError Expected '(inc 5)' to be 5 but was 6\r\n \r\nuser=&gt; (assert-equals (count (filter even? primes)) 1)\r\nAssertionError Expected '(count (filter even? primes))' to be 1 but was 2<\/pre>\n<p>Expanding this macro manually reveals how it is translated by the compiler (edited to improve readability):<\/p>\n<pre class=\"brush:java\">user=&gt; (macroexpand-1 '(assert-equals (inc 5) 5))\r\n(when-not\r\n    (= (inc 5) 5)\r\n        (throw\r\n            (java.lang.AssertionError.\r\n                (str \"Expected '\" (quote (inc 5)) \"' to be \" 5 \" but was \" (inc 5)))))<\/pre>\n<p>There is really no magic here, we could have written that ourselves. But macros avoid lots of repetitive work.<\/p>\n<h2>Bindings in macros<\/h2>\n<p>Our solution so far has one major issue. Imagine we are testing impure or slow function like this:<\/p>\n<pre class=\"brush:java\">(def question \"Answer to the Ultimate Question of Life, The Universe, and Everything\")\r\n(defn answer [q]\r\n    (do\r\n        (println \"Computing for 7\u00bd million years...\")\r\n        41))<\/pre>\n<p>As you can see it returns <a href=\"http:\/\/en.wikipedia.org\/wiki\/Phrases_from_The_Hitchhiker%27s_Guide_to_the_Galaxy#Answer_to_the_Ultimate_Question_of_Life.2C_the_Universe.2C_and_Everything_.2842.29\">wrong result<\/a>, which can be easily proved in a unit test:<\/p>\n<pre class=\"brush:java\">user=&gt; (assert-equals (answer question) 42)\r\nComputing for 7\u00bd million years...\r\nComputing for 7\u00bd million years...\r\n \r\nAssertionError Expected '(answer question)' to be 42 but was 41<\/pre>\n<p>The error message is fine, but notice that \u201c <code>Computing...<\/code>\u201d statement was printed twice. Clearly because impure <code>answer<\/code> function was called twice as well. Macro expansion reveals why:<\/p>\n<pre class=\"brush:java\">user=&gt; (macroexpand-1 '(assert-equals (answer question) 42))\r\n(when-not\r\n    (= (answer question) 42)\r\n        (throw (java.lang.AssertionError.\r\n            (str \"Expected '\" (quote (answer question)) \"' to be \" 42 \" but was \"\r\n                (answer question)))))<\/pre>\n<p><code>(answer question)<\/code> appears twice (not counting <code>quote<\/code>d one), once during comparison and second time when we generate assertion message. This is rarely desired, especially when <i>function under test<\/i> has side effects. The solution is simple: precompute <code>(answer question)<\/code> once, store it somewhere and reference when needed. But there is a twist: declaring <code>let<\/code> bindings inside macros is tricky. Sometimes you might hit unexpected name shadowing and overriding when names of variables inside macro collide with the ones used in user code. Not going into much detail, using <code>(gensym)<\/code> or convenient <code>#<\/code> suffix is enough to keep our macros safe. In both cases Clojure compiler will produce unique names making sure they don\u2019t collide. Our final solution looks like this:<\/p>\n<pre class=\"brush:java\">(defmacro assert-equals [actual expected]\r\n    `(let [actual-value# ~actual]\r\n        (when-not (= actual-value# ~expected)\r\n            (throw\r\n                (AssertionError.\r\n                   (str \"Expected '\" '~actual \"' to be \" ~expected\r\n                       \" but was \" actual-value#))))))<\/pre>\n<p>This time <code>actual-value#<\/code> binding is used to compute <code>actual<\/code> only once:<\/p>\n<pre class=\"brush:java\">user=&gt; (macroexpand-1 '(assert-equals (answer question) 42))\r\n(let [actual-value__264__auto__ (answer question)]\r\n    (when-not (= actual-value__264__auto__ 42)\r\n        (throw\r\n            (java.lang.AssertionError.\r\n                (str \"Expected '\" (quote (answer question)) \"' to be \" 42 \"\r\n                   but was \" actual-value__264__auto__)))))<\/pre>\n<p>Extra suffix replacing <code>#<\/code> symbol makes sure <code>actual-value<\/code> is not colliding with any other symbol.<\/p>\n<h2>Summary<\/h2>\n<p>Our <code>assert-equals<\/code> macro is not the most comprehensive one, just like this tutorial. But it gives you some impression of what macros can do and how they work. If you need further resources, check out this <a href=\"http:\/\/www.learningclojure.com\/2010\/09\/clojure-macro-tutorial-part-i-getting.html\">great macro tutorial<\/a> (part <a href=\"http:\/\/www.learningclojure.com\/2010\/09\/clojure-macro-tutorial-part-ii-compiler.html\">2<\/a> and <a href=\"http:\/\/www.learningclojure.com\/2010\/09\/clojure-macro-tutorial-part-ii-syntax.html\">3<\/a>). If you like the idea of enhanced assertions, <a href=\"http:\/\/hamletdarcy.blogspot.no\/2009\/05\/new-power-assertions-in-groovy.html\">Power Assertions in Groovy<\/a> are even more comprehensive. But I bet this behaviour can be reproduced in Clojure macros!<br \/>\n&nbsp;<\/p>\n<div style=\"border: 1px solid #D8D8D8; background: #FAFAFA; width: 100%; padding-left: 5px;\"><b><i>Reference: <\/i><\/b><a href=\"http:\/\/nurkiewicz.blogspot.com\/2013\/06\/clojure-macros-for-beginners.html\">Clojure macros for beginners<\/a> from our <a href=\"http:\/\/www.javacodegeeks.com\/jcg\">JCG partner<\/a> Tomasz Nurkiewicz at the <a href=\"http:\/\/nurkiewicz.blogspot.com\/\">Java and neighbourhood<\/a> blog.<\/div>\n","protected":false},"excerpt":{"rendered":"<p>This article will guide you step-by-step (or even character-by-character) through the process of writing macros in Clojure. I will focus on fundamental macro characteristics while explaining what happens behind the scenes. Imagine you are about to write an assertions library for Clojure, similar to FEST Assertions, ScalaTest assertions or Hamcrest. Of course there are such &hellip;<\/p>\n","protected":false},"author":13,"featured_media":93,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[22],"tags":[],"class_list":["post-13970","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-clojure"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Clojure macros for beginners<\/title>\n<meta name=\"description\" content=\"This article will guide you step-by-step (or even character-by-character) through the process of writing macros in Clojure. I will focus on fundamental\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.javacodegeeks.com\/2013\/06\/clojure-macros-for-beginners.html\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Clojure macros for beginners\" \/>\n<meta property=\"og:description\" content=\"This article will guide you step-by-step (or even character-by-character) through the process of writing macros in Clojure. I will focus on fundamental\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.javacodegeeks.com\/2013\/06\/clojure-macros-for-beginners.html\" \/>\n<meta property=\"og:site_name\" content=\"Java Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/javacodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2013-06-11T19:00:56+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/clojure-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Tomasz Nurkiewicz\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@https:\/\/twitter.com\/tnurkiewicz\" \/>\n<meta name=\"twitter:site\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Tomasz Nurkiewicz\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"9 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/06\\\/clojure-macros-for-beginners.html#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/06\\\/clojure-macros-for-beginners.html\"},\"author\":{\"name\":\"Tomasz Nurkiewicz\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/fb1be85725c10e8361e641fa851e79e1\"},\"headline\":\"Clojure macros for beginners\",\"datePublished\":\"2013-06-11T19:00:56+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/06\\\/clojure-macros-for-beginners.html\"},\"wordCount\":1436,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/06\\\/clojure-macros-for-beginners.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/clojure-logo.jpg\",\"articleSection\":[\"Clojure\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/06\\\/clojure-macros-for-beginners.html#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/06\\\/clojure-macros-for-beginners.html\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/06\\\/clojure-macros-for-beginners.html\",\"name\":\"Clojure macros for beginners\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/06\\\/clojure-macros-for-beginners.html#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/06\\\/clojure-macros-for-beginners.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/clojure-logo.jpg\",\"datePublished\":\"2013-06-11T19:00:56+00:00\",\"description\":\"This article will guide you step-by-step (or even character-by-character) through the process of writing macros in Clojure. I will focus on fundamental\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/06\\\/clojure-macros-for-beginners.html#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/06\\\/clojure-macros-for-beginners.html\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/06\\\/clojure-macros-for-beginners.html#primaryimage\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/clojure-logo.jpg\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/clojure-logo.jpg\",\"width\":150,\"height\":150},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/06\\\/clojure-macros-for-beginners.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"JVM Languages\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/jvm-languages\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Clojure\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/jvm-languages\\\/clojure\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"Clojure macros for beginners\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"name\":\"Java Code Geeks\",\"description\":\"Java Developers Resource Center\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"alternateName\":\"JCG\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.javacodegeeks.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/javacodegeeks\",\"https:\\\/\\\/x.com\\\/javacodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/fb1be85725c10e8361e641fa851e79e1\",\"name\":\"Tomasz Nurkiewicz\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/f2a8f9f1060fc7c1161c42f8ba901e0e79fb767dec39ec34b2d3b95cab9dc728?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/f2a8f9f1060fc7c1161c42f8ba901e0e79fb767dec39ec34b2d3b95cab9dc728?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/f2a8f9f1060fc7c1161c42f8ba901e0e79fb767dec39ec34b2d3b95cab9dc728?s=96&d=mm&r=g\",\"caption\":\"Tomasz Nurkiewicz\"},\"description\":\"Java EE developer, Scala enthusiast. Enjoying data analysis and visualization. Strongly believes in the power of testing and automation.\",\"sameAs\":[\"http:\\\/\\\/nurkiewicz.blogspot.com\\\/\",\"https:\\\/\\\/x.com\\\/https:\\\/\\\/twitter.com\\\/tnurkiewicz\"],\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/author\\\/tomasz-nurkiewicz\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Clojure macros for beginners","description":"This article will guide you step-by-step (or even character-by-character) through the process of writing macros in Clojure. I will focus on fundamental","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.javacodegeeks.com\/2013\/06\/clojure-macros-for-beginners.html","og_locale":"en_US","og_type":"article","og_title":"Clojure macros for beginners","og_description":"This article will guide you step-by-step (or even character-by-character) through the process of writing macros in Clojure. I will focus on fundamental","og_url":"https:\/\/www.javacodegeeks.com\/2013\/06\/clojure-macros-for-beginners.html","og_site_name":"Java Code Geeks","article_publisher":"https:\/\/www.facebook.com\/javacodegeeks","article_published_time":"2013-06-11T19:00:56+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/clojure-logo.jpg","type":"image\/jpeg"}],"author":"Tomasz Nurkiewicz","twitter_card":"summary_large_image","twitter_creator":"@https:\/\/twitter.com\/tnurkiewicz","twitter_site":"@javacodegeeks","twitter_misc":{"Written by":"Tomasz Nurkiewicz","Est. reading time":"9 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.javacodegeeks.com\/2013\/06\/clojure-macros-for-beginners.html#article","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/2013\/06\/clojure-macros-for-beginners.html"},"author":{"name":"Tomasz Nurkiewicz","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/fb1be85725c10e8361e641fa851e79e1"},"headline":"Clojure macros for beginners","datePublished":"2013-06-11T19:00:56+00:00","mainEntityOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2013\/06\/clojure-macros-for-beginners.html"},"wordCount":1436,"commentCount":0,"publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2013\/06\/clojure-macros-for-beginners.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/clojure-logo.jpg","articleSection":["Clojure"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.javacodegeeks.com\/2013\/06\/clojure-macros-for-beginners.html#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.javacodegeeks.com\/2013\/06\/clojure-macros-for-beginners.html","url":"https:\/\/www.javacodegeeks.com\/2013\/06\/clojure-macros-for-beginners.html","name":"Clojure macros for beginners","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2013\/06\/clojure-macros-for-beginners.html#primaryimage"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2013\/06\/clojure-macros-for-beginners.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/clojure-logo.jpg","datePublished":"2013-06-11T19:00:56+00:00","description":"This article will guide you step-by-step (or even character-by-character) through the process of writing macros in Clojure. I will focus on fundamental","breadcrumb":{"@id":"https:\/\/www.javacodegeeks.com\/2013\/06\/clojure-macros-for-beginners.html#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.javacodegeeks.com\/2013\/06\/clojure-macros-for-beginners.html"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/2013\/06\/clojure-macros-for-beginners.html#primaryimage","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/clojure-logo.jpg","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/clojure-logo.jpg","width":150,"height":150},{"@type":"BreadcrumbList","@id":"https:\/\/www.javacodegeeks.com\/2013\/06\/clojure-macros-for-beginners.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.javacodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"JVM Languages","item":"https:\/\/www.javacodegeeks.com\/category\/jvm-languages"},{"@type":"ListItem","position":3,"name":"Clojure","item":"https:\/\/www.javacodegeeks.com\/category\/jvm-languages\/clojure"},{"@type":"ListItem","position":4,"name":"Clojure macros for beginners"}]},{"@type":"WebSite","@id":"https:\/\/www.javacodegeeks.com\/#website","url":"https:\/\/www.javacodegeeks.com\/","name":"Java Code Geeks","description":"Java Developers Resource Center","publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"alternateName":"JCG","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.javacodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.javacodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.javacodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/javacodegeeks","https:\/\/x.com\/javacodegeeks"]},{"@type":"Person","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/fb1be85725c10e8361e641fa851e79e1","name":"Tomasz Nurkiewicz","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/f2a8f9f1060fc7c1161c42f8ba901e0e79fb767dec39ec34b2d3b95cab9dc728?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/f2a8f9f1060fc7c1161c42f8ba901e0e79fb767dec39ec34b2d3b95cab9dc728?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/f2a8f9f1060fc7c1161c42f8ba901e0e79fb767dec39ec34b2d3b95cab9dc728?s=96&d=mm&r=g","caption":"Tomasz Nurkiewicz"},"description":"Java EE developer, Scala enthusiast. Enjoying data analysis and visualization. Strongly believes in the power of testing and automation.","sameAs":["http:\/\/nurkiewicz.blogspot.com\/","https:\/\/x.com\/https:\/\/twitter.com\/tnurkiewicz"],"url":"https:\/\/www.javacodegeeks.com\/author\/tomasz-nurkiewicz"}]}},"_links":{"self":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/13970","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/users\/13"}],"replies":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/comments?post=13970"}],"version-history":[{"count":0,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/13970\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media\/93"}],"wp:attachment":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media?parent=13970"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/categories?post=13970"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/tags?post=13970"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}