I guess this is for Arraq:
Threadpool has been deprecated, but it's such a clever and handy api.
It allows me to write something like this:
proc move*(hypothetical:Hypothetic,dice:openArray[int]):Move =
var flowMoves:seq[FlowVar[Move]]
for pieceNr,fromSquare in hypothetical.pieces:
if fromSquare != 0 or hypothetical.cash >= piecePrice:
for die in dice:
flowMoves.add spawn hypothetical.bestMove(pieceNr,fromSquare,die)
flowMoves.mapIt(^it).sortedByIt(it.eval)[^1]
It's so concise and imminently readable - in perfect Nim fashion.
Is it really not possible to preserve this api?
import malebolgia, malebolgia / ticketlocks
proc move*(hypothetical:Hypothetic,dice:openArray[int]):Move =
var flowMoves = initTicketLock[seq[Move]]()
var m = createMaster()
m.awaitAll:
for pieceNr,fromSquare in hypothetical.pieces:
if fromSquare != 0 or hypothetical.cash >= piecePrice:
for die in dice:
m.spawn hypothetical.bestMove(pieceNr, fromSquare, die, flowMoves)
unprotected flowMoves as fm:
fm.sortedByIt(it.eval)[^1]
It's not so bad, is it.
Why do you think Malebolgia is 'very very bad' compared to thredpool ?
Because it doesn't have an intuitive bone in its body...
Hyperbole, but I can see where you're coming from.
Thanks - so any chance for a rescue attempt?
No, but it has much to do with "when can I pass a slice of an array (on the stack) to a thread (without a copy) safely and easily".
Structured concurrency has even more benefits in Nim's context than in Java's and you can read about Java's in the document I linked.
What do you mean? nim-taskpools and Malebolgia already exist.
If you can live with a parallel ("awaitAll") block or similar, std / threadpool can be revived.
What do you mean?
I don't know what I mean anymore. I tried this though:
import taskpools,cpuinfo
template taskPoolsAs(pool,codeBlock:untyped) =
var pool = Taskpool.new(num_threads = countProcessors())
codeBlock
pool.syncAll
pool.shutdown
proc move*(hypothetical:Hypothetic,dice:openArray[int]):Move =
taskPoolsAs tp:
var flowMoves:seq[FlowVar[Move]]
for pieceNr,fromSquare in hypothetical.pieces:
if fromSquare != 0 or hypothetical.cash >= piecePrice:
for i in dice.low..dice.high:
flowMoves.add tp.spawn hypothetical.bestMove(pieceNr,fromSquare,dice[i])
result = flowMoves.map(it => sync it).sortedByIt(it.eval)[^1]
It works, but it feels shaky:
I cannot use: for die in die:
because die becomes void - I suspect the macro
Also I receive a host of warnings and hints from the compiler, such as:
D:\Nim\nim-2.0.6\lib\std\isolation.nim(29, 13) Warning: `=destroy`(dest.value) can raise an unlisted exception: Exception [Effect]
C:\Users\perni\.nimble\pkgs2\taskpools-0.0.4-e43c5170d4e9ef1b27dd0956ffa0db46f992f9a6\taskpools\channels_spsc_single.nim(52, 1) Hint: 'tryRecv' cannot raise 'AssertionDefect' [XCannotRaiseY]
C:\Users\perni\.nimble\pkgs2\taskpools-0.0.4-e43c5170d4e9ef1b27dd0956ffa0db46f992f9a6\taskpools\channels_spsc_single.nim(68, 1) Hint: 'trySend' cannot raise 'AssertionDefect' [XCannotRaiseY]