Why I don't use Ruby.

S

Sean Russell

Sean O'Dell said:
You can modify values, as long as the value isn't a global (stateful data).
The key is that the function has to represent the modification, so that when
you call it with a given set of values, it always does the same thing.

Sean, scope has nothing to do with this. It has to do with state,
within or without of any given scope. If you have a "variable" --
some alias to a value -- and you change it, even within a limited
scope, you've changed state. Re-assignments are not allowed in pure
functional programming languages.

--- SER
 
S

Sean Russell

Martin DeMello said:
I'd say that the difference between a function and a method is that a
method has a distinguished argument, 'this', *within whose scope it
runs*. It's not a matter of Obj knowing about foo, or foo knowing about
Obj, it's a matter of Obj defining its own personal scope within which
foo is run.

I'd agree with this, although this is usually more of an
implementation than a paradigmatic distinction. OO defines methods as
messages sent to objects.

--- SER
 
S

Sean Russell

Mikael Brockman said:
To resist succumbing to Layne's law, I'll accept your definition.

Wow. That was a reference I had to look up.
So I'd say Ruby is a mostly-object-but-also-functional language. But if
one wants to write Scheme code in Ruby, one is unstoppable. One can
even make it look mostly like regular Ruby code, as long as one *thinks*
functionally.

I still don't see how you come to this conclusion. Ruby makes heavy
use of side effects, and I'd still suggest that it would be difficult
to program functionally in Ruby, using either NIST's or
comp.lang.functional's definition of a functional programming
language.

Out of curiosity, have you programmed functionally in Ruby, or are we
discussing abstracts here? I've written a lot of what could be
classified as functional programs in Ruby, but they've exclusively
been one-liners from the command line, where I'd normally have used
sed or awk. Any Ruby program I've ever written that grew to more than
a couple of lines (and even many of the one-liners) introduced
side-effects -- accumulators, etc -- which are violate the functional
programming paradigm. I'm just curious if you've done much of this.
It does have behavior. When I car it, it gives me its first element;

The list doesn't give you its first element. car discovers the first
element of the list. Saying that a list gives you the first element
when you car it is like saying that a painting gives me meaning when I
look at it. The painting is ignorant about whether or not it is being
observed. And if you take this discussion in a metaphysical
direction, then I'm not playing any more. :)

--- SER
 
S

Sean O'Dell

Sean, scope has nothing to do with this. It has to do with state,
within or without of any given scope. If you have a "variable" --
some alias to a value -- and you change it, even within a limited
scope, you've changed state. Re-assignments are not allowed in pure
functional programming languages.

You're right, not in the strictest sense of the term. But there are two
things you do as a programmer: program in the language and add to the
language. If a functional programming language lets you write your own
functions, so long as you don't make use of global/stateful variables so your
functions always return the same value in response to parameters passed, no
matter how many times it is called or when, to the outside world, to the
programmers calling your function, it makes no difference if you used
variables within the scope of your function or not. Your function behaves
predictably, and it fits well into an existing library of functions in a
"pure" functional language.

Do you see what I mean? You can allow local variables within the scope of a
function, and to the outside world, the function has broken no rules. So
long as it returns the same value always in response to a given set of
parameter values, no one using the function can tell that it has broken a
rule, and it doesn't affect the structure of the code.

Here's a question: are "pure" functional programming languages implemented
according to their own rules? Internally, do they also never use variables?
My guess is: no, or almost never. They break the rules internally to provide
an interface that adheres to the rules. In my opinion, a "pure" functional
language would allow you to develop your own functions and use local
variables so long as your functions interacted predictably with the outside
world.

It wouldn't be a "pure" functional language, but I would still call it a
functional language.

Sean O'Dell
 
K

Keith P Hodges

All,

Could anyone help me I need to host a simple ruby cgi script (for my
daughters blog) and I dont have a machine permanently online. The
script simple takes two rrss feeds and munges the output into
something readable.

many thanks in advance

Keith
 
S

Sean Russell

Mikael Brockman said:
....
To resist succumbing to Layne's law, I'll accept your definition.

Hey, I got to thinking about this... is it an example of Layne's law
when you are quoting authoritative sources about the definition of a
word? Is that "arguing" about the definition of a word? For example,
if I claimed that an Apple was a tiny blue fruit that grows on small
bushes, would you be succumbing to Layne's law to quote me the Oxford
English Dictionary's definition of an Apple?

--- SER
 
M

Mikael Brockman

I still don't see how you come to this conclusion. Ruby makes heavy
use of side effects, and I'd still suggest that it would be difficult
to program functionally in Ruby, using either NIST's or
comp.lang.functional's definition of a functional programming
language.

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.
The only people I know that actually program purely functionally are my
Haskell friends, and even they resort to unsafePerformIO occasionally.

Scheme has some features to make it easier, like tail call optimization,
but I don't think using tail recursion instead of looping matters much
in the large scale of things. In fact, I don't think it matters much at
all. When I write tail-recursive loops in functional languages, the
paradigm in my head tends to be imperative.
Out of curiosity, have you programmed functionally in Ruby, or are we
discussing abstracts here? I've written a lot of what could be
classified as functional programs in Ruby, but they've exclusively
been one-liners from the command line, where I'd normally have used
sed or awk. Any Ruby program I've ever written that grew to more than
a couple of lines (and even many of the one-liners) introduced
side-effects -- accumulators, etc -- which violate the functional
programming paradigm. I'm just curious if you've done much of this.

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.
The list doesn't give you its first element. car discovers the first
element of the list. Saying that a list gives you the first element
when you car it is like saying that a painting gives me meaning when I
look at it. The painting is ignorant about whether or not it is being
observed. And if you take this discussion in a metaphysical
direction, then I'm not playing any more. :)

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.

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.

mikael
 
S

Sean Russell

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
 
T

Tom Copeland

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.

Very nicely put. I find the same thing happening - first I'll be
backticking psql to run a PostgreSQL query, then I make a function to
wrap it in "psql -c", then I make a little object to do a dry run before
actually running the query. And this transition only takes 5 minutes or
so, and it's not painful to do since I'm not continually recompiling and
such. Just VIM (with VIM/Ruby, of course) and a command line. Good
times!

tom
 
M

Mikael Brockman

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.

I agree. Haskell makes it easier to write purely functional programs.
Still, it's definitely possible to write mostly functional programs in
Scheme. I think it's possible to write mostly functional programs in
Ruby, too, though probably to a lesser degree.
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.

I've had some love affairs with Haskell, too. I wrote a client for a
Napster-like file sharing service called Direct Connect, which certainly
isn't Haskell's target market, and it was beautiful. Algebraically
manipulating I/O actions is really pleasant, and monadic parser
combinators (Parsec, in my case) were awesome for parsing the wire
protocol. That parser was probably the most robust parser I've ever
written.

One of the most memorable things was writing this Scheme macro:

| (define-macro (loop action)
| (letrec ((f (lambda ()
| (action)
| (f))))
| (f)))

as this Haskell:

| loop action = action >> loop action

and algebraically simplifying it to simply

| loop = fix (>>)

Another beautiful thing was this:

| downloadFile socket size fd = write fd (read socket size)

Which, thanks to lazy evaluation, intersperses the reads and the
writes. If I wanted it to report its progress to, say, a progress bar,
I could just insert another function in the middle of the pipeline.

Damn you, Sean. You got me in the mood for writing Haskell.
Right, but I think that's the point in a purely functional language.

Yup. That doesn't mean I have to obey. :)

Thanks for a nice discussion, Sean.

mikael
 
B

bruno modulix

Sean Russell a écrit :
In this, and following posts, you make the claim (directly and
indirectly) that all languages are functional languages, rendering the
term "functional language" meaningless, or at least useless. I
oppose attempts to generalize words into meaninglessness.

There *are* good, useful definitions of what constitutes a functional
languages, and Ruby does not match the criteria for most of them.
Probably the most fundamental of all criteria is that the language
does not allow side-effects, such as assignment.

Scheme, Common Lisp and Caml -- three major fpl's -- allow assignement.
FWIW, here is the definition of 'functional programming' on the
c.l.functional's FAQ :

"""
Functional programming is a style of programming that emphasizes the
evaluation of expressions, rather than execution of commands. The
expressions in these language are formed by using functions to combine
basic values. A functional language is a language that supports and
encourages programming in a functional style.
"""

(http://www.cs.nott.ac.uk/~gmh//faq.html#functional-languages)

Following this definition, Ruby is somewhat on the functional side,
since it's an 'everything is an expression' language !-)

What else ? Anonymous functions ? Closures ? HOF ? AFAIK, Ruby has it
all (or I'm I wrong ?)...

(snip)
Now, a better example would have been to point out OCaml, which is
*both* functional *and* OO, something which I believe is fundamentally
impossible, in that it can't be pure OO and pure functional. However,
it has a lot of features associated with functional languages, and
many features associated with OO, so it can claim to be a functional
language with OO capabilities.

For the record, Common Lisp (and IIRC Scheme) also have a strong support
for OO.

Bruno
 
B

bruno modulix

Hal Fulton a écrit :
We're OT now, but my ignorance of FP is such that I can't imagine
a language without assignment.

"without assignment" should in fact read "without re-binding". Binding a
value to a symbol is perfectly legal even in Haskell, but once bound,
it's for the lifetime of the symbol...
 
S

Sean O'Dell

Hal Fulton a écrit :

"without assignment" should in fact read "without re-binding". Binding a
value to a symbol is perfectly legal even in Haskell, but once bound,
it's for the lifetime of the symbol...

I don't understand how assignment, or even just re-binding, effects the nature
of a functional programming language. From everything I remember about
functional languages, the only real evil was persistent data that could cause
function results to change from one call to another. You're not supposed to
have operators in a functional language, like =, *, + and so on, so you can't
assign values "a=10" style, but you should be able to say set(a, 10).

What does assignment or even re-binding have to do with the "functional
nature" of a functional language? Not a troll, I truly just don't see the
relationship between the two.

Sean O'Dell
 
G

Gavin Sinclair

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.

Indeed, there are (theoretically) serious optimisation gains to be
made at runtime if it's a pure FP environment: as there are no
side-effects, the call graph can be analyzed and broken into threads,
with results combined later. A good way to get the most out of big
iron. I think this is probably still a matter of research, though.

Cheers,
Gavin
 
B

bruno modulix

Sean O'Dell a écrit :
I don't understand how assignment, or even just re-binding, effects the nature
of a functional programming language.

If you can rebind a symbol then you have states and side-effects...
From everything I remember about
functional languages, the only real evil was persistent data that could cause
function results to change from one call to another. You're not supposed to
have operators in a functional language, like =, *, + and so on,

Please stop saying stupidities. Of course functional languages can have
operators, as you would now if you had STFW. BTW, an operator is usually
nothing more than syntactic sugar for a function call.
so you can't
assign values "a=10" style, but you should be able to say set(a, 10).

Where is exactly the difference from a semantic POV ?
What does assignment or even re-binding have to do with the "functional
nature" of a functional language? Not a troll, I truly just don't see the
relationship between the two.

It has to do that the definition of a 'pure' fpl include the
impossibility to re-bind a symbol.

Bruno
 
S

Sean O'Dell

Sean O'Dell a écrit :

If you can rebind a symbol then you have states and side-effects...

If the symbol is local to a function, what side-effect could there be?
Please stop saying stupidities. Of course functional languages can have
operators, as you would now if you had STFW. BTW, an operator is usually
nothing more than syntactic sugar for a function call.

Keep it polite, will you? No, functional languages are not supposed to have
operators. That's why they're called "functional languages"; they work like
functions.
Where is exactly the difference from a semantic POV ?

Functional languages set the variable in a functional way.
It has to do that the definition of a 'pure' fpl include the
impossibility to re-bind a symbol.

Facts don't exist in a vacuum; to understand what a functional language truly
is, you have to go beyond simply repeating the rules back to people. You
have to know why those rules are there, you have to understand them and the
nature of a functional language. I see no reason to allow re-binding in a
local context in a functional language.

Sean O'Dell
 
F

Florian Gross

Sean said:
Here's a question: are "pure" functional programming languages implemented
according to their own rules? Internally, do they also never use variables?
My guess is: no, or almost never. They break the rules internally to provide
an interface that adheres to the rules.

It depends. Functional languages implemented in functional languages
will be written in a functional style of course. C is no functional
language, but most function language interpreters are written in C where
you have so many side effects that you *have* to capture different
states into variables.

The idea of functional languages is that the only thing a function is
able to give to the outside is its return value.

In such a pure functional world variables are no longer needed, because
you can just use the function call itself where you would otherwise need
to use the value that was captured to the variable.
They break the rules internally to provide
an interface that adheres to the rules. In my opinion, a "pure" functional
language would allow you to develop your own functions and use local
variables so long as your functions interacted predictably with the outside
world.
It wouldn't be a "pure" functional language, but I would still call it a
functional language.

Ruby doesn't use Objects at all in its implementation. In fact C doesn't
even have Objects. Yet Ruby is a pure object-oriented language.

The implementation really has nothing to do with this IMHO. It's not
really part of the interface after all. :) (And there can be multiple
interpreters for the same language all written in different languages of
course. The really interesting parts of this are language interpreters
that are written in the very same language that they interpret.)

Regards,
Florian Gross
 
J

Jim Weirich

Sean O'Dell said:
If the symbol is local to a function, what side-effect could there be?

One of the benefits of functional languages is the ability to do
algebraic-like manipulations of the source code ... kinda like provably
correct refactorings. For example, given X=12, within the scope of X I
can replace all occurances of X with the value 12 (or the reverse, replace
all occurances of 12 with X). If X is sometimes 12 and sometimes 13, then
the substitution is no longer valid anywhere in the scope of X. That is
why even local variables are immutable in a "pure" functional language.
No, functional languages are not supposed to have
operators. That's why they're called "functional languages"; they work
like functions.

Function being defined as an operation that returns the same result given
the same input, right? Operators in functional languages are functions in
this sense. The difference is a matter of syntax, not semantics. E.g.
1+2 is allowed in a functional language. The binary operator + is treated
as a two argument function.
 
F

Florian Gross

Sean said:
No, functional languages are not supposed to have operators. That's
why they're called "functional languages"; they work like functions.

Most of those operators are exactly like functions. = isn't if its an
assignment operator, but if it is an comparison operator it indeed is
compatible to the definition of the function.

(Just because there's a different syntax for applying it doesn't mean
that it's really different -- in fact in LISP + is just a function with
a special name without any additional syntactic sugar.)
Functional languages set the variable in a functional way.

Functional languages don't enforce a specific syntax like function(arg1,
arg2) etc., but they indeed specify that a function should have no side
effects which means that the only way it should be able to interact with
the outside world is by returning values. (Lambda calculus is the origin
of functional languages and compared to computer languages its syntax is
indeed very exotic.)

I hope I was able to add something valuable.

Regards,
Florian Gross
 
S

Sean O'Dell

It depends. Functional languages implemented in functional languages
will be written in a functional style of course. C is no functional
language, but most function language interpreters are written in C where
you have so many side effects that you *have* to capture different
states into variables.

But how are they usually implemented? In ASM, C, ... ?
The idea of functional languages is that the only thing a function is
able to give to the outside is its return value.

Precisely. What is returned is most important; functions must return
consistent results for a given set of parameters, regardless of when they are
called or how often.
In such a pure functional world variables are no longer needed, because
you can just use the function call itself where you would otherwise need
to use the value that was captured to the variable.

But within a function, local variables don't affect the return value. True,
every new function a developer writes could be simply nested calls to other
functions, but for readability, local variables are very helpful, and as long
as they're not global or stateful, they don't affect the return value, so to
the outside world it's still just a function.
Ruby doesn't use Objects at all in its implementation. In fact C doesn't
even have Objects. Yet Ruby is a pure object-oriented language.

Yes, precisely. My point for asking was to illustrate how there are two
facets to any language design: the usage and the implementation. Writing
code in a language functionally, and writing new functions to extend the
language are two different things, in the sense that how a language is used
is your goal, but how it is implemented (or extended) can be anomalous to
that goal. You make exceptions for yourself when implementing a language,
just so long as the end result is what you intended. Likewise, if you use
local variables within a function, so long as to the outside world (the end
result) the function still behaves properly, the allowance of local variables
doesn't detract from the language's designation as a "functional language"
except in the very, very purest sense.
The implementation really has nothing to do with this IMHO. It's not
really part of the interface after all. :) (And there can be multiple
interpreters for the same language all written in different languages of
course. The really interesting parts of this are language interpreters
that are written in the very same language that they interpret.)

Think of new functions that developers write in the language as part of the
implementation itself. You can give them tools to write new functions in the
language which don't allow them to break the functional language paradigms,
such as local variables, just like you can implement a functional language
such a C, which is definitely NOT a functional language.

Sean O'Dell
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top