Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??

I was looking at my normal youtube feed when Leon Timmermans came up with a presentation about Raku. (Certainly interesting, and I have questions for him, but not now.) I soon realized that the zoom convention was happening, and that I could get it in essentially real time on youtube. I have them on as I go about my business, and B Estrade's talk comes on. I went about cleaning the kitchen at the start, but once it started into graph theory, I got very interested, and gave it my full attention. As things started cooking, the moderator chimed in that five minutes remained, and the presenter was left to rush through slides, to my, and seemingly, his dismay. He didn't get to running code, but I was interested enough to see what I could dig up. I feel like there was a second half to the talk that I would gladly hear. I tried to fill in the gaps by working some code, and I would like to post sources, output and questions.

I'll present with a script that came from Sub-Genius, with the exception of one line changed. It is the first of his japh examples. If you download this precise script, then the breakpoints I give here will make sense. I didn't move any working code up or down. Here is 1.japh.pl:

#!/usr/bin/env perl use v5.30.0; # implies strict use warnings; use feature 'state'; use FindBin qw/$Bin/; use lib qq{$Bin/../lib}; use Sub::Genius (); # # Implements classic JAPH, perl hacker hackerman benchmark # sequentially consistent, yet oblivious, way - that's right! # This is a Sequential Consistency Oblivious Algorithm (in the # same vein as 'cache oblivious' algorithms # # paradigm below is effective 'fork'/'join' # my $pre = q{ begin ( J & A & P & H ) end }; # Load PRE describing concurrent semantics my $sq = Sub::Genius->new(preplan => $pre ); my $GLOBAL = {}; # 'compile' PRE $sq->init_plan; # run loop-ish $sq->run_once( verbose => $ARGV[0], # 'scope' is passed as reference to all calls, effectively # acts as shared memory, federated only among subroutine # participating in the serialized excecution plan scope => { japh => [ qw/just Another perl/, q{Hacker,} ], curr => 0, contrib => [], } ); # Dump $GLOBAL that's now been changed if ( $ARGV[0] ) { print qq{\n... actual contributions of each sub ...\n}; foreach my $k ( keys %$GLOBAL ) { printf( qq{ %s() => %s\n}, $k, $GLOBAL->{$k} ); } } # # ## S T A T E S U B S ## # # # noop sub begin { my $scope = shift; state $persist = {}; # gives subroutine memory, also 'private' my $private = {}; # reset after each call return; } sub J { my $scope = shift; state $persist = { akctual => $scope->{japh}->[ $scope->{curr} ], +}; # gives subroutine memory, also 'private' + # sub's killroy $GLOBAL->{J} = $persist->{akctual}; ++$scope->{curr}; my $private = {}; + # reset after each call push @{ $scope->{contrib} }, $persist->{akctual}; return; } sub A { my $scope = shift; state $persist = { akctual => $scope->{japh}->[ $scope->{curr} ], +}; # gives subroutine memory, also 'private' + # sub's killroy $GLOBAL->{A} = $persist->{akctual}; ++$scope->{curr}; my $private = {}; + # reset after each call push @{ $scope->{contrib} }, $persist->{akctual}; return; } sub H { my $scope = shift; state $persist = { akctual => $scope->{japh}->[ $scope->{curr} ], +}; # gives subroutine memory, also 'private' + # sub's killroy $GLOBAL->{H} = $persist->{akctual}; ++$scope->{curr}; my $private = {}; + # reset after each call push @{ $scope->{contrib} }, $persist->{akctual}; return; } sub P { my $scope = shift; state $persist = { akctual => $scope->{japh}->[ $scope->{curr} ], +}; # gives subroutine memory, also 'private' + # sub's killroy $GLOBAL->{P} = $persist->{akctual}; ++$scope->{curr}; my $private = {}; + # reset after each call push @{ $scope->{contrib} }, $persist->{akctual}; return; } sub end { my $scope = shift; state $persist = {}; + # gives subroutine memory, also 'private' my $private = {}; + # reset after each call printf( "%s\n", join( q{ }, @{ $scope->{contrib} } ) ); return; } exit;

The only difference is the change from

use strict;

to

use v5.30.0; # implies strict

Normally, I would get my strictness by using the version number alone, thus:

use 5.30.0;

Q1.a) Are the above statements semantically equivalent in perl5?

Q1.b) Will they be in perl 7?

There was *a lot* said about use v in Suckitude 2020, and there seems to be many and varying opinions. I don't know where the whole thing ended up. Q1.c) Let me ask this, if I am going to use a version number, is this now preferred syntax?

use v5.30.0; # implies strict

For output I have the source files from runs with the debugger. I need to play with software to understand it. The following source worked for getting a look at this script using the debugger. I built my way to this with runs and edits:

b 70 b 82 b 94 b 106 b 118 b 126 c c v p $persist->{akctual} v c p $persist->{akctual} v c p $persist->{akctual} v c p $persist->{akctual} v c p @{$scope->{contrib}} #save 4.seq.txt

This yields:

$ perl -d 1.japh.pl jehosophat Loading DB routines from perl5db.pl version 1.55 Editor support available. Enter h or 'h h' for help, or 'man perldebug' for more help. main::(1.japh.pl:20): my $pre = q{ main::(1.japh.pl:21): begin main::(1.japh.pl:22): ( main::(1.japh.pl:23): J & main::(1.japh.pl:24): A & main::(1.japh.pl:25): P & main::(1.japh.pl:26): H main::(1.japh.pl:27): ) main::(1.japh.pl:28): end DB<1> source 4.seq.txt + >> b 70 >> b 82 >> b 94 >> b 106 >> b 118 >> b 126 >> c plan: "begin A H J P end" <<< Execute: main::begin(1.japh.pl:70): return; >> c main::A(1.japh.pl:94): return; >> v 91: ++$scope->{curr}; 92: my $private = {}; + # reset after each call 93: push @{ $scope->{contrib} }, $persist->{akctual}; 94==>b return; 95 } 96 97 sub H { 98: my $scope = shift; 99: state $persist = { akctual => $scope->{japh}->[ $scope->{cu +rr} ], }; # gives subroutine memory, also 'private' 100 + # sub's killroy >> p $persist->{akctual} just >> v 98: my $scope = shift; 99: state $persist = { akctual => $scope->{japh}->[ $scope->{cu +rr} ], }; # gives subroutine memory, also 'private' 100 + # sub's killroy 101: $GLOBAL->{H} = $persist->{akctual}; 102 103: ++$scope->{curr}; 104: my $private = {}; + # reset after each call 105: push @{ $scope->{contrib} }, $persist->{akctual}; 106:b return; 107 } >> c main::H(1.japh.pl:106): return; >> p $persist->{akctual} Another >> v 103: ++$scope->{curr}; 104: my $private = {}; + # reset after each call 105: push @{ $scope->{contrib} }, $persist->{akctual}; 106==>b return; 107 } 108 109 sub P { 110: my $scope = shift; 111: state $persist = { akctual => $scope->{japh}->[ $scope->{c +urr} ], }; # gives subroutine memory, also 'private' 112 + # sub's killroy >> c main::J(1.japh.pl:82): return; >> p $persist->{akctual} perl >> v 79: ++$scope->{curr}; 80: my $private = {}; + # reset after each call 81: push @{ $scope->{contrib} }, $persist->{akctual}; 82==>b return; 83 } 84 85 sub A { 86: my $scope = shift; 87: state $persist = { akctual => $scope->{japh}->[ $scope->{cu +rr} ], }; # gives subroutine memory, also 'private' 88 + # sub's killroy >> c main::P(1.japh.pl:118): return; >> p $persist->{akctual} Hacker, >> v 115: ++$scope->{curr}; 116: my $private = {}; + # reset after each call 117: push @{ $scope->{contrib} }, $persist->{akctual}; 118==>b return; 119 } 120 121 sub end { 122: my $scope = shift; 123: state $persist = {}; + # gives subroutine memory, also 'private' 124: my $private = {}; + # reset after each call >> c just Another perl Hacker, main::end(1.japh.pl:126): return; >> p @{$scope->{contrib}} justAnotherperlHacker, >> #save 4.seq.txt DB<14> q + $

I'm still not quite sure what all I'm looking at here, but I continue with the debugger to pick at it. Here is another source file that I found illuminating:

M b 82 c y c #save 3.2.txt
$ perl -d 1.japh.pl jesophat ... DB<1> source 3.2.txt + 1.japh.pl* 2.seq.txt 3.2.txt 4.seq.txt _Sub:: +Genius/ 1.seq.txt 3.1.txt 3.seq.txt 5.seq.txt DB<1> source 3.2.txt >> M 'FLAT.pm' => '1.0.4 from /usr/local/share/perl/5.30.0/FLAT.pm' 'FLAT/DFA.pm' => '/usr/local/share/perl/5.30.0/FLAT/DFA.pm' 'FLAT/DFA/Minimal.pm' => '/usr/local/share/perl/5.30.0/FLAT/DFA/Minima +l.pm' 'FLAT/FA.pm' => '/usr/local/share/perl/5.30.0/FLAT/FA.pm' 'FLAT/NFA.pm' => '/usr/local/share/perl/5.30.0/FLAT/NFA.pm' 'FLAT/PFA.pm' => '/usr/local/share/perl/5.30.0/FLAT/PFA.pm' 'FLAT/Regex.pm' => '/usr/local/share/perl/5.30.0/FLAT/Regex.pm' 'FLAT/Regex/Op.pm' => '/usr/local/share/perl/5.30.0/FLAT/Regex/Op.pm' 'FLAT/Regex/Parser.pm' => '/usr/local/share/perl/5.30.0/FLAT/Regex/Par +ser.pm' 'FLAT/Regex/WithExtraOps.pm' => '/usr/local/share/perl/5.30.0/FLAT/Reg +ex/WithExtraOps.pm' 'FLAT/Symbol.pm' => '/usr/local/share/perl/5.30.0/FLAT/Symbol.pm' 'FLAT/Symbol/Regex.pm' => '/usr/local/share/perl/5.30.0/FLAT/Symbol/Re +gex.pm' 'FLAT/Transition.pm' => '/usr/local/share/perl/5.30.0/FLAT/Transition. +pm' 'FLAT/Transition/Simple.pm' => '/usr/local/share/perl/5.30.0/FLAT/Tran +sition/Simple.pm' >> b 82 >> c plan: "begin A P J H end" <<< Execute: main::J(1.japh.pl:82): return; >> y $GLOBAL = HASH(0x557b5132e420) 'A' => 'just' 'J' => 'perl' 'P' => 'Another' $persist = HASH(0x557b5251d3b8) 'akctual' => 'perl' $private = HASH(0x557b5251d298) empty hash $scope = HASH(0x557b524e0fd8) 'contrib' => ARRAY(0x557b5132e3d8) 0 'just' 1 'Another' 2 'perl' 'curr' => 3 'japh' => ARRAY(0x557b510bec80) 0 'just' 1 'Another' 2 'perl' 3 'Hacker,' $sq = Sub::Genius=HASH(0x557b5214ad38) 'DFA' => FLAT::DFA=HASH(0x557b524d2410) 'ALPHA' => HASH(0x557b524e1a28) 'A' => 8 'H' => 8 'J' => 8 'P' => 8 'begin' => 1 'end' => 1 'preplan' => '[begin]([J]&[A]&[P]&[H])[end]' 'preprocess' => 1 >> c just Another perl Hacker, ... actual contributions of each sub ... H() => Hacker, P() => Another A() => just J() => perl Debugged program terminated. Use q to quit or R to restart,

It helps for me to see the notation at different stages. Also, I can quickly get to the documentation in the sources, which was excellent. You don't know what FLAT is until you do:

$ perldoc /usr/local/share/perl/5.30.0/Sub/Genius.pm $ perldoc /usr/local/share/perl/5.30.0/FLAT.pm $ perldoc /usr/local/share/perl/5.30.0/FLAT/DFA.pm

Other things I tried to grapple with, but struggled with notation, like Thompson%27s_construction. I did stumble on this, and it seems to address a lot of this history: 2007 article on regex performance. Perl compares unfavorably, and it was refuted in Re: Perl regexp matching is slow??. grinder gives an example that avoids greedy matching.

Q2.a) Is it best to avoid greedy matching unless you need it?

Q2.b) Would any of the 'no' pragmata close this performance loophole?

I thought the joke that perl was "an OS in need of a better programming language" was funny. I have one final question about the thing that keeps me in perl right now, the debugger:

Q3) Is there a term for the files one saves from debugging sessions, that is the files that are accessed using the source command?

Thanks to presenters. I've seen several and might need half a year to see them all. I appreciate your service. Thanks also for comments,


In reply to a look at Sub::Genius with the debugger, and use v in 2021 by Aldebaran

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (3)
As of 2024-04-19 01:29 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found