CSC/ECE 517 Fall 2010/ch1 1b gb

From Expertiza_Wiki
Revision as of 01:04, 7 September 2010 by Han (talk | contribs)
Jump to navigation Jump to search

What is a Closure?

Before diving into the differences of closures in Ruby viz a viz other languages, lets look at some traditional definitions of the same, and some history of closures to better understand the concept at hand.

A closure is a first-class function with free variables that are bound in the lexical environment. Closures:Wikipedia

For the layman, lets break up the technical sounding definition into easier terms. Basically a first class function is something that can be passed onto as arguments to other functions i.e. it can behave like any other object or variables. A closure has its own variables with last as long as the scope of the closure and are independent of any other scope. (We will see later, how this is of importance)

Another author of a Blog:A definition for closures defines a closure as

A closure is a function that captures the bindings of free variables in its lexical context.

It’s evident that this follows what we have written earlier.

Going further into layman’s terms, we could say that a closure is a kind of a ‘hidden function’ (similar construct in C, later) which is used by programmers in various languages to provide enhanced functionality in their programs/

Another writer states

A closure is a property associated with functions; when a function manipulates input and produces output which holds the features and characteristics of the input, then the function is said to possess (we should say 'satisfy' instead of 'possess') the closure property.Closures Definition

Landin is credited with introducing the term closure while referring to a lambda expression whose ‘Open Bindings’ or ‘free variables’ that have been bound ‘closed’ in a lexical environment resulting in a closed expression or ‘closure’.Closures:Wikipedia


Since we are here to compare all types of closures with Ruby, lets look into the closure definition of the Ruby creator. Yukihiro Matsumoto defines closure as a Nameless function object and goes on to say that A closure object has code to run, the executable, and state around the code, the scope. Blocks and Closures in Ruby



Closures in Ruby

The concept of closures is quite analogous to first-class functions i.e. it facilitate encapsulation of a certain behavior for example loop abstraction. Moving a step further it also grants access to the context which means you get to capture the environment in which the closure is based irrespective of the scope of the context.

Ruby offers – not one – but three different ways of creating closures. They are blocks , procs and lambdas. The syntax varies in a trifling way than the other however each exhibits a distinct behavior.

Let us go over all of them one by one


Blocks

The simplest way to define a block would be calling it a ‘nameless’ entity which is nothing but a group of statements. Also unlike functions you don’t have to name the block in the methods when it is called. Consider the following lines of code:

    Set = [2,3,5,7,11]  
    Set.increment! do |n|
    n+1
    end
    puts  Set.increment    
    # => [3,4,6,8,12]

It is apparent from the code that the block interacts with the array elements and squares them. Its important to note that blocks are not reusable. But their importance lies in the fact that they provide abstraction as well as transactional control in some cases.

Procs

Procs can be said to be the super-set of blocks. The difference between procs and blocks is that is since proc is called using an argument instead of using the keyword ‘yield’ like blocks, the code is reusable. Hence, one can conclude - a block is a proc which cannot be saved i.e. it can be used only once. Lets see an example to understand it better.

class Array
 def iterate!(code)
   self.each_with_index do |n, i|
     self[i] = code.call(n)
   end
 end
end

array_1 = [1, 2, 3, 4]
array_2 = [2, 3, 4, 5]

square = Proc.new do |n|
 n ** 2
end

puts array.inspect

# => [1, 4, 9, 16]

As we can see the proc has been invoked twice for two different set of elements which confirms the re-usability of procs. Hence, its safe to assume Procs as functions in RUBY.


= Lambda +

Lambda - Lambdas , more commonly known as ‘anonymous functions’ in other languages similar to procs. But unlike procs, lambdas check the number of arguments passed . Consider the following piece of code:

c = lambda{|a,b| puts a +b}
c.call(2,3)
c.call(2)

The second statement prints 5 as the output. At the same time the third gives rise to an ArgumentError Another noticeable difference would be they way return is dealt with by Procs and lambda. The return from Procs is a return from the method in which it is called whereas a return from lambda goes back to the calling function. One can also say that the return of a proc overrides the calling methods return however return from lambda does not.


References

<references/>