Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

Slice Madness

by japhy (Canon)
on Nov 09, 2005 at 15:14 UTC ( #507091=perlmeditation: print w/ replies, xml ) Need Help??

Someone on #freenode::perl just asked if $array[2..4] would return a list of elements. Their mistake was the '$' instead of a '@', but I opened a can of worms by saying that the code as shown would return $array[0] or $array[1], but I couldn't know which.

Then I said that $array[2..4] behaves differently from ($x,$y) = (2,4); $array[$x..$y]. Just for kicks, I post this here. Who knows why the two behave differently?

# given: my @array = qw( A B C ); my ($x, $y, $z) = (0, 1, 2); # explain: $array[0..1] $array[0..2] $array[1..2] $array[$x..$y] $array[$x..$z] $array[$y..$z] $array[$z..$x]
Hint here:

Jeff japhy Pinyan, P.L., P.M., P.O.D, X.S.: Perl, regex, and perl hacker
How can we ever be the sold short or the cheated, we who for every service have long ago been overpaid? ~~ Meister Eckhart

Comment on Slice Madness
Select or Download Code
Re: Slice Madness
by duff (Vicar) on Nov 09, 2005 at 15:51 UTC

    Nice one japhy but I think you give too much of a hint in your first paragraph :-)

    This is another one of those nodes that I wish I could ++ more

Re: Slice Madness
by itub (Priest) on Nov 09, 2005 at 16:32 UTC
Re: Slice Madness
by pg (Canon) on Nov 09, 2005 at 18:11 UTC

    Doesn't matter whether your explanation is precise. If one uses warnings (like everyone says here), there are plenty of warnings to make one think whether things are right:

    use Data::Dumper; use strict; use warnings; my @array = qw( A B C ); my ($x, $y, $z) = (0, 1, 2); my @a = $array[0..1]; print Dumper(\@a); @a = $array[$x..$y]; print Dumper(\@a);

    Which gives:

    Use of uninitialized value in range (or flip) at math1.pl line 8. Use of uninitialized value in range (or flop) at math1.pl line 8. $VAR1 = [ 'B' ]; Argument "" isn't numeric in array element at math1.pl line 10. $VAR1 = [ 'A' ];

    With all the warnings, one starts to fix things:

    use Data::Dumper; use strict; use warnings; my @array = qw( A B C ); my ($x, $y, $z) = (0, 1, 2); my @a = @array[0..1]; print Dumper(\@a); @a = @array[$x..$y]; print Dumper(\@a);

    Which gives the slice one wanted:

    $VAR1 = [ 'A', 'B' ]; $VAR1 = [ 'A', 'B' ];
      Glad to see that. I was wishing this was a syntax error, but at least it's a warning.
Re: Slice Madness
by Anonymous Monk on Nov 09, 2005 at 18:39 UTC
    *sigh*

    Why do we have to have nasty things like this in our language? :-(

    From perlop: Binary ".." is the range operator, which is really two different operators depending on the context. (emphasis mine)

    I always felt this was a point of needless confusion in perl. If the operator is really two operators, why not create two operators? Just make a range operator (array context only), and a flip flop operator (scalar context only), and report an error if the wrong one is used in the wrong context? That would eliminate this kind of error altogether, and make life easier to all concerned.

    Wouldn't that have been wiser? Is it too late to fix it? Will Perl6 have the same mistake?

    Me, I don't like the flip-flop operator; I didn't understand it when I first ran across it, and now that I do, I still prefer to write my conditionals more verbosely. But I'd put up with it to appease the sed people (if the are any left), and create a range operator (or function), rather than deal with this kind of ugliness for newcomers (or for me when I'm sick, overtired, or called into work in the middle of the night).

    Even a function called "range" that returned a list from the first argument to the last argument would probably do.

    Given that I can write this:

    @range = $x .. $y; @slice = @x[ @range ];
    it shouldn't be that much more confusing to write this:
    @range = range($x,$y); @slice = @x[ @range ];
    and leave the .. for the flip flop.

    Just a thought... --
    Ytrew

      I just had this exact same thought in Ruby terms today. The idea of the flip-flop operator is ... well ... dumb. It's syntactic sugar that's overloading a rather useful operator (the range) and should be banned. IMNSHO, of course.

      My criteria for good software:
      1. Does it work?
      2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?
      "Why do we have to have nasty things like this in our language?"

      Exactly, to be rude, Perl has too much shit in its syntax.

        Perl has too much shit in its syntax

        I think we can all agree that it has a lot of shit in its syntax. Whether it's too much is debatable. There's a balance between keeping things concise and letting them get too confusing. It's pretty obvious that Perl is more heavily weighted towards concise syntax than most languages. In some cases, it's quite far out of balance. But overall, my experience tells me the balance isn't completely shot.

        Well, to actually answer the question rather than cheerleading, it should be pointed out that Perl 1 was intended to be an improvement over sed and awk, and both those languages had a flipflop operator that was spelled with a comma, of all things! Switching to .. for that was (at the time) an improvement in clarity. But that was 18 years ago. It's certainly not a decision I'd make now, which is of course why Perl 6 has different shit in its syntax. :-)
      Yes, it's fixed in Perl 6. In fact, it's already fixed in Pugs:

          pugs> say ~(1..10)
          1 2 3 4 5 6 7 8 9 10

      But your solution is bad Huffman coding. Range objects are much more useful than flipflops, and therefore should get the .. operator.
        Yes, it's fixed in Perl 6. In fact, it's already fixed in Pugs:

        Yay! Three cheers for fixing stuff! :-)

        But your solution is bad Huffman coding. Range objects are much more useful than flipflops, and therefore should get the .. operator.

        Either way works for me; I was trying to be charitable to the opposing position. :-) I'll always prefer the solution that lets me keep my favourite syntax (i.e. the range operator), but I didn't know if there were a ton of hidden ex-sed and awk lurkers out there ready to gripe at me if I suggested the range operator be used instead. :-)
        --
        Ytrew

      Perl got where it is via evolution*. Evolution begets cruft. It strikes me as particularly ivory-tower-minded of people to wring their hands over these little throwbacks, particularly considering that Perl was never intended to be elegant. I trust you know where to find Ruby.

      It's not like this thing is something that's constantly tripping people up and making Perl painful to use. It's more of a wart that adds some amusing character. Yes, it's a flaw. What is there to do about it? Break backward-compatibility? That would be a worse flaw. And that's why evolution begets cruft.

      *You were thinking maybe intelligent design?


      Caution: Contents may have been coded under pressure.

        Ruby is much perfect as we Japaness are made for perfection. We are made to lead the world to its perfection even it means pain to our own nation and people.

        You were thinking maybe intelligent design?

        Yup! Larry certainly designed most of Perl intelligently enough. In some ways, it makes the areas where he didn't more jarring, because they're unexpected, and thus confusing. And by the way, thanks, Larry! :-)

        It's a small nit, but the nits add up. The more of them we can clean up, the better.

        Yes, it's a flaw. What is there to do about it? Break backward-compatibility? That would be a worse flaw.

        Yup. It doesn't have to be a flaw: we can deprecate the feature, like we've done in the past.

        Just add a warning like: "$x .. $y better written as flip_flop($x,$y)" for flip flops. Put in an explanation that flip flops must be written explictly so that they're not confused with the range operator, and in a few years, we could remove the feature entirely.

        Remember, effort at development time is easy. Until the program is put in production, it can be changed without impacting end users. Effort at mainenance time is hard; any change to the program will have to be analysed for it's impact on the end users. Fixing bugs is easy; finding bugs is hard. Giving the users one less bug is worth it, IMHO.

        --
        Ytrew

Re: Slice Madness
by Animator (Hermit) on Nov 09, 2005 at 18:46 UTC

    I think you didn't wrote backwards compatible code...

    Running something that uses these statements on v5.6.1 produces a different result then running the same thing on v5.8.7...

    It returns this on v5.6.1:

Re: Slice Madness
by Aristotle (Chancellor) on Nov 10, 2005 at 03:26 UTC

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlmeditation [id://507091]
Approved by broquaint
Front-paged by sauoq
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (6)
As of 2014-08-22 00:39 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The best computer themed movie is:











    Results (145 votes), past polls