optional arguments to functions

3,523 views
Skip to first unread message

Michael Hoisie

unread,
Jan 2, 2010, 4:07:20 AM1/2/10
to golang-nuts
Not sure if this has been discussed yet, but there are a few times
where having optional arguments in functions would be very useful. I
can imagine the syntax being something like:

func SetHeader ( name string, value string, unique := true ) {
...
}

And this can be called by either:

SetHeader ( "Set-Cookie", "a=b") or
SetHeader ( "Set-Cookie", "a=b", false)

Is this something that would be useful for others?

Risto Saarelma

unread,
Jan 2, 2010, 5:30:41 AM1/2/10
to golang-nuts
On Jan 2, 11:07 am, Michael Hoisie <hoi...@gmail.com> wrote:
> Not sure if this has been discussed yet, but there are a few times
> where having optional arguments in functions would be very useful. I
> can imagine the syntax being something like:
>
> func SetHeader ( name string, value string, unique := true ) {
> ...

Positional optional arguments are doable with the ... vararg
parameters and custom code that parses the vararg list, sets the
defaults and raises a runtime error if the parameters have the wrong
type.

The optional argument syntax would get you less typing and compile-
time validity checking though.

Having syntax for optional arguments shouldn't complicate the language
too much, since there isn't function overloading. If this is done, I'd
like something like in Python, with a possibility for the caller to
specify named parameters, which can refer to the optional parameters
non-positionally. This would make it easier to use and write functions
that have many default values with no clear order of importance. For
completeness' sake there might even be something analogous to Python's
**kwargs parameter, which allows the caller to specify arbitrary named
parameters. So you could for example do XmlElement("elementname",
arbitraryAttribute1="foo", arbitraryAttribute2="bar").

You can emulate named optional arguments with varargs too, by writing
something like XmlElement("elementname", "arbitraryAttribute1", "foo",
"arbitraryAttribute2", "bar"), and interpreting the string/value pairs
in the function. But that's less clear than the named argument syntax.
There's no way to know from looking at the function call syntax that
the first argument is supposed to be a regular argument and that the
rest are supposed to be optional argument name/value pairs,
particularly since all arguments are literal strings in this case.

Peter Bourgon

unread,
Jan 2, 2010, 5:35:09 AM1/2/10
to Risto Saarelma, golang-nuts
If I recall correctly, optional (or default) arguments are explicitly
against the Google code style guide, a maintenance headache besides,
and probably not a candidate for a feature in Go. Maybe Ross or Ian
will chime in.

Risto Saarelma

unread,
Jan 2, 2010, 6:00:32 AM1/2/10
to golang-nuts
On Jan 2, 12:30 pm, Risto Saarelma <rsaar...@gmail.com> wrote:
> You can emulate named optional arguments with varargs too, by writing
> something like XmlElement("elementname", "arbitraryAttribute1", "foo",
> "arbitraryAttribute2", "bar"), and interpreting the string/value pairs
> in the function. But that's less clear than the named argument syntax.

Of course you could do this:

package kw

type Kwarg struct {
Name string
Value interface{}
}

// kw.A for [k]ey[w]ord [a]rgument.
func A(name string, value interface{}) Kwarg { return &Kwarg{name,
value} }

package main

func XmlElement(name string, a ...) ...

XmlElement("elementname", kw.A("arbitraryAttribute1", "foo"), kw.A
("arbitraryAttribute2", "bar"))

Still pretty concise, and you can instantly tell what's going on when
looking at the function call.

And you could use reflect to parse any set of fixed optional keyword
arguments into a struct. First make a struct with fields that have the
desired types and the names of the optional parameters. Initialize the
struct to have the default values for the parameters. The pass the
initialized struct and the ... argument to the kw.Parse function,
which will fill in the rest of the fields from the vararg list and
return an error if there are invalid parameters, either non-Kwargs,
unknown parameter names or mistyped parameters:

package kw

// Kwarg-arguments not found in optParam and non-Kwarg arguments are
an error.
func Parse(optParam interface{}, a ...) os.Error

You could extend this to Python-style flexibility by optionally
allowing an *args-analogue sequence of unnamed optional arguments and
a **kwargs-analogue map of undeclared keyword arguments.

// Kwarg-arguments not found in optParam are an error.
func ParseArgs(optParam interface{}, args vector.Vector, a ...)
os.Error

// Non-Kwarg arguments are an error.
func ParseKwargs(optParam interface{}, kwargs map[string] interface{},
a ...) os.Error

// Doesn't return an error, since all types of arguments get parsed
func ParseArgsKwargs(optParam interface{}, args vector.Vector kwargs
map[string] interface{}, a ...)

Maybe this should be made into an experimental package?

SnakE

unread,
Jan 4, 2010, 12:48:06 PM1/4/10
to peter....@gmail.com, Risto Saarelma, golang-nuts
2010/1/2 Peter Bourgon <peterb...@gmail.com>

If I recall correctly, optional (or default) arguments are explicitly
against the Google code style guide, a maintenance headache besides,
and probably not a candidate for a feature in Go. Maybe Ross or Ian
will chime in.

It's OK not to use optional arguments in Java where you can have multiple overloads with different number of arguments.  But in Go there is no alternative

Jessta

unread,
Jan 4, 2010, 12:55:58 PM1/4/10
to SnakE, golang-nuts
2010/1/5 SnakE <snake...@gmail.com>:

There is.
In the rare instances you need optional argument you make wrapper
functions and give them names that describe the behaviour that you're
filling in.

- jessta

--
=====================
http://jessta.id.au

Reply all
Reply to author
Forward
0 new messages