On Tue, 02 Jul 2002 10:36:45 -0700, Erik Steven Harrisan wrote:
  ESH> my $a = 'foo';
  ESH> 
  ESH> pass_by_name ( sub { print $a} );
  ESH> 
  ESH> sub pass_by_name {
  ESH>     my $a = 'bar';
  ESH>     &@_[0];
  ESH> }
  ESH> 
  ESH> Now, I have trouble keeping Perl 6 and 5 straight, but what I think
this does is 
  ESH> print 'foo', as the sub ref is a closure, and gets $a bound to it.
Fair enough.
  ESH> 
  ESH> But in pass by name, expressions passed to a function aren't
evaluated until they 
  ESH> are used inside that function, and are evaluated in the context of
the surrounding 
  ESH> function. In a pass by name environment, the above code would print
'bar' as the 
  ESH> sub isn't evaluated until it is used in pass_by_name, and then it
gets pass_by_name's 
  ESH> value of $a. Understand? Isn't that weird?

If you s/my/local/ in your example, you WILL get 'bar' instead of `foo'. But
what you are
really describing then is dynamic scoping for variables, not pass-by-name.

BTW: I've never heard of "Jensen's Machine", but "Jensen's Device" is a
technique 
used to implement pass-by-name. 

To get a better feel for the weirdness that happens with pass-by-name,
consider this example:
  sub check_it_out {
    $_[0] = 0;  #step 1
    $_[1] = 7;  #step 2
  }

  my @a = (0,1,2,3,4);
  my $i = 2;
  check_it_out($i, $a[$i]);
  print join '', @a;

This prints '01734' under Perl 5, because the arguments ($i and $a[2]) are
passed by reference.

If the arguments to check_it_out() were passed by name instead, the result
would be '71234',
because step 1 would change $i to have the value 0, and *then* $a[$i] would
be evaluated in
step 2 (using $i's new value), causing the 7 to be assigned to $a[0] (not
$a[2]).

As Larry said elsewhere in this thread, Ruby doesn't have pass-by-name. And
I don't think
anybody seriously wants it anyway. I'm personally MUCH more interested in
Python's generators
<http://www.python.org/peps/pep-0255.html>.

A generator is like an iterator in that it can produce a series of values.
But unlike
iterators, when you ask a generator for the next value, it picks up
execution exactly where 
it left off when it returned the last value -- including all it's stack.
This makes it much
easier to solve certain classes of problems (like the same-fringe problem:
given two trees,
answer the question "do these trees have the same leaves in the same
order?")

If you are interested in Jensen's Device, or if you would like to see an
example of how 
pass-by-name MIGHT be considered useful, check out 
  http://www.cs.rit.edu/~afb/20013/plc/slides/procedures-07.html
or just google "Jensen's Device".

=thom

Reply via email to