Rand Stats




When a for loop meets a given statement

use Slang::Forgiven;

# `$num` as well as `$_` are available in the loop body
forgiven [2, -3, 4, -5] -> $num {
    # `$_` is aliased to `$num`, so `when` will know
    when * > 0 { put "$num is positive" }
    when * < 0 { put "$num is negative" }
    default    { put "neutral" }


A for loop with a parametrized block lets you iterate over things with names, and a given statement allows for topicalization. The "forgiven" statement does both: you have the usual looping but also have $_ available.

That is,

for @values -> $val {
    given $val {
        when * > 0 { "$val is positive" }

is possible as

forgiven @values -> $val {
    when * > 0 { "$val is positive" }

i.e., it's as if $_ := $val is placed immediately after the opening curly bracket. Arrays, Hashes, their destructuring, optional and/or typed parameters are possible, too; examples for them can be found in the "t/" directory.


"For fun" should be enough but this also came up in at least 2 places:

I thank "habere-et-dispertire" for the idea; this arose from their message(s). They informed me that "deoac" on exercism had mentioned it originally; so thanks to them as well! I also thank Damian Conway for their for-else writing (as well as the numerous presentations online that leave me amazed).


Grammar follows that of the "for" loop. Actions first gather the parameter names of the block of the loop, and then unshift the $_ := ... statement (a "bind" QAST::Op) to the AST of the statement list of the block.


Using pakku:

git clone https://github.com/mustafaaydn/Slang-Forgiven.git && cd "$(basename "$_" .git)"
pakku add . && cd .. && rm -rf Slang-Forgiven