All programming languages and all programming styles can be similarly dismissed as encoding one Turing-complete form into another. Why pay attention to any of them?
This article is clearly someone having fun with their language. It isn't a serious claim about C being functional, something which the author states explicitly if you read to the end.
I would say the aspect that defines a functional programming language is the support of higher order functions. I.e. functions that can take functions as arguments and more importantly can return functions as return value.
As jeremyjh already pointed out, this results in a pretty weak definition. You end up with JavaScript, Ruby, Python, and Objective-C all being lumped as "functional languages", and if you squint a little bit, you can put Java in there too (anonymous inner classes). I think C, C++ and C# could be as well, but I don't know them well enough.
So I don't think it's very productive to use a definition like this, but not because I want to be divisive, or "move the goal posts" or because I'm trying to be elitist here. It's because when a colleague asks you "what's functional programming?" I think it's much more helpful to describe the kind of programming that is encouraged in Haskell and Clojure than to just say, "well it's just map, filter, and fold in JavaScript".
Rather than saying that higher-order functions is the defining feature of functional programming, I would say that it's an essential feature to support its object of defining programs in terms of (mathematical) function application rather than procedural state changes.
I'm not that old but I remember that, back in the days, functional meant just that you are able to use plain functions (without objects) and pass them around. By that definition, C is functional language, as scheme or lisp or javascript and many others.
I don't know why, but some years ago, "functional programmers" started to change and twist the definition of functional language step by step, until all those languages fell off and only Haskel remained as "functional enough".
I think that this is an interesting area. We can support just about any style in an existing programming language, but there are often rough edges.
This reminds me of how I used to mimic OO in C years ago. At a certain point you realize that you have to forgo certain things to help the person coming after you avoid making mistake -- often they do not see the ramifications of your conventions.
I see this in Ruby right now when I write in a functional style. The code is often terse yet easy to read, but the lack of lazy evaluation makes it far more memory consumptive than code written in a straightforward procedural style. If you know you are making the tradeoff, it is fine. For many people, it is too subtle.
From that it looks like the caller always has to allocate the right amount of space on the stack to hold the result. What if the result size is known only by the callee?
Denying yourself the use of the heap is also going to make closures rather difficult. You can use this style to pass back a function pointer, but the caller would also need to allocate space for the callee's captured variables. Ick.
I disagree completely that this is a 'functional subset' of C. I also don't know a lot about this stuff, so tear me up.
A functional language isn't just one that doesn't use malloc/only uses the stack. It must actually not have state, and instead evaluate a single function down to the result. Here, after calling make_lists, the input and the result still both exist as state variables (immutable, yes, but that's not enough)! At the same time, I haven't looked at code for a lisp interpreter, but I feel safe assuming that it allocates some memory somewhere. Functional programming doesn't have anything to do with the underlying implementation. The trick here, if any, is that the "underlying implementation" and the code are in the same language/program.
I use clang with a -Wall and -Wextra, which will complain about all sorts of stuff I generally want to know about, including unused variables (I think gcc does the same?). For the rare cases where I actually want to leave a variable unused I do the above to make the warning go away.
At some point the stack is going to grow which will cause allocation at the OS level. And if we're discussing small embedded systems with fixed stacks, this code is entirely unsafe (non deterministic stack usage may cause stack overruns).
In embedded systems (non-MMU ones) you generally want to avoid repeated dynamic runtime allocation to prevent memory fragmentation.
It's a cute example, but I can't see any scenario where its better or safer than heap use.
Ditto on the addictiveness of continuation-passing style.
However, don't try it when coding with peers who are not used to it; you can be burnt at the stake. Because, even though it makes the code easier to read, to the untrained eye it is just cryptic.
"So my title is misleading. I don’t think C is a functional language. But it’s an awful lot of fun (and sometimes very useful) to use C’s functional subset."
it might have also been worthwhile to mention that the stack array declaration:
int32_t result[my_array_size];
relies on C99 support, which is not necessarily ubiquitous (especially in embedded device work). At the very least, many compilers make you explicitly enable C99 support.
GCC can eliminate tail recursion, so does that make C functional?
I don't think the author is seriously of the belief that C is a functional language. This is just a fun little example of writing C in a functional style.
[+] [-] jrajav|13 years ago|reply
1: http://en.wikipedia.org/wiki/Chicken_Scheme
2: http://wiki.call-cc.org/chicken-compilation-process
3: The homepage is called www.call-cc.org :P
[+] [-] fab13n|13 years ago|reply
This is just an encoding of a Turing-complete language into another, I don't see what's been demonstrated here.
[+] [-] rauljara|13 years ago|reply
This article is clearly someone having fun with their language. It isn't a serious claim about C being functional, something which the author states explicitly if you read to the end.
[+] [-] andrewcooke|13 years ago|reply
"everything is turing complete" is a perfect example of the kind of middle-brow dismissal i understood pg to be talking about.
[+] [-] fauigerzigerk|13 years ago|reply
>The main limitation is that you need to know the size of the return value.
[+] [-] meaty|13 years ago|reply
[+] [-] ginko|13 years ago|reply
[+] [-] spacemanaki|13 years ago|reply
So I don't think it's very productive to use a definition like this, but not because I want to be divisive, or "move the goal posts" or because I'm trying to be elitist here. It's because when a colleague asks you "what's functional programming?" I think it's much more helpful to describe the kind of programming that is encouraged in Haskell and Clojure than to just say, "well it's just map, filter, and fold in JavaScript".
[+] [-] jrajav|13 years ago|reply
[+] [-] markokocic|13 years ago|reply
I don't know why, but some years ago, "functional programmers" started to change and twist the definition of functional language step by step, until all those languages fell off and only Haskel remained as "functional enough".
[+] [-] zokier|13 years ago|reply
[+] [-] michaelfeathers|13 years ago|reply
This reminds me of how I used to mimic OO in C years ago. At a certain point you realize that you have to forgo certain things to help the person coming after you avoid making mistake -- often they do not see the ramifications of your conventions.
I see this in Ruby right now when I write in a functional style. The code is often terse yet easy to read, but the lack of lazy evaluation makes it far more memory consumptive than code written in a straightforward procedural style. If you know you are making the tradeoff, it is fine. For many people, it is too subtle.
[+] [-] chrisdew|13 years ago|reply
http://en.wikipedia.org/wiki/Chicken_(Scheme_implementation)...
[+] [-] szany|13 years ago|reply
http://conal.net/blog/posts/the-c-language-is-purely-functio...
[+] [-] cmsd2|13 years ago|reply
Denying yourself the use of the heap is also going to make closures rather difficult. You can use this style to pass back a function pointer, but the caller would also need to allocate space for the callee's captured variables. Ick.
[+] [-] Nursie|13 years ago|reply
[+] [-] xyzzy123|13 years ago|reply
[+] [-] jmilloy|13 years ago|reply
A functional language isn't just one that doesn't use malloc/only uses the stack. It must actually not have state, and instead evaluate a single function down to the result. Here, after calling make_lists, the input and the result still both exist as state variables (immutable, yes, but that's not enough)! At the same time, I haven't looked at code for a lisp interpreter, but I feel safe assuming that it allocates some memory somewhere. Functional programming doesn't have anything to do with the underlying implementation. The trick here, if any, is that the "underlying implementation" and the code are in the same language/program.
[+] [-] slig|13 years ago|reply
[+] [-] walrus|13 years ago|reply
http://stackoverflow.com/questions/8052091/void-cast-of-argc...
[+] [-] jvranish|13 years ago|reply
[+] [-] unknown|13 years ago|reply
[deleted]
[+] [-] flyinglizard|13 years ago|reply
In embedded systems (non-MMU ones) you generally want to avoid repeated dynamic runtime allocation to prevent memory fragmentation.
It's a cute example, but I can't see any scenario where its better or safer than heap use.
[+] [-] jvanenk|13 years ago|reply
The author does explicitly point this out: "While I find this style strangely addictive, I don’t think I would advocate its general use."
[+] [-] agumonkey|13 years ago|reply
[+] [-] utopkara|13 years ago|reply
However, don't try it when coding with peers who are not used to it; you can be burnt at the stake. Because, even though it makes the code easier to read, to the untrained eye it is just cryptic.
[+] [-] ibotty|13 years ago|reply
"So my title is misleading. I don’t think C is a functional language. But it’s an awful lot of fun (and sometimes very useful) to use C’s functional subset."
[+] [-] vu3rdd|13 years ago|reply
[+] [-] mellery451|13 years ago|reply
[+] [-] georgeg|13 years ago|reply
[+] [-] Evbn|13 years ago|reply
http://conal.net/blog/posts/the-c-language-is-purely-functio...
By Conal Elliot.
[+] [-] cschramm|13 years ago|reply
[+] [-] charliesome|13 years ago|reply
I don't think the author is seriously of the belief that C is a functional language. This is just a fun little example of writing C in a functional style.
[+] [-] eru|13 years ago|reply
Having first-class function values in the first place strikes me as way more important. Purity helps, too.
[+] [-] dbaupp|13 years ago|reply
[+] [-] jfb|13 years ago|reply