
The C language is purely functional (2009) - ingve
http://conal.net/blog/posts/the-c-language-is-purely-functional
======
the_af
In case someone misses the point of the article -- I know I did, originally!
-- the author explicitly lays it out in a comment:

> _" Sadly–and here is the real intent behind my post–many Haskell programmers
> believe that IO is necessary to do “real programming”, and they use Haskell
> as if it were C (relegating lots of work to IO). In other words, monadic IO
> has proved to be such a comfortable “solution” to I/O in a functional
> language, that very few folks are still searching for a genuinely (not
> merely technically) functional solution. Before monadic IO, there was a lot
> of vibrant and imaginative work on functional I/O. It hadn’t arrived yet,
> but was still in touch with the Spirit of functional programming. With the
> invention and acceptance of monadic imperative programming, it’s like the
> Haskell community wandered into an opium den and are still lying there in a
> fog._

> [...]

> _" By relating Haskell+IO to cpp+C, I’m not trying to lower the former or
> elevate the latter. Instead, I’m trying to waken functional programmers out
> of the opium fog and remind them how fun and creative genuinely functional
> programming can be."_

I love Haskell but I'm not well-versed enough to know why other alternatives
to monadic IO were discarded. I do know Haskell predates the IO monad.

~~~
RubenSandwich
Another functional approach to I/O is "effect systems". I'm not aware of
"stable" functional language with them in it though. It's mostly academic at
this point.

Here is some research on it: [https://www.microsoft.com/en-
us/research/publication/koka-pr...](https://www.microsoft.com/en-
us/research/publication/koka-programming-with-row-polymorphic-effect-types/)

~~~
ghayes
You can take a look at Effects in Idris: [http://docs.idris-
lang.org/en/latest/effects/](http://docs.idris-lang.org/en/latest/effects/)

~~~
RubenSandwich
Oh I didn't know Idris had an effect system. Thanks!

------
saagarjha
I've gotten good results annoying type theorists by mocking Scala and Haskell
for being less pure than C++ template metaprogramming.

~~~
tomcam
How many type theorists do you know?

~~~
saagarjha
A couple?

------
earenndil
The Java language is purely functional.

“Java programmers” really program not in Java, but in a purely functional
language called 'cat'. As with any purely functional language, cat consists
only of expressions, not statements. Now here’s the clever part: when
evaluated (not executed), a cat expression yields a (pure) value of type Java,
which is an ADT (abstract data type) that represents imperative programs. That
value of type Java is then executed (not evaluated) by the cat language’s RTS
(run-time system). As a clever optimization, cat’s RTS actually includes a
code generator, considerably improving performance over more naïve
implementations of the Java abstract data type.

------
dang
Discussed in 2015:
[https://news.ycombinator.com/item?id=9088676](https://news.ycombinator.com/item?id=9088676)

and in 2009:
[https://news.ycombinator.com/item?id=618817](https://news.ycombinator.com/item?id=618817)

~~~
BanazirGalbasi
I wasn't using HN back in 2015 (let alone in 2009) so I'm glad this was re-
submitted. It's been more than 4 years which is sufficient time for new users
or for people to come back to it with new opinions.

~~~
detaro
It's interesting to see what people thought 4 or 10 years ago about the same
article. Those links aren't to chide the submitter that it has been submitted
before, HN explicitly allows reposts after a year or so.

~~~
BanazirGalbasi
Ah, thanks for explaining that. I'm more used to Reddit where re-posting links
is more common but also more frowned upon, so I'm still unfamiliar with the
culture here.

------
Sharlin
> (or char *, for you type theorists, using a notation from Kleene)

I chuckled.

~~~
juped
10 years on and that one still gets a laugh from me.

------
kazinator
_#undef_ isn't impure. It isn't an assignment, but an unbinding; it asserts
that in the remainder of the translation unit, the preprocessor symbol is not
known. That symbol's status in the prior parts of the translation unit hasn't
changed.

Consider that lambda or let will also unbind:

    
    
      (let ((x 3))  ; #define x 3
        )           ; #undef x, effectively

~~~
earenndil
Not really, because in your lisp example, there is proper scoping. Variables
will always be unbound in the reverse order they were bound.

You can do something like this in c:

    
    
        #define x 3
        #define y 4
        
        #undef x
        
        // more stuff
        #undef y
    

Which is essentially equivalent to [(])

~~~
kazinator
> _there is proper scoping_

Rather, there is nesting. Nesting isn't the same thing as scoping.

> _Variables will always be unbound in the reverse order they were bound._

Counterexample:

    
    
       (let* ((x 1) (y (* 2 x)) (z (+ x y))) ;; bound in sequence
        ) ;; unbound in parallel
    
    

We could have an _unlet_ operator which introduces a new scope that explicitly
removes a binding:

    
    
       (let (x)                      ; #define x
         (let (y)                    ; #define y
           (unlet (x)                ; #undef x
             ;; y bound, x free
             )))                     ; #undef y, #undef x
    

Basically, #define and #undef can be regarded as having proper nesting: each
one creates a new scope that lasts unti the end of the translation unit,
nested relative to the previous scope.

------
equalunique
Interesting article indeed. If anyone was curious and wanted to drill down to
the source of the "Scala is Not a Functional Programming Language" discussion,
surprise, the link is dead. Here's an archive link:
[http://web.archive.org/web/20090517065705/http://enfranchise...](http://web.archive.org/web/20090517065705/http://enfranchisedmind.com/blog/posts/scala-
not-functional/)

------
glouwbug
See how far you can get with:

    
    
        #define int const int
        #define float const float
        etc...
        

It makes for some interesting patterns

------
davesque
I was about to comment to snarkily refute the claim in the title, but then the
author seemed to sarcastically do that in the article.

~~~
dTal
If you don't have that interrupt in your brain that fires when you read
something so outlandish that it surely _must_ be deliberately provocative,
you're going to spend a lot of time very upset about articles from The Onion.

------
Taniwha
From a previous Obfusticated C contest winner- towers-of-hanoi purely in cpp
(evaluated at compile time)

[https://www.cise.ufl.edu/~manuel/obfuscate/vanschnitz](https://www.cise.ufl.edu/~manuel/obfuscate/vanschnitz)

------
rramadass
On a different note, the book "Functional C" teaches C programming to ML
functional programmers. Quite interesting and gives a new perspective to C
programmers on their favourite language.

------
portal_narlish
Technically the C preprocessor is purely functional!

