<story><title>Not Lisp again (2009)</title><url>https://funcall.blogspot.com/2009/03/not-lisp-again.html</url></story><parent_chain><item><author>QuadrupleA</author><text>My previous, somewhat-cranky comment got downvoted away, but I do think Lisp&amp;#x27;s &amp;quot;higher-order magic&amp;quot; and &amp;quot;ability to do calculus&amp;quot; is being a bit exaggerated here. From below - evaluating an Nth derivative in 80s-era C is not so atrocious:&lt;p&gt;&lt;pre&gt;&lt;code&gt;    #define DX 0.0001
    typedef double (*func)(double);

    double NthDeriv(int n, func f, double x) {
        if (n == 1) {
            return (f(x + DX) - f(x)) &amp;#x2F; DX;
        }
        else {
            return (NthDeriv(n - 1, f, x + DX) - NthDeriv(n - 1, f, x)) &amp;#x2F; DX;
        }
    }

    double Cube(double x) { return x * x * x; }

    double result = NthDeriv(3, &amp;amp;Cube, 5.0);
&lt;/code&gt;&lt;/pre&gt;
As mentioned in previous discussions of this article, the equivalent in Python is pretty elegant:&lt;p&gt;&lt;pre&gt;&lt;code&gt;    &amp;gt;&amp;gt;&amp;gt; def deriv(f):
    ...   dx = 0.0001
    ...   def fp(x):
    ...     return (f(x + dx) - f(x)) &amp;#x2F; dx
    ...   return fp
    ...
    &amp;gt;&amp;gt;&amp;gt; cube = lambda x: x**3
    &amp;gt;&amp;gt;&amp;gt; deriv(cube)(2.0)
    12.000600010022566&lt;/code&gt;&lt;/pre&gt;</text></item></parent_chain><comment><author>derefr</author><text>I think the thing that impressed the author at the time was more the fact that functions, being first-class values, can be introduced at runtime in a REPL, rather than having to be &amp;quot;planned&amp;quot; at compile time. So the C code isn&amp;#x27;t really analogous, but the Python code is.&lt;p&gt;But re: the Python code—I would say that, from the perspective of the 1960s, all modern &amp;quot;dynamic&amp;quot; languages that have REPLs (like Python) &lt;i&gt;are&lt;/i&gt; Lisps in essential character.&lt;p&gt;&amp;quot;Lisp&amp;quot;, back then, referred less to &amp;quot;a language that uses a lot of parentheses&amp;quot;, and more to things like:&lt;p&gt;• runtime sum-typing using implicit tagged unions;&lt;p&gt;• parameterization of functions using linked lists (or hash-maps) of paired interned-string &amp;quot;keys&amp;quot; and arbitrary product-typed values, rather than parameterization using bitflags or product-types of optional positional parameters;&lt;p&gt;• heap allocation and garbage-collection;&lt;p&gt;• a compiler accessible by the runtime;&lt;p&gt;• &amp;quot;symbolic linkage&amp;quot; of functions and global variables, such that a named function or variable &amp;quot;slot&amp;quot; can be redefined (even to a new type!) at runtime, and its call-sites will then use the new version.&lt;p&gt;We only notice the parens as the differentiating feature of Lisps nowadays, because everything else has become widely disseminated. Perl and Python and PHP and Ruby (and even Bash) are fundamentally Lisps, in all of the above ways. Lisp &amp;quot;won.&amp;quot;</text></comment>
<story><title>Not Lisp again (2009)</title><url>https://funcall.blogspot.com/2009/03/not-lisp-again.html</url></story><parent_chain><item><author>QuadrupleA</author><text>My previous, somewhat-cranky comment got downvoted away, but I do think Lisp&amp;#x27;s &amp;quot;higher-order magic&amp;quot; and &amp;quot;ability to do calculus&amp;quot; is being a bit exaggerated here. From below - evaluating an Nth derivative in 80s-era C is not so atrocious:&lt;p&gt;&lt;pre&gt;&lt;code&gt;    #define DX 0.0001
    typedef double (*func)(double);

    double NthDeriv(int n, func f, double x) {
        if (n == 1) {
            return (f(x + DX) - f(x)) &amp;#x2F; DX;
        }
        else {
            return (NthDeriv(n - 1, f, x + DX) - NthDeriv(n - 1, f, x)) &amp;#x2F; DX;
        }
    }

    double Cube(double x) { return x * x * x; }

    double result = NthDeriv(3, &amp;amp;Cube, 5.0);
&lt;/code&gt;&lt;/pre&gt;
As mentioned in previous discussions of this article, the equivalent in Python is pretty elegant:&lt;p&gt;&lt;pre&gt;&lt;code&gt;    &amp;gt;&amp;gt;&amp;gt; def deriv(f):
    ...   dx = 0.0001
    ...   def fp(x):
    ...     return (f(x + dx) - f(x)) &amp;#x2F; dx
    ...   return fp
    ...
    &amp;gt;&amp;gt;&amp;gt; cube = lambda x: x**3
    &amp;gt;&amp;gt;&amp;gt; deriv(cube)(2.0)
    12.000600010022566&lt;/code&gt;&lt;/pre&gt;</text></item></parent_chain><comment><author>omaranto</author><text>The Scheme and Python versions both return the derivative function. The C version is significantly less cool. I&amp;#x27;d want to do something like:&lt;p&gt;&lt;pre&gt;&lt;code&gt;    func cube_3rd_deriv = NthDeriv(3, &amp;amp;Cube); &amp;#x2F;* returns a function *&amp;#x2F;
    double result = cube_3rd_derive(5.0);&lt;/code&gt;&lt;/pre&gt;</text></comment>