@sync @async with non-loop counter

function paralleloop( f::Function, NC::Int=4 )
    z = SharedArray{Float64}( NC )

    k=0
    @sync for i=1:NC
        k+=1
        # z[k]= f( k )         # works
        # @async z[i]= f( i )  # works
        @async z[k]= f( k )    # fails
    end#for

    convert(Vector{Float64}, z)  ## release sharedarray
end#function

@everywhere function sleepingworker(i::Int); sleep(rand()); println("Worker $i"); i^2; end#function

srand(0);
println( paralleloop( sleepingworker ))

I want to run the sleeper asynchronously, and then wait with @sync until we are done.

but the above code produces only Worker 4 launches.

julia understand.jl
Worker 4
Worker 4
Worker 4
Worker 4
[0.0, 0.0, 0.0, 16.0]

is this due to @sync macro trickery and one can only follow the documented construct (i.e., using the loop counter i), or do I misunderstand this fundamentally? does i have to be a specific part of the @async? at the moment of my async call, the second loop counter k was properly set. if I use async without understanding why the k is not used as I think it should be, I bet that I will have a deep bug sooner or later while using it.

also, using a for loop with i is not always natural. For example,

@everywhere function sleepingworker(i::Int); sleep(rand()); println("Worker $i"); i^2; end#function

z = SharedArray{Float64}( 3 )
k=0
@sync begin
    k=3; @async z[k]= sleepingworker( k )
    k=1; @async z[k]= sleepingworker( k )  ## could be a different function
    k=2; @async z[k]= sleepingworker( k )
end#for
display(z)

I know what is happening, but not why. all three asyncs are just queued until they encounter end#for, and then start working, picking up the final k at that point. (but this did not happen when the loop counter i was used.)

is this the correct way of starting a few asynch processes and wait-ing for completion of all?

advice appreciated, as always.