The macro as written doesn’t resolve the variables correctly:
@macroexpand function compute(input, callback)
x = @elidable foo(input)
y = @elidable bar(input)
z = @elidable baz(x, y)
return callback((;x, y, z))
end
:(function compute(input, callback)
#= REPL[3]:1 =#
#= REPL[3]:2 =#
x = $(Expr(:unnecessary, :(Main.foo(Main.input))))
#= REPL[3]:3 =#
y = $(Expr(:unnecessary, :(Main.bar(Main.input))))
#= REPL[3]:4 =#
z = $(Expr(:unnecessary, :(Main.baz(Main.x, Main.y))))
#= REPL[3]:5 =#
return callback((; x, y, z))
end)
defining it as
macro elidable(ex)
@show ex
return Expr(:unnecessary, esc(ex))
end
seems to do the trick.
I know that all bets are off at this point, but I’m not getting the desired behavior:
function foo(input)
println("foo")
2 * input
end
function bar(input)
println("bar")
2 + input
end
function baz(x, y)
println("baz")
x / y
end
function compute(input, callback)
x = @elidable foo(input)
y = @elidable bar(input)
z = @elidable baz(x, y)
return callback((;x, y, z))
end
@inline callback_xyz(nt) = nt.x + nt.y + nt.z
@inline callback_xy(nt) = nt.x + nt.y
@inline callback_xz(nt) = nt.x + nt.z
@inline callback_x(nt) = nt.x
julia> @code_typed compute(20, callback_x)
CodeInfo(
1 ─ invoke Main.println("foo"::String)::Any
│ %2 = Base.mul_int(2, input)::Int64
│ invoke Main.println("bar"::String)::Any
│ invoke Main.println("baz"::String)::Any
└── return %2
) => Int64
(@yha as I mentioned in my original post, I’m not looking to do memoization.)