From: "Mr. Shawn H. Corey" <[EMAIL PROTECTED]>
> Dr.Ruud wrote:
> >> Why do people who write these books have exercises of little
> >> practical value? 
> > 
> > An exercise needs to be educational. 
> 
> I have worked in programming for 25 years and during that time I have
> never use a closure and have never seen one used.  I may be harsh in
> my definitions but to me something that is never used is useless. 
> Teaching people to do useless things is not educational. 

Y'knaw son, I've been hacking trees down all my life with this here 
hack and its a good hack, got it from my late father, I did. And I've 
never user this what you call chainsaw and have never seen one user. 
I may be harsh, y'know, but if you ask me, something that is never 
used is useless. So go away with your chainsaw and let me go on with 
my hacking. I've got this tree to cut down and I havn't got whole day 
to do it.

> >> closure introduce another layer of compile/run to the program.  They
> >> should be avoided.   
> > 
> > Why would a "closure introduce another layer of compile/run"? 
> > A closure carries an environment, so just call it an object. 
> > 
> 
> Dealing with a closure has two phases.  A phases when its created
> (compiled phase) and one when it's executed (run phase).  When you
> write a closure you have to keep the two phases in mind (and
> separate). 

I think I know what you mean, though the choice of words is 
unfortunate.

 
> For example, in the OP's problem there are three parameters: the start
> time, the stop time, and the staring directories.  Since it doesn't
> make much sense to separate the start ans stop times, I shall treat
> them as a data set called times.  There are four ways to distribute
> them: 
> 
> 1. All are parameters to the closure generator.  In this case, the
> closure is not very flexible.  What it can tell are if a file has been
> modified between its runs. 
> 
> 2. The times are closure-generator parameters and the starting
> directories are closure parameters.  This gives a closure that can
> look at different directories but in the same time interval. 
> 
> 3. The starting directories are closure-generator parameters and the
> times are closure ones.  This gives a closure that looks at the same
> directories but with different time intervals. 
> 
> 4. All are parameters are closure ones.  This gives a closure that is
> very flexible but is little different from a common sub. 

So you proved that this exercise is not the best case for the usage 
of closures. I'd agree on that one. BTW, the 2. and 3. are 
(especially the way you explain them) perfect examples of function 
currying. Another thing you've never user nor seen used. The Perl5 
way of function parameter handling doesn't allow for nice support for 
currying though.

> The problem with closures is that you have to write them and their
> generators at the same time.  So you have to keep two different phases
> in mind, the compile phase and the run phase, while remembering what
> parameters belong to which phase. 

Well, I would not call that a problem. Let me give you a differet 
example of a closure.

Imagine you are writing a GUI. What you need to do is to specify what 
to do when this button is clicked, that button is clicked, ...

There are basically three ways to do that. (Three and half.)

First, Visual Basic, use a naming convention:
Sub ButtonName_OnClick
  SomeObject.Frobnicate
End Sub

Sub OtherButtonName_OnClick
  OtherObject.Frobnicate
End Sub


Second, C++ (I believe), use function pointers
hResult ButtonName_OnClick() {
  SomeObject.Frobnicate();
}
hResult OtherButtonName_OnClick() {
  OtherSomeObject.Frobnicate();
}
...
TheWindow.Buttons('ButtonName).AttachHandler(&ButtonName_OnClick);
TheWindow.Buttons('OtherButtonName).AttachHandler(&OtherButtonName_OnC
lick);

Second and half, C#, similar to C++ except that instead of 
&ButtonName_OnClick you have to instantiate the right delegate 
object.

In both (all) those cases you have to NAME the functions and you end 
up with lots of functions that look the same. Just lovely.


Or you can use closures ... the simple ones without a generator:

 $window->addButton(-name => 'ButtonName', -title => 'Sumfin', -
onClick => sub {$someObject->frobnicate()});
 # and the $someObject does not have to be global!!!

or if the subroutine is more complex and used more times with 
different objects:

sub frobincareObj {
  my $obj = shift;
  return sub {
    do this
    do that
    $obj->prepare( something);
    $obj->frobnicate( some params);
    ...
  }
}
...
 $window->addButton(-name => 'ButtonName', -title => 'Sumfin', 
   -onClick => frobnicateObj($someObject));
 $window->addButton(-name => 'OtherButtonName', -title => 'Sumfin 2', 
   -onClick => frobnicateObj($someObject));


You could of course do something like this with objects. That is if 
the "type system" doesn't prevent that. Something like:

class callFrobnicate : thisIsNotAClosure {
  frobnicable* the_obj;
  callFrobnicate( void *obj) { the_obj = obj }
  hResult call() {the_obj->frobnicate()}
}

...

TheWindow.Buttons('ButtonName).AttachHandler(new 
callFrobnicate(someObject));

How's that more direct?

> Objects can do the same things as closures, which is store and hide
> data, but don't have this problem of having to keep in mind two phases
> of the same code. 

I think you are just not used to the posibility that functions could 
return functions.

Jenda
===== [EMAIL PROTECTED] === http://Jenda.Krynicky.cz =====
When it comes to wine, women and song, wizards are allowed 
to get drunk and croon as much as they like.
        -- Terry Pratchett in Sourcery


-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/


Reply via email to