>> I think this optimisation should work irrespective of what fn! returns >> by the fact that the value is not used. This and more seems to happen >> in the first-order function. Here a version of first-order >> function which calls a function which returns an inferred Any: >> >> const aa = Any[1] >> hh_ret!(ar,i) = (ar[i] = hh(ar[i]); aa[1]) >> >> function f_ret(ar) >> a = aa[1] >> for i=1:n >> a=hh_ret!(ar, i) >> end >> a >> end >> julia> @time f_ret(a); >> elapsed time: 0.259893608 seconds (160 bytes allocated) >> >> It's still fast and doesn't allocate, even though it uses the value! >> > > The a= aa[1] is unused and can be removed (well if n is >=1). > > Then I would have thought that first hh_ret() is inlined, then the loop > body is visible to the optimiser and the unused value is removed as it is > optimised to ar[n]. > > But if hh_ret() was passed to f_ret() it can only be inlined if f_ret() is > re-compiled for each call with a new parameter function. Thats not > impossible in a dynamic language like Julia. But still may not work if the > function being passed as a parameter is the result of an expression that > can't be resolved at compile time. > > As Tim says its all optimisations that havn't yet been written :)
I did run it with --inline=no so the comparison to the higher order function should be fairer, i.e. the hh_ret function was indeed called. Yep, those optimisations, probably should learn how to work on them myself ;-)