Project

General

Profile

Actions

Feature #4102

closed

Proposal for 'let'. A new approach using block-defaults in 1.9

Added by banister (john mair) almost 14 years ago. Updated over 12 years ago.

Status:
Rejected
Target version:
-
[ruby-core:33483]

Description

=begin
This is a very simple function, it would be implemented as follows:

 module Kernel
   private
   def let() yield end
 end

First of all, do not dismiss this functionality out of hand because of
its simplicity.

Even though it is just a 'yield', when it is combined with Ruby 1.9's
block defaults and new block-variable scoping rules it is actually quite
powerful and it behaves exactly like a let* in lisp.

Some advantages of this functionality are:
(1) Gives you precise control over the scope of your variables.

I note that after the publication of "Metaprogramming in Ruby" by Paolo
Perrotta the following idiom has started to appear:

 proc do
   ..my code..
 end.call

It is used exactly as the proposed 'let' would be used, but is
syntactically much uglier.

Yes, i know an alternative is to just make shorter and smaller methods.
But is the ability to control and restrict scope ever a bad thing?

(2) Testing and teaching about blocks.

As the proposed 'let' simply yields to a block it can be used to
illustrate block behaviour and block concepts to a new Ruby programmer.
It also may be useful to an experienced programmer when trying out new
ideas.

Here are some example uses of the proposed 'let':

Example 1: Carve out a temporary scope, make 'x' local to that scope

 x = :outer
 let { |x| x = :inner } #=> :inner
 x #=> :outer

Example 2: Here we use Ruby 1.9's block-defaults to make 'y' block-local
and give it a value:

 let { |y=10| y } #=> 10

Example 3: Make 'x' and 'y' block-local and have 'y' value depend on 'x'
(equivalent to let* in lisp)

 let { |x=10, y=(2*x)| [x, y] } #=> [10, 20]

In summary, I think this proposal should succeed for the following
reasons:
(1) It is an exceptionally simple implementation.
(2) More control over scope is never a bad thing.
(3) I have seen people re-implementing this functionality themselves
using: proc { ..code.. }.call
(4) It is very useful for teaching and testing block behaviour.

Thanks,

John
=end

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0