Sundar R
Sundar R

Reputation: 14705

Reducer for non-parallel for loops/multiline comprehensions

Julia has a parallel macro for for loops, which allows things like:

s = @sync @parallel vcat for i in 1:9
  k = iseven(i) ? i÷2 : 3i+1
  k^2
end

and since the reducer specified is vcat, we get back an array of numbers.

Is it possible to do something like this with a normal for loop (without having to explicitly initialize and push! into the array)?

Since I'm only looking to reduce using vcat, another way to ask this question is: is there a neat readable multiline form of array comprehensions? It's possible to stretch to usual comprehension syntax like this:

 s = [
       (k = iseven(i) ? i÷2 : 3i+1;
       k^2)
       for i in 1:9
       ]

but that seems messy and less readable compared to the @parallel vcat for syntax. Is there a better way of doing multiline comprehensions?

Upvotes: 2

Views: 168

Answers (2)

Gnimuc
Gnimuc

Reputation: 8566

The short answer is to write multiline functions(or do-blocks as @phg reminds) with a single line array comprehension or map/mapreduce:

s = [
       (k = iseven(i) ? i÷2 : 3i+1;
       k^2)
       for i in 1:9
       ]

This example is pure comprehension, no reducer is involved. Array comprehension is usually written in one line, for example, s = [iseven(i) ? i÷2 : 3i+1 |> x->x^2 for i in 1:9]. As @phg suggested, multi-line functions can be enclosed in a do-block:

julia> map(1:9) do x 
         k = iseven(x) ? x÷2 : 3x+1
         k^2
       end

However, no reducer such as vcat is needed in this case, but if the output of f in the above example is a vector:

julia> function f(x)
         k = iseven(x) ? x÷2 : 3x+1
         [k^2]
       end
f (generic function with 1 method)

julia> s = [f(i) for i in 1:9]
9-element Array{Array{Int64,1},1}:
 [16] 
 [1]  
 [100]
 [4]  
 [256]
 [9]  
 [484]
 [16] 
 [784]

array comprehension will give you an array of vectors. This time you need to use mapreduce instead:

julia> mapreduce(f, vcat, 1:9)
9-element Array{Int64,1}:
  16
   1
 100
   4
 256
   9
 484
  16
 784

Upvotes: 2

phipsgabler
phipsgabler

Reputation: 20950

Extending on @Gnimuc's answer, I think mapreduce plus do-syntax is pretty nice:

julia> mapreduce(vcat, 1:9) do i
           k = iseven(i) ? i÷2 : 3i+1
           k^2
       end
9-element Array{Int64,1}:
  16
   1
 100
   4
 256
   9
 484
  16
 784

Upvotes: 2

Related Questions