In general it is, for the specific case of function it might not be (each function has its own type, so they are special in that sense). Also, there is the exception where that declaration serves as a signal for the compiler to specialize the function to that type of function (but that only should make a different if the function in case is not used, but only passed as an argument, inside the function). Thus, I do not exactly understand what is the case here, I think is a combination of the function argument and optional arguments. Someone that understands these details better will probably be able to explain this better.
@amrods add on: I think is sort of an anti-pattern also to pass a function as a parameter but use keyword arguments inside the called function. Keyword arguments are specific to the function used, so it does not match well with the flexibility given the function being a parameter.
I would suggest a pattern like this: in the inner function, decide how many parameters the function has to receive (always). Then, you change the function being passed by the caller by providing a closure:
julia> function ces(x, shares, shares1, r; normfun=logit)
n = length(x)
#shares1 = copy(shares)
sharessum = zero(eltype(shares))
for i in 1:n
shares1[i] = normfun(shares1[i],1-sharessum)
sharessum += shares1[i]
end
return _cessum(x, shares1, r)^(1/r)
end
ces (generic function with 2 methods)
julia> @benchmark ces($x, $shares, $shares1, $r; normfun=(x,max) -> logit(x,max=max))
BenchmarkTools.Trial: 10000 samples with 195 evaluations.
Range (min β¦ max): 487.031 ns β¦ 2.310 ΞΌs β GC (min β¦ max): 0.00% β¦ 0.00%
Time (median): 496.036 ns β GC (median): 0.00%
Time (mean Β± Ο): 564.994 ns Β± 132.099 ns β GC (mean Β± Ο): 0.00% Β± 0.00%
βββββββββ β β β βββ β β
βββββββββββββββββββββββββββββββββββββββββ ββ ββ β β β β βββ βββββ ββββ β
487 ns Histogram: log(frequency) by time 1.05 ΞΌs <
Memory estimate: 0 bytes, allocs estimate: 0.
With this, you disassociate the calling syntax of the function being passed from the calling syntax internally.
(this also happens to solve the allocation issue).