Loading ...
Sorry, an error occurred while loading the content.

Re: [PBML] lambdas and scope

Expand Messages
  • Jenda Krynicky
    To: perl-beginner@yahoogroups.com From: Jonas Bull Date sent: Fri, 2 Jul 2010 10:07:14 -0500 Subject:
    Message 1 of 3 , Jul 7, 2010
    View Source
    • 0 Attachment
      To: perl-beginner@yahoogroups.com
      From: Jonas Bull <me@...>
      Date sent: Fri, 2 Jul 2010 10:07:14 -0500
      Subject: [PBML] lambdas and scope
      Send reply to: perl-beginner@yahoogroups.com

      > I am playing around with the following code. fib1 is a normal
      > subroutine, fib2 is a lexically scoped lambda, and fib3 is a lambda.
      >
      > My question is, why does fib3 work more or less identically to fib1
      > but the lexically scoped fib2 require some gymnastics to be able to
      > "see" itself?
      >
      > Is there a better way to do this?
      >
      > If, for example, I wanted to create a lambda within a module how would
      > I safely pass it back to main?
      >
      > sub fib {
      > my $n=shift;
      > if ($n < 2){1}
      > else{
      > return fib($n-1)+fib($n-2));
      > }
      > };
      > my $fib2=sub {
      > my $n=shift;
      > my $fib2=shift;
      > if (($n==1)||($n==2)){
      > return $n;
      > }else{
      > return ($fib2->($n-1,$fib2)+$fib2->($n-2,$fib2));
      > }
      > };

      The catch is that the $fib2 is not declared on the left hand side of
      the statement yet. It has got nothing to do with lambdas. This lets
      you do things like:

      my $x = 15;
      print "$x\n";
      {
      my $x = $x + 10;
      print "$x\n";
      }
      print "$x\n";

      A much easier way to write this is

      my $fib2;
      $fib2=sub {
      my $n=shift;
      if (($n==1)||($n==2)){
      return $n;
      }else{
      return ($fib2->($n-1)+$fib2->($n-2));
      }
      };

      Jenda
      ===== Jenda@... === 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
    • Jonas Bull
      Thanks, I was embarrassed when I realized that. :-) My next, related, question has to do with performance. In this example, using an anonymous function yields
      Message 2 of 3 , Jul 7, 2010
      View Source
      • 0 Attachment
        Thanks, I was embarrassed when I realized that. :-)

        My next, related, question has to do with performance.

        In this example, using an anonymous function yields a 30% (average)
        increase in speed over a fully declared function. Using a lexically
        scoped variable reference increases the speed even further (20-30%).
        Why should that be?

        What other situations would anonymous functions have a significant
        performance increase?

        On 7/7/10, Jenda Krynicky <Jenda@...> wrote:
        > To: perl-beginner@yahoogroups.com
        > From: Jonas Bull <me@...>
        > Date sent: Fri, 2 Jul 2010 10:07:14 -0500
        > Subject: [PBML] lambdas and scope
        > Send reply to: perl-beginner@yahoogroups.com
        >
        >> I am playing around with the following code. fib1 is a normal
        >> subroutine, fib2 is a lexically scoped lambda, and fib3 is a lambda.
        >>
        >> My question is, why does fib3 work more or less identically to fib1
        >> but the lexically scoped fib2 require some gymnastics to be able to
        >> "see" itself?
        >>
        >> Is there a better way to do this?
        >>
        >> If, for example, I wanted to create a lambda within a module how would
        >> I safely pass it back to main?
        >>
        >> sub fib {
        >> my $n=shift;
        >> if ($n < 2){1}
        >> else{
        >> return fib($n-1)+fib($n-2));
        >> }
        >> };
        >> my $fib2=sub {
        >> my $n=shift;
        >> my $fib2=shift;
        >> if (($n==1)||($n==2)){
        >> return $n;
        >> }else{
        >> return ($fib2->($n-1,$fib2)+$fib2->($n-2,$fib2));
        >> }
        >> };
        >
        > The catch is that the $fib2 is not declared on the left hand side of
        > the statement yet. It has got nothing to do with lambdas. This lets
        > you do things like:
        >
        > my $x = 15;
        > print "$x\n";
        > {
        > my $x = $x + 10;
        > print "$x\n";
        > }
        > print "$x\n";
        >
        > A much easier way to write this is
        >
        > my $fib2;
        > $fib2=sub {
        > my $n=shift;
        > if (($n==1)||($n==2)){
        > return $n;
        > }else{
        > return ($fib2->($n-1)+$fib2->($n-2));
        > }
        > };
        >
        > Jenda
        > ===== Jenda@... === 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
        >
        >


        --

        Jonas Bull
        601-324-0324 (Office)
        228-222-2855 (Home)
      Your message has been successfully submitted and would be delivered to recipients shortly.