Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw


( #480=superdoc: print w/replies, xml ) Need Help??

If you've discovered something amazing about Perl that you just need to share with everyone, this is the right place.

This section is also used for non-question discussions about Perl, and for any discussions that are not specifically programming related. For example, if you want to share or discuss opinions on hacker culture, the job market, or Perl 6 development, this is the place. (Note, however, that discussions about the PerlMonks web site belong in PerlMonks Discussion.)

Meditations is sometimes used as a sounding-board — a place to post initial drafts of perl tutorials, code modules, book reviews, articles, quizzes, etc. — so that the author can benefit from the collective insight of the monks before publishing the finished item to its proper place (be it Tutorials, Cool Uses for Perl, Reviews, or whatever). If you do this, it is generally considered appropriate to prefix your node title with "RFC:" (for "request for comments").

User Meditations
The war against Perl, by random wikipedia editors
2 direct replies — Read more / Contribute
by Anonymous Monk
on Aug 23, 2018 at 22:13
    For many years Perl was part of the Model–view–controller page at wikipedia. At some point the Catalyst and Maypole links were quietly deleted and now everything except Perl gets a nod. This is not an isolated incident.

    Of course anyone can edit wikipedia: Let's put Perl back on the map!

Perl as mobile language
3 direct replies — Read more / Contribute
by aartist
on Aug 23, 2018 at 14:09
    I was looking at Language Comparison 2018 and see that Perl is missing in the list of 'mobile' languages. Is there any chance of mobile development with Perl ? Or why not?
Recap: The Future of Perl 5
10 direct replies — Read more / Contribute
by Ovid
on Aug 23, 2018 at 09:03

    Recently in The Future of Perl 5, there was a discussion of my keynote at the Glasgow Perl Conference. Rather than wade into that thread, I thought I should provide a brief explanation of what I was trying to achieve: a modest proposal (er, pardon that description) that was achievable, still Perl, and would not only return the conciseness of the language but would also allow Perl 5 to leapfrog many popular dynamic languages in terms of functionality (I'll skip the Perl 6 discussion and the inline discussion). This isn't a large-scale strategy to "fix everything", but a couple of small (ha!) steps which would make Perl much easier to write and maintain in large companies.

    Perl has a long, strong history. Unfortunately, because Perl was the trail-blazer for many techniques taken for granted today, it sometimes went down dead-ends and those who followed learned from Perl. Perl also stole much from other languages and it's time to steal a bit more. Consider, for example, the lowly Fibonacci function. It would be natural to write it like this:

    sub fib { my $nth = shift; return $nth if $nth <= 1; return fib( $nth - 1 ) + fib( $nth - 2 ); }

    That looks like a perfectly natural way to write that function and if you pass it expected values, it returns expected results (we'll ignore the performance and memory issues as those aren't unique to Perl 5). But what if you pass it a -2? Or an undefined value? Or a string? Or a float? Or a typeglob? Or, or, or ...

    At, we're used to working with large clients and large codebases and that sort of coding trips us up many times. It's hard building a large system, slinging data around left and write (er, "right"), without hitting these problems. In terms of maintenance, it's a nightmare. For short scripts, it's ok. When you're trying to build large-scale systems, it's a constant drag on developer time, even with tests (because you have to spend time and money to write tests to verify you've correctly handled what the language itself handles in many other languages). To write a robust Fibonacci function, you might write something like this:

    sub fib { croak("…") if @_ != 1; my $nth = $_[0]; croak("…") if not defined $nth; croak("…") if $nth !~ /^+?\d+$/a; return $nth if $nth <= 1; return fib( $nth - 1 ) + fib( $nth - 2 ); }

    But let's be honest: almost nobody does that and if you did, you'd be spending more time and money on something you often don't have to spend time and money on in other languages.

You've gotta have tests!
4 direct replies — Read more / Contribute
by talexb
on Aug 23, 2018 at 01:11

    I've been building an ecosystem of scripts for a client over the last few months, and recently I needed to make use of some functionality I'd left in place in one of my modules. Before starting development, I checked to see how the module tests were laid out, in order to give me more insight into how the module works, since I wrote it a few months ago.

    Then I discovered there were no tests.

    Narrator: A vague sense of unease flitted through the developer's mind, but he resolutely shrugged it off.

    OK, no problem -- I'd just write the tests, as it was a fairly simple module.

    Narrator: But it wasn't as simple as he imagined it to be.

    After writing the tests, I came to the realization that the way I'd written the module meant it wasn't as extensible as I originally thought. And tests might have revealed that shortcoming.

    So I spent some development time more clearly defining what I wanted to module to do, how it should be called, and made changes in one of the scripts that use the module. And found some more issues.

    Narrator: Several cups of coffee later ..

    The good news is that I now have a module that works the way I need it to, complete with tests that show that it works correctly. All of the scripts that use this module have been updated. And tomorrow I can start work on the feature that uses this improvement.

    But the moral of the story remains: It doesn't matter how simple a module is. As soon as you decided you'd put some logic into a module -- that's the point that you should have also written the tests that prove that the module's logic is correct. There's not no excuse for skipping that part.

    You've gotta have tests!

    Update: Minor edit: not -> no in second to last paragraph.

    Alex / talexb / Toronto

    Thanks PJ. We owe you so much. Groklaw -- RIP -- 2003 to 2013.

The Future of Perl 5
7 direct replies — Read more / Contribute
by Laurent_R
on Aug 18, 2018 at 09:17
    Yesterday, for the last day of The Perl Conference (formerly known as YAPC) in Glasgow, Scotland, Curtis "Ovid" Poe delivered a very inspiring keynote address on the future of Perl.

    Ovid's idea was to imagine where Perl 5 would stand in ten years from now.

    These are some of the things Perl would have in 10 years in Ovid's vision:

    As an example for the first point above, consider the following subroutine:
    sub fibonacci { my $n = shift; return 1 if $n == 1 or $n == 0; return fibonacci($n-1) + fibonacci($n-2); }
    This subroutine should work correctly if the subroutine is called with a positive integer, but a number of things could go wrong: what will happen if no parameter is passed to the subroutine? or if the parameter is a negative integer, say -3? or if the parameter is a positive number but not an integer, e.g. 3.14? or if the parameter is not a number but a string? (Note that there would also be a problem with a large integer, but that's a different story.)

    For the above subroutine to be correct, you would need to add probably half a dozen boiler plate code lines to guard against invalid input, for example maybe something like this:

    sub fibonacci { die "..." unless defined $_[0]; my $n = shift; die "..." unless is_a_number($n); # the is_a_number function is to + be defined die "..." if $n < 0; die "..." if $n != int $n; # ... }

    With (non experimental) function signatures and proper typing, all you would need might just boil down to something like:

    sub fibonacci (PositiveInt $n) { return 1 if $n <= 1; return fibonacci($n-1) + fibonacci($n-2); }
    I think this would look quite cleaner.

    I hope the video of Ovid's talk will on-line soon.

    Comments are welcome.

    Update (Aug 23): ovid created a new meditation explaining his views with some details here: Recap: The Future of Perl 5.

RFC: A DSL for SQL (part 1)
No replies — Read more | Post response
by LanX
on Aug 17, 2018 at 18:10

    this is just a rough hack demonstrating a proof of concept for a "SQL::DSL".

    (and a general pattern for designing complex domain specific languages)

    I'm currently refactoring it out into clean sub-modules but wanted to show something already.

    The demonstrated ideas here are already sufficiently complex to discuss.

    (The implementation of named operators like BETWEEN and a JOIN mechanism are subject of threads to come)

    given this input:

    my ($user, $workhrs0, $geo0, $workhrs1, $geo1) = ('NWIGER', '20', 'ASIA', '50', 'EURO'); query { package Table; WHERE ( ANDS ( user == $user, ORS ( ANDS ( workhrs > $workhrs0 , geo == 20 ), ORS ( $workhrs1 < workhrs, geo == $geo1 ) ) ) ); };

    will the function query return an AST (abstract syntax tree) of nested "SQL::DSL" objects, which can be rendered into a target dialect like MySQL, Oracle ... (or maybe even SQL::Abstract or DBIx code ).

    Some basic ideas are:

    • SQL-Tables (here "Table") are realized as packages
    • These packages are limited to the scope of the surrounding code-block such that no namespace pollution occurs (a common problem with DSLs)
    • The Columns (here user) are realized as constants in this namespace returning "SQL::DSL::Column" objects
    • The operators are overloaded for Column objects and return "SQL::DSL::Operator" objects with nested Operand objects
    • Literal operands (like 20) are identified because they are readonly
    • Variable operands are identified and can be replaced by ? placeholders at render-time
    • actual values of the placeholders can be captured as variable references from the closure-vars and can be bound to the DBI->execute() later
    • "higher order" operations on nested operations just return the nested objects in a higher blessed container augmenting the AST
    • the rendering happens by walking the generated AST and calling a render methods on the encountered objects
    • the whole algorithm might look slow but we only need to run it once and memoize the result for later executions.
    Here the steps in the middle:

    === B::Deparse of the Code: { package Table; use warnings; use strict; use feature 'say'; WHERE(ANDS(user() == $user, ORS(ANDS(workhrs() > $workhrs0, geo() +== 20), ORS($workhrs1 < workhrs(), geo() == $geo1)))); } at d:/Users/lanx/vm_share/perl/Talks/DSL/2018_GPW/exp/SQL_abstract.p +l line 51. === Tidy of deparsed Perl-code: { package Table; use warnings; use strict; use feature 'say'; WHERE( ANDS( user() == $user, ORS( ANDS( workhrs() > $workhrs0, geo() == 20 ), ORS( $workhrs1 < workhrs(), geo() == $geo1 ) ) ) ); } === Abstract Syntax Tree (simplified): :'WHERE' is ::Clause :'ANDS' is ::Joiner :'=' is ::Infix :'user' is ::Column :'NWIGER' is ::Placeholder ["\n ", "NWIGER"] :'ORS' is ::Joiner :'ANDS' is ::Joiner :'>' is ::Infix :'workhrs' is ::Column :'20' is ::Placeholder ["\n ", 20] :'=' is ::Infix :'geo' is ::Column :'20' is SCALAR :'ORS' is ::Joiner :'<' is ::Infix :'50' is ::Placeholder ["\n ", 50] :'workhrs' is ::Column :'=' is ::Infix :'geo' is ::Column :'EURO' is ::Placeholder ["\n ", "EURO"] === Produced SQL: WHERE ( user = ? AND ( ( workhrs > ? AND geo = 20 ) OR ( ? < workhrs OR geo = ? ) ) ) at d:/Users/lanx/vm_share/perl/Talks/DSL/2018_GPW/exp/SQL_abstr line 59.

    here the code

    Any comments so far? :)

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

Does Go steal from Perl? :-)
3 direct replies — Read more / Contribute
by reisinge
on Aug 03, 2018 at 04:28

    I've started to read The Go Programming Language. I have come across this example code:

    // Dup1 prints the text of each line that appears more than // once in the standard input, preceded by its count. package main import ( "bufio" "fmt" "os" ) func main() { counts := make(map[string]int) input := bufio.NewScanner(os.Stdin) for input.Scan() { counts[input.Text()]++ } // NOTE: ignoring potential errors from input.Err() for line, n := range counts { if n > 1 { fmt.Printf("%d\t%s\n", n, line) } } }

    The counts[input.Text()]++ construct looks pretty familiar, like a hash autovivification in Perl. Was this idea taken from Perl and put into Go?

    Leave no stone unturned. -- Euripides
RIP Win 10
2 direct replies — Read more / Contribute
by (anonymized user)
on Jul 30, 2018 at 11:01
    17 years ago I erased Windows from my home environment owing to the relative richness of multimedia applications available from planet CCRMA (for Fedora linux). Indeed, at that time, the best open source DVD ripper was written in Perl and intended mainly for linux.

    Then, seven years later, certain annoying office-related circumstances drove me back to using Windows XP at home. When that got unsupported I skipped the detestable Windows 7 and upgraded to 8. I lived with that thru 10 until recently.

    What happened next was that something went wrong in the April 2018 upgrade which didn't even hit my Win 10 until July -- whataver had been happening to delay windows upgrade is not related to the next bug I suffered: it wouldn't run windows updates because of old SIDs in the registry that did not match any users. But when these were removed (I had to carefully check the valid SIDs and edit the registry), it refused to log in because some typically nasty MS programming was linking these old SIDs to the PIN and password details instead of the new SIDs created by the upgrade. Too late to create a backup admin logon and my project (carefully backed up elsewhere) was ready to migrate to linux (as previously planned), so it was enough reason, relative to faint counter-argument, once again to banish windows from my home computers.

    You only live twice, Mister Gates...

    One world, one people

RFC: Inline::Blocks or inline as a keyword?
4 direct replies — Read more / Contribute
by shmem
on Jul 30, 2018 at 02:26

    Some days ago, Ovid on the perl5porters mailing list asked under the subject "inline keyword?"

    I know people have tried to inline Perl subs before but with little success. Instead of going down that road, have we ever considered an inline keyword where the developer says what can be inlined?

    There have been only a few answers, most off the point (mine included in the latter).

    I haven't considered inlining of subroutines as do blocks at all up to now, and whipped up some benchmark code to prove Ovids point.

    That's pretty impresssive. But the inlined subroutine consists of just one integer division.

    Experimenting further, I found that adding seven reciprocals as 1 / $_; to the plain sub set it in par with the sub subroutine. This means that the overhead of calling a subroutine against plain inlined code is that of seven integer divisions. With heavily used small subs, inlining gives the most benefit in performance; the percentage drops as those subs get more complex, but inlining can be a significant performance boost.

    What do you think? Should we have an inline keyword in Perl?

    Or should we delegate that to a module?

    Making inline into a Perl keyword proper would mean giving it an opcode, cloning of optrees and injecting them at the places where an inlined subroutine is called. Leaving it to a module would mean source filtering.

    Thinking about it, inlining subroutines isn't anything special to the language. It is just duplicating code - for some reason - all over the place, something you don't want to do statically for the sake of DRY (Don't Repeate Yourself) and avoiding a maintenance nightmare. So you want to leave that to some mechanism at compile time, let the computer do it, and don't have the results in the source code.

    Since implementing inline as a keyword proper is much more difficult than whipping up a source filter, I decided to do the latter, and for being lazy.

    Before you go O Noes, another source filter module o_O - that's brittle, evil eval etc think about that: the whole perl source code relies on a source code filter named C pre-processor. All perl C source code is shoven through the preprocessor prior to compilation. If preprocessing fails, there's no compilation; cpp doesn't prove whether it produces valid C code, but fails within its own rules. Validating the procuded code is a task of the compiler.

    The same applies for Perl source filters. The fact that the source filter is invoked in the compile phase doesn't change that, that is just how perl works - it switches between parsing, compiling and runtime in the compile phase (think BEGIN blocks and use), so there's nothing special about it.

    Source filters have their merits. For instance, IO::All is a wonderful tool in my box, and I use it where appropriate.

    After that long preamble providing the rationale and defense for the perpetration, here's the module.

    update: edited according to tobyinks remarks below. The match variables are no longer package globals, and overridable via import parameters.

    Using this module, the following

    use Inline::Blocks; inline sub capitalize_next; print uppercaseIncrementAsString('a'..'f'), "\n"; sub uppercaseIncrementAsString { my @l = @_; my $ret; $ret .= capitalize_next($_) for @l; $ret; } sub capitalize_next { my ($thing) = @_; uc inline increase($thing); } sub increase { my ($foo) = @_; ++$foo; }

    results (via B::Deparse) in

    use Inline::Blocks; print uppercaseIncrementAsString(('a', 'b', 'c', 'd', 'e', 'f')), "\n" +; sub uppercaseIncrementAsString { my(@l) = @_; my $ret; $ret .= do { my($thing) = $_; uc do { my($foo) = $thing; ++$foo } } foreach (@l); $ret; } sub capitalize_next { my($thing) = @_; uc do { my($foo) = $thing; ++$foo }; } sub increase { my($foo) = @_; ++$foo; }

    What do you think? does that suffice or should we have an inline keyword? Apart of answers to that question, critics are welcome, improvements also, e.g. for the regexps in the regexp variables, their names etc.

    perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'
use Memoize;
2 direct replies — Read more / Contribute
by Anonymous Monk
on Jul 16, 2018 at 15:18
    I was porting a script to a module and noticed it kept getting slower. The script could initialize its expensive data structure once at the top and be done with it, but in order to encapsulate, the module was calling the function several times. I remembered the core module Memoize and added one line to the top of the program and now it runs fast again, 4x faster than without Memoize!
    use Memoize; memoize('some_sub');
    Only 1.5 seconds to start a program that was taking 6 seconds!
Find the shortest word in the English Language with: a b c d e f
9 direct replies — Read more / Contribute
by usemodperl
on Jul 03, 2018 at 20:41
    Edit: Not going to edit this node because of replies but Eily noticed there is an extra single quote at the end of my port :-/

    This recent post in r/programming poses an interesting question for a bit of golf: "What is the shortest word in the English Language which contains: a b c d e f?" Some Junk™ code was posted to figure this out and my Perl version is a bit shorter. I know you perl better than me, if you do, and can see how else to do this:

    The Junk Code:
    sorted([w.strip() for w in open('/usr/share/dict/words', 'r').readline +s() if set(list('abcdef')).issubset(set(list(w.strip())))], key=lambda x: +len(x))
    My Perl Port:
    open$:,"</usr/share/dict/words";while(<$:>){next unless/(?=.*a)(?=.*b) +(?=.*c)(?=.*d)(?=.*e)(?=.*f)/i;push@_,$_}@_=sort{length$a<=>length$b} +@_'

    For your convenience:

    Print the list:
    open$:,"</usr/share/dict/words";while(<$:>){next unless/(?=.*a)(?=.*b) +(?=.*c)(?=.*d)(?=.*e)(?=.*f)/i;push@_,$_}print for sort{length$a<=>le +ngth$b}@_
    Print the word:
    open$:,"</usr/share/dict/words";while(<$:>){next unless/(?=.*a)(?=.*b) +(?=.*c)(?=.*d)(?=.*e)(?=.*f)/i;push@_,$_}for(sort{length$a<=>length$b +}@_){print;last}
    Compare length of Perl to Junk:
    #!/usr/bin/perl -lw use strict; my $PERL = <<'PERL'; open$:,"</usr/share/dict/words";while(<$:>){next unless/(?=.*a)(?=.*b) +(?=.*c)(?= .*d)(?=.*e)(?=.*f)/i;push@_,$_}@_=sort{length$a<=>length$b}@_' PERL { no strict; $JUNK = <<JUNK; sorted([w.strip() for w in open('/usr/share/dict/words', 'r').readline +s() if set(list('abcdef')).issubset(set(list(w.strip())))], key=lambda x: +len(x)) JUNK print length $PERL, ' PERL: ', $PERL; print length $JUNK, ' JUNK: ', $JUNK; } # I think junk could lose 4 spaces making it 148. __END__ PERL: 144 JUNK: 152
    Of course different versions of dict give different results...

Avoiding perl's Atof when assigning floating point values
5 direct replies — Read more / Contribute
by syphilis
on Jun 28, 2018 at 21:35

    Most perls assign floating point values using perl's internal Atof function - and that includes perls that define "Perl_strtod".
    But Perl's Atof function is notoriously incorrect, and a far better alternative IMO is to have floats assigned using Perl_strtod, which is just a wrapper around C's strtod() or strtold() or strtoflt128() - whichever is appropriate for the particular perl's nvtype.

    First up, I should point out that -Dusequadmath builds (ie builds for which $Config{nvtype} reports "__float128") already use Perl_strtod(), with the result that the __float128 values are assigned correctly, in my experience on Ubuntu-16.04. (By "correctly", I mean rounded to nearest, ties to even.)

    But when perl's nvtype is "double" or "long double", then values are being assigned using perl's Atof function and there's a fair chance that values are being assigned incorrectly.
    The magnitude of Atof's inaccuracies is not particularly large - mostly it's only 1 unit of least precision (ULP). But it can be as large as 7 ULP when nvtype is "double" and and as large as 54 ULP when nvtype is the extended precision "long double".
    (The figures of "7" and "54" are the largest I've found, having tested millions of random values - and those 2 numbers turn up often enough.)
    The actual likelihood of striking inaccuracies with Atof depends upon the exponent range that you're working in. If the exponent is in the range (say) -10 to 10 the likelihood of an incorrect assignment is about 10%.
    But when I randomly select values across the full exponent range, I'm finding that the chances of an incorrect assignment rise to around 97% for "doubles" and 82% for "long doubles".
    When I hack the perl source to use Perl_strtod, the chances of an incorrect assignment become 0. (Ok ... I haven't checked every value ... but I've not yet found a value that has been incorrectly assigned by Perl_strtod on Ubuntu.)

    It turns out that using Perl_strtod instead of perl's Atof is very easy to implement. We just need to open up numeric.c in the top level perl source folder, replace (the one occurrence of) "strtoflt128" with "Perl_strtod", replace every occurrence of "USE_QUADMATH" with "Perl_strtod", and rebuild perl.
    The actual patch (for perl-5.28.0 source) can be downloaded from my scratchpad.

    UPDATE: Better to grab this patch because:
    a) it's a portable patch for both mingw-w64 built Windows perl && Linux perl;
    b) at some time I'll probably clear my scratchpad.

    That's about it. If your perl's nvtype is "__float128" or your build of perl doesn't define "Perl_strtod", then applying the patch will not change anything.
    Otherwise, however, if you build perl using the patched numeric.c then perl will assign floating point values using Perl_strtod instead of perl's Atof.

    It's very much the same story on MS Windows wrt to mingw-w64 builds of perl whose nvtype is "double", where exactly the same patch makes equally dramatic improvements to the assigning of floating point values.
    Sadly, however, for "long doubles" on Windows, there's and that complicate matters.
    And there's also an issue wrt to strtold's assigning of some subnormal long double values - for which I've yet to submit a bug report.
    (More about Windows at a later date.)

    Here's the script I use to check $ARGV[1] randomly selected values within a specified exponent range (-$ARGV[0] to +$ARGV[0]).
    # # Test a range of values for # correctness of assignment use strict; use warnings; use Math::MPFR qw(:mpfr); die "Upgrade to Math-MPFR-4.03" unless $Math::MPFR::VERSION >= 4.03; die "Usage: perl maximum_exponent how_many_values" unless @ARGV == 2; $|++; my $display = 0; while($display !~ /^y/i && $display !~ /^n/i) { print("Do you want mismatched values to be displayed ? [y|n]: \n"); $display = <STDIN>; } $display = 0 if $display =~ /n/i; my($mant, $exp, $perl_unpacked, $mpfr_unpacked, $str_value); my($count, $diff, $max_diff, $min_diff) = (0, 0, 0, 0); my $max_exp = $ARGV[0]; $max_exp++; # $workspace is the Math::MPFR object to which # the value being tested is assigned. # Here we set the precision of $workspace to the # same number of bits as perl's NV. my $workspace = Rmpfr_init2($Math::MPFR::BITS); my $failed = 0; my($perl_nv, $mpfr_nv); for(;;) { $count++; $mant = int(rand(10)) . '.' . int(rand(10)) . int(rand(10)) . int(rand(10)) . int(rand(10)) . int(rand(10)) . int(rand(10)) . int(rand(10)) . int(rand(10)) ; $exp = int(rand($max_exp)); $exp = "-$exp" if $count % 2; $str_value = $mant . "e$exp"; # Assign $str_value to $mpfr_nv using mpfr $mpfr_nv = atonv($workspace, $str_value); # Assign $str_value to $perl_nv using perl $perl_nv = "$str_value" + 0; # $mpfr_nv and $perl_nv should be exactly equivalent. # Else atleast one of mpfr and perl has assigned incorrectly. # IME, mpfr does not assign incorrectly. unless($perl_nv == $mpfr_nv) { $failed++; $perl_unpacked = scalar reverse unpack "h*", pack "F<", $perl_nv; $mpfr_unpacked = scalar reverse unpack "h*", pack "F<", $mpfr_nv; print "$str_value: $mpfr_nv:\n $perl_unpacked vs $mpfr_unpacked\n\ +n" if $display; $diff = hex(substr($perl_unpacked, -8, 8)) - hex(substr($mpfr_unpa +cked, -8, 8)); if($diff > $max_diff) { $max_diff = $diff; } elsif($diff < $min_diff) { $min_diff = $diff; } } last if $count == $ARGV[1]; } print "Count: $count\n"; print "Failed: $failed\n"; print "Largest differences were $max_diff ULPs and $min_diff ULPs\n"; print "Failed: $failed\n"; print "Largest differences were $max_diff ULPs and $min_diff ULPs\n";
    It requires Math-MPFR-4.03. If you want to test values in the subnormal range, you should build Math::MPFR against mpfr-4.0.x as earlier versions of mpfr were buggy in their calculation of subnormals.
    As a starter, run perl 300 100, opting to display mismatches, and see how that fares.
    Whenever I run that command against a patched perl-5.28.0, 0 mismatches are detected, irrespective of perl's nvtype.
    Whenever I run that command against an unpatched perl-5.28.0, about 80 failures are detected unless, of course, nvtype is "__float128" - in which case no failures still occur.

    There's probably not many who would bother, but I certainly intend to continue building perl with this hack in place.

    UPDATE: For the record, gcc version on my Ubuntu box is 5.4.0, and libc version is 2.23

Why did you become a Perl expert (or programmer)?
12 direct replies — Read more / Contribute
by QM
on Jun 25, 2018 at 05:23
    Prompted by this comic at Commit Strip.

    Me? (Not that I'm an expert.) Because Perl was handy, extremely useful, and didn't require a separate compile phase. Because I could solve other people's problems with it. Because it was general purpose, and not specifically geared for stream picking / editing. Because it was free. Because it was more fun than any other language I knew at the time.

    Quantum Mechanics: The dreams stuff is made of

The CPAN Apocalypse: June 25, 2018
4 direct replies — Read more / Contribute
by usemodperl
on Jun 19, 2018 at 16:06
    I wonder what will happen the day goes away, and the day after. One more week and we will know! Does Perlmonks get flooded with identical questions? Does FUD gleefully announcing the death of Perl and CPAN make the rounds?? Do those redirects work???

Review of CGI::Alternatives
11 direct replies — Read more / Contribute
by Anonymous Monk
on Jun 09, 2018 at 11:44
    CGI::Alternatives is a module that "doesn't do anything"1 except vehemently deny and propogandize against the utility of one of the most useful forms of programming EVER conceived: CGI2 programming.

    CGI::Alternatives perpetuates all the common fallicies against CGI that if heeded only disempower independent developers. This includes advocating the replacement of all of Perl's wonderful and extremely simple, stable, mature, powerful CGI modules with vastly more byzantine "frameworks"1 which rigidly enforce all sorts of corporate nonsense like "full separation of concerns"1, total object-oriented lack of any possible function-ality, and the absurd complication of allowing oneself to be used by something as annoyingly totalitarian as templates1 EVEN when they're not appropriate! All of these techniques have their place of course, mostly in big projects, with lots of tiny modules (to confuse management, ensure job stability, in competitive workplaces, stretching hours into months, for the children), but not usually in code written by us individuals for fun, prototyping, and extreme levels of pure: results.3

    With all due respect to the author's efforts to change how we Perl into something his bosses find acceptable, the author of CGI::Alternatives is actually in charge of! How is this even possible? I realize the author is a talented programmer who has contributed significantly to CPAN, but this quote directly reflects his inappropriate state of mind towards the CGI paradigm (while is derided with that weird novelty-obsessed bigotry for being "old", as he removes perfectly sensible functions, only to prove his pointless point):

    "You can't just hand a template to the web-designers and allow them to work their magic. Don't mix the business logic and the presentation layer. Just don't."

    This guy doesn't even know what a CGI programmer does yet he dictates to us? This is CRAZY! We ARE the web-designers, OF the business logic, AND the presentation layer--ALL mixed together--like a SWISS ARMY CHAINSAW: this is our TECHINQUE! THIS IS Perl! Something YOU (Lee) obviously don't understand. Mixing it all up is exactly how some other language(s) seized the web from Perl (along with plenty of well-funded corporate FUD). Even though we still do it far better.

    We have been here from the beginning and we remain no matter how many of our tools you try to disable or how much FUD you spread about our primordially awesome technique of producing ONE UNIFIED FILE, USING CORE MODULES, QUITE OFTEN VASTLY SUPERIOR TO FRAGMENTED TEMPLATES, WRITTEN BY ONE PERL GENIUS, RATHER THAN A TEAM OF HOPELESSLY ABSTRACTED CORPORATE DRONES: Because Larry wrote and maintains Perl that way; Blessed be.

    How dare you tell us to stop doing what we love and what Perl empowers us to do? How dare you remove the HTML generation functions from Who do you think you are anyway? People who come to Perl and say things have got to change don't appreciate Perl and should be led as far away from Perl as possible (Python), not in charge of (formerly, unfortunately) core modules!

    Can someone who cares please take away from Lee Johnson (LEEJO)? I would feel far more comfortable with someone we can trust, like ikegami or Merlyn3, in charge of maintaining At least we know they would give us what we want and need, and more, rather than inflicting torture by removing legacy functionality FOR EMOTIONAL REASONS thereby violating operational stability.

    News for you Lee: What worked 20 years ago still works today: UNIX, POSIX, BASH, PERL, ME, AND MAYBE EVEN YOU. Mature technology never stops working! I appreciate innovation so don't necessarily stop trying to reinvent the wheel, but please do stop trying to shove your shiny new wheels in sheep's clothing down our throats because PERL ALREADY WON.4

    If we stopped wasting time and spirit listening to ideologically driven flame warrior infiltrators who keep trying to change Perl we would already have a perfectly backward compatible and "fixed" (even though it has never failed me to this very day thank you Lincoln Stein5) on the corelist joined by other bits we desperately need and use EVERY SINGLE DAY like CGI::Carp, Data::Dumper and File::Slurp.

    Some examples:

    This extremely useful one-line CGI dubugger is now broken thanks to LEEJO (thanks!):

    print header('text/plain'), Dumper $data; exit;

    This is never ever going away:

    start_html now reduces efficiency by 100%!:

    '</body></html>' end_html # removed from, for ideological anti-reasons

    If you agree PLEASE respond! If you do NOT agree please DO NOT hijack the thread because you guys already kinda won and I hope this thread can be for CGI programmers to chime in and support this seemingly lost cause which is really not even close to lost in the real non-ideological world of actual programmers who GET STUFF DONE.


    1. CGI::Alternatives

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

  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?

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

    How do I use this? | Other CB clients
    Other Users?
    Others surveying the Monastery: (4)
    As of 2018-12-10 02:37 GMT
    Find Nodes?
      Voting Booth?
      How many stories does it take before you've heard them all?

      Results (47 votes). Check out past polls.

      • (Sep 10, 2018 at 22:53 UTC) Welcome new users!