Ocaml is a functionnal langage of the ML family. It means it abuses of
pattern matching and allows for side effects. As far as I know, lisp and
scheme are pure functionnal langage as they don’t allow side effects.
But perhaps I’m wrong. And I’m often wrong.
Standard ml (SML) allows for sideeffects too. Don’t know about Lisp/Scheme.
About Ruby, I must tell I find it hard to see where Ruby is functionnal
langage. Coding recursivity in ruby is most of the time so uneasy. I
just wonder, if someone can explain, he’ll be welcome.
For instance the following piece of code are responsible for matching
a charclass. @succ points to the next node in the AST. @set is an Array, e.g. [‘a’…‘z’, ‘_’, ‘0’…‘9’]
See the third line from the bottom, how recursion is working.
class Inside < Base
def initialize(succ, set) @succ = succ @set = set
super()
end
attr_reader :succ, :set
def ==(other)
(self.class == other.class) and
(@set == other.set) and
(@succ == other.succ)
end
def check_not_endofinput(context)
return if context.input.has_next?
context.raise_mismatch(“(Inside) end of input”)
end
def is_member_of_set?(symbol) @set.each do |i|
return true if i.kind_of?(Range) and i.include?(symbol)
return true if i == symbol
end
false
end
def check_member_of_set(context)
symbol = context.current
return if is_member_of_set?(symbol)
context.raise_mismatch(
“(Inside) symbol #{symbol.inspect} is not in set #{@set.inspect}”)
end
def match(context) #puts “Inside, set=#{@set.inspect}”
check_not_endofinput(context)
check_member_of_set(context)
context.input_next { @succ.match(context) }
end
end
Lisp and Scheme can have side effects. Lisp has (setf) and Scheme has
(set!) that allow assignment. Lisp especially, as if I recall correctly, you
can do:
(setf (car a) x)
And it will actually change the value of (car a), so you can change lists
instead of creating new ones (I’m a little rusty, though, so I may be wrong).
Ruby can have a functional ‘feel’ at times, since a lot of things can be done
by passing around blocks, which are a lot like lambda expressions. However,
Smalltalk has blocks and I doubt anyone would accuse Smalltalk of being
functional.
Lack of nice tail recursion would probably limit Ruby from being as efficient
at functional programming as languages designed for it, though.
Ruby has some superficial niceties borrowed from functional languages
(map, filter, etc.) and some deep features inspired by them (lexical
closures), but at the end of the day, it’s difficult to say Ruby is
functional when it doesn’t have functions
Cheers,
Gavin
···
On Saturday, May 1, 2004, 8:49:01 PM, Lionel wrote:
About Ruby, I must tell I find it hard to see where Ruby is functionnal
langage. Coding recursivity in ruby is most of the time so uneasy. I
just wonder, if someone can explain, he’ll be welcome.
This surprises me quite a bit, because I wouldn’t think implementing
callcc is an easy thing. But I am sure it is great way to
attract scheme programmers to Ruby.
“What is this ‘Ruby’ beast you are talking about? Oh, it
has call/cc, then I must surely give it a try!”
Kristof
···
On Sun, 02 May 2004 17:18:10 +0900, Jean-Hugues ROBERT wrote:
I have to mention callcc was added not because to make Ruby a real
functional language, but because we happened to succeed to implement
it, and there was no reason to remove.
matz.
I guess this really deserved to be called “pragmatism”
I’d say lambda expressions are more of a defining characteristic of functional
languages.
I think that the distinction between procedural and functional languages
has become less important than it used to be. Procedural
languages/programmers used to depend heavily on global variables and
gotos. Some languages didn’t even support recursion. Today, through the
evolution of languages and “good programming style” the procedural
languages have become “more functional”, to the extent where it even may
be hard to tell whether a language is functional or not.
I would say the two remaining distinguishing characterstics for a
functional language are:
(1) discourage side effects
No feature complete language is really free from side effects,
since you can’t do I/O or draw to the screen without them. (Unless
you employ a contorted definition of what a “side effect” is.) But
functional languages try to keep their side effects in check and not
letting them roam free.
(2) functions as first class values
You can write a function that takes a function and returns a new
modified function with reasonable syntax.
C fails on both accounts. In C++ you can sort of do (2) with templates,
but that fails the “reasonable syntax” test.
Ruby, and indeed all object-oriented languages, fail (1) since the main
thing they do is to pass around mutable objects. (2) is a bit harder to
call. But I would say Ruby fails this too. Mainly because of the fact
that “methods” have a different calling syntax than “method objects” and
“procs”.
So I wouldn’t say that Ruby is a functional language.
You can write a function that takes a function and returns a new
modified function with reasonable syntax.
C fails on both accounts.
In C you can return a pointer to a function. Of course it
totally fails the “reasonable syntax”.
In C++ you can sort of do (2) with templates,
but that fails the “reasonable syntax” test.
Ruby, and indeed all object-oriented languages, fail (1) since the main
thing they do is to pass around mutable objects. (2) is a bit harder to
call. But I would say Ruby fails this too. Mainly because of the fact
that “methods” have a different calling syntax than “method objects” and
“procs”.
So I wouldn’t say that Ruby is a functional language.
I agree on everything except point (2). Just because there are
also methods, which are different things as procs, doesn’t mean
that there are no first class functions. Take the following code:
add = lambda { |x| lambda { |y| y + x }}
add2 = add.call(2)
add2.call(5)
=> 7
add2.call(7)
=> 9
This works just like it does in scheme. I would say it fits
very nicely in (2). The “reasonable syntax” is a bit subjective,
and I admit there is an extra level of indirection. But this is
just the way in Ruby to perform an action on an object, so that’s
rather a confirmation of the fact that functions (proc objects)
have an equal status as all other values (objects).
Kristof
···
On Mon, 03 May 2004 10:21:07 +0200, Niklas Frykholm wrote:
I would say the two remaining distinguishing characterstics for a
functional language are:
(1) discourage side effects
(2) functions as first class values
You can write a function that takes a function and returns a new
modified function with reasonable syntax.
Ruby, and indeed all object-oriented languages, fail (1) since the main
thing they do is to pass around mutable objects. (2) is a bit harder to
call. But I would say Ruby fails this too. Mainly because of the fact that
“methods” have a different calling syntax than “method objects” and “procs”.
Would the last one succeed if there was something like a Lvalue class,
with auto dereferencing by the interpretor ?
f = ref proc { |*args| p args } # or f = ref method :p, “ref” creates a
Lvalue instance.
f( “hello”) # => [“hello”], proc/meth’s getter() invoked, alias for
p f # => , proc’s proc/meth’s getter() invoked, alias for
f = “world” # => [“world”], proc/meth’s setter(x) invoked, alias for
something like =() ?
getter/setter are bad names, I hope to find better ones by
the time I issue the “match, assign & Lvalue” RCR.
EOM
Yours,
Jean-Hugues
···
At 17:24 03/05/2004 +0900, you wrote:
So I wouldn’t say that Ruby is a functional language.
I agree on everything except point (2). Just because there are
also methods, which are different things as procs, doesn’t mean
that there are no first class functions. Take the following code:
add = lambda { |x| lambda { |y| y + x }}
add2 = add.call(2)
add2.call(5)
=> 7
add2.call(7)
=> 9
you can use var[args] with callable objects (continuations, methods,
procs)
This works just like it does in scheme.
I’m not an expert, but ruby models should be closer to LISP than
scheme, cause function/methods are not in the same ‘namespace’, wich
is true in scheme. I mean, we have method() and LISP has the
sharp-quote notation. But I may be cmpletely wrong.
···
il Mon, 03 May 2004 12:30:53 +0200, Kristof Bastiaensen kristof@vleeuwen.org ha scritto::