Can/could type inference & specialisation barriers be created at regions other than function calls?

Type specialisation happens at function calls, which is why the common function-barrier pattern arises.

Speculating a bit: what would be the issue with having some construct that enforces a type-specialisation for a block within the middle of a function? I.e. some statement that, when hit, would pause execution of the function, inspect the types of all variables used in the rest of the function, then specialise the rest of the function on those types.

Perhaps this kind of thing could be achieved quite easily with some macro that generates a closure? Not sure if a closure would have some overhead though - keen to hear from someone who knows this stuff well!

Thanks

One fairly easy thing would be a macro which splits a function definition into two. In something like:

@bar function f(x::Int, n::Int)
    y = ntuple(_->x, n)
    @bar
    z = zeros(y...)
    z .+ n
end

the first @bar can see what variables the second half of the function uses, and expand to

function f(x::Int, n::Int)
    y = ntuple(_->x, n)
    _f(y, n)
end
function _f(y, n)
    z = zeros(y...)
    z .+ n
end

Maybe someone has already written this? I do not think it would have overhead.

1 Like

That’s a nice idea. I agree - this does feel like something someone would have tried.

Here’s a simple solution using a macro and do-block syntax to automatically construct a closure which acts as a function barrier:

macro barrier(f, args...)
    f.args[1].args = [args...]
    esc(:($f($(args...))))
end

function f(x::Int, n::Int)
    y = ntuple(_->x, n)
    @barrier(y) do
        z = zeros(y...)
        z .+ n
    end
end
5 Likes