perl6: why is array skipping calculated values inside declaration?

perl list
perl 6 tutorial
perl add to list
perl empty list
perl array
perl list variable
perl how to replace a value in array element
perl list foreach

I am learning Perl6 from Perl5.

In order to make this compile, I'll post the whole program:

sub lgamma ( Num(Real) \n --> Num ){
  use NativeCall;
  sub lgamma (num64 --> num64) is native {}
  lgamma( n )
}

sub pvalue (@a, @b) {
  if @a.elems <= 1 {
    return 1.0;
  }
  if @b.elems <= 1 {
    return 1.0;
  }
  my Rat $mean1 = @a.sum / @a.elems;
  my Rat $mean2 = @b.sum / @b.elems;
  if $mean1 == $mean2 {
    return 1.0;
  }
  my Rat $variance1 = 0.0;
  my Rat $variance2 = 0.0;

  for @a -> $i {
    $variance1 += ($mean1 - $i)**2#";" unnecessary for last statement in block
  }
  for @b -> $i {
    $variance2 += ($mean2 - $i)**2
  }
  if ($variance1 == 0 && $variance2 == 0) {
    return 1.0;
  }
  $variance1 /= (@a.elems - 1);
  $variance2 /= (@b.elems - 1);

  my $WELCH_T_STATISTIC = ($mean1-$mean2)/sqrt($variance1/@a.elems+$variance2/@b.elems);
    my $DEGREES_OF_FREEDOM = (($variance1/@a.elems+$variance2/@b.elems)**2)
    /
    (
    ($variance1*$variance1)/(@a.elems*@a.elems*(@a.elems-1))+
    ($variance2*$variance2)/(@b.elems*@b.elems*(@b.elems-1))
    );
    my $A = $DEGREES_OF_FREEDOM/2;
    my $value = $DEGREES_OF_FREEDOM/($WELCH_T_STATISTIC*$WELCH_T_STATISTIC+$DEGREES_OF_FREEDOM);
  my Num $beta = lgamma($A)+0.57236494292470009-lgamma($A+0.5);
    my Rat $acu = 10**(-15);
    my ($ai,$cx,$indx,$ns,$pp,$psq,$qq,$rx,$temp,$term,$xx);
# Check the input arguments.
    return $value if $A <= 0.0;# || $q <= 0.0;
    return $value if $value < 0.0 || 1.0 < $value;
# Special cases
    return $value if $value == 0.0 || $value == 1.0;
    $psq = $A + 0.5;
    $cx = 1.0 - $value;
    if $A < $psq * $value {
        ($xx, $cx, $pp, $qq, $indx) = ($cx, $value, 0.5, $A, 1);
    } else {
        ($xx, $pp, $qq, $indx) = ($value, $A, 0.5, 0);
    }
    $term = 1.0;
    $ai = 1.0;
    $value = 1.0;
    $ns = $qq + $cx * $psq;
  $ns = $ns.Int;
#Soper reduction formula.
    $rx = $xx / $cx;
    $temp = $qq - $ai;
    $rx = $xx if $ns == 0;
    while (True) {
        $term = $term * $temp * $rx / ( $pp + $ai );
        $value = $value + $term;
        $temp = $term.abs;
        if $temp <= $acu && $temp <= $acu * $value {
        $value = $value * ($pp * $xx.log + ($qq - 1.0) * $cx.log - $beta).exp / $pp;
        $value = 1.0 - $value if $indx;
        last;
        }
        $ai++;
        $ns--;
        if 0 <= $ns {
            $temp = $qq - $ai;
            $rx = $xx if $ns == 0;
        } else {
            $temp = $psq;
            $psq = $psq + 1.0;
        }
    }
    return $value;
}

my @array2d = ([27.5,21.0,19.0,23.6,17.0,17.9,16.9,20.1,21.9,22.6,23.1,19.6,19.0,21.7,21.4],
 [27.1,22.0,20.8,23.4,23.4,23.5,25.8,22.0,24.8,20.2,21.9,22.1,22.9,20.5,24.4],#0.

 [17.2,20.9,22.6,18.1,21.7,21.4,23.5,24.2,14.7,21.8],
 [21.5,22.8,21.0,23.0,21.6,23.6,22.5,20.7,23.4,21.8,20.7,21.7,21.5,22.5,23.6,21.5,22.5,23.5,21.5,21.8],

 [19.8,20.4,19.6,17.8,18.5,18.9,18.3,18.9,19.5,22.0],
 [28.2,26.6,20.1,23.3,25.2,22.1,17.7,27.6,20.6,13.7,23.2,17.5,20.6,18.0,23.9,21.6,24.3,20.4,24.0,13.2],

 [30.02,29.99,30.11,29.97,30.01,29.99],
 [29.89,29.93,29.72,29.98,30.02,29.98],

 [3.0,4.0,1.0,2.1],
 [490.2,340.0,433.9],

 [<1.0/15.0>, <10.0/62.0>],
 [<1.0/10>, <2/50.0>],

 [0.010268,0.000167,0.000167],
 [0.159258,0.136278,0.122389],

 [9/23.0,21/45.0,0/38.0],
 [0/44.0,42/94.0,0/22.0]);

 say @array2d[11][0];

 my @CORRECT_ANSWERS = (0.021378001462867,
 0.148841696605327,
 0.0359722710297968,
 0.090773324285671,
 0.0107515611497845,
 0.00339907162713746,
 0.52726574965384,
 0.545266866977794);

my UInt $i = 0;
my Real $error = 0.0;
for @array2d -> @left, @right {
  my $pvalue = pvalue(@left, @right);
  $error += ($pvalue - @CORRECT_ANSWERS[$i]).abs;
  say "$i [" ~ @left.join(',') ~ '] [' ~ @right ~ "] = $pvalue";
  if $error > 10**-9 {
    say "\$p = $pvalue, but should be @CORRECT_ANSWERS[$i]";
    die;
  }
#  printf("Test sets %u p-value = %.14g\n",$i+1,$pvalue);
  $i++
}

printf("the cumulative error is %g\n", $error);

What makes this sub-array different is that it has the "/" for division. How can I make Perl6 for-loop evaluate this sub-array?

EDIT: I'm struggling with what constitutes a minimal working example. I'm posting the entire code so that it will compile.

Third and final answer

.oO (He says, hopefully. Has anyone ever written four answers to an SO question?!? 🤭 )

If you swap these lines in your data:

  [<1.0/15.0>, <10.0/62.0>],
  [<1.0/10>, <2/50.0>],

  [0.010268,0.000167,0.000167],
  [0.159258,0.136278,0.122389],

to instead be the other way around:

  [0.010268,0.000167,0.000167],
  [0.159258,0.136278,0.122389],

  [<1.0/15.0>, <10.0/62.0>],
  [<1.0/10>, <2/50.0>],

then the output of your program (at least my version of it from my rewrite of your code nanswer) is:

0.159258
0 [27.5,21,19,23.6,17,17.9,16.9,20.1,21.9,22.6,23.1,19.6,19,21.7,21.4] [27.1 22 20.8 23.4 23.4 23.5 25.8 22 24.8 20.2 21.9 22.1 22.9 20.5 24.4] = 0.02137800146286709
1 [17.2,20.9,22.6,18.1,21.7,21.4,23.5,24.2,14.7,21.8] [21.5 22.8 21 23 21.6 23.6 22.5 20.7 23.4 21.8 20.7 21.7 21.5 22.5 23.6 21.5 22.5 23.5 21.5 21.8] = 0.14884169660532756
2 [19.8,20.4,19.6,17.8,18.5,18.9,18.3,18.9,19.5,22] [28.2 26.6 20.1 23.3 25.2 22.1 17.7 27.6 20.6 13.7 23.2 17.5 20.6 18 23.9 21.6 24.3 20.4 24 13.2] = 0.035972271029797116
3 [30.02,29.99,30.11,29.97,30.01,29.99] [29.89 29.93 29.72 29.98 30.02 29.98] = 0.09077332428566681
4 [3,4,1,2.1] [490.2 340 433.9] = 0.010751561149784494
5 [0.010268,0.000167,0.000167] [0.159258 0.136278 0.122389] = 0.003399071627137453
6 [1.0/15.0,10.0/62.0] [1.0/10 2/50.0] = 0.5272657496538401
7 [0.391304,0.466667,0] [0 0.446809 0] = 0.5452668669777938
the cumulative error is 5.50254e-15

In retrospect this was very obviously what was wrong. 2020 hindsight and all that. :)

Lists, sequences, and arrays, If you want to create a statement list inside parenthesis, use a sigil before the parenthesis: That way, we can skip even elements using .skip-one . Iterator role can be lazy, which means that their values are computed on demand and stored for later use. my @b := Array[Int](1, 2, 3); # Rakudo shortcut for the same code. Perl 6 is a highly capable, feature-rich programming language made for at least the next hundred years. The primary Perl 6 compiler is called Rakudo, which runs on the JVM and the MoarVM. Meta-note: double pound signs (##) are used to indicate paragraphs, while single pound signs (#) indicate notes. #=> represents the output of a command.

class Array, Adds the elements from LIST to the front of the array, modifying it in-place. By default, i.e. if no type constraint is given during declaration, the method returns (​Mu) . Index is always counted from the beginning of the list, regardless of whether the On Rakudo, 64-bit systems have a limit of 2³¹-1 and 32-bit systems have a  The scalar function is sort of a casting function that - among other things - converts an array to a scalar. Due to an arbitrary, but clever decision this conversion yields the size of the array. Loop on the indexes of an array. There are cases when looping over the values of an array is not enough.

Learn perl6 in Y Minutes, In Perl 6, you declare a lexical variable using the `my` keyword: my $variable; Here the third element # is being accessed. say "Interpolate an array using if $i == 3; # `next` skips to the next iteration, like `continue` # in other languages. only the 15 needed values will be calculated. say @numbers; #=> 0 1 2 3 4 3 9 15  An array is a variable that stores an ordered list of scalar values. Array variables are preceded by an "at" (&commat;) sign. To refer to a single element of an array, you will use the dollar sign ($) with the variable name followed by the index of the element in square brackets.

Day 18 – Sized, Typed, Shaped, In Perl 6, we do not (yet) have full-fledged support for PDL (or a PDL-like module)​, but we do have support for specific features: sized types, shaped variables (and typed arrays). Skip to content Instead, we can declare a typed array: calculate the size necessary to store the elements: we know that int,  In Excel, an Array Formula allows you to do powerful calculations on one or more value sets. The result may fit in a single cell or it may be an array. An array is just a list or range of values, but an Array Formula is a special type of formula that must be entered by pressing Ctrl + Shift + Enter.

Slurpy parameters and flattening in Raku – Andrew Shitov's Blog, Skip to content Perl 6 allows passing scalars, arrays, hashes, or objects of any other type as the There are no restrictions regarding the combination and its order in a sub declaration. the sub, and it contains only the values from the array passed in the sub call. Creating a Calculator (1); Chapter 4. Static array initialization - Initializes all elements of array during its declaration. Dynamic array initialization - The declared array is initialized some time later during execution of program. Static initialization of array. We define value of all array elements within a pair of curly braces {and } during its declaration. Values are

18. Implementing negative array subscripts in Raku – Andrew , Negative indices are not allowed in Perl 6 for a reason. see what kind of additional problems arise if you allow negative indices). [<statement><.​eat_terminator> ]* ] } What does Rakudo say when the calculated index is negative? can be accessed in the array—that call returns the required element. Stores the result of an expression as a named variable, which can then be passed as an argument to other measure expressions. Once resultant values have been calculated for a variable expression, those values do not change, even if the variable is referenced in another expression. Syntax VAR <name> = <expression> Parameters

Comments
  • First, it happens even if you do it in a simple array too. Second, it's evaluated to a Rat. That Rats happens to be printed that way if it's in an Array. If you use say, put or print it's going to be Num-ified to 0.161... Same if you declare them as part of a list. It's the same number.
  • @jjmerelo "First, it happens even if you do it in a simple array too." I've edited the question, to me it seems that with a 1D array like I've shown, it is evaluated, is this what you meant?
  • the point is that it's simply the way it's displayed. The value, when you work with it, is going to be the same. If you want it to be displayed with decimal point, simply add .Num to numify it.
  • 1.0/15.0 is exactly the same as 1/15 is exactly the same as Rat.new(1,15). I ran your code and those calculations do indeed happen. Are you calling .perl or dd? Both of which will print <1/15>, but that is because there are repeating digits.
  • Hi @con. Let me summarize my three (!!!) answers to your question. I'm "sure" my Third and final answer is right. It's just a data error. I'm hopeful my second (Rewrite) "nanswer" (not-at-answer) has some value. My first (What's wrong?) "sanswer" (answer-without-an-answer) hopefully reduces fear of Rats rather than increases it. All in all an interesting trip around the mulberry bush. As they say, it's about the journey, not the destination. :)
  • "while "thanks" comments are normally shunned, your extraordinary patience merits an exception, thank you for your patience @raiph
  • (1) Hopefully, even if it wasn't about numerics or P6, and even if you didn't like my coding style, you'll absorb something good from my other answers. (2) I searched SO for the top dozen or so languages and the word "thanks". It seems to be roughly one sixth of the total for most languages. I see a dip to about one tenth for more formal languages (eg Haskell). To my surprise, [perl6] is at this dipped level .oO ( I wonder if t correlates with questions without accepted answers. Hmm. ) Anyhoo, saying "thanks for the thanks" won't help our stats but practice makes perfect... :)
  • hi @raiph, thanks, I re-edited the question to explain that this is part of a for loop, which is skipping the sub-arrays
  • Hi @con. Your current edit doesn't compile. When I fix it to compile, including replacing func with say, it works... I suggest you consider taking a break, doing something else with P6 today, or even skipping P6 for the rest of today, then returning to this with fresh eyes tomorrow, because then it'll probably all instantly make sense to you, as these sorts of things often do... :)
  • I am having trouble coming up with a link, but I was the one who wrote the lgamma sub.
  • I thought it was on irc or a gist or somewhere else. I honestly didn't think to look here.