Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is "await do" in Perl 6?

Tags:

raku

I see the following code in Perl 6:

await do for @files -> $file {
    start {
       #do something ...    }
}

which runs in async mode. Why does the above code need do? What is the purpose of do in Perl 6? Could someone please explain the above code in detail?

Also is there are an option to write something like this:

for @files -> $file {
    start {
       #do something ...    }
}

and await after the code for the promises to be fulfilled?

like image 698
smith Avatar asked Nov 23 '16 10:11

smith


1 Answers

The purpose of do

The for keyword can be used in two different ways:

1) As a stand-alone block statement:

for 1..5 { say $_ }

2) As a statement modifier appended to the end of a statement:

say $_ for 1..5;

When the bare for keyword is encountered in the middle of a larger statement, it is interpreted as that second form.

If you want to use the block form inside a larger statement (e.g. as the argument to the await function), you have to prefix it with do to tell the parser that you're starting a block statement here, and want its return value.

More generally, do makes sure that what follows it is parsed using the same rules it would be parsed as if it were its own statement, and causes it to provide a return value. It thus allows us to use any statement as an expression inside a larger statement. do if, do while, etc. all work the same way.


Explanation of your code

The code you showed...

await do for @files -> $file {
    start {
       #do somthing ...    }
}

...does the following:

  • It loops of over the array @files.
  • For each iteration, it uses the start keyword to schedule an asynchronous task, which presumably does something with the current element $file. (The $*SCHEDULER variable decides how the task is actually started; by default it uses a simple thread pool scheduler.)
  • Each invocation of start immediately returns a Promise that will be updated when the asynchronous task has completed.
  • The do for collects a sequence of all the return values of the loop body (i.e. the promises).
  • The await function accepts this sequence as its argument, and waits until all the promises have completed.

How to "await after the code"

Not entirely sure what you mean here. If you want to remember the promises but not await them just jet, simply store them in an array:

my @promises = do for @files -> $file {
    start {
       #do something ...    }
}

#other code ...

await @promises;

There is no convenience functionality for awaiting all scheduled/running tasks. You always have to keep track of the promises.

like image 79
smls Avatar answered Oct 14 '22 21:10

smls