Skip to content

Instantly share code, notes, and snippets.

@wicz
Forked from mislav/procs-vs-lambda.md
Created May 23, 2016 09:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wicz/5fb9a73caa4932be52c10ebfdb1e3ee1 to your computer and use it in GitHub Desktop.
Save wicz/5fb9a73caa4932be52c10ebfdb1e3ee1 to your computer and use it in GitHub Desktop.
Jim Weirich on the differences between procs and lambdas in Ruby

Jim Weirich:

This is how I explain it… Ruby has Procs and Lambdas. Procs are created with Proc.new { }, lambdas are created with lambda {} and ->() {}.

In Ruby 1.8, proc {} creates lambda, and Ruby 1.9 it creates procs (don't ask).

Lambdas use method semantics when handling parameters, procs use assignment semantics when handling parameters.

This means lambdas, like methods, will raise an ArgumentError when called with fewer arguments than they were defined with. Procs will simply assign nil to variables for arguments that were not passed in.

Starting from Ruby 1.9, both procs and lambdas—like methods—support defining arguments with default values. To lambdas, such arguments are then optional at call time.

Lambdas act like anonymous functions w.r.t. the return statement (i.e. return will return from the lambda). Procs are invisible to return, so a return statement will return from the enclosing function. The technical way to say this is that Procs follow the Tennent Correspondence Principle w.r.t. return statements. This allows you to wrap some code in a proc and immediately call the proc without changing the semantics of the code.

That leaves blocks. Blocks don't actually exist as things manipulated by the Ruby language. When I talk about blocks, I am referring to the syntactical construct of putting do/end or {} after a method invocation. When you write code with this syntactical construction, Ruby arranges for the code in the block to be passed to method being called. MRI will create a proc object representing the block only if you reference the block with a &block parameter in the calling sequence. This is a mere implementation detail.

Gary Bernhardt:

A: “Everything is an object in Ruby! :D”
B: “What is the class of a block?”
A: “:-[”

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment