FAQ
I was wondering what the proper idiom would be for wrapping C++ functions
that contain a number of optional parameters. For instance:

bool write (const std::string &filename,
             const std::string &fileformat = std::string(),
             ProgressCallback progress callback=NULL)

Is it preferable to expose this in Go as a single function, where the user
would always have to pass the full set of values:

func Write(filename, fileformat string, progress ProgressCallback) bool

Write("foo.jpg", "", nil)
Write("foo", "jpg", nil)
Write("foo", "jpg", myCallback)

Or should it be broken out into explicit Write* calls:

func Write(filename string) bool
func WriteFormat(filename, fileformat string) bool
func WriteFormatCallback(filename, fileformat string, progress
ProgressCallback) bool

This is a smaller example. There are functions that contain 1 required and
4 optional. So I could end up with a number of variants of the call vs one
where they have to pass in at least zero value params.

--
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+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Search Discussions

  • Ian Lance Taylor at Apr 20, 2014 at 7:16 pm

    On Sat, Apr 19, 2014 at 1:52 PM, Justin Israel wrote:
    I was wondering what the proper idiom would be for wrapping C++ functions
    that contain a number of optional parameters. For instance:

    bool write (const std::string &filename,
    const std::string &fileformat = std::string(),
    ProgressCallback progress callback=NULL)

    Is it preferable to expose this in Go as a single function, where the user
    would always have to pass the full set of values:

    func Write(filename, fileformat string, progress ProgressCallback) bool

    Write("foo.jpg", "", nil)
    Write("foo", "jpg", nil)
    Write("foo", "jpg", myCallback)

    Or should it be broken out into explicit Write* calls:

    func Write(filename string) bool
    func WriteFormat(filename, fileformat string) bool
    func WriteFormatCallback(filename, fileformat string, progress
    ProgressCallback) bool

    This is a smaller example. There are functions that contain 1 required and 4
    optional. So I could end up with a number of variants of the call vs one
    where they have to pass in at least zero value params.
    There is no one answer. Optional parameters are a form of function
    overloading. Go encourages people to choose good names for different
    versions of functions, rather than overloading a single name with
    different meanings. So one approach is to think of the different ways
    that a function is used, and choose good names. Or, if optional
    parameters are there simply to provide options with typical defaults,
    perhaps an Options struct would be appropriate.

    Ian

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Justin Israel at Apr 20, 2014 at 7:54 pm
    Thanks Ian. Since there is a bit of variation in the options between the
    many functions being wrapped, then I take away from this that writing
    variants of the same function is the way to go.
      On Apr 21, 2014 7:16 AM, "Ian Lance Taylor" wrote:
    On Sat, Apr 19, 2014 at 1:52 PM, Justin Israel wrote:

    I was wondering what the proper idiom would be for wrapping C++ functions
    that contain a number of optional parameters. For instance:

    bool write (const std::string &filename,
    const std::string &fileformat = std::string(),
    ProgressCallback progress callback=NULL)

    Is it preferable to expose this in Go as a single function, where the user
    would always have to pass the full set of values:

    func Write(filename, fileformat string, progress ProgressCallback) bool

    Write("foo.jpg", "", nil)
    Write("foo", "jpg", nil)
    Write("foo", "jpg", myCallback)

    Or should it be broken out into explicit Write* calls:

    func Write(filename string) bool
    func WriteFormat(filename, fileformat string) bool
    func WriteFormatCallback(filename, fileformat string, progress
    ProgressCallback) bool

    This is a smaller example. There are functions that contain 1 required and 4
    optional. So I could end up with a number of variants of the call vs one
    where they have to pass in at least zero value params.
    There is no one answer. Optional parameters are a form of function
    overloading. Go encourages people to choose good names for different
    versions of functions, rather than overloading a single name with
    different meanings. So one approach is to think of the different ways
    that a function is used, and choose good names. Or, if optional
    parameters are there simply to provide options with typical defaults,
    perhaps an Options struct would be appropriate.

    Ian
    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Jsor at Apr 21, 2014 at 10:09 am
    I generally decide on a case by case basis. On some mathematical functions,
    there will be certain "canonical" or "common" states that are set as
    defaults. For instance, in OpenCV it sets the default aperture size of the
    filter in Canny edge detection to 3. I would choose to just make that a
    mandatory parameter and note in the comments that it's "commonly 3".
    Sometimes I might add a constant like const DefaultApertureSize = 3, but
    not frequently unless behavior can get really wonky without the default
    value.

    In other cases, I'll make a few with different names. To prevent an
    explosion, when there's like 5 or 6 optional parameters I take time to
    consider whether I really need 5 or 6 functions. Sometimes it turns out
    that if they're going to set one, they're probably going to set the rest of
    them. Or, at best, the optional parameters come in groups of two or three.
    In this case, I think it ends up easier on both you and the user to only
    make 2 or 3 versions, so they don't always have to pass every parameter,
    but might occasionally run into a time when they have to set one or two
    they didn't really need to. For example, I've seen functions that are like
    DoSomething(int a, int b, int max=3, int min=1). It logically makes sense
    here to do DoSomething(a,b int) and DoSomethingThreshold(a,b int, max,min
    int). Sure, they technically may just want to increase max and keep min at
    default, but it's a logical grouping of parameters.

    I've never used an "option struct" before and can't immediately think of a
    time it would be appropriate, but that seems like it could work if you
    really had a lot of optional parameters without much dependency between
    them.
    On Sunday, April 20, 2014 12:54:01 PM UTC-7, Justin Israel wrote:

    Thanks Ian. Since there is a bit of variation in the options between the
    many functions being wrapped, then I take away from this that writing
    variants of the same function is the way to go.
    On Apr 21, 2014 7:16 AM, "Ian Lance Taylor" wrote:

    On Sat, Apr 19, 2014 at 1:52 PM, Justin Israel <justin...@gmail.com<javascript:>>
    wrote:
    I was wondering what the proper idiom would be for wrapping C++ functions
    that contain a number of optional parameters. For instance:

    bool write (const std::string &filename,
    const std::string &fileformat = std::string(),
    ProgressCallback progress callback=NULL)

    Is it preferable to expose this in Go as a single function, where the user
    would always have to pass the full set of values:

    func Write(filename, fileformat string, progress ProgressCallback) bool

    Write("foo.jpg", "", nil)
    Write("foo", "jpg", nil)
    Write("foo", "jpg", myCallback)

    Or should it be broken out into explicit Write* calls:

    func Write(filename string) bool
    func WriteFormat(filename, fileformat string) bool
    func WriteFormatCallback(filename, fileformat string, progress
    ProgressCallback) bool

    This is a smaller example. There are functions that contain 1 required and 4
    optional. So I could end up with a number of variants of the call vs one
    where they have to pass in at least zero value params.
    There is no one answer. Optional parameters are a form of function
    overloading. Go encourages people to choose good names for different
    versions of functions, rather than overloading a single name with
    different meanings. So one approach is to think of the different ways
    that a function is used, and choose good names. Or, if optional
    parameters are there simply to provide options with typical defaults,
    perhaps an Options struct would be appropriate.

    Ian
    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Justin Israel at Apr 21, 2014 at 11:08 am
    Right on, thanks for that. I had figured it was about a balance of offering
    just enough variation to make the most common form succinct, and to group
    the rest logically.
    Good to hear some feedback about this.

    On Mon, Apr 21, 2014 at 10:09 PM, Jsor wrote:

    I generally decide on a case by case basis. On some mathematical
    functions, there will be certain "canonical" or "common" states that are
    set as defaults. For instance, in OpenCV it sets the default aperture size
    of the filter in Canny edge detection to 3. I would choose to just make
    that a mandatory parameter and note in the comments that it's "commonly 3".
    Sometimes I might add a constant like const DefaultApertureSize = 3, but
    not frequently unless behavior can get really wonky without the default
    value.

    In other cases, I'll make a few with different names. To prevent an
    explosion, when there's like 5 or 6 optional parameters I take time to
    consider whether I really need 5 or 6 functions. Sometimes it turns out
    that if they're going to set one, they're probably going to set the rest of
    them. Or, at best, the optional parameters come in groups of two or three.
    In this case, I think it ends up easier on both you and the user to only
    make 2 or 3 versions, so they don't always have to pass every parameter,
    but might occasionally run into a time when they have to set one or two
    they didn't really need to. For example, I've seen functions that are like
    DoSomething(int a, int b, int max=3, int min=1). It logically makes sense
    here to do DoSomething(a,b int) and DoSomethingThreshold(a,b int, max,min
    int). Sure, they technically may just want to increase max and keep min at
    default, but it's a logical grouping of parameters.

    I've never used an "option struct" before and can't immediately think of a
    time it would be appropriate, but that seems like it could work if you
    really had a lot of optional parameters without much dependency between
    them.
    On Sunday, April 20, 2014 12:54:01 PM UTC-7, Justin Israel wrote:

    Thanks Ian. Since there is a bit of variation in the options between the
    many functions being wrapped, then I take away from this that writing
    variants of the same function is the way to go.
    On Apr 21, 2014 7:16 AM, "Ian Lance Taylor" wrote:

    On Sat, Apr 19, 2014 at 1:52 PM, Justin Israel <justin...@gmail.com>
    wrote:
    I was wondering what the proper idiom would be for wrapping C++ functions
    that contain a number of optional parameters. For instance:

    bool write (const std::string &filename,
    const std::string &fileformat = std::string(),
    ProgressCallback progress callback=NULL)

    Is it preferable to expose this in Go as a single function, where the user
    would always have to pass the full set of values:

    func Write(filename, fileformat string, progress ProgressCallback) bool

    Write("foo.jpg", "", nil)
    Write("foo", "jpg", nil)
    Write("foo", "jpg", myCallback)

    Or should it be broken out into explicit Write* calls:

    func Write(filename string) bool
    func WriteFormat(filename, fileformat string) bool
    func WriteFormatCallback(filename, fileformat string, progress
    ProgressCallback) bool

    This is a smaller example. There are functions that contain 1 required and 4
    optional. So I could end up with a number of variants of the call vs one
    where they have to pass in at least zero value params.
    There is no one answer. Optional parameters are a form of function
    overloading. Go encourages people to choose good names for different
    versions of functions, rather than overloading a single name with
    different meanings. So one approach is to think of the different ways
    that a function is used, and choose good names. Or, if optional
    parameters are there simply to provide options with typical defaults,
    perhaps an Options struct would be appropriate.

    Ian
    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedApr 19, '14 at 8:52p
activeApr 21, '14 at 11:08a
posts5
users3
websitegolang.org

People

Translate

site design / logo © 2021 Grokbase