develooper Front page | perl.perl6.users | Postings from December 2021

Re: Subscripting, semicolons, and adverbs

Thread Previous | Thread Next
From:
Sean McAfee
Date:
December 11, 2021 21:30
Subject:
Re: Subscripting, semicolons, and adverbs
Message ID:
CANan03b2mYYmctftz_vY=zeXfq3C10hbxMgX1qo1Cwo1KqZdSA@mail.gmail.com
On Sat, Dec 11, 2021 at 11:28 AM Ralph Mellor <ralphdjmellor@gmail.com>
wrote:

> On Fri, Dec 10, 2021 at 9:49 PM Sean McAfee <eefacm@gmail.com> wrote:
> >
> > @array[-1]:exists is a syntax error, even though it looks like
> > it should just evaluate to True.
>
> In Raku `foo[-N]` is invalid. At compile-time if N is statically
> known, otherwise at run-time.
>

It's not, though, if certain adverbs such as :exists are present, as in my
original message.

> @array[-1]:exists  <-- compile time error

> my $i = -1; @array[$i]:exists  <-- evaluates to False

To me it appears that the first case should also evaluate to False, but
that the compiler is trying to aggressively catch negative-indexing errors
without considering whether any adverbs are present that might make the
expression sensible.

Another example is the :v adverb.  I was recently delighted to discover
that I could easily have a sliding window over an array, where the window
might hang over either end of the array.

> my @a = <a b c d e>
[a b c d e]
> say @a[^3 + $_]:v for -2 .. 4
(a)
(a b)
(a b c)
(b c d)
(c d e)
(d e)
(e)

But anyway, my original use case was driven by a desire to simplify a
routine similar to the following.  Given a 2-D array and an x- and
y-coordinate, I want to increment the number at the given coordinates, but
only if the coordinates are valid.  My first effort went like this:

sub increment(@array, $x, $y) {
    ++@array[$y][$x] if 0 <= $y < @array && 0 <= $x < @array[$y];
}

Then I remembered semicolon subscripting and :exists, and tried changing
the body of the routine to this:

    ++@array[$y; $x] if @array[$y; $x]:exists;

I thought that was a vast improvement; let Raku figure out if the indices
are valid!  But while it does work--that is, I get the right answers at the
end--it results in a slew of "unhandled Failure detected in DESTROY"
warnings.  I haven't observed this ever happening when using :exists with a
single index, only with subscripts that use semicolons.  So for now, I'm
getting by with:

    ++@array[$y; $x] if @array[$y]:exists and @array[$y][$x]:exists;

[snipped a bunch of comments about the pitfalls of using negative numbers
to index from the end of arrays, with which I am in total agreement]

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About