If I’m understanding your question correctly, you can do the same thing in Julia:
callee!(x::Ref{Int}) = x[] = 1
function caller()
x = Ref{Int}()
callee!(x)
println(x[])
end
But you shouldn’t do this generally. Julia is quite good about not allocating at all for the return value, effectively allowing values to move into registers and making it faster than pre-allocating storage for the return value:
julia> using BenchmarkTools
julia> @noinline callee!(x::Ref{Int}) = x[] = 1
callee! (generic function with 1 method)
julia> @noinline fastcallee(::Any) = 1
fastcallee (generic function with 1 method)
julia> x = Ref{Int}();
julia> @btime callee!($x)
3.141 ns (0 allocations: 0 bytes)
1
julia> @btime fastcallee($x)
1.264 ns (0 allocations: 0 bytes)
1