I know almost nothing about functonal programing, but I think that you would gain some insight from looking at how functional programing languages handle threads and recurson.
Consider the cannonical example of qsort in Haskell:
quicksort :: (Ord a) => [a] -> [a]
quicksort  = 
quicksort (x:xs) =
let smallerSorted = quicksort [a | a <- xs, a <= x]
biggerSorted = quicksort [a | a <- xs, a > x]
in smallerSorted ++ [x] ++ biggerSorted
The way I read that code, the list get split into those elements larger than the pivot and those smaller than the pivot. Each list is recursively sorted, and the Haskell runtime is free to do those two sorts in parallel.