Hacker News new | past | comments | ask | show | jobs | submit login

Isn't the derivate relatively easy in C?

    #include <stdio.h>
  
    const double delta = 1.0e-6;
    double cube(double x) { return x * x * x; }
    double deriv(double (*f)(double), double x) { return (f(x+delta) - f(x)) / delta; }

    int main()
    {
        printf("%f", deriv(&cube, 2));
        return 0;
    }
Am I missing something?



I think it's that you can calculate the value, but you can't (or can't as easily) create a new function that is the derivative of another function, and pass that around.


yeah you can return a new function, but it is less easy than in lisp, or F#

but in general a lot of that stuff in the article seems mundane today, you have to imagine seeing it in 1983


> yeah you can return a new function

How?


You could do it with JIT compilation or self-modifying code. I'm not sure if there's a simpler way in C


You can exec a C compiler and use dlopen on the generated object file, or use libtcc[1].

https://www.bellard.org/tcc/


That makes sense, thanks. And as others have mentioned it's therefore not easy to compose higher order derivatives.


In a language with higher-order procedures like Lisp or Julia, you can write code that actually returns the derivative as a function, as opposed to differentiate at a given point. This is harder to do (gracefully, anyway) in e.g. C. The beauty of the functional approach is that it corresponds much more closely to how we think about math. See for example Structure & Interpretation of Classical Mechanics (http://mitpress.mit.edu/sites/default/files/titles/content/s...). This is especially powerful when combined with automatic differentiation, as is done in the ScmUtils system that goes along with SICM. (Finite differencing has numerical stability issues when carried too far.)


With only the functions you've defined, how do you calculate the second derivative?

If the `deriv` function instead returned a function instead of a number, you could apply the `deriv` function twice.


You're missing that:

- you can't write a C macro which will do this symbolically. We really just want to be calculating 3 * x * x.

- having cube and deriv, you can't write an expression which combines these two, and is itself a function.

BTW, the & is unnecessary in &cube; a primary expression which names a function evaluates to a pointer to that function.


While you can take the address of cube, you can't do this trick more than one level deep: you can't return a new function from "deriv".


Here's the generic C++ version (https://gcc.godbolt.org/z/mMln6L):

    constexpr double delta = 1.0e-6;
    
    constexpr auto deriv = [] (auto f) { 
        return [=] (double x) { 
            return (f(x+delta) - f(x)) / delta; 
        };
    };

    constexpr auto f¨ = [] (auto f) { return deriv(deriv(f)); }; 

    double res = f¨([] (double x) { return x*x*x; })(2.0);


Here's a deriv example in Go: https://play.golang.org/p/kUM5qn7oiXg

I find that it follows the functional spec quite closely, thanks to Go functions being first class citizens.


I agree, it isn't the greatest example for showing the power of Lisp.

Here's a much better one that uses a macro to do symbolic differentiation in <150 lines:

https://github.com/aksiazek/symbolic-differentiation

Much harder to do that in C ;-)

Peter Norvig's book "Paradigms of Artificial Intelligence" uses symbolic differentiation as an example in one of the early chapters.


article is talking about 1983. your example relies heavily on Greenspun's 10th rule.


It'd look slightly different in 1983 but the functionality would all be there. const->#define and maybe you'd need to change the function signatures to K&R style, but that's it.


I was about to suggest the same thing. This is simply computational finite difference and almost follows directly from the equation https://en.wikipedia.org/wiki/Difference_quotient




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: