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

Re^6: A short whishlist of Perl5 improvements leaping to Perl7

by LanX (Saint)
on Nov 25, 2020 at 14:10 UTC ( [id://11124196]=note: print w/replies, xml ) Need Help??


in reply to Re^5: A short whishlist of Perl5 improvements leaping to Perl7
in thread A short whishlist of Perl5 improvements leaping to Perl7

I'm not sure why rtoa has to be in the closure.

you can mimic your semantic in Python by using a generator function acting as closure, defining a nested function roman_to_dec and returning it.

I don't have Python installed and am not a Py expert, so please accept my semantically equal Perl interpolation.

(untested)

sub generator { my %rtoa = ( M=>1000, D=>500, C=>100, L=>50, X=>10, V=>5, I=>1 ); my $c_nested = sub { reduce { $a+$b-$a%$b*2 } map { $rtoa{$_} } split//, uc(sh +ift); }; return $c_nested; } *roman_to_dec = generator();

NB: This will look much easier in Python because it's automatically dereferencing.

UPDATE

I suppose most Pythonistas would rather prefer making rtoa a class variable and using roman_to_dec as a method. TIMTOWTDI. ;-)

Cheers Rolf
(addicted to the Perl Programming Language :)
Wikisyntax for the Monastery

Replies are listed 'Best First'.
Re^7: A short whishlist of Perl5 improvements leaping to Perl7 (Python TMTOWTDI)
by eyepopslikeamosquito (Archbishop) on Nov 26, 2020 at 06:46 UTC

    I suppose most Pythonistas would rather prefer making rtoa a class variable and using roman_to_dec as a method. TIMTOWTDI. ;-)
    Ha ha! Yes, despite the Zen of Python aiming for "There should be one -- and preferably only one—obvious way to do it" I could not help but notice when playing code golf in multiple languages that Python sometimes out-TMTOWTDI-ed them all! Also, without TMTOWTDI code golf is no fun at all and, surprisingly, code golf is way more popular in Python than Perl nowadays.

    The TMTOWTDI examples below were taken from:

    Consider how to create a "Dear John" string in each of the four languages:

    "Dear $name" # Perl and PHP "Dear %s" % expr # Python and Ruby % printf-like operator "Dear {0}".format(expr) # Python format string method "Dear "+`expr` # Python backticks (TMTOWTDI) "Dear #{expr}" # Ruby string interpolation "Dear @{[expr]}" # Perl "Baby Cart" string interpolation

    Curiously, Python is the only member of the gang of four languages to allow you to reverse the order of the two string multiply operands:

    5 * "X" also produces "XXXXX" in Python! TMTOWTDI! :) 5 * "X" ... but not in Ruby (won't compile: type error) 5 x "X" ... or Perl (produces empty string)
    That is, the string multiply operator is commutative in Python, but not in Perl or Ruby. This language idiosyncrasy makes string multiply based solutions most attractive in Python. To illustrate, note these code snippets from my string multiply based solutions to this game:
    $"x(318%$_/9) Perl " "*(318%i/9) Ruby 318%i/9*" " Python
    This is a very rare example of Python out-golfing both Perl and Ruby.

    From my early 195-stroke function-based Python solution:

    n=99 z=lambda:`n or 99`+" bottle"+"s of beer on the wall"[n==1:] while n:y=z();n-=1;print"%s, %s.\n"*2%(y,y[:-12],n and"Take one down a +nd pass it around"or"Go to the store and buy some more",z())
    notice the expression:
    n and"Take one down and pass it around"or"Go to the store and buy some + more"
    Shortening the two strings above to "Take" and "Go to" for clarity, let's consider the many and varied ways of doing this in Python (TMTOWTDI):
    "Take"if n else"Go to" (n>0)*"Take"or"Go to" ["Go to","Take"][n>0] ("Go to","Take")[n>0] n and"Take"or"Go to" "GToa kteo"[n>0::2] # "Slice and Dice" wins this golf!
    As you can see, I missed the winning Python "Slice and Dice" tactical trick in this game.

Re^7: A short whishlist of Perl5 improvements leaping to Perl7
by eyepopslikeamosquito (Archbishop) on Nov 28, 2020 at 08:24 UTC

    I'm not sure why rtoa has to be in the closure.
    Just realised it doesn't thanks to the introduction of state variables in perl v5.10.
    use v5.10; use strict; use warnings; use List::Util qw(reduce); sub roman_to_dec { state %rtoa = ( M=>1000, D=>500, C=>100, L=>50, X=>10, V=>5, I=>1 ); reduce { $a+$b-$a%$b*2 } map { $rtoa{$_} } split//, uc(shift); } my @testdata = ( "XLII", "LXIX", "mi" ); for my $r (@testdata) { print "$r: ", roman_to_dec($r), "\n"; }

      I don't like state in named subroutines. It makes it hard to reïnitialise the variable and causes hard to debug problems. An anonymous sub is OK, because the state variable is reïnitialised every time the sub is created.

      But in this particular case, it's not highly probable you'd ever need to reïnitialise the variable. But, if you plan to convert from different digit systems, you'll quickly see why state is not the solution.

      map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
      > > I'm not sure why rtoa has to be in the closure.

      I should have been clearer... I don't understand why you didn't go the easy way of defining my %rtoa either on file or function scope. No problem translating this to python.

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery

        I don't understand why you didn't go the easy way of defining my %rtoa either on file or function scope.
        Though that was easier, I am pedantic and just couldn't bring myself to do it:
        1. I didn't want %rtoa at file scope because other functions in the same file have no business knowing about its existence - it is a roman_to_dec() implementation detail after all and I should be able to later change the implementation of this function with complete confidence that doing so cannot possibly break other functions in the same file ... which is why I originally created the bare block, solely to hide %rtoa from other functions in the same file.
        2. I didn't want my %rtoa at function scope because it is gratuitously inefficient to (unnecessarily) initialise %rtoa each and every time the function is called (it is a constant after all). More importantly, expressing that %rtoa is const and is used only by roman_to_dec aids code clarity (BTW, I miss C++'s const keyword when coding in Perl).
        BTW, it seems to me that state variables were added to perl expressly to solve the above two concerns.

        Update: Re the rationale for introducing state variables, found a quote from Larry himself in Re: About "state" variables in Perl 5.10:

        However, that difference is not why we introduced state variables. The big win is the psychological one of not having to look outside of the sub to find the definition of $x. (That, and we wanted it as a primitive in Perl 6 so that people could write stateful macro constructs without forcing the user to define the state variable externally; in fact, we also use it ourselves in order to implement the stateful flipflop operator without having to build the flipflop in as a primitive, as it is in Perl 5.)

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others surveying the Monastery: (6)
As of 2024-03-28 19:52 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found