Callbacks: can they be captured with arguments attached?

I am squinting at how Elixir handles function callbacks… specifically, I’m wondering whether you can capture a function WITH arguments attached.

So instead of something like this:

myfunc = fn(a,b) -> a + b end
myfunc2 = &(IO.puts/1)

myfunc.(1,2)
myfunc2.("Hello World!")

where you have to provide the arguments when you call the captured functions, I’m wondering if there is some way to capture the ARGUMENTs too so that you can just say “that thing I saved? Run that now please.”

I can’t even think whether such a structure would be possible in any language. I’m thinking of something more like PHP’s call_user_func(). I suppose the proper way to do something like this in Elixir would be to implement a behavior with a defined arity and dispatch to it. The thing that sent my brain into a spin was thinking that the callback may not have the proper variable available when it needed to execute. Sorry if I’m talking crazy…

What’s wrong with:

myfunc3 = fn () -> myfunc2.("Hello World!") end
myfunc3.()

or

myfunc3 = fn () -> apply(myfunc2, ["Hello World!"]) end
myfunc3.()

i.e. the arguments are captured (“attached”) as part of the closure.

3 Likes

Or something like this perhaps?

iex(16)> say_hello = &(fn -> IO.puts("Hello, #{&1}") end)
#Function<6.128620087/1 in :erl_eval.expr/5>
iex(17)> say_hello_world = say_hello.("world")
#Function<20.128620087/0 in :erl_eval.expr/5>
iex(18)> say_hello_world.()
Hello, world
:ok
iex(19)>
2 Likes

I love you guys. OF COURSE!!! Why didn’t I think of that?

1 Like

I think what you need is currying, together with partial application:

add = fn a -> fn b -> a + b end end
inc = add.(1)

inc.(5) # returns 6

This is a technique often used in FP, is allows you to pass arguments as you use them to functions and it saves their parameters in the closure.

1 Like