4
\$\begingroup\$

So i was trying to find sum of an array using 3 ways in perl6

  • for
  • while
  • recursive

(I know there are inbuilt perl6 functions for this)

I want to know if there is a better way to do this or is this it?

sub sumFor(@list)
{
   my $sum = 0;
   for (@list)
   {
      $sum += $_;
   }
   return $sum;
}


sub sumWhile(@list)
{
   my $sum = 0;
   my $index = 0;
   while ($index < @list.elems)
   {
      $sum += @list[$index++];
   }
   return $sum;
}

sub sumRec(@list, $index = 0)
{
   my $sum = 0;
   if ($index < @list.elems)
   {
      $sum = @list[$index] + sumRec(@list,$index+1);
   }
   return $sum;
}

my @list = 1,2,3,4;

say sumFor(@list);
say sumWhile(@list);
say sumRec(@list);
\$\endgroup\$
  • \$\begingroup\$ And do you have any particular concerns about these 3 versions to be reviewed? \$\endgroup\$ – πάντα ῥεῖ Jan 8 '17 at 17:47
  • \$\begingroup\$ "I want to know if there is a better way to do this or is this it?" Do you want to know which is the best out of these 3 ways, or getting a completely different solution? Your question is still unclear for me. \$\endgroup\$ – πάντα ῥεῖ Jan 8 '17 at 18:05
  • \$\begingroup\$ These are programs written for learning, i don't want a comparison between functions or performance review, rather a general review which looks into usage of language features \$\endgroup\$ – tejas Jan 8 '17 at 18:29
5
\$\begingroup\$

You may already know the following Perl 6 tidbits, but for others reading along:

  • The ordinary OO way to express the sum of a list of numbers in a variable list is list.sum;

  • The ordinary functional way to express the same thing is sum list;

  • A less common functional idiom that produces the same result is [+] list which is a reduction.

Imo your code is fine. That said:

Parentheses are frequently optional

Larry often pipes up about what he calls "superstitious parens". More generally I think there's a rough consensus among Perl 6 folk that readability for most folk is best served by omitting optional parentheses when the meaning remains clear without them. This is almost always true around conditional expressions. I generally omit them around argument lists too. If I were writing the code you've written I'd likely have dropped seven pairs of "superstitious parens" thus:

sub sumFor(@list)
{
   my $sum = 0;
   for @list
   {
      $sum += $_;
   }
   return $sum;
}

sub sumWhile(@list)
{
   my $sum = 0;
   my $index = 0;
   while $index < @list.elems
   {
      $sum += @list[$index++];
   }
   return $sum;
}

sub sumRec(@list, $index = 0)
{
   my $sum = 0;
   if $index < @list.elems
   {
      $sum = @list[$index] + sumRec @list,$index+1;
   }
   return $sum;
}

my @list = 1,2,3,4;

say sumFor @list;
say sumWhile @list;
say sumRec @list;

Sigils are frequently optional

I don't know of any emerging consensus about use of sigil'd variables vs non-sigil'd variables but you can slash sigils like this:

sub sumRec(\list, \index = 0)
{
   my $sum = 0;
   if index < list.elems
   {
      $sum = list[index] + sumRec(list,index+1);
   }
   return $sum;
}

Stronger typing

Most built in operations accept arguments of a wide range of types and automatically coerce them to fit the operation. This highly generic approach is considered a strength. Thus, for example:

say sum '21', '21'; # 42

This genericity is the default in Perl 6 code. But sometimes you may prefer to explicitly specify types. Thus, perhaps:

subset NumericList of List where .all ~~ Numeric;

sub sumFor(NumericList \list )
{
   my $sum = 0;
   for list
   {
      $sum += $_;
   }
   return $sum;
}

my \list = 1,2,3,4,'a';
say sumFor list; # "Constraint type check failed..."
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.