Stream: helpdesk (published)

Topic: Convenient pattern for optional kwargs in callback function


view this post on Zulip DrChainsaw (Nov 13 2024 at 09:30):

Here is a situation that pops up for me every now and then: I have a function which takes a callback function from the end user which needs to support a wide variety of options, for example like this:

function my_library_function(f, args...)
# Stuff...
customization = f(x; <lots of keyword arguments)
# More stuff
end

Is there a way (e.g. in my_library_function) to make it so that the end user can supply a function with this signature:

end_users_callback(x; the_only_kwarg_they_need_for_this_particular_customization) = # Stuff....

Note that I want the end user to be able to omit slurping the kwargs or else there would be no need for me to post this :)

I know the best way is probably to not have those options, but for the sake of brevity, assume this is not applicable here.

One option is to have a signature where the optional arguments are supplied as one big named tuple so users just pick out what they want, e.g. like this

function end_users_callback(x, options)
flag = options.the_only_kwarg_they_need_for_this_particular_customization
# Stuff ...
end

But I'm wondering if there is an even more convenient way to do it.

view this post on Zulip Gunnar Farnebäck (Nov 13 2024 at 09:47):

I would design the callback to take optional stuff in a single argument that could be either a named tuple, a dictionary, or a struct, whatever works best.

view this post on Zulip aplavin (Nov 13 2024 at 12:55):

Passing a named tuple (or any struct for that matter) and selecting specific values from it is quite convenient.
Try this

function end_users_callback(x, (; the_only_kwarg_they_need_for_this_particular_customization))
# Stuff ...
end

instead of

function end_users_callback(x, options)
flag = options.the_only_kwarg_they_need_for_this_particular_customization
# Stuff ...
end

Reads almost like kwargs :)

view this post on Zulip DrChainsaw (Nov 13 2024 at 15:17):

aplavin said:

Try this

Thats a nice one! I somehow thought that destructuring requires that you collect all members. I'll add this as a tip in the documentation.


Last updated: Dec 28 2024 at 04:38 UTC