Hey, C Is a Functional Language Too
spin.atomicobject.com
spin.atomicobject.com
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
This is just an encoding of a Turing-complete language into another, I don't see what's been demonstrated here.
>The main limitation is that you need to know the size of the return value.
The only way I see is to allocate (almost) the entire machine memory to the stack, create one giant array in that chunk of memory and then put all lists in that single array. That's tantamount to reimplementing malloc on the stack.
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.
"everything is turing complete" is a perfect example of the kind of middle-brow dismissal i understood pg to be talking about.
Just not depending on anything in the environment either except globals, which is a huge limitation. So writing a function inc by = \x -> x + by becomes unnecessarily difficult for example.
For example, an instance map is just a cons and a recursive call. No state change needed. You can say something about exposing unwanted details in the cons, but that is a hairier point of contention.
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".
What I do not agree is when "functional programmers" claim that language is not "functional" just because it is not "pure functional" or Haskel alike.
Pure functions. (Only Haskell and friends are strictly pure, as is SQL if you squint.)
Higher order functions. (Java 7 doesn't allow you to pass around a callable function without embedding a link language with reflection or using one-method Runnable.)
First class functions. (Basic, SQL do not have this.)
Generic functions. (C does not have this. C++ does. Java does.)
These are three orthogonal properties a Lang age may have some or all of.
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".
Same goes for OO, which has something like 9 well-known defining features.
The scenario I described wasn't hypothetical. When a colleague asked our whole office "what's functional programming?" I listened while someone told him that it was just map, filter, and fold. He'd used these in JavaScript already, and was prepared to accept that as an answer. I didn't think that was sufficient, so chimed in and offered some alternative features from other languages that I think are as important as higher order functions, mostly related to minimizing mutable state with managed references and persistent data structures. I think he appreciated my contribution, but I honestly don't know for sure. Maybe it just created more questions.
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.
http://en.wikipedia.org/wiki/Chicken_(Scheme_implementation)...
http://conal.net/blog/posts/the-c-language-is-purely-functio...
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.
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.
int main(int argc, char * argv[]) {
(void)argc;
(void)argv;
I've programmed C while in school, but I don't remember ever seeing this and I'm not sure how to google it.http://stackoverflow.com/questions/8052091/void-cast-of-argc...
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.
The author does explicitly point this out: "While I find this style strangely addictive, I don’t think I would advocate its general use."
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."
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.http://conal.net/blog/posts/the-c-language-is-purely-functio...
By Conal Elliot.
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.
int factorial(int x) {
if (x > 1) return x * factorial(x-1);
else return 1;
}
will be optimized by GCC to int factorial(int x) {
int result = 1;
while (x > 1) result *= x--;
return result;
}
(http://ridiculousfish.com/blog/posts/will-it-optimize.html)Having first-class function values in the first place strikes me as way more important. Purity helps, too.
What would happen without tail call elimination?
Summing up numbers is inherently strict, so you'd want tail call elimination for that. But functional mainstains, like say, map or filter are usually not implemented with tail recursion in Haskell, because that would be too strict and would break on infinite lists.