Posso paralelizar a execução usando o Hyper e funciona:
$ raku -e 'race for (^8).race(batch => 1, degree => 4) {sleep rand; .say}'
0
3
5
2
1
7
4
6
Mas como posso adicionar comportamento gather/take a esse loop?
Nessa abordagem, take não detectará que está encapsulado no contexto gather:
$ raku -e '
my @x = gather race for (^8).race(batch => 1, degree => 4) {
sleep rand;
take $_;
};
@x.say
'
Died at:
take without gather
Nessa abordagem, o gather consumirá o HyperSeq sem realmente "hiper" sobre ele:
$ raku -e '
my @x = race gather for (^8).race(batch => 1, degree => 4) {
sleep rand;
take $_;
};
@x.say
'
[0 1 2 3 4 5 6 7]
O que você está pedindo, por baixo dos panos, é uma estrutura de dados paralelizada (nesse caso, o contêiner para os resultados de gather/take) que proteja as operações de gravação de vários threads. Embora a sintaxe do raku não impeça uma implementação como essa, ela não visa tornar as estruturas de dados padrão atômicas, pois isso adiciona uma sobrecarga substancial e potencial para deadlocks. Nesse tipo de requisito, o raku tem uma ótima sintaxe de simultaneidade que ajudará você a mapear/reduzir seus cálculos em vários processos.
Veja a nota na parte inferior da documentação do gather take que menciona um problema semelhante com react/whenever, ou seja, que não há um manipulador para a exceção de controle nos novos threads. Por exemplo:
Mas somente às terças-feiras. Imagino que você já saiba essa primeira parte da minha resposta, mas o compilador tem permissão para decidir se deve paralelizar. Para citar incorretamente, mas de forma justa, o documento de design relevante com minha ênfase adicional :
----
Citando o documento de design novamente:
Ou seja, usar
race
significa que você já obtém automaticamente o comportamentogather
/take
de graça, sem realmente ter que usargather
/take
.----
Não sei bem o que fazer com esses dois cenários.
----
Em sua resposta a Quais mecanismos de simultaneidade são fornecidos pelo Raku ...? , Jonathan Worthington menciona isto sobre
gather
/take
:Não tenho certeza sobre o parêntesis. Não consigo analisar "This isn't of in any context developing", e a última parte da frase parece ambígua.
----
Uma coisa que me chamou a atenção é que
gather
/take
é default para lazy . O uso derace
should substitui isso e o torna eager , mas pensei comigo mesmo que o Rakudo poderia plausivelmente ter um bug que o deixava lazy e me perguntei se o comportamento lazy estava levando ao comportamento visto no seurace gather ...
código. No entanto, tentei inserir um expliciteager
onde pensei que poderia ser necessário e nada do que tentei fez diferença.