<instructions>Your goal is to analyze the following comment and estimate how highly it will be upvoted by the Hacker News community.</instructions><comment><author>snikeris</author><text>My favorite example for this is the lame idiom you see in Java code:&lt;p&gt;&lt;pre&gt;&lt;code&gt;    if (log.isDebugEnabled()) {
        log.debug(&amp;quot;expensive&amp;quot; + debug + message);
    }
&lt;/code&gt;&lt;/pre&gt;
This is &amp;quot;better&amp;quot; than just log.debug(...) because with the latter, your expensive log message argument needs to be evaluated even if debug is disabled.&lt;p&gt;However, in a language w&amp;#x2F; macros, you just say:&lt;p&gt;&lt;pre&gt;&lt;code&gt;    (debug (str &amp;quot;expensive&amp;quot; debug message))
&lt;/code&gt;&lt;/pre&gt;
and these considerations are already taken care of for you:&lt;p&gt;&lt;a href=&quot;https:&amp;#x2F;&amp;#x2F;github.com&amp;#x2F;clojure&amp;#x2F;tools.logging&amp;#x2F;blob&amp;#x2F;master&amp;#x2F;src&amp;#x2F;main&amp;#x2F;clojure&amp;#x2F;clojure&amp;#x2F;tools&amp;#x2F;logging.clj#L91&quot; rel=&quot;nofollow&quot;&gt;https:&amp;#x2F;&amp;#x2F;github.com&amp;#x2F;clojure&amp;#x2F;tools.logging&amp;#x2F;blob&amp;#x2F;master&amp;#x2F;src&amp;#x2F;mai...&lt;/a&gt;</text><parent_chain><item><author>Xophmeister</author><text>Could someone please explain the difference between Lisp macros and, say, languages that have first-class functions? I get that a Lisp macro will be expanded into the respective code, while a function&amp;#x27;s execution is different. However, at the practical (i.e., developer&amp;#x27;s) level, are there any additional benefits?&lt;p&gt;Can, say, a Lisp macro be &amp;#x27;partially formed&amp;#x27;, in the sense that it can expand into some boilerplate that represents an incomplete syntax tree? (Whereas a higher-order-function is necessarily complete.) I can see that being useful, but not inasmuch a it&amp;#x27;s made out.</text></item><item><author>WalterGR</author><text>The article doesn&amp;#x27;t discuss macros, which is one of the answers to &amp;quot;Why Lisp?&amp;quot;&lt;p&gt;I didn&amp;#x27;t &amp;quot;get&amp;quot; macros until I read a footnote in the (freely available) book &lt;i&gt;Practical Common Lisp&lt;/i&gt;.  In chapter 7, it introduces the `dolist` macro.&lt;p&gt;&lt;pre&gt;&lt;code&gt;    DOLIST loops across the items of a list, executing the loop
    body with a variable holding the successive items of the list.
    This is the basic skeleton (leaving out some of the more
    esoteric options):

    (dolist (var list-form)
      body-form*)

    ...For instance:

    CL-USER&amp;gt; (dolist (x &amp;#x27;(1 2 3))
               (print x))
    1
    2
    3
    NIL
&lt;/code&gt;&lt;/pre&gt;
Buried in a footnote is this:&lt;p&gt;&amp;quot;DOLIST is similar to Perl&amp;#x27;s `foreach` or Python&amp;#x27;s `for`.  Java added a similar kind of loop construct with the &amp;#x27;enhanced&amp;#x27; for loop in Java 1.5, as part of JSR-201.&lt;p&gt;Notice what a difference macros make.  A Lisp programmer who notices a common pattern in their code can write a macro to give themselves a source-level abstraction of that pattern.  A Java programmer who notices the same pattern has to convince Sun that this particular abstraction is worth adding to the language.  Then Sun has to publish a JSR and convene an industry-wide &amp;quot;expert group&amp;quot; to hash everything out.  That process--according to Sun--takes an average of 18 months.  After that, the compiler writers all have to go upgrade their compilers to support the new feature.  And even once the Java programmer&amp;#x27;s favorite compiler supports the new version of Java, they probably still can&amp;#x27;t use the new feature until they&amp;#x27;re allowed to break source compatibility with older versions of Java.&lt;p&gt;So an annoyance that Common Lisp programmers can resolve for themselves within five minutes plagues Java programmers for years.&amp;quot;&lt;p&gt;&lt;a href=&quot;http:&amp;#x2F;&amp;#x2F;www.gigamonkeys.com&amp;#x2F;book&amp;#x2F;macros-standard-control-constructs.html&quot; rel=&quot;nofollow&quot;&gt;http:&amp;#x2F;&amp;#x2F;www.gigamonkeys.com&amp;#x2F;book&amp;#x2F;macros-standard-control-cons...&lt;/a&gt;</text></item></parent_chain></comment><story><title>Why Lisp?</title><url>http://blog.rongarret.info/2015/05/why-lisp.html</url></story>
<instructions>Your goal is to analyze the following comment and estimate how highly it will be upvoted by the Hacker News community.</instructions><comment><author>beeworker</author><text>One difference is flow control. When you call a function, all the arguments are evaluated before being passed into the function. If you want to delay evaluation, you have to wrap the argument values in a function. When you call a macro, the text forms get passed with no evaluation.&lt;p&gt;Say Clojure forgot to ship with the boolean &amp;quot;or&amp;quot;. &amp;quot;or&amp;quot; should evaluate its arguments one at a time (to allow for short circuiting) and return the first non-false value. You could do this with functions, but you have the source-level overhead of manually wrapping everything, and performance overhead of defining and passing an anonymous function for each argument. With a macro, at compile time you just translate the &amp;quot;or&amp;quot; macro into a simpler form that uses &amp;quot;if&amp;quot;. This is how Clojure actually implements &amp;quot;or&amp;quot;:&lt;p&gt;&lt;pre&gt;&lt;code&gt;    (defmacro or
      &amp;quot;Evaluates exprs one at a time, from left to right. If a form
      returns a logical true value, or returns that value and doesn&amp;#x27;t
      evaluate any of the other expressions, otherwise it returns the
      value of the last expression. (or) returns nil.&amp;quot;
      {:added &amp;quot;1.0&amp;quot;}
      ([] nil)
      ([x] x)
      ([x &amp;amp; next]
          `(let [or# ~x]
             (if or# or# (or ~@next)))))&lt;/code&gt;&lt;/pre&gt;</text><parent_chain><item><author>Xophmeister</author><text>Could someone please explain the difference between Lisp macros and, say, languages that have first-class functions? I get that a Lisp macro will be expanded into the respective code, while a function&amp;#x27;s execution is different. However, at the practical (i.e., developer&amp;#x27;s) level, are there any additional benefits?&lt;p&gt;Can, say, a Lisp macro be &amp;#x27;partially formed&amp;#x27;, in the sense that it can expand into some boilerplate that represents an incomplete syntax tree? (Whereas a higher-order-function is necessarily complete.) I can see that being useful, but not inasmuch a it&amp;#x27;s made out.</text></item><item><author>WalterGR</author><text>The article doesn&amp;#x27;t discuss macros, which is one of the answers to &amp;quot;Why Lisp?&amp;quot;&lt;p&gt;I didn&amp;#x27;t &amp;quot;get&amp;quot; macros until I read a footnote in the (freely available) book &lt;i&gt;Practical Common Lisp&lt;/i&gt;.  In chapter 7, it introduces the `dolist` macro.&lt;p&gt;&lt;pre&gt;&lt;code&gt;    DOLIST loops across the items of a list, executing the loop
    body with a variable holding the successive items of the list.
    This is the basic skeleton (leaving out some of the more
    esoteric options):

    (dolist (var list-form)
      body-form*)

    ...For instance:

    CL-USER&amp;gt; (dolist (x &amp;#x27;(1 2 3))
               (print x))
    1
    2
    3
    NIL
&lt;/code&gt;&lt;/pre&gt;
Buried in a footnote is this:&lt;p&gt;&amp;quot;DOLIST is similar to Perl&amp;#x27;s `foreach` or Python&amp;#x27;s `for`.  Java added a similar kind of loop construct with the &amp;#x27;enhanced&amp;#x27; for loop in Java 1.5, as part of JSR-201.&lt;p&gt;Notice what a difference macros make.  A Lisp programmer who notices a common pattern in their code can write a macro to give themselves a source-level abstraction of that pattern.  A Java programmer who notices the same pattern has to convince Sun that this particular abstraction is worth adding to the language.  Then Sun has to publish a JSR and convene an industry-wide &amp;quot;expert group&amp;quot; to hash everything out.  That process--according to Sun--takes an average of 18 months.  After that, the compiler writers all have to go upgrade their compilers to support the new feature.  And even once the Java programmer&amp;#x27;s favorite compiler supports the new version of Java, they probably still can&amp;#x27;t use the new feature until they&amp;#x27;re allowed to break source compatibility with older versions of Java.&lt;p&gt;So an annoyance that Common Lisp programmers can resolve for themselves within five minutes plagues Java programmers for years.&amp;quot;&lt;p&gt;&lt;a href=&quot;http:&amp;#x2F;&amp;#x2F;www.gigamonkeys.com&amp;#x2F;book&amp;#x2F;macros-standard-control-constructs.html&quot; rel=&quot;nofollow&quot;&gt;http:&amp;#x2F;&amp;#x2F;www.gigamonkeys.com&amp;#x2F;book&amp;#x2F;macros-standard-control-cons...&lt;/a&gt;</text></item></parent_chain></comment><story><title>Why Lisp?</title><url>http://blog.rongarret.info/2015/05/why-lisp.html</url></story>