Optional parameters: Difference between revisions

Go solution
m (→‎{{header|Ada}}: rename reserved-word-named variable)
(Go solution)
Line 665:
[|"a"; "b"; "c"|]
[|""; "q"; "z"|]</pre>
=={{header|Go}}==
The most idiomatic way to write this particular sorting function would be a single function that required all three parameters. Wherever practical in Go, the zero value is used as a default, and that seems meaningful in this situation. Calling t.sort(nil, 0, false) to "take the defaults" would make sense.
 
In the spirit of the task though, another solution would be to pass a struct with the three "parameters" as fields. While Go does not have named function parameters, it ''does'' have named fields in struct literals. Given,
<lang go>type spec struct {
ordering func(cell, cell) bool
column int
reverse bool
}</lang>
the following struct literal fills in zero values for ordering and column and assigns true to the field reverse.
<lang go>spec{reverse: true}</lang>
Structs in Go are values and are copied when passed as parameters. The result of having a single struct parameter is that the three fields are pushed on the stack, just about like they would if they were separate parameters. The effect is named parameters with unmentioned parameters defaulting to their zero value.
 
A complete program to demonstrate:
<lang go>package main
 
import (
"fmt"
"sort"
)
 
type cell string
type row []cell
type table struct {
rows []row
column int
less func(cell, cell) bool
}
 
func (t table) printRows(heading string) {
fmt.Println("--", heading)
for _, row := range t.rows {
fmt.Println(row)
}
fmt.Println("")
}
 
// sort.Interface
func (t table) Len() int { return len(t.rows) }
func (t table) Swap(i, j int) { t.rows[i], t.rows[j] = t.rows[j], t.rows[i] }
func (t table) Less(i, j int) bool {
return t.less(t.rows[i][t.column], t.rows[j][t.column])
}
 
// struct implements named parameter-like capability
type spec struct {
ordering func(cell, cell) bool
column int
reverse bool
}
 
 
func (t *table) sort(s spec) {
// set up column and comparison function for sort
t.column = s.column
switch {
case s.ordering != nil:
t.less = s.ordering
case s.reverse:
t.less = func(a, b cell) bool { return a > b }
default:
t.less = func(a, b cell) bool { return a < b }
}
 
// sort
sort.Sort(t)
 
// reverse if necessary
if s.ordering == nil || !s.reverse {
return
}
last := len(t.rows) - 1
for i := last / 2; i >= 0; i-- {
t.rows[i], t.rows[last-i] = t.rows[last-i], t.rows[i]
}
}
 
func main() {
t := table{rows: []row{
{"pail", "food"},
{"pillbox", "nurse maids"},
{"suitcase", "airedales"},
{"bathtub", "chocolate"},
{"schooner", "ice cream sodas"},
}}
 
t.printRows("song")
 
// no "parameters"
t.sort(spec{})
t.printRows("sorted on first column")
 
// "named parameter" reverse.
t.sort(spec{reverse: true})
t.printRows("reverse sorted on first column")
 
// "named parameters" column and ordering
t.sort(spec{
column: 1,
ordering: func(a, b cell) bool { return len(a) > len(b) },
})
t.printRows("sorted by descending string length on second column")
}</lang>
Output:
<pre>-- song
[pail food]
[pillbox nurse maids]
[suitcase airedales]
[bathtub chocolate]
[schooner ice cream sodas]
 
-- sorted on first column
[bathtub chocolate]
[pail food]
[pillbox nurse maids]
[schooner ice cream sodas]
[suitcase airedales]
 
-- reverse sorted on first column
[suitcase airedales]
[schooner ice cream sodas]
[pillbox nurse maids]
[pail food]
[bathtub chocolate]
 
-- sorted by descending string length on second column
[schooner ice cream sodas]
[pillbox nurse maids]
[suitcase airedales]
[bathtub chocolate]
[pail food]</pre>
 
=={{header|J}}==
1,707

edits