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?
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.
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?
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.
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