Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I get elements out of a hyperoperator in the original order?

Tags:

raku

I wanted to split a string into words and print each word on a separate line, so I tried the following:

"foo bar baz".words>>.say

However, the results weren't in order:

baz
foo
bar

What's wrong with this?

like image 362
Christopher Bottoms Avatar asked Dec 09 '25 06:12

Christopher Bottoms


2 Answers

Hyperoperators actually do return the results in order. The problem with your code is that hyperops aren't looping constructs; they are list operators. As such, their execution order is not guaranteed, and code that uses them as though it were is incorrect. If you care about execution order, you should use a construct like for that guarantees it.

For example, this

my @a = "foo bar baz".words>>.split("a");

results in @a containing elements in the order you expect, regardless of the order in which each element was calculated:

foo b r b z
like image 176
darch Avatar answered Dec 10 '25 19:12

darch


To quote the design docs,

A hyperoperator is one of the ways that you can promise to the optimizer that your code is parallelizable.

Other ways to do so are hyper and race, which I don't think are implemented in Rakudo.

If you do care about order of evaluation, use a a for loop, map or .map instead of hyper operators, eg

"foo bar baz".words.map(&say)

The direct equivalent of your original code using the method form of say would read

"foo bar baz".words.map(*.say)
like image 42
Christoph Avatar answered Dec 10 '25 18:12

Christoph