Optional parameters: Difference between revisions

m
→‎{{header|Wren}}: Changed to Wren S/H
m (→‎{{header|Sidef}}: modified the code to work with Sidef 2.30)
m (→‎{{header|Wren}}: Changed to Wren S/H)
 
(38 intermediate revisions by 21 users not shown)
Line 1:
{{task|Basic language learning}}
{{omit from|Rust}}
 
;Task:
Define a function/method/subroutine which sorts a sequence ("table") of sequences ("rows") of strings ("cells"), by one of the strings. Besides the input to be sorted, it shall have the following optional parameters:
:{|
Line 20 ⟶ 22:
See also:
* [[Named Arguments]]
<br><br>
 
=={{header|Ada}}==
Line 25 ⟶ 28:
As described in [[Named_parameters]], all parameters have to be named. You can use positional or keyed association. Optional parameters are the ones with default values.
 
<langsyntaxhighlight Adalang="ada">package Tables is
 
type Table is private;
Line 38 ⟶ 41:
private
... -- implementation specific
end Tables;</langsyntaxhighlight>
 
example of use:
<langsyntaxhighlight Adalang="ada">with Tables;
procedure Table_Test is
My_Table : Tables.Table;
Line 50 ⟶ 53:
Sort (It => My_Table, Reverse_Ordering => True); -- use default sorting in reverse order
... -- other stuff
end Table_Test;</langsyntaxhighlight>
 
=={{header|ALGOL 68}}==
<langsyntaxhighlight lang="algol68"># as the options have distinct types (INT, BOOL and PROC( STRING, STRING )INT) the #
# easiest way to support these optional parameters in Algol 68 would be to have an array #
# with elements of these types #
Line 87 ⟶ 90:
configurable sort( data, ( 2, ( STRING a, STRING b )INT: default compare( a[ LWB a + 1 : ], b[ LWB b + 1 : ] ) ) );
# default sort #
configurable sort( data, () )</langsyntaxhighlight>
 
=={{header|AppleScript}}==
AppleScript supports named, positional & prepositional parameters, but not default or optional parameters. Though that behavior can be simulated by passing lists or records as the parameter. Handler/functions can be passed as a parameter if they are part of a script object. AppleScript does not have built-in sorting functionality.
<langsyntaxhighlight AppleScriptlang="applescript">on sortTable(x)
set {sortOrdering, sortColumn, sortReverse} to {sort_lexicographic, 1, false}
try
Line 110 ⟶ 113:
return table
end sort
end script</langsyntaxhighlight>
Examples of use:
<langsyntaxhighlight AppleScriptlang="applescript">-- Another sort function.
script sort_colex
on sort(table, column, reverse)
Line 126 ⟶ 129:
sortTable({sequence:table, ordering:sort_colex, column:2, reverse:true})
sortTable({sequence:table, reverse:true})
sortTable({sequence:table})</langsyntaxhighlight>
 
=={{header|Arturo}}==
 
<syntaxhighlight lang="rebol">sortTable: function [tbl][
column: "0"
reversed?: false
unless null? c: <= attr 'column -> column: to :string c
unless null? attr 'reverse -> reversed?: true
 
result: new sort.by: column map tbl 'r [
to :dictionary flatten couple 0..dec size r r
]
 
if reversed? -> reverse 'result
 
return map result 'r -> values r
]
 
printTable: function [tbl, title][
print ["==" title]
loop tbl 'row [
print row
]
print ""
]
 
lst: [
["a", "b", "c"]
["", "q", "z"]
["zap", "zip", "Zot"]
]
 
printTable sortTable lst "Default sort"
printTable sortTable.column:1 lst "Sorting by column=1"
printTable sortTable.reverse lst "Sorting, reversed"
printTable sortTable.reverse.column:1 lst "Sorting by column=1, reversed"</syntaxhighlight>
 
{{out}}
 
<pre>== Default sort
q z
a b c
zap zip Zot
 
== Sorting by column=1
a b c
q z
zap zip Zot
 
== Sorting, reversed
zap zip Zot
a b c
q z
 
== Sorting by column=1, reversed
zap zip Zot
q z
a b c</pre>
 
=={{header|AutoHotkey}}==
built in support for table sorting is available through the standard Win32 listview.
<langsyntaxhighlight AutoHotkeylang="autohotkey">Gosub start ; create and show the gui
sort_table("Text", column := 2, reverse := 1) ; lexicographic sort
Sleep, 2000
Line 162 ⟶ 223:
 
GuiClose:
ExitApp</langsyntaxhighlight>
 
=={{header|BASIC}}==
Line 186 ⟶ 247:
=={{header|BBC BASIC}}==
BBC BASIC doesn't have optional parameters, but functions can have multiple entry points which take different numbers of parameters, avoiding the need to duplicate code or call a sub-function. Omitted parameters can be declared as LOCAL, which initialises them to zero/false.
<langsyntaxhighlight lang="bbcbasic"> DIM table$(100,100)
PROCsort_default(table$())
PROCsort_options(table$(), TRUE, 1, FALSE)
Line 195 ⟶ 256:
REM The sort goes here, controlled by the options
REM Zero/FALSE values for the options shall select the defaults
ENDPROC</langsyntaxhighlight>
 
=={{header|Bracmat}}==
Bracmat functions always have exactly one parameter, which is references by <code>!arg</code> in the function body. Positional and (optional) named 'parameters' are retrieved from this single parameter <code>!arg</code> by pattern matching. It is a good custom to separate positional parameters by commas or periods and to separate the named parameters by spaces.
<langsyntaxhighlight lang="bracmat">( ( sortTable
= table ordering column reverse
. !arg
Line 220 ⟶ 281:
: ?table
& sortTable$(!table.(column.2) (reverse.yes))
);</langsyntaxhighlight>
 
=={{header|C}}==
<langsyntaxhighlight lang="c">#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
Line 389 ⟶ 450:
printTable(&table, stdout, colFmts);
return 0;
}</langsyntaxhighlight>
 
=={{header|C++}}==
This implementation only accepts function pointers for the comparators, and does not accept function objects, for simplicity.
<langsyntaxhighlight lang="cpp">#include <vector>
#include <algorithm>
#include <string>
Line 483 ⟶ 544:
 
return 0;
}</langsyntaxhighlight>
 
=={{header|Clojure}}==
There is a built-in sort routine, but rather than figure out what all these arguments are supposed to mean, I've just defined the interface.
 
<syntaxhighlight lang="clojure">(defn sort [table & {:keys [ordering column reverse?]
:or {ordering :lex, column 1}}]
(println table ordering column reverse?))
 
(sort [1 8 3] :reverse? true)
[1 8 3] :lex 1 true</syntaxhighlight>
 
=={{header|Common Lisp}}==
 
Common Lisp has both named and positional parameters. The following example shows optional named parameters, using the <code>&key</code> keyword. Optional positional parameters are specified using the <code>&optional</code> keyword.
 
<syntaxhighlight lang="lisp">(defun sort-table (table &key (ordering #'string<)
(column 0)
reverse)
(sort table (if reverse
(complement ordering)
ordering)
:key (lambda (row) (elt row column))))</syntaxhighlight>
 
(Notes: The builtin [http://www.lispworks.com/documentation/HyperSpec/Body/f_sort_.htm sort] takes a "less than" predicate function. The [http://www.lispworks.com/documentation/HyperSpec/Body/f_comple.htm complement] function inverts a predicate.)
 
Example uses:
<syntaxhighlight lang="lisp">CL-USER> (defparameter *data* '(("a" "b" "c") ("" "q" "z") ("zap" "zip" "Zot")))
*DATA*
 
CL-USER> (sort-table *data*)
(("" "q" "z") ("a" "b" "c") ("zap" "zip" "Zot"))
 
CL-USER> (sort-table *data* :column 2)
(("zap" "zip" "Zot") ("a" "b" "c") ("" "q" "z"))
 
CL-USER> (sort-table *data* :column 1)
(("a" "b" "c") ("" "q" "z") ("zap" "zip" "Zot"))
 
CL-USER> (sort-table *data* :column 1 :reverse t)
(("zap" "zip" "Zot") ("" "q" "z") ("a" "b" "c"))
 
CL-USER> (sort-table *data* :ordering (lambda (a b) (> (length a) (length b))))
(("zap" "zip" "Zot") ("a" "b" "c") ("" "q" "z"))</syntaxhighlight>
 
=={{header|D}}==
{{trans|Python}}
<langsyntaxhighlight lang="d">import std.stdio, std.algorithm, std.functional;
 
string[][] sortTable(string[][] table,
Line 514 ⟶ 618:
show(sortTable(data, null, 1, true));
show(sortTable(data, (a,b) => b.length > a.length));
}</langsyntaxhighlight>
{{out}}
<pre>["a", "b", "c"]
Line 541 ⟶ 645:
</pre>
Another way to emulate optional arguments is with function overloading, creating several functions with a different number of arguments.
=={{header|Delphi}}==
{{libheader| System.SysUtils}}
{{Trans|D}}
<syntaxhighlight lang="delphi">program Optional_parameters;
 
{$APPTYPE CONSOLE}
=={{header|Clojure}}==
There is a built-in sort routine, but rather than figure out what all these arguments are supposed to mean, I've just defined the interface.
 
uses
<lang Clojure>(defn sort [table & {:keys [ordering column reverse?]
System.SysUtils;
:or {ordering :lex, column 1}}]
(println table ordering column reverse?))
 
type
(sort [1 8 3] :reverse? true)
TRow = TArray<string>;
[1 8 3] :lex 1 true</lang>
 
TOrderingFun = TFunc<TRow, TRow, Boolean>;
=={{header|Common Lisp}}==
 
TTable = array of TRow;
Common Lisp has both named and positional parameters. The following example shows optional named parameters, using the <code>&key</code> keyword. Optional positional parameters are specified using the <code>&optional</code> keyword.
 
TRowHelper = record helper for TRow
<lang lisp>(defun sort-table (table &key (ordering #'string<)
public
(column 0)
procedure Swap(var other: TRow);
reverse)
function ToString: string;
(sort table (if reverse
function Length: Integer;
(complement ordering)
end;
ordering)
:key (lambda (row) (elt row column))))</lang>
 
TTableHelper = record helper for TTable
(Notes: The builtin [http://www.lispworks.com/documentation/HyperSpec/Body/f_sort_.htm sort] takes a "less than" predicate function. The [http://www.lispworks.com/documentation/HyperSpec/Body/f_comple.htm complement] function inverts a predicate.)
private
procedure ExchangeRow(i, j: Integer);
public
procedure Sort(OrderingFun: TOrderingFun);
procedure Reverse;
function ToString: string;
end;
 
function Max(a, b: Integer): Integer;
Example uses:
begin
<lang lisp>CL-USER> (defparameter *data* '(("a" "b" "c") ("" "q" "z") ("zap" "zip" "Zot")))
if a > b then
*DATA*
exit(a);
Result := b;
end;
 
{ TRowHelper }
CL-USER> (sort-table *data*)
(("" "q" "z") ("a" "b" "c") ("zap" "zip" "Zot"))
 
function TRowHelper.Length: Integer;
CL-USER> (sort-table *data* :column 2)
begin
(("zap" "zip" "Zot") ("a" "b" "c") ("" "q" "z"))
Result := System.Length(self);
end;
 
procedure TRowHelper.Swap(var other: TRow);
CL-USER> (sort-table *data* :column 1)
var
(("a" "b" "c") ("" "q" "z") ("zap" "zip" "Zot"))
aLengthOther, aLengthSelf, aLength: Integer;
tmp: string;
i: Integer;
begin
aLengthOther := other.Length;
aLengthSelf := self.Length;
aLength := max(aLengthOther, aLengthSelf);
if aLength = 0 then
exit;
 
SetLength(self, aLength);
CL-USER> (sort-table *data* :column 1 :reverse t)
SetLength(other, aLength);
(("zap" "zip" "Zot") ("" "q" "z") ("a" "b" "c"))
 
for i := 0 to aLength - 1 do
CL-USER> (sort-table *data* :ordering (lambda (a b) (> (length a) (length b))))
begin
(("zap" "zip" "Zot") ("a" "b" "c") ("" "q" "z"))</lang>
tmp := self[i];
self[i] := other[i];
other[i] := tmp;
end;
 
SetLength(self, aLengthOther);
SetLength(other, aLengthSelf);
end;
 
function TRowHelper.ToString: string;
var
i: Integer;
begin
Result := '[';
for i := 0 to High(self) do
begin
if i > 0 then
Result := Result + ', ';
Result := Result + '"' + self[i] + '"';
end;
Result := Result + ']';
end;
 
{ TTableHelper }
 
procedure TTableHelper.ExchangeRow(i, j: Integer);
begin
Self[i].Swap(self[j]);
end;
 
procedure TTableHelper.reverse;
var
aLength, aHalfLength: Integer;
i: Integer;
begin
aLength := Length(self);
aHalfLength := aLength div 2;
for i := 0 to aHalfLength - 1 do
ExchangeRow(i, aLength - i - 1);
end;
 
procedure TTableHelper.Sort(OrderingFun: TOrderingFun);
var
i, j, aLength: Integer;
begin
if not Assigned(OrderingFun) then
exit;
 
aLength := Length(self);
for i := 0 to aLength - 2 do
for j := i + 1 to aLength - 1 do
if OrderingFun(self[i], self[j]) then
ExchangeRow(i, j);
end;
 
function TTableHelper.ToString: string;
var
i: Integer;
begin
Result := '[';
for i := 0 to High(self) do
begin
if i > 0 then
Result := Result + #10;
Result := Result + self[i].ToString;
end;
Result := Result + ']';
end;
 
function SortTable(table: TTable; Ordering: TOrderingFun = nil; column: Integer
= 0; reverse: Boolean = false): TTable;
var
acolumn: Integer;
begin
acolumn := column;
if not Assigned(Ordering) then
Ordering :=
function(left, right: TRow): Boolean
begin
Result := left[acolumn] > right[acolumn];
end;
 
table.Sort(Ordering);
if (reverse) then
table.reverse();
Result := table;
end;
 
var
data: TTable = [['a', 'b', 'c'], ['', 'q', 'z'], ['zap', 'zip', 'Zot']];
 
begin
Writeln(data.ToString, #10);
Writeln(SortTable(data).ToString, #10);
Writeln(SortTable(data).ToString, #10);
Writeln(SortTable(data, nil, 2).ToString, #10);
Writeln(SortTable(data, nil, 1).ToString, #10);
Writeln(SortTable(data, nil, 1, True).ToString, #10);
Writeln(SortTable(data,
function(left, right: TRow): Boolean
begin
Result := left.Length > right.Length;
end).ToString, #10);
Readln;
end.</syntaxhighlight>
{{out}}
<pre>
[["a", "b", "c"]
["", "q", "z"]
["zap", "zip", "Zot"]]
 
[["", "q", "z"]
["a", "b", "c"]
["zap", "zip", "Zot"]]
 
[["", "q", "z"]
["a", "b", "c"]
["zap", "zip", "Zot"]]
 
[["zap", "zip", "Zot"]
["a", "b", "c"]
["", "q", "z"]]
 
[["a", "b", "c"]
["", "q", "z"]
["zap", "zip", "Zot"]]
 
[["zap", "zip", "Zot"]
["", "q", "z"]
["a", "b", "c"]]
 
[["zap", "zip", "Zot"]
["", "q", "z"]
["a", "b", "c"]]</pre>
 
=={{header|E}}==
Line 589 ⟶ 848:
In E, as in Java and Smalltalk, optional parameters are defined as different methods with the same base name. Methods are distinguished by name (''verb'') and number of parameters (''arity'').
 
<langsyntaxhighlight lang="e">def defaultOrdering(a, b) { return a.op__cmp(b) }
 
def sort {
Line 610 ⟶ 869:
}
 
}</langsyntaxhighlight>
 
Named parameters are not builtin, but map-patterns may be used as a substitute. (TODO: Example of this) [[Category:E examples needing attention]]
 
=={{header|Ecstasy}}==
<syntaxhighlight lang="java">
module OptionalParameters {
typedef Type<String >.Orderer as ColumnOrderer;
typedef Type<String[]>.Orderer as RowOrderer;
 
static String[][] sort(String[][] table,
ColumnOrderer? orderer = Null,
Int column = 0,
Boolean reverse = False,
) {
// provide a default orderer
orderer ?:= (s1, s2) -> s1 <=> s2;
 
// optionally reverse the order
ColumnOrderer byString = reverse
? ((s1, s2) -> orderer(s1, s2).reversed)
: orderer;
 
// sort the indicated column
RowOrderer byColumn = (row1, row2) -> byString(row1[column], row2[column]);
 
return table.sorted(byColumn);
}
 
void run() {
String[][] table =
[
["c", "x", "i"],
["a", "y", "p"],
["b", "z", "a"],
];
 
show("original input", table);
show("by default sort on column 0", sort(table));
show("by column 2", sort(table, column=2));
show("by column 2 reversed", sort(table, column=2, reverse=True));
}
 
void show(String title, String[][] table) {
@Inject Console console;
console.print($"{title}:");
for (val row : table) {
console.print($" {row}");
}
console.print();
}
}
</syntaxhighlight>
 
{{out}}
<pre>
original input:
[c, x, i]
[a, y, p]
[b, z, a]
 
by default sort on column 0:
[a, y, p]
[b, z, a]
[c, x, i]
 
by column 2:
[b, z, a]
[c, x, i]
[a, y, p]
 
by column 2 reversed:
[a, y, p]
[c, x, i]
[b, z, a]
</pre>
 
=={{header|Elixir}}==
{{trans|Ruby}}
<langsyntaxhighlight lang="elixir">defmodule Optional_parameters do
def sort( table, options\\[] ) do
options = options ++ [ ordering: :lexicographic, column: 0, reverse: false ]
Line 646 ⟶ 978:
end
 
Optional_parameters.task</langsyntaxhighlight>
 
{{out}}
Line 659 ⟶ 991:
 
=={{header|Erlang}}==
<syntaxhighlight lang="erlang">
<lang Erlang>
-module( optional_parameters ).
 
Line 699 ⟶ 1,031:
table_row2() -> {"456", "0789", "123"}.
table_row3() -> {"0789", "123", "456"}.
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 709 ⟶ 1,041:
sort numeric [{"123","456","0789"},{"456","0789","123"},{"0789","123","456"}]
reverse [{"0789","123","456"},{"456","0789","123"},{"123","456","0789"}]
</pre>
 
=={{header|F_Sharp|F#}}==
{{trans|Oz}}
 
F# supports optional parameters for members only, not for free-standing functions.
 
Optional parameters are marked by using a question mark in front of the identifier. Their values are passed as option types, i.e. as <code>Some value</code> or <code>None</code>. The helper function <code>defaultArg</code> can be used to specify default values. In the example below, we use shadowing in order to reuse the identifiers <code>ordering</code>, <code>column</code> and <code>reverse</code>.
 
Typically, parameters are named at the caller site when optional parameters are involved. However, this is not technically required as long as only right-most arguments are omitted.
 
<syntaxhighlight lang="fsharp">type Table(rows:string[][]) =
// in-place sorting of rows
member x.Sort(?ordering, ?column, ?reverse) =
let ordering = defaultArg ordering compare
let column = defaultArg column 0
let reverse = defaultArg reverse false
 
let factor = if reverse then -1 else 1
let comparer (row1:string[]) (row2:string[]) =
factor * ordering row1.[column] row2.[column]
 
Array.sortInPlaceWith comparer rows
member x.Print() =
for row in rows do printfn "%A" row
 
// Example usage
let t = new Table([| [|"a"; "b"; "c"|]
[|""; "q"; "z"|]
[|"can"; "z"; "a"|] |])
 
printfn "Unsorted"; t.Print()
 
t.Sort()
printfn "Default sort"; t.Print()
 
t.Sort(column=2)
printfn "Sorted by col. 2"; t.Print()
 
t.Sort(column=1)
printfn "Sorted by col. 1"; t.Print()
 
t.Sort(column=1, reverse=true)
printfn "Reverse sorted by col. 1"; t.Print()
 
t.Sort(ordering=fun s1 s2 -> compare s2.Length s1.Length)
printfn "Sorted by decreasing length"; t.Print()</syntaxhighlight>
 
Output:
<pre>Unsorted
[|"a"; "b"; "c"|]
[|""; "q"; "z"|]
[|"can"; "z"; "a"|]
Default sort
[|""; "q"; "z"|]
[|"a"; "b"; "c"|]
[|"can"; "z"; "a"|]
Sorted by col. 2
[|"can"; "z"; "a"|]
[|"a"; "b"; "c"|]
[|""; "q"; "z"|]
Sorted by col. 1
[|"a"; "b"; "c"|]
[|""; "q"; "z"|]
[|"can"; "z"; "a"|]
Reverse sorted by col. 1
[|"can"; "z"; "a"|]
[|""; "q"; "z"|]
[|"a"; "b"; "c"|]
Sorted by decreasing length
[|"can"; "z"; "a"|]
[|"a"; "b"; "c"|]
[|""; "q"; "z"|]</pre>
 
=={{header|Factor}}==
Factor doesn't have special support for optional parameters, so the idiom is to define a tuple with desired initial values, set the desired slots, then pass it to a word.
<syntaxhighlight lang="factor">USING: accessors combinators io kernel math.order prettyprint
sequences sorting ;
 
TUPLE: table-sorter
data
{ column initial: 0 }
reversed?
{ ordering initial: [ ] } ;
 
: <table-sorter> ( -- obj ) table-sorter new ;
 
: sort-table ( table-sorter -- matrix )
{
[ data>> ]
[ column>> [ swap nth ] curry ]
[ ordering>> compose ]
[ reversed?>> [ >=< ] [ <=> ] ? [ bi@ ] prepose curry ]
} cleave [ sort ] curry call( x -- x ) ;
 
 
! ===== Now we can use the interface defined above =====
 
CONSTANT: table
{ { "a" "b" "c" } { "" "q" "z" } { "can" "z" "a" } }
 
"Unsorted" print
table simple-table.
 
"Default sort" print
<table-sorter>
table >>data
sort-table simple-table.
 
"Sorted by col 2" print
<table-sorter>
table >>data
2 >>column
sort-table simple-table.
 
"Sorted by col 1" print
<table-sorter>
table >>data
1 >>column
sort-table simple-table.
 
"Reverse sorted by col 1" print
<table-sorter>
table >>data
1 >>column
t >>reversed?
sort-table simple-table.
 
"Sorted by decreasing length" print
<table-sorter>
table >>data
t >>reversed?
[ length ] >>ordering
sort-table simple-table.</syntaxhighlight>
{{out}}
<pre>
Unsorted
a b c
q z
can z a
Default sort
q z
a b c
can z a
Sorted by col 2
can z a
a b c
q z
Sorted by col 1
a b c
q z
can z a
Reverse sorted by col 1
can z a
q z
a b c
Sorted by decreasing length
can z a
a b c
q z
</pre>
 
Line 716 ⟶ 1,209:
In Fortran, each argument has its "name". The <tt>optional</tt> attribute can be used to specify that an argument is optional, and its presence (or absence) can be tested using the <tt>present</tt> intrinsic (so that we can give a default value, or execute accordingly a totally different code).
 
<langsyntaxhighlight lang="fortran">module ExampleOptionalParameter
! use any module needed for the sort function(s)
! and all the interfaces needed to make the code work
Line 784 ⟶ 1,277:
end subroutine sort_table
 
end module ExampleOptionalParameter</langsyntaxhighlight>
 
<langsyntaxhighlight lang="fortran">program UsingTest
use ExampleOptionalParameter
implicit none
Line 821 ⟶ 1,314:
call sort_table(table, column=2)
 
end program UsingTest</langsyntaxhighlight>
 
=={{header|F_Sharp|F#}}==
{{trans|Oz}}
 
=={{header|FreeBASIC}}==
F# supports optional parameters for members only, not for free-standing functions.
<syntaxhighlight lang="freebasic">Function power(n As Integer, p As Integer = 2) As Double
Return n ^ p
End Function
 
Print power(2) ' muestra 4
Optional parameters are marked by using a question mark in front of the identifier. Their values are passed as option types, i.e. as <code>Some value</code> or <code>None</code>. The helper function <code>defaultArg</code> can be used to specify default values. In the example below, we use shadowing in order to reuse the identifiers <code>ordering</code>, <code>column</code> and <code>reverse</code>.
Print power(2, 3) ' muestra 8
Sleep</syntaxhighlight>
 
Typically, parameters are named at the caller site when optional parameters are involved. However, this is not technically required as long as only right-most arguments are omitted.
 
=={{header|Go}}==
<lang fsharp>type Table(rows:string[][]) =
Go does not have optional parameters so we list the idiomatic alternatives and some less idiomatic ways of achieving an effect similar to optional parameters.
// in-place sorting of rows
member x.Sort(?ordering, ?column, ?reverse) =
let ordering = defaultArg ordering compare
let column = defaultArg column 0
let reverse = defaultArg reverse false
 
===Idiomatic (non-solutions)===
let factor = if reverse then -1 else 1
let comparer (row1:string[]) (row2:string[]) =
factor * ordering row1.[column] row2.[column]
 
'''Zero values'''
Array.sortInPlaceWith comparer rows
member x.Print() =
for row in rows do printfn "%A" row
 
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. Given a table t with method <tt>(table) sort(less func(cell, cell) bool, column int, reverse bool)</tt>, calling <tt>t.sort(nil, 0, false)</tt> to "take the defaults" would make sense. This approach is probably closest to "positional parameters" mentioned in the task description. Note an idiomatic way of specifying an ordering in Go is to provide a "less" function, a function that takes two values and returns true if the the first is "less than" the second in whatever sense specifies the ordering.
// Example usage
let t = new Table([| [|"a"; "b"; "c"|]
[|""; "q"; "z"|]
[|"can"; "z"; "a"|] |])
 
'''Struct'''
printfn "Unsorted"; t.Print()
 
As the number of optional parameters grows, at some point it can be easier to pass a struct containing all of the "parameters". An advantage with this is that you can write a constructor function that sets defaults other than zero values. This is also idiomatic.
t.Sort()
printfn "Default sort"; t.Print()
 
Here is a partial example, partial because it doesn't really have the feel yet of "optional parameters." Note the call to do the reverse sort takes three lines of code, one to construct the parameter struct, one to set the option, and one more to make the call.
t.Sort(column=2)
printfn "Sorted by col. 2"; t.Print()
 
<syntaxhighlight lang="go">type cell string
t.Sort(column=1)
printfn "Sorted by col. 1"; t.Print()
 
type spec struct {
t.Sort(column=1, reverse=true)
less func(cell, cell) bool
printfn "Reverse sorted by col. 1"; t.Print()
column int
reverse bool
}
 
func newSpec() (s spec) {
t.Sort(ordering=fun s1 s2 -> compare s2.Length s1.Length)
// initialize any defaults
printfn "Sorted by decreasing length"; t.Print()</lang>
return
}
 
// sort with all defaults
Output:
t.sort(newSpec())
<pre>Unsorted
[|"a"; "b"; "c"|]
[|""; "q"; "z"|]
[|"can"; "z"; "a"|]
Default sort
[|""; "q"; "z"|]
[|"a"; "b"; "c"|]
[|"can"; "z"; "a"|]
Sorted by col. 2
[|"can"; "z"; "a"|]
[|"a"; "b"; "c"|]
[|""; "q"; "z"|]
Sorted by col. 1
[|"a"; "b"; "c"|]
[|""; "q"; "z"|]
[|"can"; "z"; "a"|]
Reverse sorted by col. 1
[|"can"; "z"; "a"|]
[|""; "q"; "z"|]
[|"a"; "b"; "c"|]
Sorted by decreasing length
[|"can"; "z"; "a"|]
[|"a"; "b"; "c"|]
[|""; "q"; "z"|]</pre>
 
// reverse sort
=={{header|Go}}==
s := newSpec
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. This approach is probably closest to "positional parameters" mentioned in the task description.
s.reverse = true
t.sort(s)</syntaxhighlight>
 
===Struct literal with keyed elements===
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 {
A solution providing more the feel of optional parameters is to pass a struct literal. Go allows a
struct literal to be initialized with named fields but does not require all fields to be specified and does not require them to be specified in order. Thus passing a struct literal can provide very much the feel of optional named parameters. Given,
<syntaxhighlight lang="go">type spec struct {
ordering func(cell, cell) bool
column int
reverse bool
}</langsyntaxhighlight>
the following struct literal fills in zero values for ordering and column and assigns true to the field reverse.
<syntaxhighlight lang ="go">spec{reverse: true}</langsyntaxhighlight>
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.
 
While the effect is close to that of optional parameters, Go idioms have evolved to make this technique quite non-idiomatic. The very popular tool <tt>go vet</tt> issues a warning if a struct literal only initializes a partial set of elements. Popular code grading services on the internet run go vet and will give your code a lower grade for using this technique.
A complete program to demonstrate:
 
<lang go>package main
Nevertheless, a complete program to demonstrate:
<syntaxhighlight lang="go">package main
 
import (
Line 1,002 ⟶ 1,471:
})
t.printRows("sorted by descending string length on second column")
}</langsyntaxhighlight>
Output:
<pre>
Line 1,033 ⟶ 1,502:
["pail" "food"]
</pre>
 
===Functional options===
A technique that gets a nod of approval from the idiom police is sometimes termed "functional options." This technique involves a bit of tricky machinery though and so has not really gained wide popularity. It makes use of Go's variadic arguments and uses functions to initialize a parameter struct. A full solution:
 
<syntaxhighlight 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 (c cell) String() string {
return fmt.Sprintf("%q", string(c))
}
 
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
}
 
// A defined option type is not really needed by the technique, but has
// a nice advantage for documentation. If this type is exported, then
// the the Go documentation tool go doc will organize all of the option
// functions together under the type. (Go doc will see them as constructors
// for the type.)
type Option func(*spec)
 
func ordering(o func(cell, cell) bool) Option {
return func(s *spec) { s.ordering = o }
}
 
func column(c int) Option {
return func(s *spec) { s.column = c }
}
 
func reverse() Option {
return func(s *spec) { s.reverse = true }
}
 
func (t *table) sort(options ...Option) {
var s spec
for _, o := range options {
o(&s)
}
// 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()
t.printRows("sorted on first column")
 
// "named parameter" reverse.
t.sort(reverse())
t.printRows("reverse sorted on first column")
 
// "named parameters" column and ordering
byLen := func(a, b cell) bool { return len(a) > len(b) }
t.sort(column(1), ordering(byLen))
t.printRows("sorted by descending string length on second column")
}</syntaxhighlight>
Output same as previous solution.
 
=={{header|Groovy}}==
Optional Parameters:
<langsyntaxhighlight lang="groovy">def orderedSort(Collection table, column = 0, reverse = false, ordering = {x, y -> x <=> y } as Comparator) {
table.sort(false) { x, y -> (reverse ? -1 : 1) * ordering.compare(x[column], y[column])}
}</langsyntaxhighlight>
 
Test code:
<langsyntaxhighlight lang="groovy">def table = [['a', 'b', 'c'], ['', 'q', 'z'], ['zap', 'zip', 'Zot']]
 
assert orderedSort(table) == [['', 'q', 'z'], ['a', 'b', 'c'], ['zap', 'zip', 'Zot']]
Line 1,047 ⟶ 1,633:
assert orderedSort(table, 1) == [['a', 'b', 'c'], ['', 'q', 'z'], ['zap', 'zip', 'Zot']]
assert orderedSort(table, 1, true) == [['zap', 'zip', 'Zot'],['', 'q', 'z'],['a', 'b', 'c']]
assert orderedSort(table, 0, false, {x, y -> y?.size() <=> x?.size()} as Comparator) == [['zap', 'zip', 'Zot'],['a', 'b', 'c'],['', 'q', 'z']]</langsyntaxhighlight>
 
Named Parameters:
<langsyntaxhighlight lang="groovy">Collection.metaClass.orderedSort = { params ->
def column = params?.column ?: 0
def reverse = params?.reverse ?: false
Line 1,056 ⟶ 1,642:
 
table.sort(false) { x, y -> (reverse ? -1 : 1) * ordering.compare(x[column], y[column])}
}</langsyntaxhighlight>
 
Test Code:
 
<langsyntaxhighlight lang="groovy">def table = [['a', 'b', 'c'], ['', 'q', 'z'], ['zap', 'zip', 'Zot']]
 
assert table.orderedSort() == [['', 'q', 'z'], ['a', 'b', 'c'], ['zap', 'zip', 'Zot']]
Line 1,066 ⟶ 1,652:
assert table.orderedSort(column: 1) == [['a', 'b', 'c'], ['', 'q', 'z'], ['zap', 'zip', 'Zot']]
assert table.orderedSort(column: 1, reverse: true) == [['zap', 'zip', 'Zot'],['', 'q', 'z'],['a', 'b', 'c']]
assert table.orderedSort(ordering: {x, y -> y?.size() <=> x?.size()} as Comparator) == [['zap', 'zip', 'Zot'],['a', 'b', 'c'],['', 'q', 'z']]</langsyntaxhighlight>
 
=={{header|Haskell}}==
Option 1: Using haskell's record update syntax, we can simulate named default arguments. This method has the drawback of not allowing for a parameter to be positional and named simultaneously.
<langsyntaxhighlight lang="haskell">
{-# LANGUAGE RecordWildCards #-}
 
Line 1,086 ⟶ 1,672:
sorter defSortArgs [[]]
return ()
</syntaxhighlight>
</lang>
 
Option 2: This method has the drawback of being a bit verbose and requiring you to supply "Maybe a" arguments.
<langsyntaxhighlight lang="haskell">
import Data.Maybe (fromMaybe)
-- Use fromMaybe as an operator because its prettier
Line 1,102 ⟶ 1,688:
sorter (Just "foo") (Just 1) (Just True)
sorter Nothing Nothing Nothing
</syntaxhighlight>
</lang>
 
=={{header|Icon}} and {{header|Unicon}}==
Optional named parameters are not the norm in Icon/Unicon. In the example below ''bubblesortf'' would be a version of [[Sorting_algorithms/Bubble_sort#Icon_and_Unicon|Bubble Sort]] modified to sort on a column number (Ordering is already supported). It could equally be replaced by any similarly modified Rosetta sort. The use of ''reverse'' on a list is a Unicon extension; in Icon a procedure from the IPL must be linked.
<langsyntaxhighlight Iconlang="icon">
procedure main()
X := [ [1,2,3], [2,3,1], [3,1,2]) # A list of lists
Line 1,126 ⟶ 1,712:
}
return (\reverseorder|1)(bubblesortf(X,\c|1,\op|"<<")) # reverse or return the sorted list
end</langsyntaxhighlight>
 
=={{header|J}}==
 
<langsyntaxhighlight lang="j">srtbl=: verb define
'' srtbl y
:
'`ordering column reverse'=. x , (#x)}. ]`0:`0:
|.^:reverse y /: ordering (column {"1 ])y
)</langsyntaxhighlight>
 
For simplicity, the optional arguments are all functions, and are positional (on the left -- the table, with its arbitrary number of rows and columns, is on the right). Note also that the ordering function is expected to map its entire argument (since this offers much better efficiencies than a binary comparison).
 
'''Example Use'''
<langsyntaxhighlight lang="j"> ]Table=: ('a';'b';'c'),('';'q';'z'),:'zip';'zap';'Zot'
┌───┬───┬───┐
│a │b │c │
Line 1,179 ⟶ 1,765:
├───┼───┼───┤
│zip│zap│Zot│
└───┴───┴───┘</langsyntaxhighlight>
 
=={{header|Java}}==
Line 1,185 ⟶ 1,771:
Java has no optional parameters, but methods can be overloaded on the number and types of arguments, which can be used to effectively achieve optional positional parameters.
 
<langsyntaxhighlight lang="java">import java.util.*;
 
public class OptionalParams {
Line 1,257 ⟶ 1,843:
// prints: [[zap, zip, Zot], [a, b, c], [, q, z]]
}
}</langsyntaxhighlight>
 
=={{header|JavaScript}}==
See [[Named parameters#JavaScript]], to pass named parameters one uses an object with properties set:
<langsyntaxhighlight lang="javascript">function sorter(table, options) {
opts = {}
opts.ordering = options.ordering || 'lexicographic';
Line 1,270 ⟶ 1,856:
}
 
sorter(the_data, {reverse: true, ordering: 'numeric'});</langsyntaxhighlight>
 
=={{header|jq}}==
Line 1,300 ⟶ 1,886:
interpreted by jq. The key to understanding this is that jq functions
are compiled into closures. Here is an example:
<langsyntaxhighlight lang="jq">def bar: 2 *.;
 
def foo: {"a": bar};</langsyntaxhighlight>
The expression <tt>3 | foo.a</tt> evaluates to 6.
 
Line 1,309 ⟶ 1,895:
sort_table(ordering; column; reverse) is already defined. To specify the lexicographic
ordering on strings in terms of an arity-0 filter, we define less_than_or_equal/0 as follows:
<langsyntaxhighlight lang="jq">def less_than_or_equal: .[0] <= .[1];</langsyntaxhighlight>
 
'''The Task''':
<langsyntaxhighlight lang="jq">def sorter(options):
sort_table( if (options|has("ordering")) then options.ordering
else less_than_or_equal
Line 1,320 ⟶ 1,906:
 
# If jq > 1.4 is being used, we may also define:
def sorter: sorter({});</langsyntaxhighlight>
'''Examples''':
<langsyntaxhighlight lang="jq">[1,2] | sorter({ "reverse": true, "ordering": less_than_or_equal } )
 
[1,2] | sorter({ "reverse": true })
 
# If sorter/0 has also been defined:
[1,2] | sorter</langsyntaxhighlight>
 
=={{header|Julia}}==
Julia supports both named and positional optional parameters. We can define both versions at the same time if we want:
<langsyntaxhighlight lang="julia">sorttable(T; ordering=<, column=1, reverse=false) =
sort(T, by = t -> t[column], lt = reverse ? (a,b) -> ordering(b,a) : ordering)
sorttable(T, ordering=<, column=1, reverse=false) =
sorttable(T, ordering=ordering, column=column, reverse=reverse)</langsyntaxhighlight>
where the <code>;</code> in the argument list denotes the named-parameter variant, and we have used Julia's built-in higher-order <code>sort</code> function to do the work. Note that we simply pass a comparison function for the ordering, and the built-in <code><</code> operator is actually just a function that (on strings) compares in lexicographic order.
 
Example output:
<langsyntaxhighlight lang="julia">julia> data = {["a", "b", "c"], ["", "q", "z"], ["zap", "zip", "Zot"]}
3-element Array{Any,1}:
["a","b","c"]
Line 1,354 ⟶ 1,940:
["zap","zip","Zot"]
["","q","z"]
["a","b","c"] </langsyntaxhighlight>
 
=={{header|Klingphix}}==
<syntaxhighlight lang="klingphix">include ..\Utilitys.tlhy
 
:mypower
1 tolist flatten len
1 equal
( [pop drop 2]
[pop pop drop]
) if
power
;
"2 ^2 = " print 2 mypower ?
"2 ^3 = " print ( 2 3 ) mypower ?
 
"End " input</syntaxhighlight>
 
=={{header|Kotlin}}==
<syntaxhighlight lang="scala">// version 1.1.51
 
typealias Table = List<List<String>>
 
/* Note that if ordering is specified, first two parameters are ignored */
fun Table.sort(
column: Int = 0,
reverse: Boolean = false,
ordering: Comparator<List<String>> =
if (!reverse) compareBy { it[column] }
else compareByDescending { it[column] }
) = this.sortedWith(ordering)
 
fun Table.print(title: String) {
println(title)
for (i in 0 until this.size) {
for (j in 0 until this[0].size) System.out.print("%-3s ".format(this[i][j]))
println()
}
println()
}
 
fun main(args: Array<String>) {
val table = listOf(
listOf("a", "b", "c"),
listOf("", "q", "z"),
listOf("zap", "zip", "Zot")
)
table.print("Original:")
 
val titles = listOf(
"Sorted by col 0:", "Sorted by col 1:", "Sorted by col 2:",
"Reverse sorted by col 0:", "Reverse sorted by col 1:", "Reverse Sorted by col 2"
)
val params = listOf(
0 to false, 1 to false, 2 to false, 0 to true, 1 to true, 2 to true
)
for ((i, title) in titles.withIndex()) {
val table2 = table.sort(params[i].first, params[i].second)
table2.print(title)
}
// using non-default Comparator (case insensitive by col 2, reversed)
val comp: Comparator<List<String>> = compareByDescending { it[2].toLowerCase() }
val table3 = table.sort(ordering = comp)
table3.print("Reverse case insensitive sort by col 2:")
}</syntaxhighlight>
 
{{out}}
<pre>
Original:
a b c
q z
zap zip Zot
 
Sorted by col 0:
q z
a b c
zap zip Zot
 
Sorted by col 1:
a b c
q z
zap zip Zot
 
Sorted by col 2:
zap zip Zot
a b c
q z
 
Reverse sorted by col 0:
zap zip Zot
a b c
q z
 
Reverse sorted by col 1:
zap zip Zot
q z
a b c
 
Reverse Sorted by col 2
q z
a b c
zap zip Zot
 
Reverse case insensitive sort by col 2:
zap zip Zot
q z
a b c
</pre>
 
=={{header|Lasso}}==
Lasso can handle both positional and named params. Methods support multiple dispatch where each dispatch defines it's own set of parameters.
<langsyntaxhighlight Lassolang="lasso">define sortarray( // params are set by position
items::array, // required param
ordering::string = 'lexicographic', // optional param
Line 1,390 ⟶ 2,084:
sortarray(-items = #items, -reverse)
 
sortarray(#items)</langsyntaxhighlight>
 
=={{header|TIScript}}==
 
TIScript allows to define optional parameters with default values:
 
<lang javascript>function sorter(table, ordering = "lexicographic", column = 0, reverse = false) {
// ...
}
 
sorter(the_data,"numeric");</lang>
 
=={{header|Logo}}==
{{works with|UCB Logo}}
<langsyntaxhighlight lang="logo">to sort :table [:column 1] [:ordering "before?] [:reverse "false]
; ...
end</langsyntaxhighlight>
The function "sort" has a default arity of 1 for the required parameter. When overriding default parameters, you must wrap the call in parentheses to specify the different arity.
<langsyntaxhighlight lang="logo">sort :table
(sort :table 2)
(sort :table 3 "less? "true)</langsyntaxhighlight>
 
=={{header|Lua}}==
<syntaxhighlight lang="lua">
function showTable(tbl)
if type(tbl)=='table' then
local result = {}
for _, val in pairs(tbl) do
table.insert(result, showTable(val))
end
return '{' .. table.concat(result, ', ') .. '}'
else
return (tostring(tbl))
end
end
 
function sortTable(op)
local tbl = op.table or {}
local column = op.column or 1
local reverse = op.reverse or false
local cmp = op.cmp or (function (a, b) return a < b end)
local compareTables = function (a, b)
local result = cmp(a[column], b[column])
if reverse then return not result else return result end
end
table.sort(tbl, compareTables)
end
 
A = {{"quail", "deer", "snake"},
{"dalmation", "bear", "fox"},
{"ant", "cougar", "coyote"}}
print('original', showTable(A))
 
sortTable{table=A}
print('defaults', showTable(A))
 
sortTable{table=A, column=2}
print('col 2 ', showTable(A))
 
sortTable{table=A, column=3}
print('col 3 ', showTable(A))
 
sortTable{table=A, column=3, reverse=true}
print('col 3 rev', showTable(A))
 
sortTable{table=A, cmp=(function (a, b) return #a < #b end)}
print('by length', showTable(A))
</syntaxhighlight>
{{out}}
<pre>
original {{quail, deer, snake}, {dalmation, bear, fox}, {ant, cougar, coyote}}
defaults {{ant, cougar, coyote}, {dalmation, bear, fox}, {quail, deer, snake}}
col 2 {{dalmation, bear, fox}, {ant, cougar, coyote}, {quail, deer, snake}}
col 3 {{ant, cougar, coyote}, {dalmation, bear, fox}, {quail, deer, snake}}
col 3 rev {{quail, deer, snake}, {dalmation, bear, fox}, {ant, cougar, coyote}}
by length {{ant, cougar, coyote}, {quail, deer, snake}, {dalmation, bear, fox}}
</pre>
 
=={{header|Maple}}==
<syntaxhighlight lang="maple">
<lang Maple>
OptionalSort := proc(input, {
ordering :: Or(procedures,identical("lexicographic")) := "lexicographic",
Line 1,426 ⟶ 2,166:
end if;
sort( input, compare );
end proc:</langsyntaxhighlight>
 
Some examples of this procedure in action:
<syntaxhighlight lang="maple">
<lang Maple>
> L := [[1, 2], [3, 4], [-5, 7]]:
> OptionalSort(L);
Line 1,437 ⟶ 2,177:
> OptionalSort(L, reverse, column = 2);
[[-5, 7], [3, 4], [1, 2]]
</syntaxhighlight>
</lang>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<langsyntaxhighlight Mathematicalang="mathematica">Options[OptionalSort]={ordering->lexicographic,column->1,reverse-> False};
OptionalSort[x_List,OptionsPattern[]]:=If[OptionValue[reverse]==True,
SortBy[x ,#[[OptionValue[column]]]&]//Reverse,
Line 1,449 ⟶ 2,189:
 
OptionalSort[{{"a" ,"b", "c"}, {"", "q", "z"},{"zap" ,"zip", "Zot"}},{ordering->lexicographic,column->2,reverse-> True} ]
->{{zap,zip,Zot},{,q,z},{a,b,c}}</langsyntaxhighlight>
 
=={{header|Nemerle}}==
It's possible to use either optional parameters or overloading on parameter number (or type). However, it's less code repetition to use optional parameters when possible (unless, of course, the implementation varies drastically with different parameters).
<langsyntaxhighlight Nemerlelang="nemerle">Sorter (table : list[list[string]], ordering = "lexicographic", column = 0, reverse = false) : list[list[string]]
{
// implementation goes here
}</langsyntaxhighlight>
 
=={{header|Nim}}==
<langsyntaxhighlight lang="nim">import algorithm, strutils, futuresugar
 
proc printTable(a: seq[seq[string]]) =
for row in a:
for x in row: stdout.write x, repeatCharrepeat(' ', 4 - x.len)
echo ""
echo ""
Line 1,480 ⟶ 2,220:
printTable sortTable(data, column = 1)
printTable sortTable(data, column = 1, reverse = true)
printTable sortTable(data, ordering = (a,b) => cmp[int](b.len,a.len))</langsyntaxhighlight>
Output:
<pre>a b c
Line 1,508 ⟶ 2,248:
=={{header|Objective-C}}==
Without getting into any detail, here is one way you might implement optional arguments. (Note that since Objective-C is a strict superset of C, any C solution can be used as well.)
<langsyntaxhighlight lang="objc">typedef enum { kOrdNone, kOrdLex, kOrdByAddress, kOrdNumeric } SortOrder;
 
@interface MyArray : NSObject {}
Line 1,532 ⟶ 2,272:
}
 
@end</langsyntaxhighlight>
 
=={{header|OCaml}}==
Line 1,538 ⟶ 2,278:
OCaml has optional named parameters. It is conventional to place a non-optional parameter after the optional parameters, because if the optional parameters were at the end, then if you don't provide them, it will just look like a partial application (because OCaml supports [[currying]]), resulting in a function which still expects the optional parameters.
 
<langsyntaxhighlight lang="ocaml">let sort_table ?(ordering = compare) ?(column = 0) ?(reverse = false) table =
let cmp x y = ordering (List.nth x column) (List.nth y column) * (if reverse then -1 else 1) in
List.sort cmp table</langsyntaxhighlight>
 
Example uses:
<langsyntaxhighlight lang="ocaml"># let data = [["a"; "b"; "c"]; [""; "q"; "z"]; ["zap"; "zip"; "Zot"]];;
val data : string list list =
[["a"; "b"; "c"]; [""; "q"; "z"]; ["zap"; "zip"; "Zot"]]
Line 1,560 ⟶ 2,300:
# sort_table ~ordering:(fun a b -> compare (String.length b) (String.length a)) data;;
- : string list list =
[["zap"; "zip"; "Zot"]; ["a"; "b"; "c"]; [""; "q"; "z"]]</langsyntaxhighlight>
 
OCaml does not support optional positional parameters, because, since OCaml supports currying, it would conflict with partial applications, where you do not provide all the arguments to a function, and it results in a function which expects the remaining arguments.
Line 1,566 ⟶ 2,306:
=={{header|Oz}}==
Oz supports optional parameters only for methods, not for functions.
<langsyntaxhighlight lang="oz">declare
class Table
attr
Line 1,595 ⟶ 2,335:
{T sort(column:2)}
{T sort(column:2 reverse:true)}
{T sort(ordering:fun {$ A B} {Length B} < {Length A} end)}</langsyntaxhighlight>
 
=={{header|PARI/GP}}==
As it happens the built-in <code>vecsort()</code> function fulfills all the requirements of this task. In general optional arguments are handled in GP by default values:
<langsyntaxhighlight lang="parigp">sort(v, ordering=0, column=0, reverse=0)</langsyntaxhighlight>
while in PARI it is handled by checking for NULL (assuming parser code DG, see 5.7.3 in the User's Guide to the PARI library):
<syntaxhighlight lang="c">/*
<lang C>/*
GP;install("test_func", "vDG", "test", "path/to/test.gp.so");
*/
Line 1,610 ⟶ 2,350:
else
pari_printf("Argument was: %Ps\n", x);
}</langsyntaxhighlight>
 
=={{header|Perl}}==
Line 1,617 ⟶ 2,357:
This function expects its first argument to be a reference to an array of arrays. It interprets any remaining arguments as a hash of optional parameters.
 
<langsyntaxhighlight lang="perl">sub sorttable
{my @table = @{shift()};
my %opt =
Line 1,626 ⟶ 2,366:
{$func->($a->[$col], $b->[$col])}
@table;
return ($opt{reverse} ? [reverse @result] : \@result);}</langsyntaxhighlight>
 
An example of use:
 
<langsyntaxhighlight lang="perl">my $a = [["a", "b", "c"], ["", "q", "z"], ["zap", "zip", "Zot"]];
foreach (@{sorttable $a, column => 1, reverse => 1})
{foreach (@$_)
{printf "%-5s", $_;}
print "\n";}</langsyntaxhighlight>
 
=={{header|Perl 6}}==
Using named parameters:
<lang perl6>method sorttable(:$column = 0, :$reverse, :&ordering = &infix:<cmp>) {
my @result = self»[$column].sort: &ordering;
return $reverse ?? @result.reverse !! @result;
}</lang>
 
=={{header|Phix}}==
{{libheader|Phix/basics}}
Optional parameters are specified simply by declaring a default value. They must however be grouped on the right.
 
<!--<syntaxhighlight lang="phix">-->
<lang Phix>function increment(integer i, integer inc=1)
<span style="color: #008080;">function</span> <span style="color: #000000;">increment</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">inc</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
return i+inc
<span style="color: #008080;">return</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">inc</span>
end function
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
 
?increment(5) -- shows 6
<span style="color: #0000FF;">?</span><span style="color: #000000;">increment</span><span style="color: #0000FF;">(</span><span style="color: #000000;">5</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- shows 6</span>
?increment(5,2) -- shows 7</lang>
<span style="color: #0000FF;">?</span><span style="color: #000000;">increment</span><span style="color: #0000FF;">(</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- shows 7</span>
<!--</syntaxhighlight>-->
 
You can also use a variable length sequence to emulate optional parameters.
 
<!--<syntaxhighlight lang="phix">-->
<lang Phix>printf(1,"%d records sorted in %3.2s\n",{records,time()-t0})</lang>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%d records sorted in %3.2s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">records</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">time</span><span style="color: #0000FF;">()-</span><span style="color: #000000;">t0</span><span style="color: #0000FF;">})</span>
<!--</syntaxhighlight>-->
 
In other words printf always accepts exactly three arguments, but the third should contain the correct number of
Line 1,662 ⟶ 2,400:
The following incomplete snippet from demo\pGUI\listview.exw shows the basic idea for sorting a table by any column, up or down:
 
<!--<syntaxhighlight lang="phix">-->
<lang Phix>integer sortcol = 0
<span style="color: #004080;">integer</span> <span style="color: #000000;">sortcol</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span>
integer sortdir = 1
<span style="color: #000000;">sortdir</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">by_column</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">sortdir</span><span style="color: #0000FF;">*</span><span style="color: #7060A8;">compare</span><span style="color: #0000FF;">(</span><span style="color: #000000;">data</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">][</span><span style="color: #000000;">sortcol</span><span style="color: #0000FF;">],</span><span style="color: #000000;">data</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">][</span><span style="color: #000000;">sortcol</span><span style="color: #0000FF;">])</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">tags</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #000000;">table_size</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- {1,2,..table_size}</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">click_cb</span><span style="color: #0000FF;">(</span><span style="color: #004080;">Ihandle</span> <span style="color: #000000;">self</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">l</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">atom</span> <span style="color: #000000;">pStatus</span><span style="color: #0000FF;">)</span>
<span style="color: #0000FF;">...</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">sortc</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"SORTSIGN%d"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">c</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">sortdir</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">IupGetAttribute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">self</span><span style="color: #0000FF;">,</span><span style="color: #000000;">sortc</span><span style="color: #0000FF;">)=</span><span style="color: #008000;">"DOWN"</span><span style="color: #0000FF;">?-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">:</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">IupSetAttribute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">self</span><span style="color: #0000FF;">,</span><span style="color: #000000;">sortc</span><span style="color: #0000FF;">,</span><span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">sortdir</span><span style="color: #0000FF;">=-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">?</span><span style="color: #008000;">"UP"</span><span style="color: #0000FF;">:</span><span style="color: #008000;">"DOWN"</span><span style="color: #0000FF;">))</span>
<span style="color: #000000;">sortcol</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">c</span>
<span style="color: #000000;">tags</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">custom_sort</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">routine_id</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"by_column"</span><span style="color: #0000FF;">),</span><span style="color: #000000;">tags</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">value_cb</span><span style="color: #0000FF;">(</span><span style="color: #004080;">Ihandle</span> <span style="color: #000080;font-style:italic;">/*self*/</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">l</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">l</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">tags</span><span style="color: #0000FF;">[</span><span style="color: #000000;">l</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">data</span><span style="color: #0000FF;">[</span><span style="color: #000000;">l</span><span style="color: #0000FF;">][</span><span style="color: #000000;">c</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<!--</syntaxhighlight>-->
 
=={{header|Phixmonti}}==
<syntaxhighlight lang="phixmonti">def mypower
1 tolist flatten len
1 == if
1 get 2
else
2 get swap 1 get rot
endif
power
nip
enddef
 
"2 ^2 = " print 2 mypower print nl
"2 ^3 = " print 2 3 2 tolist mypower print</syntaxhighlight>
More elegant.
<syntaxhighlight lang="phixmonti">include ..\Utilitys.pmt
 
def mypower
1 tolist flatten len
1 == if
pop drop 2
else
pop pop drop
endif
power
enddef
 
"2 ^2: " print 2 mypower ?
"2 ^3: " print ( 2 3 ) mypower ?</syntaxhighlight>
More in line with the task description
<syntaxhighlight lang="phixmonti">include ..\Utilitys.pmt
 
( ( "a" "b" "c" )
( "" "q" "z" )
( "zap" "zip" "Zot" ) )
 
def mysort /# column reverse #/
len >ps
tps 0 == if drop ( 1 false ) endif
ps> 1 == if false 0 put endif
pop swap >ps pop drop swap
len for var i
i get
tps extract swap 1 put
i set
endfor
sort
swap if reverse endif
len for var i
i get
pop swap tps put
i set
endfor
ps> drop
enddef
 
pstack
( ) mysort pstack
( 3 ) mysort pstack
( 2 ) mysort pstack
( 2 true ) mysort pstack
</syntaxhighlight>
{{out}}
<pre>
[[["a", "b", "c"], ["", "q", "z"], ["zap", "zip", "Zot"]]]
 
[[["", "q", "z"], ["a", "b", "c"], ["zap", "zip", "Zot"]]]
 
[[["zap", "zip", "Zot"], ["a", "b", "c"], ["", "q", "z"]]]
function by_column(integer i, integer j)
return sortdir*compare(data[i][sortcol],data[j][sortcol])
end function
 
[[["a", "b", "c"], ["", "q", "z"], ["zap", "zip", "Zot"]]]
sequence tags = tagset(table_size) -- {1,2,..table_size}
 
[[["zap", "zip", "Zot"], ["", "q", "z"], ["a", "b", "c"]]]
function click_cb(Ihandle self, integer l, integer c, atom pStatus)
string sortc
...
sortc = sprintf("SORTSIGN%d",c)
sortdir = iff(IupGetAttribute(self,sortc)="DOWN"?-1:1)
IupSetAttribute(self,sortc,iff(sortdir=-1?"UP":"DOWN"))
sortcol = c
tags = custom_sort(routine_id("by_column"),tags)
 
=== Press any key to exit ===</pre>
function value_cb(Ihandle /*self*/, integer l, integer c)
l = tags[l]
return data[l][c]
end function</lang>
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(de sortTable (Tbl . @)
(let (Ordering prog Column 1 Reverse NIL) # Set defaults
(bind (rest) # Bind optional params
Line 1,693 ⟶ 2,509:
sort
Tbl ) )
(if Reverse (flip Tbl) Tbl) ) ) )</langsyntaxhighlight>
Output:
<pre>(de *Data ("a" "bcdef" "X") (" " "qrst" "z") ("zap" "zip" "Zot"))
Line 1,713 ⟶ 2,529:
 
Using a pretty-printer for the table
<langsyntaxhighlight lang="python">>>> def printtable(data):
for row in data:
print ' '.join('%-5s' % ('"%s"' % cell) for cell in row)
Line 1,747 ⟶ 2,563:
"a" "b" "c"
"" "q" "z"
>>></langsyntaxhighlight>
 
See the Python entry in [[Named_Arguments#Python|Named Arguments]] for a more comprehensive description of Python function parameters and call arguments.
Line 1,767 ⟶ 2,583:
=={{header|R}}==
Optional parameters are given using a name=value syntax within the function header.
<langsyntaxhighlight Rlang="r">tablesort <- function(x, ordering="lexicographic", column=1, reverse=false)
{
# Implementation
Line 1,773 ⟶ 2,589:
 
# Usage is e.g.
tablesort(mytable, column=3)</langsyntaxhighlight>
 
=={{header|Racket}}==
 
<langsyntaxhighlight lang="racket">
#lang racket
 
Line 1,788 ⟶ 2,604:
ordering)
#:key (λ (row) (list-ref row column))))
</syntaxhighlight>
</lang>
 
=={{header|Raku}}==
(formerly Perl 6)
Using named parameters:
<syntaxhighlight lang="raku" line>method sorttable(:$column = 0, :$reverse, :&ordering = &infix:<cmp>) {
my @result = self»[$column].sort: &ordering;
return $reverse ?? @result.reverse !! @result;
}</syntaxhighlight>
 
Using optional positional parameters:
<syntaxhighlight lang="raku" line>method sorttable-pos($column = 0, $reverse?, &ordering = &infix:<cmp>) {
my @result = self»[$column].sort: &ordering;
return $reverse ?? @result.reverse !! @result;
}</syntaxhighlight>
 
=={{header|REXX}}==
The REXX language allows for default values for positional arguments as well as an easy method to check if a string is part of a parameter.
<br>Also allowed are named parameters.
<br><br>The REXX language doesn't have any native sorting functions, &nbsp; so you have to write your own sorting subroutine.
<langsyntaxhighlight lang="rexx">sortStrings: procedure expose @. /*the stemmed array is named: @. */
col= 1; reverse='NO'; order='LEXICOGRAPHIC' /*set some defaults (here and below). */
reverse= 'NO'
arg options
order= 'LEXICOGRAPHIC'
do j=1 for words(options); x=word(options,j)
arg options /*obtain the options (in uppercase). */
 
do j=1 for words(options) /*examine all the words (options). */
x= word(options, j)
select
when datatype(x, 'W') then col= x / 1 /*normalize the number. */
when pos('=', x)==0 then order= x /*has it an equal sign? */
otherwise parse var x nam '=' value /*get value.*/
end /*select*/
end /*j*/
 
/*╔═══════════════════════════════════════════════════════════╗
/*╔═══════════════════════════════════════════════════════════╗
║ check for errors here: COL isn't a positive integer ···, ║
check for errors here: REVERSE valueCOL isn't a NO orpositive integer YES···, ║
ORDER REVERSE value isisn't NO recognized ···or YES,
║ ORDER value is recognized ··· ║
╚═══════════════════════════════════════════════════════════╝*/
╚═══════════════════════════════════════════════════════════╝*/
 
... main body of string sort here ...
 
return /*stick a fork in it, we're done.*/</lang>
return /*stick a fork in it, we're all done. */</syntaxhighlight>
An example use is:
<langsyntaxhighlight lang="rexx">/*REXX example uses the SortStrings subroutine with withsome (passed) optional argsarguments. */
 
/*···define array (@.nnn) of strings here···*/
 
@.1= 'one'; @.2= "two"; @.3= 'three' /*define an array (@.) of strings here.*/
 
 
call sortStrings 'Reverse=no' 3
/*stick a fork in it, we're all done. */</syntaxhighlight>
</lang>
 
=={{header|Ruby}}==
Ruby allows default values for positional arguments, but they have disadvantages. In the next example, if you want to pass ''reverse=true'', you must also give values for ''ordering'' and ''column''.
 
<langsyntaxhighlight lang="ruby">def table_sort(table, ordering=:<=>, column=0, reverse=false)
# ...</langsyntaxhighlight>
 
Ruby 2.0 added keyword arguments to the language. These provide the most natural solution.
 
{{works with|Ruby|2.0}}
<langsyntaxhighlight lang="ruby">def table_sort(table, ordering: :<=>, column: 0, reverse: false)
p = ordering.to_proc
if reverse
Line 1,843 ⟶ 2,681:
["Mexico City", "Mexico"],
]
p table_sort(table, column: 1)</langsyntaxhighlight>
 
Older versions of Ruby can fake the effect with a Hash (as detailed in [[Named parameters#Ruby]]). The next example needs Ruby 1.8.7 only because the sort code calls <code>Symbol#to_proc</code>; the passing of parameters would yet work with Ruby older than 1.8.7.
 
{{works with|Ruby|1.8.7}}
<langsyntaxhighlight lang="ruby">def table_sort(table, opts = {})
defaults = {:ordering => :<=>, :column => 0, :reverse => false}
opts = defaults.merge(opts)
Line 1,859 ⟶ 2,697:
table.sort {|a, b| p.call(a[c], b[c])}
end
end</langsyntaxhighlight>
 
=={{header|Rust}}==
 
Rust doesn't really have optional parameters.
One way could be to use the <code>Option</code> syntax, but then you still would have to specify the optional parameters in the function calls as <code>None</code>, which would kind of defeat the purpose.
Here we use Rust's "standard way" to have optional parameters, i.e. by using builders instead.
 
<syntaxhighlight lang="rust">use std::cmp::Ordering;
 
struct Table {
rows: Vec<Vec<String>>,
ordering_function: fn(&str, &str) -> Ordering,
ordering_column: usize,
reverse: bool,
}
 
impl Table {
fn new(rows: Vec<Vec<String>>) -> Table {
Table {
rows: rows,
ordering_column: 0,
reverse: false,
ordering_function: |str1, str2| str1.cmp(str2),
}
}
}
 
impl Table {
fn with_ordering_column(&mut self, ordering_column: usize) -> &mut Table {
self.ordering_column = ordering_column;
self
}
 
fn with_reverse(&mut self, reverse: bool) -> &mut Table {
self.reverse = reverse;
self
}
 
fn with_ordering_fun(&mut self, compare: fn(&str, &str) -> Ordering) -> &mut Table {
self.ordering_function = compare;
self
}
 
fn sort(&mut self) {
let fun = &mut self.ordering_function;
let idx = self.ordering_column;
if self.reverse {
self.rows
.sort_unstable_by(|vec1, vec2| (fun)(&vec1[idx], &vec2[idx]).reverse());
} else {
self.rows
.sort_unstable_by(|vec1, vec2| (fun)(&vec1[idx], &vec2[idx]));
}
}
}
 
#[cfg(test)]
mod test {
use super::Table;
 
fn generate_test_table() -> Table {
Table::new(vec![
vec!["0".to_string(), "fff".to_string()],
vec!["2".to_string(), "aab".to_string()],
vec!["1".to_string(), "ccc".to_string()],
])
}
 
#[test]
fn test_simple_sort() {
let mut table = generate_test_table();
table.sort();
assert_eq!(
table.rows,
vec![
vec!["0".to_string(), "fff".to_string()],
vec!["1".to_string(), "ccc".to_string()],
vec!["2".to_string(), "aab".to_string()],
],
)
}
 
#[test]
fn test_ordering_column() {
let mut table = generate_test_table();
table.with_ordering_column(1).sort();
assert_eq!(
table.rows,
vec![
vec!["2".to_string(), "aab".to_string()],
vec!["1".to_string(), "ccc".to_string()],
vec!["0".to_string(), "fff".to_string()],
],
)
}
 
#[test]
fn test_with_reverse() {
let mut table = generate_test_table();
table.with_reverse(true).sort();
assert_eq!(
table.rows,
vec![
vec!["2".to_string(), "aab".to_string()],
vec!["1".to_string(), "ccc".to_string()],
vec!["0".to_string(), "fff".to_string()],
],
)
}
 
#[test]
fn test_custom_ordering_fun() {
let mut table = generate_test_table();
// Simple ordering function that reverses stuff.
// Should operate like the test before.
table.with_ordering_fun(|x, y| x.cmp(y).reverse()).sort();
assert_eq!(
table.rows,
vec![
vec!["2".to_string(), "aab".to_string()],
vec!["1".to_string(), "ccc".to_string()],
vec!["0".to_string(), "fff".to_string()],
],
)
}
 
#[test]
fn test_everything_together() {
let mut table = generate_test_table();
// Using the reversing cmp function, then reverse (= don't do anything)
// then sort from column 1.
table
.with_ordering_fun(|x, y| x.cmp(y).reverse())
.with_reverse(true)
.with_ordering_column(1)
.sort();
assert_eq!(
table.rows,
vec![
vec!["2".to_string(), "aab".to_string()],
vec!["1".to_string(), "ccc".to_string()],
vec!["0".to_string(), "fff".to_string()],
],
)
}
}
</syntaxhighlight>
 
=={{header|Scala}}==
With Scala 2.8 optional and named parameters are build in.
<langsyntaxhighlight lang="scala"> def sortTable(data: List[List[String]],
ordering: (String, String) => Boolean = (_ < _),
column: Int = 0,
Line 1,869 ⟶ 2,854:
val result = data.sortWith((a, b) => ordering(a(column), b(column)))
if (reverse) result.reverse else result
}</langsyntaxhighlight>
<langsyntaxhighlight lang="scala">val data=List(List("a","b","c"), List("","q","z"), List("zap","zip","Zot"))
println(data)
//-> List(List(a, b, c), List(, q, z), List(zap, zip, Zot))
Line 1,880 ⟶ 2,865:
//-> List(List(zap, zip, Zot), List(a, b, c), List(, q, z))
println(sortTable(data, ((a, b)=> b.size<a.size)))
//-> List(List(zap, zip, Zot), List(a, b, c), List(, q, z))</langsyntaxhighlight>
 
=={{header|Sidef}}==
<langsyntaxhighlight lang="ruby">func table_sort(table, ordering: '<=>', column: 0, reverse: false) {
if (reverse) {
table.sort {|a,b| b[column].$ordering(a[column])}
Line 1,898 ⟶ 2,883:
];
 
say table_sort(table, column: 1);</langsyntaxhighlight>
{{out}}
<pre>[["Ottowa", "Canada"], ["Mexico City", "Mexico"], ["Washington", "USA"]]</pre>
 
Missing the point, we can also create and provide a custom method for sorting to ''ordering'':
<langsyntaxhighlight lang="ruby">class String {
method my_sort(arg) {
(self.len <=> arg.len) ->
Line 1,911 ⟶ 2,896:
}
say table_sort(table, column: 1, ordering: 'my_sort');</langsyntaxhighlight>
{{out}}
<pre>[["Washington", "USA"], ["Ottowa", "Canada"], ["Mexico City", "Mexico"]]</pre>
Line 1,917 ⟶ 2,902:
=={{header|Slate}}==
In Slate, named optional parameters may be specified in the method signature, but not defaults, so there is a macro <tt>defaultsTo:</tt> for specifying that within the method body at run-time.
<langsyntaxhighlight lang="slate">s@(Sequence traits) tableSort &column: column &sortBy: sortBlock &reverse: reverse
[
column `defaultsTo: 0.
Line 1,924 ⟶ 2,909:
ifTrue: [sortBlock := [| :a :b | (sortBlock applyTo: {a. b}) not]].
s sortBy: [| :a :b | sortBlock applyTo: {a at: column. b at: column}]
].</langsyntaxhighlight>
 
=={{header|Swift}}==
<langsyntaxhighlight lang="swift">enum SortOrder { case kOrdNone, kOrdLex, kOrdByAddress, kOrdNumeric }
 
func sortTable(table: [[String]], less: (String,String)->Bool = (<), column: Int = 0, reversed: Bool = false) {
// . . . Actual sort goes here . . .
}</langsyntaxhighlight>
 
=={{header|Tcl}}==
Line 1,939 ⟶ 2,924:
The optional positional parameter style works like this:<br>
{{works with|Tcl|8.4}}
<langsyntaxhighlight lang="tcl">proc tablesort {table {ordering ""} {column 0} {reverse 0}} {
set direction [expr {$reverse ? "-decreasing" : "-increasing"}]
if {$ordering ne ""} {
Line 1,953 ⟶ 2,938:
puts [tablesort $data {
apply {{a b} {expr {[string length $a]-[string length $b]}}}
}]</langsyntaxhighlight>
 
When using the second style, it is often common to use [[Named Arguments]] (and in fact the “<code>lsort</code>” already works very much like this). Note that it is most common to use named arguments that start with a “<code>-</code>”, but we omit them here so that we formally match the requirements of the task.
<br>
{{works with|Tcl|8.5}}
<langsyntaxhighlight Tcllang="tcl">package require Tcl 8.5; # Only for the list expansion syntax
 
proc tablesort {table args} {
Line 1,975 ⟶ 2,960:
puts [tablesort $data ordering {
apply {{a b} {expr {[string length $b]-[string length $a]}}}
}]</langsyntaxhighlight>
 
=={{header|TIScript}}==
 
TIScript allows to define optional parameters with default values:
 
<syntaxhighlight lang="javascript">function sorter(table, ordering = "lexicographic", column = 0, reverse = false) {
// ...
}
 
sorter(the_data,"numeric");</syntaxhighlight>
 
=={{header|UNIX Shell}}==
{{works with|bash|4.2}}
<syntaxhighlight lang="bash">#!/usr/bin/env bash
# sort-args.sh
 
data() {
cat <<EOF
123 456 0789
456 0789 123
0789 123 456
EOF
}
 
# sort_table [column NUM | KIND | reverse] ... <INPUT >OUTPUT
# KIND = lexicographical | numeric | human
 
sort_table() {
local opts='-b'
local column=1
while (( $# > 0 )) ; do
case "$1" in
column|col|c) column=${2?Missing column number} ; shift ;;
lexicographical|lex|l) opts+=' -d' ;;
numeric|num|n) opts+=' -g' ;;
human|hum|h) opts+=' -h' ;;
reverse|rev|r) opts+=' -r' ;;
esac
shift
done
eval "sort $opts -k $column,$column -"
}
 
echo sort defaults ; data | sort_table
echo sort defaults reverse ; data | sort_table reverse
echo sort column 2 ; data | sort_table col 2
echo sort column 2 reverse ; data | sort_table col 2 reverse
echo sort numeric ; data | sort_table numeric
echo sort numeric reverse ; data | sort_table numeric reverse
</syntaxhighlight>
{{out}}
<pre>
$ ./sort-args.sh
sort defaults
0789 123 456
123 456 0789
456 0789 123
sort defaults reverse
456 0789 123
123 456 0789
0789 123 456
sort column 2
456 0789 123
0789 123 456
123 456 0789
sort column 2 reverse
123 456 0789
0789 123 456
456 0789 123
sort numeric
123 456 0789
456 0789 123
0789 123 456
sort numeric reverse
0789 123 456
456 0789 123
123 456 0789
</pre>
 
=={{header|Ursala}}==
Line 1,996 ⟶ 3,059:
that is applicable to a list of data to be sorted.
 
<langsyntaxhighlight Ursalalang="ursala">#import std
#import nat
 
Line 2,005 ⟶ 3,068:
reversed %b
 
sorter = +^(~reversed?/~&x! ~&!,-<+ +^/~ordering ~~+ ~&h++ //skip+ predecessor+ ~column)</langsyntaxhighlight>
Here is a test program using the function above to sort a table
five different ways, mentioning only the information that differs from the
defaults. The table is stored as a list of lists, with one list for each
row, hence three rows and two columns.
<langsyntaxhighlight Ursalalang="ursala">example_table =
 
<
Line 2,026 ⟶ 3,089:
(sorter ss[column: 2]) example_table, # etc.
(sorter ss[reversed: true]) example_table,
(sorter ss[reversed: true,column: 2]) example_table></langsyntaxhighlight>
In practice, these five functions would have been more conveniently expressed using the
built in sort operator as <code>-<&h</code>, <code>leql-<&h</code>, <code>-<&th</code>, <code>-<x&h</code>, and <code>-<x&th</code>
Line 2,037 ⟶ 3,100:
<<'foo','b '>,<'bazzz','c'>,<'barr','a '>>,
<<'bazzz','c'>,<'foo','b '>,<'barr','a '>>></pre>
 
=={{header|VBA}}==
<syntaxhighlight lang="vb">Private Sub optional_parameters(theRange As String, _
Optional ordering As Integer = 0, _
Optional column As Integer = 1, _
Optional reverse As Integer = 1)
ActiveSheet.Sort.SortFields.Clear
ActiveSheet.Sort.SortFields.Add _
Key:=Range(theRange).Columns(column), _
SortOn:=SortOnValues, _
Order:=reverse, _
DataOption:=ordering 'the optional parameter ordering and above reverse
With ActiveSheet.Sort
.SetRange Range(theRange)
.Header = xlGuess
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End Sub
Public Sub main()
'Sort the strings in the active sheet in Excel
'Supply the range of cells to be sorted
'Optionally specify ordering, default is 0,
'which is normal sort, text and data separately;
'ordering:=1 treats text as numeric data.
'Optionally specify column number, default is 1
'Optionally specify reverse, default is 1
'which sorts in ascending order.
'Specifying reverse:=2 will sort in descending order.
optional_parameters theRange:="A1:C4", ordering:=1, column:=2, reverse:=1
End Sub</syntaxhighlight>
 
=={{header|Wren}}==
{{libheader|Wren-sort}}
{{libheader|Wren-seq}}
Wren doesn't support optional parameters as such but does support method overloading by ''arity'' (i.e. number of parameters) which makes it easy to simulate them.
<syntaxhighlight lang="wren">import "./sort" for Cmp, Sort
import "./seq" for Lst
 
class TableSorter {
// uses 'merge' sort to avoid mutating original table
// column is zero based
static sort(table, ordering, column, reverse) {
if (ordering == null) ordering = Fn.new { |r1, r2| Cmp.string.call(r1[column], r2[column]) }
var sorted = Sort.merge(table, ordering)
if (reverse) Lst.reverse(sorted)
return sorted
}
 
// overloads to simulate optional parameters
static sort(table) { sort(table, null, 0, false) }
static sort(table, ordering) { sort(table, ordering, 0, false) }
static sort(table, ordering, column) { sort(table, ordering, column, false) }
}
 
var table = [
["first", "1"],
["second", "2"],
["fourth", "4"],
["fifth", "5"],
["third", "3"]
]
 
System.print("Original table:")
System.print(table.join("\n"))
 
System.print("\nAfter lexicographic sort by first column:")
var table2 = TableSorter.sort(table)
System.print(table2.join("\n"))
 
System.print("\nAfter sorting in length order of first column:")
var ordering = Fn.new { |r1, r2| (r1[0].count - r2[0].count).sign }
table2 = TableSorter.sort(table, ordering)
System.print(table2.join("\n"))
 
System.print("\nAfter lexicographic sort by second column:")
table2 = TableSorter.sort(table, null, 1)
System.print(table2.join("\n"))
 
System.print("\nAfter reverse lexicographic sort by second column:")
table2 = TableSorter.sort(table, null, 1, true)
System.print(table2.join("\n"))</syntaxhighlight>
 
{{out}}
<pre>
Original table:
[first, 1]
[second, 2]
[fourth, 4]
[fifth, 5]
[third, 3]
 
After lexicographic sort by first column:
[fifth, 5]
[first, 1]
[fourth, 4]
[second, 2]
[third, 3]
 
After sorting in length order of first column:
[first, 1]
[fifth, 5]
[third, 3]
[second, 2]
[fourth, 4]
 
After lexicographic sort by second column:
[first, 1]
[second, 2]
[third, 3]
[fourth, 4]
[fifth, 5]
 
After reverse lexicographic sort by second column:
[fifth, 5]
[fourth, 4]
[third, 3]
[second, 2]
[first, 1]
</pre>
 
=={{header|XSLT}}==
You can give any template parameter a default value using the optional "select" attribute.
<langsyntaxhighlight lang="xml"><xsl:template name="sort">
<xsl:param name="table" />
<xsl:param name="ordering" select="'lexicographic'" />
Line 2,046 ⟶ 3,231:
<xsl:param name="reversed" select="false()" />
...
</xsl:template></langsyntaxhighlight>
 
=={{header|Yabasic}}==
<syntaxhighlight lang="yabasic">sub power(n, p)
if numparams = 1 p = 2
return n^p
end sub
 
print power(2)
print power(2, 3)</syntaxhighlight>
 
=={{header|zkl}}==
zkl does left to right parameters, each with an optional default. No named parameters (ala Smalltalk). There isn't type enforcement either, a parameter can be anything (although you can set a hint to tell the compiler what you think it will be). If you do want to play named parameters, you can pass in a dictionary (ala Python). The parameters are basically a [varargs] list that you can access in traditional ways.
<langsyntaxhighlight lang="zkl">const lex="L";
fcn mystrySort(table,ordering=lex,column=0,reverse=False,other){
vm.arglist.println();
Line 2,059 ⟶ 3,253:
mystrySort("table",lex,1,True,D("row",35,"type","foobar"));
 
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 2,069 ⟶ 3,263:
 
 
{{omit from|Factor}}
{{omit from|GUISS}}
{{omit from|TI-83 BASIC}} {{omit from|TI-89 BASIC}}
9,476

edits