Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

Re: Programming in Perl without semicolon

by JavaFan (Canon)
on Jan 31, 2009 at 02:15 UTC ( [id://740368]=note: print w/replies, xml ) Need Help??


in reply to Programming in Perl without semicolon

With caching (so it runs fast for large numbers), with variables, and not generating warnings/errors if strict and/or warnings were to be turned on:
{@::cache = (0, 1)} sub fib { {push @::n, shift} {return pop @::n if $::n[-1] < 2} {$::cache [$::n[-1]] ||= fib ($::n[-1] - 1) + fib ($::n[-1] - 2)} {return $::cache[pop @::n]} }

Replies are listed 'Best First'.
Re^2: Programming in Perl without semicolon
by ikegami (Patriarch) on Jan 31, 2009 at 03:00 UTC

    Yuck! Use use vars.

    { use vars qw( @cache @n ) } {@cache = (0, 1)} sub fib { {push @n, shift} {return pop @n if $n[-1] < 2} {$cache [$n[-1]] ||= fib ($n[-1] - 1) + fib ($n[-1] - 2)} {return $cache[pop @n]} }

    Bonus: Doesn't confine you to the main namespace!


    Now if we could only localize variables, we wouldn't need to manage our own stack.

    { use vars qw( @cache ) } {@cache = (0, 1)} sub fib { (local (our $n = shift)) && do { {return $n if $n < 2} {$cache[$n] ||= fib ($n - 1) + fib ($n - 2)} {return $cache[$n]} } }

    Bonus: Don't have to use use vars except for globals!


    By the way, the body simplifies down to a single expression, and your cache initialiser is not needed.

    { use vars qw( @cache ) } sub fib { (local (our $n) = shift), ( $n < 2 ? $n : $cache[$n] ||= fib ($n - 1) + fib ($n - 2) ) }

    Update: Replaced buggy
    (local our $n = shift) && ...
    with
    (local (our $n) = shift) && ...

      Bonus: Doesn't confine you to the main namespace!
      That's only a bonus if you can switch packages without a semicolon. I haven't figured out how, except for the useless:
      {package Foo}
      (local our $n = shift) && do { ... }
      I'm surprised this works. I would have expected 'our' to be in effect after the statement, just like 'my'. (If you replace 'local our' with 'my', the code wouldn't compile under 'strict').

      Unfortunally, it's not a general technique. It works here because 'fib(0)' is supposed to return '0'; the block isn't executed if the argument of the function is 0.

        That's only a bonus if you can switch packages without a semicolon.

        Oh yeah. Well, no bonus, but it still makes it more readable.

        I'm surprised this works.

        Me too, but it makes sense. It allows for

        our $state = $next_states{$state};

        Unfortunally, it's not a general technique.

        Oops! Just replace the and op with a list op or replace the sassign op with an aassign op.

        (local our $n = shift), ...

        or

        (local (our $n) = shift) && ...

        The former is simpler. The latter has the advantage that it doesn't affect the return value in list context.

        Unfortunally, it's not a general technique. It works here because 'fib(0)' is supposed to return '0'; the block isn't executed if the argument of the function is 0.
        But it can be written as:
        local our ($n, $m) = (shift, 0)) && do { }
        and then it will always do the 'do'.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://740368]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chanting in the Monastery: (2)
As of 2024-04-20 04:21 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found