I agree with about everything but the best part is the function pointer chapter.
Function pointers are an insanely novel concept. They're not even a C thing per se but since C has first-class pointers they fit right it.
Nevertheless, most design patterns, closures, higher-order functions, more complex dispatching, etc. are effectively just a function pointer and possibly some userdata. You can think in Lisp but do it all in C with function pointers.
I agree that the paragraphs about tables driven programs and function pointers are the best part. You can read "Combining datadriven programs with function pointers leads to an astonishingly expressive way of working, a way that, in my experience, has often led to pleasant surprises." as much as an endorsement of functional languages than the endorsement of OO-like techniques it was meant to.
Though C is not really adequate to do Lisp-like programming. Because you can't capture free variables with C function pointers. Of course you can get around this restriction with lambda lifting [1], but why would you want to do the job of the compiler?
As an example, it is quite hard to encode function composition in C, i.e. write a function that takes two function and returns their composition. Or the same specification in (non-idiomatic [2]) Haskell:
composition :: (b -> c) -> (a -> b) -> a -> c
composition f g =
let h a = f (g a)
in h
I don't know of any way to make up new functions / function pointers in C at runtime.
Not even a C thing per se, as in "C has function pointers but it's not really a C specific feature as some other languages have them too. Like assembly, very obviously."
Many other languages don't. If they're sufficiently high-level they might have function objects or closures, which often cover everything you want. If they're Java they have neither but you can write a Visitor-style class or some other scheme from the design patterns book that emulates the behaviour of a function pointer.
But fundamentally (and when the program is compiled down to machine code also hopefully) they're just function pointers.
I agree. Though what it gets compiled down to depends on the compilation strategy. If your compiler is smart enough, and your use of functions as variables / function pointers is weak [1] enough, your functions may, say, just get inlined into a big case-statement-like construct.
Function pointers are an insanely novel concept. They're not even a C thing per se but since C has first-class pointers they fit right it.
Nevertheless, most design patterns, closures, higher-order functions, more complex dispatching, etc. are effectively just a function pointer and possibly some userdata. You can think in Lisp but do it all in C with function pointers.