4

In this comment, it was stated that Ruby doesn't have functions, only methods. If Ruby doesn't have functions, is it not possible to do functional programming in it? Or am I confused about the term "function"?

I mean "functional programming" in the sense of functions as first class objects, not as in prohibiting mutable state.

Community
  • 1
  • 1
Andrew Grimm
  • 78,473
  • 57
  • 200
  • 338

4 Answers4

6

Blocks and Procs are first-class functions. You can pass them around to methods and functions. That's how Ruby is able to support FP-ish things like map and reduce.

More generally, a method can be viewed as a function with extra associated state (its self), but methods are rarely passed around in Ruby — though they can be — so in practice they're not as important to FP-ish idioms as blocks and Procs.

Chuck
  • 234,037
  • 30
  • 302
  • 389
  • I'm not sure it's accurate to call blocks first-class. You can pass them around, yes, but you can't store them in variables or return them without converting them to Procs first. – sepp2k Sep 06 '12 at 00:14
  • 1
    @sepp2k: Hence why I grouped blocks and Procs together. They're essentially different ways of dealing with the same thing for the purposes of this discussion. – Chuck Sep 06 '12 at 01:27
4

Yes. Method vs function is quite a fine distinction.

It's easy to view each particular method implementation as a function; just have it take as an extra parameter the object on which the method was invoked (if your language doesn't pass it explicitly; not terribly familiar with Ruby). That doesn't quite give you virtual method calls (i.e. where the particular implementation called is determined by the object at runtime). But it's also very easy to imagine a virtual method call as calling a function that just inspects its first parameter (self, this, whatever it's called) and uses it to determine which method implementation to call. With those conventions established, object.method(param1, param2) differs from method(object, param1, param2) only in a trivial syntactic way.

Personally, I view the above as "the truth", and that object-oriented languages just offer syntactic sugar and optimised execution for this because it's such a core part of writing/executing OO programs. That sort of system is also exactly how you do OO when you have functions but not true classes/methods.

It's also trivially easy to implement functions with methods, if you think methods aren't functions. Just have an object with a single method and no attributes! This is also how you do functional programming in languages like Java that insist upon everything being an object and don't let you pass methods/functions as first-class values.

All you need to do functional programming is things you can pass around as first-class values, which can be used to execute code determined by the creator of the "thing" (rather than determined by the code that's using the "thing"), on demand by code that has access to the "thing". I can't think of a programming language that doesn't have this capability.

Ben
  • 68,572
  • 20
  • 126
  • 174
2

A function (or more precisely a procedure, since we are not talking about referential transparency here) is isomorphic to an object with only a single method.

That's how first-class procedures are faked in Java, for example: with so-called SAM interfaces (Single Abstract Method). It's also how first-class procedures are "faked" in Ruby: anything which responds to call (and maybe to_proc) is a first-class procedure. There is a convenience class called Proc which provides additional features for "procedures" such as currying, and there is literal syntax (-> (x, y) { x + y }) for procedures which creates instances of the Proc class, but those two aren't strictly necessary:

def (i_am_a_first_class_procedure = Object.new).call(x) p x end

i_am_a_first_class_procedure.(42)
# 42

Scala is similar, except the method is called apply, not call. In Python, it's a "magic" method called __call__.

Note: I am ignoring closures here. Closures are procedures with state, and objects of course can have state, too, so there's not a real problem in representing them, but expressing the lexical capture of free variables in terms of an object with instance variables gets rather hairy.

Jörg W Mittag
  • 363,080
  • 75
  • 446
  • 653
-2

Naturally yes, as long as the language is Turing complete.

Added later:

Actually, Ruby supports several cases of typical functional programming. Matz himself stated something about "providing toys for functional programming kids" when he wass adding #curry method to Proc class in Ruby 1.9 But you can do functional programming with methods as well.

Boris Stitnicky
  • 12,444
  • 5
  • 57
  • 74
  • 1
    I haven't downvoted the answer yet, but it isn't a very informative answer. – Andrew Grimm Sep 06 '12 at 05:11
  • Have you ever heard about Occam razor? – Boris Stitnicky Sep 06 '12 at 05:35
  • 2
    Yes. I do not think it means what you think it means. – Andrew Grimm Sep 06 '12 at 06:08
  • 1
    This "Anything you can do in one language, you can do in any other Turing-complete language" meme needs to die. The true version of that statement is "All Turing-complete languages are capable of universal computation" — but that's a much more limited claim! Specific programming techniques are language-specific. Case in point: Whitespace is Turing-complete, but you cannot do functional programming in Whitespace, as it does not have functions. – Chuck Sep 07 '12 at 20:34
  • Non-mathematicians will surely agree with your statement. – Boris Stitnicky Sep 08 '12 at 00:54