It will be hard to interface with every function like that. One alternative is to keep the internal interface fixed and use closures:
function foo(distribution::F, x) where {F<:Function}
y = x + rand(distribution())
end
# call with
x = 2.0
foo(() -> Normal(0,1), x)
Thus, your function expects, always, a function without parameters (or whatever), and interfacing with it is done by defining anonymous functions which adapt to that interface.