Closure over a function with keyword arguments while keeping access to the keyword arguments

Hi everyone,

I have the following problem. I have a function foo(x; y = 1) and would like to obtain a function that calls foo while keeping x constant, but still allows me to specify different values for y. I would like something like:

PSEUDOCODE:

foo(x; y = 1) = x + y

x = 1

foo_closure( ; y = 1) = foo(x; y = 1)

foo_closure()      -> 2
foo_closure(y = 1) -> 2
foo_closure(y = 2) -> 3

Is this possible?

The reason I want this is that I can broadcast over y

y = range(0, stop = 1, 100)
foo_closure.(y = y)
foo_closure(y = 2) -> 3

Why would this happen when

foo(x; y = 1) = x + 1

and x is constant 1?

I am sorry, I meant of course

foo(x; y = 1) = x + y

Then

x = 1

foo_closure( ; y = 1) = foo(x; y = 1)

Would be effectively the same as foo_closure(y) = y + 1

foo_closure( ; y = 1) = foo(x; y = y)

?

Or just

foo_closure( ; kwargs...) = foo(x; kwargs...)

to pass along all the kwargs.

1 Like

Thanks, I will try it tomorrow :slight_smile:

This is amazing, thanks a lot! :slight_smile:

I have one more question. Using the example from above, I would like to broadcast over a different values for the keyword argument.

# Create a function with one kwarg
foo(x; y = 1) = x .+ y
# Fix x
x = 1
# Define closure
foo_closure(; kwargs...) = foo(x; kwargs...)
# Create range of values I want to broadcast over
test_var = range(0, stop = 1, length = 2)

So this runs smoothly

julia> foo.(test_var)
2-element Array{Float64,1}:
 1.0
 2.0

But it does not seem to work with the kwarg:

julia> foo_closure.(y = test_var)
1.0:1.0:2.0

Does the f.() broadcasting interface not work with kwargs or do I have to change something? I know I could just write

res = zeros(2,1)
for i in 1:length(test_var)
    res[i] = foo_closure(y = test_var[i])
end

or better perhaps

res = [foo_closure(y = x) for x in test_var]

AFAIU keywords are constants under broadcasting.

1 Like

try with collect(test_var), it just turned the 0:1:1 range to 1:1:2