On Friday, April 24, 2015 at 6:33:08 PM UTC+10, Mauro wrote:
>
> >> >> >> function f(fn!,ar) 
> >> >> >>     for i=1:n 
> >> >> >>         fn!(ar, i) # fn! updates ar[i] somehow, returns nothing 
> >> >> >>         nothing    # to make sure output of f is discarded 
> >> >> >>     end 
> >> >> >> end 
> > 
> > 
> > I'm curious how you would see it optimised? IIUC Julia doesn't know fn! 
> at 
> > compile time, so it doesn't know if it returns something, or not, so it 
> has 
> > to allow for a return value even if its to throw it away immediately. 
>
> Well it seems Julia should know that nothing is used from fn!, without 
> knowing anything about fn!.  That is at least what @code_warntype 
> suggest (with julia --inline=no).  For 
>
> function f(ar) 
>     for i=1:n 
>         hh!(ar, i) 
>     end 
> end 
>
> the loop gives: 
>
>       GenSym(1) = $(Expr(:call1, :(top(next)), GenSym(0), :(#s1::Int64))) 
>       i = $(Expr(:call1, :(top(getfield)), GenSym(1), 1)) 
>       #s1 = $(Expr(:call1, :(top(getfield)), GenSym(1), 2)) # line 71: 
>       $(Expr(:call1, :hh!, :(ar::Array{Float64,1}), :(i::Int64))) 
>       3: 
>       unless $(Expr(:call1, :(top(!)), :($(Expr(:call1, :(top(!)), 
> :($(Expr(:call1, :(top(done)), GenSym(0), :(#s1::Int64))))))))) goto 2 
>
> For 
> function g(fn!,ar) 
>     a = 0 
>     for i=1:n 
>         fn!(ar, i) 
>     end 
>     a 
> end 
>
> the loop gives: 
>       2: 
>       GenSym(1) = $(Expr(:call1, :(top(next)), GenSym(0), :(#s1::Int64))) 
>       i = $(Expr(:call1, :(top(getfield)), GenSym(1), 1)) 
>       #s1 = $(Expr(:call1, :(top(getfield)), GenSym(1), 2)) # line 78: 
>       (fn!::F)(ar::Array{Float64,1},i::Int64)::Any 
>

Wouldn't it (or fn!) need to allocate for this Any here ^

IIUC its fn! that decides if it returns something, and even if the caller 
doesn't need it, the return value still has to be stored somewhere.  Maybe 
fn! does the allocating, but it still happens.
 

>       3: 
>       unless $(Expr(:call1, :(top(!)), :($(Expr(:call1, :(top(!)), 
> :($(Expr(:call1, :(top(done)), GenSym(0), :(#s1::Int64))))))))) goto 2 
>
> So, at least from my naive viewpoint, it looks like there is no need for 
> an allocation in this case.  Or is there ever a case when the return 
> value of fn! would be used? 
>
> I think this is quite different from the case when the return value of 
> fn! is used because then, as long as Julia cannot do type inference on 
> the value of fn!, it cannot know what the type is. 
>

Which is why its ::Any above I guess and my understanding is Any means 
boxed and allocated on the heap?

Reply via email to