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);
-
\$\begingroup\$ And do you have any particular concerns about these 3 versions to be reviewed? \$\endgroup\$πάντα ῥεῖ– πάντα ῥεῖ2017年01月08日 17:47:02 +00:00Commented Jan 8, 2017 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\$πάντα ῥεῖ– πάντα ῥεῖ2017年01月08日 18:05:04 +00:00Commented Jan 8, 2017 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– tejas2017年01月08日 18:29:20 +00:00Commented Jan 8, 2017 at 18:29
1 Answer 1
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
islist.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..."
Explore related questions
See similar questions with these tags.