Hi all,

I have an API that I'm not satisfied with and wanted to see what
others do. I have a function in my API, the details don't really
matter so let's call it Foo and say it returns type Bar (the return
type we can't mess with):

    Foo() Bar

Most of the time we have all the information we need to compute Foo()
and return Bar. However, on rare occasions, the thing Foo is doing
does not have enough information and the users application needs to
provide logic for computing that info, or fetching it from a database,
etc. So I need to let the user provide some logic for getting that
info (let's assume it's a string):

    Foo(f func() (string, error)) Bar

Normally this would be a fine, simple API. However, f is almost never
needed. This means that <large-percentage> of the time when they
actually call Foo (let's say it's in the baz package), they'll be
writing:

    bar := baz.Foo(nil)

This isn't terrible; but it doesn't feel great to introduce a random
nil with no information about what it is into the users code just so
that a fraction of the time they can put a callback there.

Other atlernatives might be to use a variadic function and take
multiple callback funcs (so that having one at all is optional):

    Foo(f ...func() (string, error)) Bar

Now the user can write:

    bar := baz.Foo()
    bar := baz.Foo(func() (string, error) {…})

That feels dirty because we appear to be telling the user that
multiple callbacks are acceptable by encoding that into the function
signature (even though it doesn't make sense and only the first one
would ever be used).

We might also provide a Foo() function and a FooCallback(f func()
(string, error)) function, but this doesn't really provide us any
benefit over saving us typing three characters most of the time and
means we have a bigger API surface to keep track of (and it just looks
ugly in the docs, there are other Foo like functions and none of them
will have an alternative implementation; it also makes it easier for
the user to mix them up and use the wrong one when info is or is not
needed, etc.)

Thoughts? Is requiring the (nil) argument 90% of the time not so bad?
Is there an obvious benefit to doing it another way I'm not noticing,
or another pattern I'm ignoring? It's so rare that the callback is
needed (but it will be needed sometimes and there's nothing I can do
about that; so I can't just get rid of it entirely), that all the
options here just feel poor.

Thanks,
Sam

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to