Ruby methods aren’t first-class, but procs are first-class

Ruby methods are not functions or first-class citizens because they cannot be passed to other methods as arguments, returned by other methods, or assigned to variables. Ruby procs are first-class, similar to JavaScript’s first-class functions.

Jorg Mittag says it well:

Ruby doesn’t have functions. It only has methods (which aren’t first-class) and Procs which are first-class, but are not associated with any object.

The following code demonstrates how Ruby methods cannot be stored in variables or returned from methods and therefore do not meet the ‘first-class’ criteria:

class Dog
  def speak
    'ruff'
  end
end

fido = Dog.new
# Ruby methods cannot be stored in variables
# Methods are executed and variables only store values
x = fido.speak
# x stores the method's return value, not the method itself
x # => 'ruff'

# Methods cannot return other methods
# Methods can only return values from other methods
def hi
  Dog.new.speak
end
# hi returns the method's return value, not the method itself
hi # => 'ruff'

Here is the Wikipedia definition of first-class functions:

In computer science, a programming language is said to have first-class functions if it treats functions as first-class citizens. Specifically, this means the language supports passing functions as arguments to other functions, returning them as the values from other functions, and assigning them to variables or storing them in data structures.

The first-class function definition depends on the definition of first-class citizens:

In programming language design, a first-class citizen (also object, entity, or value) in a given programming language is an entity which supports all the operations generally available to other entities. These operations typically include being passed as a parameter, returned from a function, and assigned to a variable.

JavaScript is a language that has first-class functions that can be returned from other functions, assigned to variables, and stored in data structures.

function hi() {
  return('hello');
}

// functions can be assigned to a variable
var x = hi;
// x stores the actual function, not the return value of the function
console.log(x); // returns hi function
// variable can be used to invoke function
x(); // => 'hello'

// function can be returned by another function
function blah() { return hi; }
blah() // returns hi function

// functions can be stored in data structures
[hi, 3, 4, 'boo']

Ruby procs are objects that are like anonymous functions and are treated as first-class citizens.

# procs can be assigned to variables
multiplier = Proc.new {|x, y| x * y}

# procs can be returned from methods
def proc_returner(proc)
  proc
end
proc_returner(multiplier) # => multiplier proc

# procs can be stored in data structures
a = [multiplier]
a.first.call(3, 4) # => 12
Advertisements

2 thoughts on “Ruby methods aren’t first-class, but procs are first-class

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s