Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

Re^2: Trinary Operator Semantics

by hardburn (Abbot)
on May 27, 2005 at 14:01 UTC ( [id://461066]=note: print w/replies, xml ) Need Help??


in reply to Re: Trinary Operator Semantics
in thread Trinary Operator Semantics

Tail recursion would be a great optimization to have, but Perl doesn't do it except through the clunky use of goto BLOCK;. And that doesn't appear to give any time optimization (admittedly, that p5p message could be long out of date).

I don't think there's any support for the idea that until the Perl6 effort, Perl was anything but ad hoc design. The difficulties in dis-ambiguizing the defined-or operator from an empty regex should be proof of that. The fact that you can't get a context-free grammar for Perl should be proof of that. The steps perl has to go through (and still ocasionally get it wrong) to figure out if map {. . .} @array should contain a block or a hashref should be proof of that.

I don't mean to insult the p5p people, as they make my work easy in many cases. Perl has simply been extended over the years from an awk/sed killer into a part imparative, part functional, part OO language, and that process would inevitably introduce some rather odd designs.

"There is no shame in being self-taught, only in not trying to learn in the first place." -- Atrus, Myst: The Book of D'ni.

Replies are listed 'Best First'.
Tail recursion using goto ⊂ (was: Re^3: Trinary Operator Semantics)
by Joost (Canon) on May 27, 2005 at 16:50 UTC
    Tail recursion would be a great optimization to have, but Perl doesn't do it except through the clunky use of goto BLOCK;. And that doesn't appear to give any time optimization (admittedly, that p5p message could be long out of date).

    I think you mean goto ⊂

    #!perl use strict; use Benchmark; sub normal { return 0 unless $_[0]; @_ = ($_[0] - 1); return normal(@_); } sub tail { return 0 unless $_[0]; @_ = ($_[0] - 1); goto &tail; } timethese( 10, { "normal" => sub { normal(500000) }, "tail" => sub { tail(500000) }, } );
    Output:
    normal: 25 wallclock secs (23.19 usr + 0.59 sys = 23.78 CPU) @ 0 +.42/s (n=10) tail: 18 wallclock secs (17.44 usr + 0.03 sys = 17.47 CPU) @ 0 +.57/s (n=10
    Not very impressive, but there is a clear improvement in speed. The improvement in wallclock seconds becomes far larger if you start swapping with the normal recursive call (at my machine at 1_000_000 levels of recursion). I tried this only with 1 iteration because I got impatient:
    #!perl use strict; use Benchmark; sub normal { return 0 unless $_[0]; @_ = ($_[0] - 1); return normal(@_); } sub tail { return 0 unless $_[0]; @_ = ($_[0] - 1); goto &tail; } timethese( 1, { "normal" => sub { normal(1000000) }, "tail" => sub { tail(1000000) }, } );
    output:
    Benchmark: timing 1 iterations of normal, tail... normal: 123 wallclock secs ( 6.58 usr + 1.13 sys = 7.71 CPU) @ +0.13/s (n=1) (warning: too few iterations for a reliable count) tail: 3 wallclock secs ( 3.50 usr + 0.01 sys = 3.51 CPU) @ 0 +.28/s (n=1) (warning: too few iterations for a reliable count)
      Oddly enough, "optimized" tail recursion is significantly slower than recursing the same way without the goto:
      sub faster { return 0 unless $_[0]; @_ = ($_[0] - 1); &faster; }
      Using this test:
      cmpthese( -10, { "normal" => sub { normal(50000) }, "tail" => sub { tail(50000) }, "faster" => sub { faster(50000) }, } );
      I got these results:
      Rate normal tail faster normal 2.34/s -- -0% -41% tail 2.35/s 0% -- -41% faster 3.96/s 69% 68% --

      Caution: Contents may have been coded under pressure.

        Of course a loop is even faster...

        #!perl use strict; use Benchmark qw(cmpthese); my %counter; sub normal { return 0 unless $_[0]; @_ = ($_[0] - 1); $counter{(caller(0))[3]}++; return normal(@_); } sub tail { return 0 unless $_[0]; @_ = ($_[0] - 1); $counter{(caller(0))[3]}++; goto &tail; } sub faster { return 0 unless $_[0]; @_ = ($_[0] - 1); $counter{(caller(0))[3]}++; &faster; } sub loop { for (0..$_[0]) { $counter{(caller(0))[3]}++; } return 0; } cmpthese( -3, { "normal" => sub { normal(50000) }, "tail" => sub { tail(50000) }, "faster" => sub { faster(50000) }, "loop" => sub { loop(50000) }, } ); __END__ Rate normal tail faster loop normal 2.15/s -- -8% -18% -38% tail 2.35/s 9% -- -11% -32% faster 2.64/s 23% 12% -- -24% loop 3.45/s 60% 47% 31% --

        I put the caller thingee in there to ensure that the for loop didnt get optimized away. Which is in itself also a good argument for just using a loop in the first place.

        ---
        $world=~s/war/peace/g

Re^3: Trinary Operator Semantics
by chromatic (Archbishop) on May 27, 2005 at 16:27 UTC
    I don't think there's any support for the idea that until the Perl6 effort, Perl was anything but ad hoc design.

    Compare it to a real example of ad hoc language design: PHP.

Re^3: Trinary Operator Semantics
by kscaldef (Pilgrim) on May 27, 2005 at 16:55 UTC

    The fact that you can't get a context-free grammar for Perl should be proof of that.

    I wouldn't jump to that conclusion so fast. Human languages are not context-free. Giving a language a CFG certainly makes it easier for computers to understand it; it's less clear that it makes it easier for the human programmer.

      I don't know of any human languages that were consciously designed (at least, ones that are actually used by a significant precentage of the population, which discounts Esperonto and Klingon). They're always ad hoc. So is Perl, and that's what that statement was trying to prove.

      "There is no shame in being self-taught, only in not trying to learn in the first place." -- Atrus, Myst: The Book of D'ni.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others surveying the Monastery: (4)
As of 2024-04-25 13:35 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found