Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LAST phaser fires for some loops that never ran #5517

Open
sorpigal opened this issue Jan 24, 2024 · 1 comment
Open

LAST phaser fires for some loops that never ran #5517

sorpigal opened this issue Jan 24, 2024 · 1 comment
Labels
Fixed in RakuAST This issue has been fixed in RakuAST tests committed

Comments

@sorpigal
Copy link

The Problem

While experimenting with loop phasers I found that the LAST phaser will fire for at least some loops when FIRST did not fire and indeed the loop was never entered.

The phaser documentation at https://github.com/Raku/doc/blob/main/doc/Language/phasers.rakudoc says this about loop phasers:

FIRST {...} # at loop initialization time, before any ENTER
NEXT {...} # at loop continuation time, before any LEAVE
LAST {...} # at loop termination time, after any LEAVE

It also says this about LAST:

Runs when a loop is finished because the condition is met, or when it exits
using last or return; it is executed after LEAVE.

For a loop where the condition is never met, or where there is no condition, this implies that LAST will not fire.

Suspiciously, there is no test case for LAST at https://github.com/Raku/roast/tree/master/S04-phasers where the tests for FIRST/ENTER/LEAVE are found.

Expected Behavior

The behavior of the for and while loops should match in terms of what phasers fire when the loop is never entered. Either LAST should fire for both, or for neither. A plain reading of the documentation suggests that "neither" is correct. For the loop case you could argue that the condition is met because the test must have evaluated to False once, but it seems more logical to never run LAST if the loop body executed zero times.

If the current behavior is intended then I will re-file this as a documentation issue so it can become more clear that LAST will fire in this case, and why.

Actual Behavior

The LAST phaser fired even though the loop was never run (and no matching FIRST phaser fired).

Steps to Reproduce

Expected:

$ raku -e "my @a; for () { FIRST @a.push: 'first'; ENTER @a.push: 'enter'; NEXT @a.push: 'next'; LEAVE @a.push: 'leave'; LAST @a.push: 'last'; }; @a.say"
[]

Unexpected:

$ raku -e "my @a; while () { FIRST @a.push: 'first'; ENTER @a.push: 'enter'; NEXT @a.push: 'next'; LEAVE @a.push: 'leave'; LAST @a.push: 'last'; }; @a.say"
[last]

$ raku -e "my @a; loop (;False;) { FIRST @a.push: 'first'; ENTER @a.push: 'enter'; NEXT @a.push: 'next'; LEAVE @a.push: 'leave'; LAST @a.push: 'last'; }; @a.say"
[last]
@lizmat lizmat added the Fixed in RakuAST This issue has been fixed in RakuAST label Jan 24, 2024
@lizmat
Copy link
Contributor

lizmat commented Jan 24, 2024

It looks like these issues have been fixed in RakuAST.

@lizmat lizmat added the tests needed Issue is generally resolved but tests were not written yet label Jan 24, 2024
@ab5tract ab5tract added tests committed and removed tests needed Issue is generally resolved but tests were not written yet labels May 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Fixed in RakuAST This issue has been fixed in RakuAST tests committed
Projects
None yet
Development

No branches or pull requests

3 participants