Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris

new keyword "size" to avoid scalar trap ? ( scalar @array != scalar(LIST) )

by LanX (Bishop)
on Dec 07, 2012 at 16:40 UTC ( #1007787=perlmeditation: print w/replies, xml ) Need Help??


I'm meditating if Perl should introduce an explicit keyword size (or count ¹) always return the number of elements of lists and arrays... (length is already taken and scalar is to overloaden)


size @a := scalar @a;


size (a..c) := scalar @{[a..c]}

I know "explicit is better than implicit" is more a Python dogma, but since even popes still fall into the scalar trap we should maybe consider "another way to do it" (best Perl tradition =).

Cheers Rolf

PS: I tried to provide an example implementation of size, something like

sub size([@$];@) { ... }

but was to lazy to fiddle around with prototypes.

Anyway IMHO a reliable implementation will need more parsing magic than prototypes can bring to avoid disambiguation.

¹) or whatever

Replies are listed 'Best First'.
Re: new keyword "size" to avoid scalar trap ? ( scalar @array != scalar(LIST) )
by tobyink (Abbot) on Dec 07, 2012 at 16:51 UTC

    Do you even need prototypes?

    use 5.010; sub size { @_ + 0 } say size 'a' .. 'z'; my @foo = (1, 2, 3); say size @foo;
    perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
      hmm good point...

      you are forcing everything into an array,


      sub size { scalar @_ }
      is easier to read.

      it's like explicitly wrapping lists and arrays into scalar @{[ ... ]}

      But w/o prototypes this would mean to copy huge arrays around...

      And something like size %hash couldn't be extended to find scalar keys %hash.

      Anyway your example fits as a proof of concept! =)

      (But an efficient implementation should be done in XS. Edit: see benchmark)

      Cheers Rolf

        Inline::C allows a pretty fast implementation...

        use 5.010; use Benchmark qw(cmpthese); use Inline C => <<'INLINE'; int count1 (SV* name1, ...) { Inline_Stack_Vars; return Inline_Stack_Items; } INLINE sub count2 { scalar @_ } sub count3 { 0 + @_ } sub count4 { my $_ = @_ } sub count5 (\@) { scalar @{$_[0]} } my @array = 'a'..'z'; my %implementations = ( count1 => sub { count1(@array) }, count2 => sub { count2(@array) }, count3 => sub { count3(@array) }, count4 => sub { count4(@array) }, count5 => sub { count5(@array) }, ); for my $i (sort keys %implementations) { say $i, ": ", $implementations{$i}->(); } cmpthese(250_000, \%implementations);

        XS may well allow faster still.

        perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
Re: new keyword "size" to avoid scalar trap ? ( scalar @array != scalar(LIST) )
by moritz (Cardinal) on Dec 07, 2012 at 17:06 UTC

    size is a terrible name, because it doesn't imply any unit. It could stand for string length in characters, string length in bytes, used memory, number of allocated elements in a container, number of actual elements in a container or any other size you can think of.

    It makes sense to you now because it's not too bad in the mental context you are in, but from the outside it's not good.

    Anyway, if you don't fiddle with prototypes at all, the argument list of a subroutine is automatically in list context, so you can just write

    sub elems { scalar @_ }

    and don't need a new keyword at all.

      I care less about the name than the functionality, could be also "count" or whatever suits.

      I suppose "elems" is already known from ruby or perl6? So why not.¹

      But² tobyinks and your suggestion w/o prototypes is considerably slower on large arrays.

      DB<106> use Time::HiRes qw(time) DB<107> sub elems { scalar @_ } DB<108> @a=(1..1e6);0 DB<109> $t=time; $count = scalar @a; print time-$t 7.10487365722656e-05 DB<110> $t=time; $count = elems @a; print time-$t 0.0554749965667725

      Perl 5.10!

      Cheers Rolf

      ¹) Well the plural in "elems" somehow indicates a list to be returned.

      ²) as already said

        It is most probably the copying of the argument list (the full array) in the function call that takes this time difference.

        Passing a reference to the array would probably solve the issue, but the syntax would become less obvious to use.

Re: new keyword "size" to avoid scalar trap ? ( scalar @array != scalar(LIST) )
by roboticus (Chancellor) on Dec 07, 2012 at 17:05 UTC


    With the scalar operator and arrays evaluating to their length in scalar contect, I don't see a need for it. But if someone decided to change perl to do something like this, I'd rather see them overload length to accept a hash, array or reference to a hash or array.


    When your only tool is a hammer, all problems look like your thumb.

      > I don't see a need for it.

      Honestly, did you immediately spot the problem in BUK's code?

      Re: Idiom to return 0 or random number of array elements


      Do you really prefer explaining goatse "op"  =()= and turtle "op" @{[ ]} to newbes who simply need to count the elements a function returns?


      > I'd rather see them overload length to accept a hash, array or reference to a hash or array.

      Then it's quite impossible to tell what length ($str) is supposed to return. 1 for the list-size or the char-size of $str?

      Cheers Rolf


        No, I didn't notice the error. And I've never used goatse, turtle or kite. Perhaps if I had, I'd see the need for it.

        As far as the practicality of what length $str is supposed to return, I didn't give it much thought. I was just expressing my color preference for new new shed out back. ;^)


        When your only tool is a hammer, all problems look like your thumb.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlmeditation [id://1007787]
Front-paged by Arunbear
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (2)
As of 2018-07-21 06:26 GMT
Find Nodes?
    Voting Booth?
    It has been suggested to rename Perl 6 in order to boost its marketing potential. Which name would you prefer?

    Results (444 votes). Check out past polls.