Mikael Brockman said:
I agree that it's difficult to program functionally in Ruby according to
those definitions. I also think it's difficult to do so with Scheme.
There is quite a debate about how much of a functional language Scheme
is. I've heard it referred to as "relatively functional", and heard
it said that Scheme "encourages" functional programming. This isn't a
trivial point; there are serious reasons for enforcing purity in
functional programming, unlike the common reasons for enforcing purity
in OO languages which often are based on aesthetic reasons. Purely
functional are verifiable and thread safe, which can be important.
However, I know that some Schemers get touchy about this point, so I
don't want to get into an argument about it. Suffice to say that
there's enough of a debate among people smarter than I about the
purity of Scheme to give that opinion some validity.
Nope, I haven't. I try to follow the grain of the language as much as
possible, so with Ruby, I tend to write imperative object-oriented
programs. Of course, many habits from my functional experience follow
me: defining new control structures, using heavy abstraction, etc.
In my experience, many of my programs in Ruby start out being
functional. Just a line or two return results per line of a file.
Then they grow to be imperative, and I'm defining functions. The
final stage is when they metamorphose into true OO programs; I wrap up
the functions in reusable Objects, and wrap the application up into a
single (or a very few) instantiations and method invocations. This is
one of the reasons why I like Ruby so much. Even though it is more OO
than Java, Java is more of a pain because you have to start out in the
OO paradigm, even when you don't need it.
Real functional programming is also nice, though, and encourages you
to think about the data you're working with. I worked on one
data-driven project where the "specification" ended up looking like a
bunch of Haskell function declarations, so that's what I chose to
write the application in. It was, probably, the most robust
application I've ever written.
That's only true if you think of the data and its operations as
completely separate entities. Doing so isn't easily justifiable in
Ruby, since they're defined in their own little indented scope.
Right, but I think that's the point in a purely functional language.
You have data, and you have functions that operate on that data. The
functions are meaningless without the data -- they are defined in
*terms* of the data, so there's dependancy there -- however, the data
is ignorant of the functions, and are *not* defined in terms of the
functions that operate on it, unlike an OO language where an object is
defined by its state AND the messages that can be sent to the object.
If I were to design in Scheme, say, a library for mutable queues, I
would think of the data and its operations as an object, just like I do
when I'm programming in an object-oriented language. Real functional
hackers probably think differently.
Yes, I think they do. You yourself said that you're an imperative
programmer. I am too, because I learned programming with Basic, 6502
Assembly, and C. I believe the OO paradigm is a bit overblown. I
have noticed that people who learned programming with a functional
language *do* think differently about the problems they solve, and
they come up with different solutions. Imperative and OO programmers
almost never use tail recursion; FPers use it almost exclusively.
There's a much closer relationship between FP, Math and set theory
than there is between IP and OO and those fields.
--- SER