Named parameters: Difference between revisions
added a Prolog implementation of named parameters |
m →{{header|Wren}}: Changed to Wren S/H |
||
(38 intermediate revisions by 25 users not shown) | |||
Line 13: | Line 13: | ||
* [[wp:Named parameter|Wikipedia: Named parameter]] |
* [[wp:Named parameter|Wikipedia: Named parameter]] |
||
<br><br> |
<br><br> |
||
=={{header|11l}}== |
|||
<syntaxhighlight lang="11l">F sqlen(x = 0, y = 0, z = 0) |
|||
R x*x + y*y + z*z |
|||
print(sqlen(z' 3)) // equivalent to print(sqlen(0, 0, 3))</syntaxhighlight> |
|||
=={{header|Ada}}== |
=={{header|Ada}}== |
||
All callable entities (procedures, functions, entries) require named arguments. All of them can be called using either positional or keyed association of the actual arguments. The arguments supplied with default values can be omitted. |
All callable entities (procedures, functions, entries) require named arguments. All of them can be called using either positional or keyed association of the actual arguments. The arguments supplied with default values can be omitted. |
||
< |
<syntaxhighlight lang="ada">procedure Foo (Arg_1 : Integer; Arg_2 : Float := 0.0);</syntaxhighlight> |
||
It can be equivalently called as: |
It can be equivalently called as: |
||
< |
<syntaxhighlight lang="ada">Foo (1, 0.0); |
||
Foo (1); |
Foo (1); |
||
Foo (Arg_2 => 0.0, Arg_1 => 1); |
Foo (Arg_2 => 0.0, Arg_1 => 1); |
||
Foo (Arg_1 => 1);</ |
Foo (Arg_1 => 1);</syntaxhighlight> |
||
=={{header|ALGOL 68}}== |
=={{header|ALGOL 68}}== |
||
{{trans|Lua}} |
{{trans|Lua}} |
||
<syntaxhighlight lang="algol68">BEGIN |
|||
{{works with|ALGOL 68|Revision 1 - no extensions to language used.}} |
|||
MODE OPTNAME = STRUCT(STRING name), |
|||
{{works with|ALGOL 68G|Any - tested with release [http://sourceforge.net/projects/algol68/files/algol68g/algol68g-1.18.0/algol68g-1.18.0-9h.tiny.el5.centos.fc11.i386.rpm/download 1.18.0-9h.tiny].}} |
|||
OPTSPECIES = STRUCT(STRING species), |
|||
{{wont work with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d] - due to extensive use of '''format'''[ted] ''transput''.}} |
|||
OPTBREED = STRUCT(STRING breed), |
|||
Note: this method of implementing Named Parameters is experimental and to date has never been used outside of rosettacode.org. |
|||
OWNER=STRUCT(STRING first name, middle name, last name); |
|||
<lang algol68>#!/usr/local/bin/a68g --script # |
|||
# Version 2 of Algol 68G would not allow empty options to be specified as () so # |
|||
MODE OPTNAME = STRUCT(STRING name), |
|||
# VOID would need to be included in the MODEs for options and Empty option lists # |
|||
OPTSPECIES = STRUCT(STRING species), |
|||
# would need to be written as (EMPTY) # |
|||
OPTBREED = STRUCT(STRING breed), |
|||
MODE OPTIONS = FLEX[1:0]UNION(OPTNAME,OPTSPECIES,OPTBREED,OWNER); # add ,VOID for Algol 68G version 2 # |
|||
OWNER=STRUCT(STRING first name, middle name, last name); |
|||
# due to the Yoneda ambiguity simple arguments must have an unique operator defined # |
# due to the Yoneda ambiguity simple arguments must have an unique operator defined # |
||
# E.g. a string cannot be coerced to a structure with a single string field # |
|||
OP NAME = (STRING name)OPTNAME: (OPTNAME opt; name OF opt := name; opt), |
|||
OP NAME = (STRING name)OPTNAME: (OPTNAME opt; name OF opt := name; opt), |
|||
SPECIES = (STRING species)OPTSPECIES: (OPTSPECIES opt; species OF opt := species; opt), |
|||
BREED = (STRING breed)OPTBREED: (OPTBREED opt; breed OF opt := breed; opt); |
|||
PROC print pet = ( |
PROC print pet = (OPTIONS option)VOID: ( |
||
STRING name:="Rex", species:="Dinosaur", breed:="Tyrannosaurus"; # Defaults # |
STRING name:="Rex", species:="Dinosaur", breed:="Tyrannosaurus"; # Defaults # |
||
OWNER owner := ("George","W.","Bush"); |
OWNER owner := ("George","W.","Bush"); |
||
FOR i TO UPB option DO |
FOR i TO UPB option DO |
||
CASE option[i] IN |
CASE option[i] IN |
||
(OPTNAME option): name := name OF option, |
(OPTNAME option): name := name OF option, |
||
(OPTSPECIES option): species := species OF option, |
(OPTSPECIES option): species := species OF option, |
||
(OPTBREED option): breed := breed OF option, |
(OPTBREED option): breed := breed OF option, |
||
(OWNER option): owner := option |
(OWNER option): owner := option |
||
ESAC |
ESAC |
||
OD; |
OD; |
||
print(("Details: " |
|||
printf(($gx$,"Details: a",breed,species,"named",name,"owned by",owner,$l$)) |
|||
,IF CHAR c = breed[LWB breed]; char in string( c, NIL, "AaEeIiOoUu" ) THEN "an " ELSE "a " FI |
|||
); |
|||
,breed, " ", species, " named ",name," owned by ",owner, newline)) |
|||
); |
|||
print pet((NAME "Mike", SPECIES "Dog", BREED "Irish Setter", OWNER("Harry", "S.", "Truman"))); |
print pet((NAME "Mike", SPECIES "Dog", BREED "Irish Setter", OWNER("Harry", "S.", "Truman"))); |
||
print pet(()) # use print pet((EMPTY)) for Algol 68G version 2 # |
|||
print pet(())</lang> |
|||
END</syntaxhighlight> |
|||
Output: |
Output: |
||
<pre> |
<pre> |
||
Details: |
Details: an Irish Setter Dog named Mike owned by HarryS.Truman |
||
Details: a Tyrannosaurus Dinosaur named Rex owned by |
Details: a Tyrannosaurus Dinosaur named Rex owned by GeorgeW.Bush |
||
</pre> |
</pre> |
||
=={{header|AppleScript}}== |
=={{header|AppleScript}}== |
||
AppleScript does not implement default or optional parameters, but they can be simulated using records. |
AppleScript does not implement default or optional parameters, but they can be simulated using records. |
||
< |
<syntaxhighlight lang="applescript">on getName(x) |
||
set {firstName, lastName} to {"?", "?"} |
set {firstName, lastName} to {"?", "?"} |
||
try |
try |
||
Line 72: | Line 84: | ||
set lastName to x's lastName |
set lastName to x's lastName |
||
end try |
end try |
||
end getName</lang> |
|||
return firstName & ", " & lastName |
|||
end getName</syntaxhighlight> |
|||
Examples: |
Examples: |
||
< |
<syntaxhighlight lang="applescript ">getName({firstName:"John", lastName:"Doe"}) |
||
--> Returns: "John, Doe" |
--> Returns: "John, Doe" |
||
getName({lastName:"Doe"}) |
getName({lastName:"Doe"}) |
||
--> Returns: "?, Doe"</ |
--> Returns: "?, Doe"</syntaxhighlight> |
||
---- |
|||
An easier way to achieve the above is by concatenating a record containing default values for the expected properties to the record actually passed. The result will contain the labels and values from both records, except that where the same label exists in both records, there'll only be one instance in the result and its value will be that from the first record: |
|||
<syntaxhighlight lang="applescript">on getName(x) -- x assumed to be a record for this demo. |
|||
set x to x & {firstName:"?", lastName:"?"} |
|||
return x's firstName & ", " & x's lastName |
|||
end getName |
|||
getName({lastName:"Doe"}) |
|||
--> "?, Doe"</syntaxhighlight> |
|||
One of AppleScript's handler types has long been "handlers with labeled parameters". These haven't proved particularly popular as they have a limited set of AppleScript-defined labels, which can require some creativity when choosing one to make sense in the script narrative. However, labelled parameters can be given in any order in calls: |
|||
<syntaxhighlight lang="applescript">on getName from firstName beside lastName |
|||
return firstName & ", " & lastName |
|||
end getName |
|||
getName beside "Doe" from "John" |
|||
--> "John, Doe"</syntaxhighlight> |
|||
However, it's also possible to define user labels, with the same flexibility of order, using a slightly different syntax: |
|||
<syntaxhighlight lang="applescript">on getName given firstName:firstName, lastName:lastName |
|||
return firstName & ", " & lastName |
|||
end getName |
|||
getName given lastName:"Doe", firstName:"John" |
|||
--> "John, Doe"</syntaxhighlight> |
|||
AppleScript-defined and user labels can be combined, but the AppleScript ones must be given first if used. The <tt>given</tt> syntax also has a neat feature whereby if the value to be passed is a boolean, the keyword <tt>with</tt> or <tt>without</tt> can be used instead in the call. In fact the compiler imposes this anyway when a boolean is hard-coded into the call: |
|||
<syntaxhighlight lang="applescript">on getName given firstName:firstName, lastName:lastName, comma:comma |
|||
if (comma) then |
|||
return firstName & ", " & lastName |
|||
else |
|||
return firstName & space & lastName |
|||
end if |
|||
end getName |
|||
getName given lastName:"Doe", firstName:"John" comma:true -- compiles as: getName with comma given lastName:"Doe", firstName:"John" |
|||
--> "John, Doe" |
|||
getName without comma given lastName:"Doe", firstName:"John" |
|||
--> "John Doe"</syntaxhighlight> |
|||
Since Mac OS X 10.10, it ''has'' been possible to make labelled parameters optional by defining default values for them in the handler declarations. But at least one parameter must be provided in any call: |
|||
<syntaxhighlight lang="applescript">use AppleScript version "2.4" -- Mac OS X 10.10 (Yosemite) or later. |
|||
on getName under category : "Misc: " given firstName:firstName : "?", lastName:lastName : "?", comma:comma : true |
|||
if (comma) then |
|||
return category & firstName & ", " & lastName |
|||
else |
|||
return category & firstName & space & lastName |
|||
end if |
|||
end getName |
|||
getName given lastName:"Doe" |
|||
--> "Misc: ?, Doe"</syntaxhighlight> |
|||
=={{header|Applesoft BASIC}}== |
=={{header|Applesoft BASIC}}== |
||
Function definitions in Applesoft BASIC using the DEF FN statement can only have one parameter. Subroutines and functions with many parameters can be simulated using global variables which are effectively named parameters. Default or optional parameters can be simulated with a check in the subroutine. |
Function definitions in Applesoft BASIC using the DEF FN statement can only have one parameter. Subroutines and functions with many parameters can be simulated using global variables which are effectively named parameters. Default or optional parameters can be simulated with a check in the subroutine. |
||
< |
<syntaxhighlight lang="applesoftbasic"> 100 IF LAST$ = "" THEN PRINT "?"; |
||
110 IF LAST$ < > "" THEN PRINT LAST$; |
110 IF LAST$ < > "" THEN PRINT LAST$; |
||
120 IF FIRST$ < > "" THEN PRINT ", "FIRST$; |
120 IF FIRST$ < > "" THEN PRINT ", "FIRST$; |
||
200 FIRST$ = "" |
200 FIRST$ = "" |
||
210 LAST$ = "" |
210 LAST$ = "" |
||
220 RETURN</ |
220 RETURN</syntaxhighlight> |
||
<pre>]FIRST$ = "JOHN" : GOSUB 100"PRINT NAME |
<pre>]FIRST$ = "JOHN" : GOSUB 100"PRINT NAME |
||
Line 95: | Line 168: | ||
]FIRST$ = "JOHN" : LAST$ = "DOE" : GOSUB 100"PRINT NAME |
]FIRST$ = "JOHN" : LAST$ = "DOE" : GOSUB 100"PRINT NAME |
||
DOE, JOHN</pre> |
DOE, JOHN</pre> |
||
=={{header|Arturo}}== |
|||
<syntaxhighlight lang="rebol">func: function [x][ |
|||
print ["argument x:" x] |
|||
print ["attribute foo:" attr 'foo] |
|||
print ["attribute bar:" attr 'bar] |
|||
print "" |
|||
] |
|||
func 1 |
|||
func .foo:"foo" 2 |
|||
func .bar:"bar" 3 |
|||
func .foo:123 .bar:124 4 |
|||
func .bar:124 .foo:123 5</syntaxhighlight> |
|||
{{out}} |
|||
<pre>argument x: 1 |
|||
attribute foo: null |
|||
attribute bar: null |
|||
argument x: 2 |
|||
attribute foo: foo |
|||
attribute bar: null |
|||
argument x: 3 |
|||
attribute foo: null |
|||
attribute bar: bar |
|||
argument x: 4 |
|||
attribute foo: 123 |
|||
attribute bar: 124 |
|||
argument x: 5 |
|||
attribute foo: 123 |
|||
attribute bar: 124</pre> |
|||
=={{header|AutoHotkey}}== |
=={{header|AutoHotkey}}== |
||
AutoHotkey doesn't have named parameters, but they can be simulated as follows. |
AutoHotkey doesn't have named parameters, but they can be simulated as follows. |
||
ahk [http://www.autohotkey.com/forum/viewtopic.php?p=280499 discussion] |
ahk [http://www.autohotkey.com/forum/viewtopic.php?p=280499 discussion] |
||
< |
<syntaxhighlight lang="autohotkey">MyFunc( "Val=0, w=1024, Text=The Quick Brown Fox, newVar=I'm New" ) |
||
MyFunc( _overrides="" ) { |
MyFunc( _overrides="" ) { |
||
Static x=5, y=5, w=100, h=100, Count |
Static x=5, y=5, w=100, h=100, Count |
||
Name:="AutoHotkey", Type:="Scripting", Text:="qwerty", Val:=True |
Name:="AutoHotkey", Type:="Scripting", Text:="qwerty", Val:=True |
||
Loop, Parse, _overrides,`,=, %A_Space% ; Override routine for Local/Static variables |
Loop, Parse, _overrides,`,=, %A_Space% ; Override routine for Local/Static variables |
||
A_Index & 1 ? (_:=A_LoopField) : (%_%:=A_LoopField) |
A_Index & 1 ? (_:=A_LoopField) : (%_%:=A_LoopField) |
||
Listvars |
Listvars |
||
WinWaitClose, %A_ScriptFullPath% |
WinWaitClose, %A_ScriptFullPath% |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Bracmat}}== |
=={{header|Bracmat}}== |
||
In Bracmat, all functions have exactly one argument, called "arg". To split the argument and assign values to local variables, you always have to use pattern matching. |
In Bracmat, all functions have exactly one argument, called "arg". To split the argument and assign values to local variables, you always have to use pattern matching. |
||
In this task, the pattern is just made a bit more complex than would have been the case without explicit parameter names in the argument. |
In this task, the pattern is just made a bit more complex than would have been the case without explicit parameter names in the argument. |
||
< |
<syntaxhighlight lang="bracmat">( ( testproc |
||
= i x y z |
= i x y z |
||
. out$"Calling testproc" |
. out$"Calling testproc" |
||
Line 134: | Line 244: | ||
& testproc$((z,4) (x,2) (y,3)) { order is not important } |
& testproc$((z,4) (x,2) (y,3)) { order is not important } |
||
& testproc$((i,1) (y,2) (z,3)) |
& testproc$((i,1) (y,2) (z,3)) |
||
);</ |
);</syntaxhighlight> |
||
Output: |
Output: |
||
<pre>Calling testproc |
<pre>Calling testproc |
||
Line 150: | Line 260: | ||
{{works with|C99}} |
{{works with|C99}} |
||
< |
<syntaxhighlight lang="c">#include <stdio.h> |
||
// 1. Named parameters |
// 1. Named parameters |
||
Line 187: | Line 297: | ||
FTest((FTest_args){ .y = 10, .z = 42 }); |
FTest((FTest_args){ .y = 10, .z = 42 }); |
||
FT( .z = 47, .y = 10, .x = 42 ); |
FT( .z = 47, .y = 10, .x = 42 ); |
||
// Default parameters |
// Default parameters |
||
DFT(); |
DFT(); |
||
DFT( .z = 99 ); |
DFT( .z = 99 ); |
||
// Default parameters with wrapper |
// Default parameters with wrapper |
||
DF2(); |
DF2(); |
||
DF2( .z = 99 ); |
DF2( .z = 99 ); |
||
return 0; |
return 0; |
||
}</ |
}</syntaxhighlight> |
||
As a bonus, default values for the parameters left unspecified can be either implicitly set to zero by the struct initializer, or supplied in a wrapper-macro definition. But this is not idiomatic C by any stretch. |
As a bonus, default values for the parameters left unspecified can be either implicitly set to zero by the struct initializer, or supplied in a wrapper-macro definition. But this is not idiomatic C by any stretch. |
||
=={{header|C sharp|C#}}== |
|||
{{works with|C sharp|C#|4.0}} |
|||
Named parameters were added in C# 4.0. The examples below demonstrate how named parameters and optional parameters are a single concept in the language. |
|||
<syntaxhighlight lang="csharp">using System; |
|||
namespace NamedParams |
|||
{ |
|||
class Program |
|||
{ |
|||
static void AddWidget(string parent, float x = 0, float y = 0, string text = "Default") |
|||
{ |
|||
Console.WriteLine("parent = {0}, x = {1}, y = {2}, text = {3}", parent, x, y, text); |
|||
} |
|||
static void Main(string[] args) |
|||
{ |
|||
AddWidget("root", 320, 240, "First"); |
|||
AddWidget("root", text: "Origin"); |
|||
AddWidget("root", 500); |
|||
AddWidget("root", text: "Footer", y: 400); |
|||
} |
|||
} |
|||
}</syntaxhighlight> |
|||
Output: |
|||
<pre>parent = root, x = 320, y = 240, text = First |
|||
parent = root, x = 0, y = 0, text = Origin |
|||
parent = root, x = 500, y = 0, text = Default |
|||
parent = root, x = 0, y = 400, text = Footer</pre> |
|||
=={{header|C++}}== |
=={{header|C++}}== |
||
Line 206: | Line 350: | ||
You wrap the parameters in a class, and make the function a friend of the parameter class. |
You wrap the parameters in a class, and make the function a friend of the parameter class. |
||
< |
<syntaxhighlight lang="cpp">class foo_params{ |
||
friend void foo(foo_params p); |
friend void foo(foo_params p); |
||
public: |
public: |
||
Line 230: | Line 374: | ||
int required_param_; |
int required_param_; |
||
int optional_x_; |
int optional_x_; |
||
int optional_y_; |
int optional_y_; |
||
float optional_z_; |
float optional_z_; |
||
};</ |
};</syntaxhighlight> |
||
Declare the function to take the parameter class as its only parameter. |
Declare the function to take the parameter class as its only parameter. |
||
< |
<syntaxhighlight lang="cpp">void foo(foo_params p){ . . .}</syntaxhighlight> |
||
Call the function using the parameter object constructor with the required parameters and chaining the optional parameters. |
Call the function using the parameter object constructor with the required parameters and chaining the optional parameters. |
||
< |
<syntaxhighlight lang="cpp">foo(foo_params(42).x(7).z(23.54));</syntaxhighlight> |
||
{{libheader|Boost}} |
{{libheader|Boost}} |
||
If you want real named parameters you can use The Boost Parameter Library. |
If you want real named parameters you can use The Boost Parameter Library. |
||
< |
<syntaxhighlight lang="cpp">#include <boost/parameter/name.hpp> |
||
#include <boost/parameter/preprocessor.hpp> |
#include <boost/parameter/preprocessor.hpp> |
||
#include <string> |
#include <string> |
||
Line 260: | Line 404: | ||
tag, // part of the deep magic. If you use BOOST_PARAMETER_NAME you need to put "tag" here. |
tag, // part of the deep magic. If you use BOOST_PARAMETER_NAME you need to put "tag" here. |
||
(required // names and types of all required parameters, parentheses are required. |
(required // names and types of all required parameters, parentheses are required. |
||
(foo, (int)) |
(foo, (int)) |
||
(bar, (float)) |
(bar, (float)) |
||
) |
) |
||
Line 266: | Line 410: | ||
(baz, (bool) , false) |
(baz, (bool) , false) |
||
(bonk, (std::string), "default value") |
(bonk, (std::string), "default value") |
||
) |
) |
||
) |
) |
||
{ |
{ |
||
if (baz && (bar > 1.0)) return foo; |
if (baz && (bar > 1.0)) return foo; |
||
return bonk.size(); |
return bonk.size(); |
||
}</ |
}</syntaxhighlight> |
||
Once the definition is written, using it is easy, by name or position. |
Once the definition is written, using it is easy, by name or position. |
||
< |
<syntaxhighlight lang="cpp">function_with_named_parameters(1, 10.0); |
||
function_with_named_parameters(7, _bar = 3.14); |
function_with_named_parameters(7, _bar = 3.14); |
||
function_with_named_parameters( _bar = 0.0, _foo = 42); |
function_with_named_parameters( _bar = 0.0, _foo = 42); |
||
function_with_named_parameters( _bar = 2.5, _bonk= "Hello", _foo = 9); |
function_with_named_parameters( _bar = 2.5, _bonk= "Hello", _foo = 9); |
||
function_with_named_parameters(9, 2.5, true, "Hello");</ |
function_with_named_parameters(9, 2.5, true, "Hello");</syntaxhighlight> |
||
=={{header|C sharp|C#}}== |
|||
{{works with|C sharp|C#|4.0}} |
|||
Named parameters were added in C# 4.0. The examples below demonstrate how named parameters and optional parameters are a single concept in the language. |
|||
<lang csharp>using System; |
|||
namespace NamedParams |
|||
{ |
|||
class Program |
|||
{ |
|||
static void AddWidget(string parent, float x = 0, float y = 0, string text = "Default") |
|||
{ |
|||
Console.WriteLine("parent = {0}, x = {1}, y = {2}, text = {3}", parent, x, y, text); |
|||
} |
|||
static void Main(string[] args) |
|||
{ |
|||
AddWidget("root", 320, 240, "First"); |
|||
AddWidget("root", text: "Origin"); |
|||
AddWidget("root", 500); |
|||
AddWidget("root", text: "Footer", y: 400); |
|||
} |
|||
} |
|||
}</lang> |
|||
Output: |
|||
<pre>parent = root, x = 320, y = 240, text = First |
|||
parent = root, x = 0, y = 0, text = Origin |
|||
parent = root, x = 500, y = 0, text = Default |
|||
parent = root, x = 0, y = 400, text = Footer</pre> |
|||
=={{header|Clojure}}== |
=={{header|Clojure}}== |
||
Line 319: | Line 429: | ||
Clojure doesn't have built-in support for named or keyword arguments, but you can use destructuring to achieve a similar effect. |
Clojure doesn't have built-in support for named or keyword arguments, but you can use destructuring to achieve a similar effect. |
||
< |
<syntaxhighlight lang="clojure">(defn foo [& opts] |
||
(let [opts (merge {:bar 1 :baz 2} (apply hash-map opts)) |
(let [opts (merge {:bar 1 :baz 2} (apply hash-map opts)) |
||
{:keys [bar baz]} opts] |
{:keys [bar baz]} opts] |
||
[bar baz]))</ |
[bar baz]))</syntaxhighlight> |
||
Clojure 1.2 supports destructuring of trailing arguments as a map: |
Clojure 1.2 supports destructuring of trailing arguments as a map: |
||
< |
<syntaxhighlight lang="clojure">(defn foo [& {:keys [bar baz] :or {bar 1, baz 2}}] |
||
[bar baz])</ |
[bar baz])</syntaxhighlight> |
||
You can also use <code>defnk</code> from <code>clojure.contrib.def</code>, which is a macro that works similarly. |
You can also use <code>defnk</code> from <code>clojure.contrib.def</code>, which is a macro that works similarly. |
||
< |
<syntaxhighlight lang="clojure">(use 'clojure.contrib.def) |
||
(defnk foo [:bar 1 :baz 2] |
(defnk foo [:bar 1 :baz 2] |
||
[bar baz])</ |
[bar baz])</syntaxhighlight> |
||
Sample output for all variants: |
Sample output for all variants: |
||
Line 347: | Line 457: | ||
=={{header|Common Lisp}}== |
=={{header|Common Lisp}}== |
||
< |
<syntaxhighlight lang="lisp">(defun print-name (&key first (last "?")) |
||
(princ last) |
(princ last) |
||
(when first |
(when first |
||
(princ ", ") |
(princ ", ") |
||
(princ first)) |
(princ first)) |
||
(values))</ |
(values))</syntaxhighlight> |
||
<code>&key</code> indicates that further parameters are named (keyword parameters); a bare symbol (e.g. <var>first</var>) has a default of NIL, whereas a list (e.g. <code>(<var>last</var> "?")</code>) gives the variable name and the default value (which is evaluated when the function is called, unlike Python). |
<code>&key</code> indicates that further parameters are named (keyword parameters); a bare symbol (e.g. <var>first</var>) has a default of NIL, whereas a list (e.g. <code>(<var>last</var> "?")</code>) gives the variable name and the default value (which is evaluated when the function is called, unlike Python). |
||
< |
<syntaxhighlight lang="lisp">CL-USER> (print-name) |
||
? |
? |
||
CL-USER> (print-name :first "John") |
CL-USER> (print-name :first "John") |
||
Line 363: | Line 473: | ||
Doe, John |
Doe, John |
||
CL-USER> (print-name :last "Doe") |
CL-USER> (print-name :last "Doe") |
||
Doe</ |
Doe</syntaxhighlight> |
||
In Common Lisp, the arguments to a function are always a simple list of values; the <code>&key</code> facility merely defines an interpretation of that list by the function: alternating keys and values. (As a result of this, mixing [[varargs]] (<code>&rest</code>) with named parameters is not recommended as it requires some additional means of distinguishing them. On the other hand, functions which pass their arguments on to other functions need not handle named arguments distinctly.) |
In Common Lisp, the arguments to a function are always a simple list of values; the <code>&key</code> facility merely defines an interpretation of that list by the function: alternating keys and values. (As a result of this, mixing [[varargs]] (<code>&rest</code>) with named parameters is not recommended as it requires some additional means of distinguishing them. On the other hand, functions which pass their arguments on to other functions need not handle named arguments distinctly.) |
||
{{omit from|D}} |
{{omit from|D}} |
||
=={{header|Delphi}}== |
|||
{{libheader| System.SysUtils}} |
|||
{{Trans|C++}} |
|||
Delphi not support named params in any version, this is a uneficient, but functional, adaptation of c++ answer. |
|||
<syntaxhighlight lang="delphi"> |
|||
program Named_parameters; |
|||
{$APPTYPE CONSOLE} |
|||
uses |
|||
System.SysUtils; |
|||
type |
|||
TParams = record |
|||
fx, fy, fz: Integer; |
|||
function x(value: Integer): TParams; |
|||
function y(value: Integer): TParams; |
|||
function z(value: Integer): TParams; |
|||
class function _: TParams; static; |
|||
end; |
|||
function Sum(Param: TParams): Integer; |
|||
begin |
|||
Result := Param.fx + Param.fy + Param.fz; |
|||
end; |
|||
{ TParams } |
|||
function TParams.x(value: Integer): TParams; |
|||
begin |
|||
Result := Self; |
|||
Result.fx := value; |
|||
end; |
|||
function TParams.y(value: Integer): TParams; |
|||
begin |
|||
Result := Self; |
|||
Result.fy := value; |
|||
end; |
|||
function TParams.z(value: Integer): TParams; |
|||
begin |
|||
Result := Self; |
|||
Result.fz := value; |
|||
end; |
|||
class function TParams._: TParams; |
|||
begin |
|||
Result.fx := 0; // default x |
|||
Result.fy := 0; // default y |
|||
Result.fz := 0; // default z |
|||
end; |
|||
begin |
|||
writeln(sum(TParams._.x(2).y(3).z(4))); // 9 |
|||
writeln(sum(TParams._.z(4).x(3).y(5))); // 12 |
|||
{$IFNDEF UNIX} readln; {$ENDIF} |
|||
end.</syntaxhighlight> |
|||
=={{header|Dyalect}}== |
|||
Dyalect supports both named and optional parameters. |
|||
<syntaxhighlight lang="dyalect">func fun(x, y = 0, z = 12.2, dsc = "Useless text") { |
|||
print("x=\(x), y=\(y), z=\(z), dsc=\(dsc)") |
|||
} |
|||
fun(12, z: 24.4, dsc: "Foo", y: 3) |
|||
fun(y: 42, x: 12)</syntaxhighlight> |
|||
{{out}} |
|||
<pre>x=12, y=3, z=24.4, dsc=Foo |
|||
x=12, y=42, z=12.2, dsc=Useless text</pre> |
|||
=={{header|E}}== |
|||
Since E supports arbitrary pattern matching (in the sense of [[Pattern Matching]] in parameter lists, a map-pattern can be used to provide named parameters, though the syntax is sufficiently noisy that this is not used casually. |
|||
<syntaxhighlight lang="e">def printName([=> first := null, => last := null]) { |
|||
if (last == null) { |
|||
print("?") |
|||
} else { |
|||
print(last) |
|||
} |
|||
if (first != null) { |
|||
print(", ") |
|||
print(first) |
|||
} |
|||
}</syntaxhighlight> |
|||
(Note: In map literals and map patterns, “<code>=> <var>x</var></code>” is shorthand for “<code>"<var>x</var>" => <var>x</var></code>”.) |
|||
<syntaxhighlight lang="e">? printName(["first" => "John"]) |
|||
?, John |
|||
? printName(["last" => "Doe"]) |
|||
Doe |
|||
? printName(["first" => "John", "last" => "Doe"]) |
|||
Doe, John</syntaxhighlight> |
|||
=={{header|Ecstasy}}== |
|||
Method and function arguments are passed in order, unless argument names are specified by the caller. Both named arguments and default values for arguments are supported. Ordered and named arguments can both be used in the same invocation, but once a named argument is specified, all subsequent arguments in the invocation must also be named. |
|||
A common example of using named arguments is a "wither" method: |
|||
<syntaxhighlight lang="java"> |
|||
module NamedParams { |
|||
const Point(Int x, Int y) { |
|||
Point with(Int? x=Null, Int? y=Null) { |
|||
return new Point(x ?: this.x, y ?: this.y); |
|||
} |
|||
} |
|||
@Inject Console console; |
|||
void run() { |
|||
Point origin = new Point(0, 0); |
|||
console.print($"origin={origin}"); |
|||
Point moveRight = origin.with(x=5); |
|||
console.print($"moveRight(x=5)={moveRight}"); |
|||
Point moveUp = moveRight.with(y=3); |
|||
console.print($"moveUp(y=3)={moveUp}"); |
|||
} |
|||
} |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
origin=(x=0, y=0) |
|||
moveRight(x=5)=(x=5, y=0) |
|||
moveUp(y=3)=(x=5, y=3) |
|||
</pre> |
|||
=={{header|Elixir}}== |
=={{header|Elixir}}== |
||
Line 373: | Line 619: | ||
The easiest and visually most appealing way to have named parameters is using a proplist as last parameter of the function. |
The easiest and visually most appealing way to have named parameters is using a proplist as last parameter of the function. |
||
<syntaxhighlight lang="elixir"> |
|||
<lang Elixir> |
|||
def fun(bar: bar, baz: baz), do: IO.puts "#{bar}, #{baz}." |
def fun(bar: bar, baz: baz), do: IO.puts "#{bar}, #{baz}." |
||
fun(bar: "bar", baz: "baz") |
fun(bar: "bar", baz: "baz") |
||
</syntaxhighlight> |
|||
</lang> |
|||
For this way to use them, order matters, as well as you can't define default values for arguments. |
For this way to use them, order matters, as well as you can't define default values for arguments. |
||
Line 383: | Line 629: | ||
=={{header|Erlang}}== |
=={{header|Erlang}}== |
||
At a guess "named parameters" are supposed to be used like proplists in Erlang. |
At a guess "named parameters" are supposed to be used like proplists in Erlang. |
||
<syntaxhighlight lang="erlang"> |
|||
<lang Erlang> |
|||
Fun = fun( Proplists ) -> |
Fun = fun( Proplists ) -> |
||
Argument1 = proplists:get_value( argument1, Proplists, 1 ), |
Argument1 = proplists:get_value( argument1, Proplists, 1 ), |
||
Line 389: | Line 635: | ||
io:fwrite( "~p ~s~n", [Argument1, Kalle] ) |
io:fwrite( "~p ~s~n", [Argument1, Kalle] ) |
||
end. |
end. |
||
</syntaxhighlight> |
|||
</lang> |
|||
The function can now be called like these examples. |
The function can now be called like these examples. |
||
Line 401: | Line 647: | ||
</pre> |
</pre> |
||
=={{header| |
=={{header|F Sharp|F#}}== |
||
F# supports named method arguments directly. However they are not supported for functions, function values, or lambda functions. |
|||
Since E supports arbitrary pattern matching (in the sense of [[Pattern Matching]] in parameter lists, a map-pattern can be used to provide named parameters, though the syntax is sufficiently noisy that this is not used casually. |
|||
This example comes from the F# documentation: |
|||
<lang e>def printName([=> first := null, => last := null]) { |
|||
<syntaxhighlight lang="fsharp"> |
|||
if (last == null) { |
|||
type SpeedingTicket() = |
|||
print("?") |
|||
member this.GetMPHOver(speed: int, limit: int) = speed - limit |
|||
} else { |
|||
print(last) |
|||
} |
|||
if (first != null) { |
|||
print(", ") |
|||
print(first) |
|||
} |
|||
}</lang> |
|||
let CalculateFine (ticket : SpeedingTicket) = |
|||
(Note: In map literals and map patterns, “<code>=> <var>x</var></code>” is shorthand for “<code>"<var>x</var>" => <var>x</var></code>”.) |
|||
let delta = ticket.GetMPHOver(limit = 55, speed = 70) |
|||
if delta < 20 then 50.0 else 100.0 |
|||
let ticket1 : SpeedingTicket = SpeedingTicket() |
|||
<lang e>? printName(["first" => "John"]) |
|||
printfn "%f" (CalculateFine ticket1) |
|||
?, John |
|||
</syntaxhighlight> |
|||
? printName(["last" => "Doe"]) |
|||
Doe |
|||
? printName(["first" => "John", "last" => "Doe"]) |
|||
Doe, John</lang> |
|||
=={{header|Factor}}== |
=={{header|Factor}}== |
||
Line 432: | Line 668: | ||
Named parameters in Factor are as simple as changing the <code>:</code> word to <code>::</code> and using the variables defined in the stack effect declaration. |
Named parameters in Factor are as simple as changing the <code>:</code> word to <code>::</code> and using the variables defined in the stack effect declaration. |
||
<syntaxhighlight lang="factor"> |
|||
<lang Factor> |
|||
:: my-named-params ( a b -- c ) a b * ; |
:: my-named-params ( a b -- c ) a b * ; |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Forth}}== |
=={{header|Forth}}== |
||
Line 442: | Line 678: | ||
{{works with|Gforth}} |
{{works with|Gforth}} |
||
< |
<syntaxhighlight lang="forth">256 buffer: first-name |
||
256 buffer: last-name |
256 buffer: last-name |
||
: is ( a "name" -- ) parse-name rot place ; |
: is ( a "name" -- ) parse-name rot place ; |
||
: greet ( -- ) |
: greet ( -- ) |
||
cr ." Hello, " first-name count type space last-name count type ." !" ; |
cr ." Hello, " first-name count type space last-name count type ." !" ; |
||
Line 454: | Line 690: | ||
require mini-oof2.fs |
require mini-oof2.fs |
||
require string.fs |
require string.fs |
||
object class |
object class |
||
field: given-name |
field: given-name |
||
field: surname |
field: surname |
||
end-class Person |
end-class Person |
||
: hiya ( -- ) |
: hiya ( -- ) |
||
cr ." Hiya, " given-name $. space surname $. ." !" ; |
cr ." Hiya, " given-name $. space surname $. ." !" ; |
||
Person new >o s" Bob" given-name $! s" Hall" surname $! hiya o></ |
Person new >o s" Bob" given-name $! s" Hall" surname $! hiya o></syntaxhighlight> |
||
{{out}}<pre>Hello, Bob Hall! |
{{out}}<pre>Hello, Bob Hall! |
||
Line 472: | Line 708: | ||
Fortran accepts named parameter and optional parameter. Arguments are always named: if the name is omitted, the order used in the definition of the function / subroutine must be used. |
Fortran accepts named parameter and optional parameter. Arguments are always named: if the name is omitted, the order used in the definition of the function / subroutine must be used. |
||
< |
<syntaxhighlight lang="fortran">subroutine a_sub(arg1, arg2, arg3) |
||
integer, intent(in) :: arg1, arg2 |
integer, intent(in) :: arg1, arg2 |
||
integer, intent(out), optional :: arg3 |
integer, intent(out), optional :: arg3 |
||
! ... |
! ... |
||
end subroutine a_sub</ |
end subroutine a_sub</syntaxhighlight> |
||
< |
<syntaxhighlight lang="fortran">! usage |
||
integer :: r |
integer :: r |
||
call a_sub(1,2, r) |
call a_sub(1,2, r) |
||
call a_sub(arg2=2, arg1=1)</ |
call a_sub(arg2=2, arg1=1)</syntaxhighlight> |
||
The presence of an optional argument can be tested with <tt>PRESENT</tt>; if optional arguments come before a non optional argument, the usage of the name of the argument is mandatory. |
The presence of an optional argument can be tested with <tt>PRESENT</tt>; if optional arguments come before a non optional argument, the usage of the name of the argument is mandatory. |
||
< |
<syntaxhighlight lang="fortran">subroutine b_sub(arg1, arg2) |
||
integer, intent(in), optional :: arg1 |
integer, intent(in), optional :: arg1 |
||
integer, intent(in) :: arg2 |
integer, intent(in) :: arg2 |
||
!... |
!... |
||
end subroutine b_sub</ |
end subroutine b_sub</syntaxhighlight> |
||
< |
<syntaxhighlight lang="fortran">call b_sub(1) ! error: missing non optional arg2 |
||
call b_sub(arg2=1) ! ok |
call b_sub(arg2=1) ! ok |
||
call b_sub(1, 2) ! ok: arg1 is 1, arg2 is 2 |
call b_sub(1, 2) ! ok: arg1 is 1, arg2 is 2 |
||
call b_sub(arg2=2, arg1=1) ! the same as the previous line</ |
call b_sub(arg2=2, arg1=1) ! the same as the previous line</syntaxhighlight> |
||
=={{header|FreeBASIC}}== |
|||
{{trans|Visual Basic}} |
|||
<syntaxhighlight lang="freebasic">Dim Shared foo As Long, bar As Integer, baz As Byte, qux As String |
|||
'la función |
|||
Sub LoqueSea(foo As Long, bar As Integer, baz As Byte, qux As String) |
|||
'... |
|||
End Sub |
|||
'llamando a la función |
|||
Sub Algo() |
|||
LoqueSea(bar = 1, baz = 2, foo = -1, qux = "Probando") |
|||
End Sub</syntaxhighlight> |
|||
=={{header|Go}}== |
=={{header|Go}}== |
||
Line 502: | Line 753: | ||
Here's a simple example. |
Here's a simple example. |
||
< |
<syntaxhighlight lang="go">package main |
||
import ( |
import ( |
||
Line 521: | Line 772: | ||
t := myFunc(params{y: 2}) // only one field, others set to zero |
t := myFunc(params{y: 2}) // only one field, others set to zero |
||
fmt.Println("t =", t) |
fmt.Println("t =", t) |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 533: | Line 784: | ||
We can simulate named, but not moveable arguments, with nullary data constructors: |
We can simulate named, but not moveable arguments, with nullary data constructors: |
||
< |
<syntaxhighlight lang="haskell">data X = X |
||
data Y = Y |
data Y = Y |
||
data Point = Point Int Int deriving Show |
data Point = Point Int Int deriving Show |
||
Line 540: | Line 791: | ||
createPointAt X x Y y = Point x y |
createPointAt X x Y y = Point x y |
||
main = print $ createPointAt X 5 Y 3</ |
main = print $ createPointAt X 5 Y 3</syntaxhighlight> |
||
We can also emulate named, moveable, optional arguments with record syntax: |
We can also emulate named, moveable, optional arguments with record syntax: |
||
< |
<syntaxhighlight lang="haskell">data Point = Point {x, y :: Int} deriving Show |
||
defaultPoint = Point {x = 0, y = 0} |
defaultPoint = Point {x = 0, y = 0} |
||
createPointAt :: Point -> Point |
createPointAt :: Point -> Point |
||
createPointAt = id |
createPointAt = id |
||
main = print $ createPointAt (defaultPoint { y = 3, x = 5 })</ |
main = print $ createPointAt (defaultPoint { y = 3, x = 5 })</syntaxhighlight> |
||
Though this is cumbersome without using template Haskell, as the call site must supply the defaults. |
Though this is cumbersome without using template Haskell, as the call site must supply the defaults. |
||
Line 562: | Line 813: | ||
< |
<syntaxhighlight lang="icon">procedure main() |
||
testproc("x:=",1,"y:=",2,"z:=",3) |
testproc("x:=",1,"y:=",2,"z:=",3) |
||
testproc("x:=",3,"y:=",1,"z:=",2) |
testproc("x:=",3,"y:=",1,"z:=",2) |
||
Line 577: | Line 828: | ||
((variable(a[1:-2]) := get(A)) | # assign |
((variable(a[1:-2]) := get(A)) | # assign |
||
runerr(205,a))) # . . problem |
runerr(205,a))) # . . problem |
||
write(" x:=",x) |
write(" x:=",x) |
||
write(" y:=",y) |
write(" y:=",y) |
||
write(" z:=",z) |
write(" z:=",z) |
||
end</ |
end</syntaxhighlight> |
||
{{improve|Icon|there is currently a bug in Icon that causes assignments via variable("x") to fail for local and static variables. Remove this when this is fixed. The bug does not appear in Unicon.}} |
{{improve|Icon|there is currently a bug in Icon that causes assignments via variable("x") to fail for local and static variables. Remove this when this is fixed. The bug does not appear in Unicon.}} |
||
Line 603: | Line 854: | ||
J is similar to Perl in that all arguments to functions come in as separate elements in an array. But it is possible to emulate more complex calling conventions. For example, using the [http://www.jsoftware.com/svn/DanBron/trunk/environment/calling_convention.ijs calling convention J script], one could write: |
J is similar to Perl in that all arguments to functions come in as separate elements in an array. But it is possible to emulate more complex calling conventions. For example, using the [http://www.jsoftware.com/svn/DanBron/trunk/environment/calling_convention.ijs calling convention J script], one could write: |
||
< |
<syntaxhighlight lang="j">NB. Strand notation |
||
myFunc['c:\file.txt' 906 'blue' fs] |
myFunc['c:\file.txt' 906 'blue' fs] |
||
NB. Commas, like other langs |
NB. Commas, like other langs |
||
myFunc['c:\file.txt', 906, 'blue' fs] |
myFunc['c:\file.txt', 906, 'blue' fs] |
||
NB. Unspecified args are defaulted ("optional") |
NB. Unspecified args are defaulted ("optional") |
||
myFunc['c:\file.txt' fs] |
myFunc['c:\file.txt' fs] |
||
NB. Can use named arguments, like eg VB |
NB. Can use named arguments, like eg VB |
||
myFunc[color='blue' fs] |
myFunc[color='blue' fs] |
||
NB. Often values needn't be quoted |
NB. Often values needn't be quoted |
||
myFunc[color= blue fs] |
myFunc[color= blue fs] |
||
NB. Combination of comma syntax and name=value |
NB. Combination of comma syntax and name=value |
||
myFunc[max=906, color=blue fs] |
myFunc[max=906, color=blue fs] |
||
NB. Spelling of names is flexible |
NB. Spelling of names is flexible |
||
myFunc[MAX=906, COLOR=blue fs] |
myFunc[MAX=906, COLOR=blue fs] |
||
Line 626: | Line 877: | ||
NB. Order of names is flexible |
NB. Order of names is flexible |
||
myFunc[COLOR=blue, MAX=906 fs] |
myFunc[COLOR=blue, MAX=906 fs] |
||
NB. Even the delimiters are flexible... |
NB. Even the delimiters are flexible... |
||
myFunc<MAX=906, COLOR=blue fs></ |
myFunc<MAX=906, COLOR=blue fs></syntaxhighlight> |
||
For further discussion, see the [http://www.jsoftware.com/pipermail/programming/2009-July/015571.html corresponding thread in the J Forums]. |
For further discussion, see the [http://www.jsoftware.com/pipermail/programming/2009-July/015571.html corresponding thread in the J Forums]. |
||
Line 634: | Line 885: | ||
=={{header|Java}}== |
=={{header|Java}}== |
||
Like C++, Java also does not support named parameters. Named parameters can however be simulated simply with the "Builder pattern". ([http://drdobbs.com/java/208403883?pgno=2 Joshua Bloch: Builder Pattern]) |
Like C++, Java also does not support named parameters. Named parameters can however be simulated simply with the "Builder pattern". ([http://drdobbs.com/java/208403883?pgno=2 Joshua Bloch: Builder Pattern]) |
||
< |
<syntaxhighlight lang="java">processNutritionFacts(new NutritionFacts.Builder(240, 8).calories(100).sodium(35).carbohydrate(27).build());</syntaxhighlight> |
||
Follow the link for extra details about the 'NutritionFacts' class example. |
Follow the link for extra details about the 'NutritionFacts' class example. |
||
=={{header|JavaScript}}== |
=={{header|JavaScript}}== |
||
JavaScript only has positional parameters, but named parameters can be emulated by passing an object with the appropriate properties: |
JavaScript only has positional parameters, but named parameters can be emulated by passing an object with the appropriate properties: |
||
< |
<syntaxhighlight lang="javascript">function example(options) { |
||
// assign some defaults where the user's has not provided a value |
// assign some defaults where the user's has not provided a value |
||
opts = {} |
opts = {} |
||
Line 650: | Line 901: | ||
example({grill: "lamb kebab", bar: 3.14}); |
example({grill: "lamb kebab", bar: 3.14}); |
||
// => "foo is 0, bar is 3.14, and grill is lamb kebab"</ |
// => "foo is 0, bar is 3.14, and grill is lamb kebab"</syntaxhighlight> |
||
===ECMAScript 2015 (ES6) variants=== |
===ECMAScript 2015 (ES6) variants=== |
||
With this version, ECMAScript adds destrucuring assignments and destructuring in function parameters. Thus you could do something like this (this works in ES6 Fiddle, but is syntax error in Mozilla SpiderMonkey JS Shell, so uses console.log instead of print):< |
With this version, ECMAScript adds destrucuring assignments and destructuring in function parameters. Thus you could do something like this (this works in ES6 Fiddle, but is syntax error in Mozilla SpiderMonkey JS Shell, so uses console.log instead of print):<syntaxhighlight lang="javascript">let |
||
example = // The member name in the object can either be the same as the parameter (as in bar, grill), |
example = // The member name in the object can either be the same as the parameter (as in bar, grill), |
||
// or a different parameter name as in the case of member foo being assigned to parameter a here. |
// or a different parameter name as in the case of member foo being assigned to parameter a here. |
||
Line 663: | Line 914: | ||
// foo is 0 , bar is 3.14 , and grill is lamb kebab |
// foo is 0 , bar is 3.14 , and grill is lamb kebab |
||
example({foo:null}); |
example({foo:null}); |
||
// foo is , bar is 1 , and grill is pork chops</ |
// foo is , bar is 1 , and grill is pork chops</syntaxhighlight> |
||
=={{header|jq}}== |
=={{header|jq}}== |
||
Line 669: | Line 920: | ||
For example, here is the jq analog of "print-name" defined in the Common Lisp section above. Here we format the full name and return it as a string: |
For example, here is the jq analog of "print-name" defined in the Common Lisp section above. Here we format the full name and return it as a string: |
||
<syntaxhighlight lang="jq"> |
|||
<lang jq> |
|||
def formatName(obj): |
def formatName(obj): |
||
({ "name": "?"} + obj) as $obj # the default default value is null |
({ "name": "?"} + obj) as $obj # the default default value is null |
||
| ($obj|.name) as $name |
| ($obj|.name) as $name |
||
| ($obj|.first) as $first |
| ($obj|.first) as $first |
||
| if ($first == null) then $name |
| if ($first == null) then $name |
||
else $name + ", " + $first |
else $name + ", " + $first |
||
end; |
end; |
||
</syntaxhighlight> |
|||
</lang> |
|||
Here are examples of how the function can be invoked: |
Here are examples of how the function can be invoked: |
||
<lang |
<syntaxhighlight lang="jq"> |
||
formatName({"first": "George", "name": "Eliot"}) |
formatName({"first": "George", "name": "Eliot"}) |
||
Line 690: | Line 941: | ||
formatName({}) |
formatName({}) |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Julia}}== |
=={{header|Julia}}== |
||
Julia supports arbitrary named keyword arguments, which are listed (with their default values) after a <code>;</code> in the function definition: |
Julia supports arbitrary named keyword arguments, which are listed (with their default values) after a <code>;</code> in the function definition: |
||
< |
<syntaxhighlight lang="julia">function surround(string ; border = :default, padding = 0) |
||
ve, ho, ul, ur, dl, dr = |
ve, ho, ul, ur, dl, dr = |
||
border == :round ? ("\u2502","\u2500","\u256d","\u256e","\u2570","\u256f") : |
border == :round ? ("\u2502","\u2500","\u256d","\u256e","\u2570","\u256f") : |
||
border == :bold ? ("\u2503","\u2501","\u250F","\u2513","\u2517","\u251b") : |
border == :bold ? ("\u2503","\u2501","\u250F","\u2513","\u2517","\u251b") : |
||
border == :double? ("\u2551","\u2550","\u2554","\u2557","\u255a","\u255d") : |
border == :double ? ("\u2551","\u2550","\u2554","\u2557","\u255a","\u255d") : |
||
border == :dotted? ("\u254e","\u254c","\u250c","\u2510","\u2514","\u2518") : |
border == :dotted ? ("\u254e","\u254c","\u250c","\u2510","\u2514","\u2518") : |
||
border == :cross ? ("\u2502","\u2500","\u253c","\u253c","\u253c","\u253c") : |
border == :cross ? ("\u2502","\u2500","\u253c","\u253c","\u253c","\u253c") : |
||
("\u2502","\u2500","\u250c","\u2510","\u2514","\u2518") |
("\u2502","\u2500","\u250c","\u2510","\u2514","\u2518") |
||
println(ul, ho^(length(string) + 2padding), ur, "\n", |
println(ul, ho^(length(string) + 2padding), ur, "\n", |
||
ve, " "^padding, string," "^padding, ve, "\n", |
ve, " "^padding, string," "^padding, ve, "\n", |
||
dl, ho^(length(string) + 2padding), dr) |
dl, ho^(length(string) + 2padding), dr) |
||
end</ |
end</syntaxhighlight> |
||
{{Out}} |
{{Out}} |
||
Line 721: | Line 972: | ||
=={{header|Kotlin}}== |
=={{header|Kotlin}}== |
||
< |
<syntaxhighlight lang="scala">// version 1.0.6 |
||
fun someFunction(first: String, second: Int = 2, third: Double) { |
fun someFunction(first: String, second: Int = 2, third: Double) { |
||
Line 729: | Line 980: | ||
fun main(args: Array<String>) { |
fun main(args: Array<String>) { |
||
// using positional parameters |
// using positional parameters |
||
someFunction("positional", 1, 2.0) |
someFunction("positional", 1, 2.0) |
||
// using named parameters |
// using named parameters |
||
Line 738: | Line 989: | ||
// using first and third parameters in reverse |
// using first and third parameters in reverse |
||
someFunction(third = 2.0, first = "reversed") |
someFunction(third = 2.0, first = "reversed") |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 749: | Line 1,000: | ||
</pre> |
</pre> |
||
=={{header| |
=={{header|LabVIEW}}== |
||
Function calls in LabVIEW are implemented as instantiated VIs, small icons representing the function to be called. All parameters are positional, by drawing wires to different points along the icon edge. By right-clicking on the VI icon and unchecking "View as Icon", the parameter names can be shown. The parameter names are mainly informational for the user. |
Function calls in LabVIEW are implemented as instantiated VIs, small icons representing the function to be called. All parameters are positional, by drawing wires to different points along the icon edge. By right-clicking on the VI icon and unchecking "View as Icon", the parameter names can be shown. The parameter names are mainly informational for the user. |
||
Line 758: | Line 1,009: | ||
=={{header|Lasso}}== |
=={{header|Lasso}}== |
||
< |
<syntaxhighlight lang="lasso">define mymethod( |
||
-first::integer, // with no default value the param is required |
-first::integer, // with no default value the param is required |
||
-second::integer, |
-second::integer, |
||
Line 773: | Line 1,024: | ||
-first = 54, |
-first = 54, |
||
-delimiter = '#' |
-delimiter = '#' |
||
)</ |
)</syntaxhighlight> |
||
-> 54:45 |
-> 54:45 |
||
Line 780: | Line 1,031: | ||
=={{header|Lingo}}== |
=={{header|Lingo}}== |
||
Lingo does not support named function parameters. But this can be simulated by using a single property list (hash) with named properties as function argument. You can also create functions that support both calling methods, like e.g. this function that accepts either 3 integers or a single property list with such named properties: |
Lingo does not support named function parameters. But this can be simulated by using a single property list (hash) with named properties as function argument. You can also create functions that support both calling methods, like e.g. this function that accepts either 3 integers or a single property list with such named properties: |
||
< |
<syntaxhighlight lang="lingo">-- accepts either 3 integers or a single property list |
||
on foo (arg1, arg2, arg3) |
on foo (arg1, arg2, arg3) |
||
if ilk(arg1)=#propList then |
if ilk(arg1)=#propList then |
||
Line 801: | Line 1,052: | ||
-- "arg1=" |
-- "arg1=" |
||
-- "arg2=" |
-- "arg2=" |
||
-- "arg3=3"</ |
-- "arg3=3"</syntaxhighlight> |
||
=={{header|Lua}}== |
=={{header|Lua}}== |
||
<syntaxhighlight lang="lua"> |
|||
<lang Lua> |
|||
function CreatePet(options) |
function CreatePet(options) |
||
local name=options.name |
local name=options.name |
||
Line 813: | Line 1,064: | ||
CreatePet{name='Rex',species='Dog',breed='Irish Setter'} |
CreatePet{name='Rex',species='Dog',breed='Irish Setter'} |
||
--position does not matter here. |
--position does not matter here. |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|M2000 Interpreter}}== |
=={{header|M2000 Interpreter}}== |
||
Line 819: | Line 1,070: | ||
Passing optionals in modules may cause problems if we have values in stack, so we can use Stack New {] to open an empty current stack (the old one is hidden until exit from that block), or using ? as "use standard value". |
Passing optionals in modules may cause problems if we have values in stack, so we can use Stack New {] to open an empty current stack (the old one is hidden until exit from that block), or using ? as "use standard value". |
||
<syntaxhighlight lang="m2000 interpreter"> |
|||
<lang M2000 Interpreter> |
|||
module namedparam (x as decimal=10, y as integer=50) { |
module namedparam (x as decimal=10, y as integer=50) { |
||
Print type$(x), x |
Print type$(x), x |
||
Line 834: | Line 1,085: | ||
} |
} |
||
namedparam %x=1, %y=1 |
namedparam %x=1, %y=1 |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Maple}}== |
=={{header|Maple}}== |
||
< |
<syntaxhighlight lang="maple">f := proc(a, {b:= 1, c:= 1}) |
||
print (a*(c+b)); |
print (a*(c+b)); |
||
end proc: |
end proc: |
||
Line 846: | Line 1,097: | ||
3 |
3 |
||
f(2, b = 5, c = 3);#b and c can be put in any order |
f(2, b = 5, c = 3);#b and c can be put in any order |
||
16</ |
16</syntaxhighlight> |
||
=={{header|Mathematica}}== |
=={{header|Mathematica}}/{{header|Wolfram Language}}== |
||
< |
<syntaxhighlight lang="mathematica">Options[fn]={Add->False,Offset-> 0}; |
||
fn[x_,y_,OptionsPattern[]]:=If[OptionValue[Add]==True,x+y+OptionValue[Offset],{x,y,OptionValue[Offset]}] |
fn[x_,y_,OptionsPattern[]]:=If[OptionValue[Add]==True,x+y+OptionValue[Offset],{x,y,OptionValue[Offset]}] |
||
fn[3,4,{Add->True,Offset->2}] |
fn[3,4,{Add->True,Offset->2}] |
||
fn[3,4,{Offset->2,Add->True}]</syntaxhighlight> |
|||
->9 |
|||
{{out}} |
|||
fn[3,4,{Offset->2,Add->True}] |
|||
<pre>9 |
|||
->9</lang> |
|||
9</pre> |
|||
=={{header|MATLAB}} / {{header|Octave}}== |
=={{header|MATLAB}} / {{header|Octave}}== |
||
Line 861: | Line 1,112: | ||
Named parameters are not natively supported. However, the following code can be used to implement them. |
Named parameters are not natively supported. However, the following code can be used to implement them. |
||
<lang |
<syntaxhighlight lang="matlab"> function foo(varargin) |
||
for k= 1:2:length(varargin); |
for k= 1:2:length(varargin); |
||
switch (varargin{k}) |
switch (varargin{k}) |
||
Line 868: | Line 1,119: | ||
case {'param2'} |
case {'param2'} |
||
param2 = varargin{k+1}; |
param2 = varargin{k+1}; |
||
end; |
end; |
||
end; |
end; |
||
printf('param1: %s\n',param1); |
printf('param1: %s\n',param1); |
||
printf('param2: %s\n',param2); |
printf('param2: %s\n',param2); |
||
end; |
end; |
||
foo('param1','a1','param2','b2'); |
|||
foo('param2','b2','param1','a1'); </lang> |
|||
foo('param1','a1','param2','b2'); |
|||
Output: |
|||
foo('param2','b2','param1','a1'); </syntaxhighlight> |
|||
Output: |
|||
<pre>>> foo('param1','a1','param2','b2'); |
|||
param1: a1 |
param1: a1 |
||
param2: b2 |
param2: b2 |
||
>> foo('param2','b2','param1','a1'); |
>> foo('param2','b2','param1','a1'); |
||
param1: a1 |
param1: a1 |
||
param2: b2</pre> |
param2: b2</pre> |
||
=={{header|Modula-3}}== |
=={{header|Modula-3}}== |
||
Much like [[Ada]], Modula-3 allows either positional or keyed association of actual parameters. Defaults can also be ignored. |
Much like [[Ada]], Modula-3 allows either positional or keyed association of actual parameters. Defaults can also be ignored. |
||
< |
<syntaxhighlight lang="modula3">PROCEDURE Foo(Arg1: INTEGER; Arg2: REAL := 0.0);</syntaxhighlight> |
||
It can be equivalently called as: |
It can be equivalently called as: |
||
< |
<syntaxhighlight lang="modula3">Foo(1, 0.0); |
||
Foo(1); |
Foo(1); |
||
Foo(Arg2 := 0.0, Arg1 := 1); |
Foo(Arg2 := 0.0, Arg1 := 1); |
||
Foo(Arg1 := 1);</ |
Foo(Arg1 := 1);</syntaxhighlight> |
||
=={{header|Nemerle}}== |
=={{header|Nemerle}}== |
||
< |
<syntaxhighlight lang="nemerle">Foo(number : int, word = "Default", option = true) : void // note type inference with default values |
||
Foo(word = "Bird", number = 3) // an argument with a default value can be omitted from function call |
Foo(word = "Bird", number = 3) // an argument with a default value can be omitted from function call |
||
Foo(3, option = false, word = "Bird") // unnamed arguments must be in same order as function definition and precede named arguments |
Foo(3, option = false, word = "Bird") // unnamed arguments must be in same order as function definition and precede named arguments |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Nim}}== |
=={{header|Nim}}== |
||
In Nim, a regular parameter of a procedure can be used as either a positional or a named parameter. |
In Nim, a regular parameter of a procedure can be used as either a positional or a named parameter. |
||
< |
<syntaxhighlight lang="nim">proc subtract(x, y): auto = x - y |
||
echo subtract(5, 3) # used as positional parameters |
echo subtract(5, 3) # used as positional parameters |
||
echo subtract(y = 3, x = 5) # used as named parameters</ |
echo subtract(y = 3, x = 5) # used as named parameters</syntaxhighlight> |
||
Parameters can be made optional by providing a default argument. |
|||
=={{header|Objective-C}}== |
=={{header|Objective-C}}== |
||
Objective-C, like Smalltalk, has a method call syntax that is visually identical to named arguments, but they are not optional and may not be reordered. (Optional arguments may be simulated by defining multiple methods with the same leading name part.) |
Objective-C, like Smalltalk, has a method call syntax that is visually identical to named arguments, but they are not optional and may not be reordered. (Optional arguments may be simulated by defining multiple methods with the same leading name part.) |
||
< |
<syntaxhighlight lang="objc">@interface Demo : NSObject { |
||
// Omitted ... |
// Omitted ... |
||
} |
} |
||
Line 920: | Line 1,172: | ||
- (double) hypotenuseOfX: (double)x andY: (double)y andZ: (double)z; |
- (double) hypotenuseOfX: (double)x andY: (double)y andZ: (double)z; |
||
@end</ |
@end</syntaxhighlight> |
||
< |
<syntaxhighlight lang="objc">@implementation Demo |
||
- (double) hypotenuseOfX: (double)x andY: (double)y { |
- (double) hypotenuseOfX: (double)x andY: (double)y { |
||
Line 930: | Line 1,182: | ||
} |
} |
||
@end</ |
@end</syntaxhighlight> |
||
< |
<syntaxhighlight lang="objc">Demo *example = [[Demo alloc] init]; |
||
double h = [example hypotenuseOfX:1.23 andY:3.79];</ |
double h = [example hypotenuseOfX:1.23 andY:3.79];</syntaxhighlight> |
||
Note in the example above that the name of the method, the ''selector''; is actually “<code>hypotenuseOfX:andY:</code>”. |
Note in the example above that the name of the method, the ''selector''; is actually “<code>hypotenuseOfX:andY:</code>”. |
||
=={{header|OCaml}}== |
=={{header|OCaml}}== |
||
You can make a named argument (called ''labels'' in OCaml) by putting a tilde (~) before the name: |
You can make a named argument (called ''labels'' in OCaml) by putting a tilde (~) before the name: |
||
< |
<syntaxhighlight lang="ocaml"># let foo ~arg1 ~arg2 = arg1 + arg2;; |
||
val foo : arg1:int -> arg2:int -> int = <fun> |
val foo : arg1:int -> arg2:int -> int = <fun> |
||
# let foo ~arg1:x ~arg2:y = x + y;; (* you can also use different variable names internally if you want *) |
# let foo ~arg1:x ~arg2:y = x + y;; (* you can also use different variable names internally if you want *) |
||
val foo : arg1:int -> arg2:int -> int = <fun> |
val foo : arg1:int -> arg2:int -> int = <fun> |
||
# foo ~arg2:17 ~arg1:42;; |
# foo ~arg2:17 ~arg1:42;; |
||
- : int = 59</ |
- : int = 59</syntaxhighlight> |
||
Named arguments can be re-ordered, but two arguments of the same label cannot be re-ordered relative to each other. |
Named arguments can be re-ordered, but two arguments of the same label cannot be re-ordered relative to each other. |
||
Line 952: | Line 1,206: | ||
=={{header|Oz}}== |
=={{header|Oz}}== |
||
For <b>methods</b>, Oz does support named parameters with default values. The named parameters can be freely reordered. |
For <b>methods</b>, Oz does support named parameters with default values. The named parameters can be freely reordered. |
||
< |
<syntaxhighlight lang="oz">declare |
||
class Foo |
class Foo |
||
meth init skip end |
meth init skip end |
||
Line 966: | Line 1,220: | ||
{O bar(1 named1:2 named2:3 namedWithDefault:4)} %% ok |
{O bar(1 named1:2 named2:3 namedWithDefault:4)} %% ok |
||
{O bar(1 named2:2 named1:3)} %% ok |
{O bar(1 named2:2 named1:3)} %% ok |
||
{O bar(1 named1:2)} %% not ok, "missing message feature in object application"</ |
{O bar(1 named1:2)} %% not ok, "missing message feature in object application"</syntaxhighlight> |
||
For <b>procedures</b> only positional parameters are supported. However, you can emulate named parameters by using records: |
For <b>procedures</b> only positional parameters are supported. However, you can emulate named parameters by using records: |
||
<syntaxhighlight lang="oz"> |
|||
<lang oz> |
|||
declare |
declare |
||
proc {Foo PP Other=unit(named1:N1 named2:N2 ...)} |
proc {Foo PP Other=unit(named1:N1 named2:N2 ...)} |
||
Line 979: | Line 1,233: | ||
{Foo 1 unit(named1:2 named2:3 namedWithDefault:4)} |
{Foo 1 unit(named1:2 named2:3 namedWithDefault:4)} |
||
{Foo 1 unit(named2:2 named1:3)} |
{Foo 1 unit(named2:2 named1:3)} |
||
{Foo 1 unit(named1:2)} %% not ok...</ |
{Foo 1 unit(named1:2)} %% not ok...</syntaxhighlight> |
||
The procedure Foo is defined with pattern matching in the argument list. The ellipsis means that additional record fields are allowed. To access optional record fields, we have to explicitly try to select a field and provide a default value in case it is missing ("CondSelect"). |
The procedure Foo is defined with pattern matching in the argument list. The ellipsis means that additional record fields are allowed. To access optional record fields, we have to explicitly try to select a field and provide a default value in case it is missing ("CondSelect"). |
||
{{omit from|Pascal}} |
|||
=={{header|Perl}}== |
=={{header|Perl}}== |
||
Perl has no non-experimental formal parameters. Instead, Perl subroutines access all of their arguments through the special array <code>@_</code>. You can easily implement named arguments by making your function interpret <code>@_</code> (or part of it) as a hash. |
Perl has no non-experimental formal parameters. Instead, Perl subroutines access all of their arguments through the special array <code>@_</code>. You can easily implement named arguments by making your function interpret <code>@_</code> (or part of it) as a hash. |
||
< |
<syntaxhighlight lang="perl">sub funkshun { |
||
my %h = @_; |
my %h = @_; |
||
# Print every argument and its value. |
# Print every argument and its value. |
||
Line 997: | Line 1,253: | ||
# Otherwise, say that it's off. |
# Otherwise, say that it's off. |
||
print "Safe mode ", ($h{safe} ? 'on' : 'off'), ".\n"; |
print "Safe mode ", ($h{safe} ? 'on' : 'off'), ".\n"; |
||
}</ |
}</syntaxhighlight> |
||
The semantics of calling such a function follow directly from the semantics of using a hash. For instance, if you provide multiple values for the same named argument, only the last one will be used. An example call: |
The semantics of calling such a function follow directly from the semantics of using a hash. For instance, if you provide multiple values for the same named argument, only the last one will be used. An example call: |
||
< |
<syntaxhighlight lang="perl">funkshun( |
||
verbosity => 3, |
verbosity => 3, |
||
password => 'foobie blech', |
password => 'foobie blech', |
||
Line 1,006: | Line 1,262: | ||
'42' => 'answer', |
'42' => 'answer', |
||
password => 'joshua' |
password => 'joshua' |
||
);</ |
);</syntaxhighlight> |
||
Its output: |
Its output: |
||
Line 1,016: | Line 1,272: | ||
Safe mode off.</pre> |
Safe mode off.</pre> |
||
Further flexibility can be obtained by using [[Pass by reference]] semantics:< |
Further flexibility can be obtained by using [[Pass by reference]] semantics:<syntaxhighlight lang="perl">sub event |
||
{ |
{ |
||
my ($params_ref, $name) = @_; |
my ($params_ref, $name) = @_; |
||
Line 1,022: | Line 1,278: | ||
my @known_params = qw(attendees event food time); |
my @known_params = qw(attendees event food time); |
||
printf "%s called event() with the following named parameters:\n", |
printf "%s called event() with the following named parameters:\n", |
||
$name // 'Anonymous'; |
$name // 'Anonymous'; |
||
say sort map { |
say sort map { |
||
sprintf "%s: %s\n", |
sprintf "%s: %s\n", |
||
ucfirst $_, |
ucfirst $_, |
||
ref $params{$_} eq ref [] |
ref $params{$_} eq ref [] |
||
? join ', ', @{ $params{$_} } |
? join ', ', @{ $params{$_} } |
||
: $params{$_}; |
: $params{$_}; |
||
Line 1,042: | Line 1,298: | ||
event( |
event( |
||
{ # Curly braces with no label (e.g. 'sub' before it) |
{ # Curly braces with no label (e.g. 'sub' before it) |
||
# create a reference to an anonymous hash |
# create a reference to an anonymous hash |
||
attendees => ['Bob', 'Betty', 'George', 'Bertha'], |
attendees => ['Bob', 'Betty', 'George', 'Bertha'], |
||
Line 1,052: | Line 1,308: | ||
}, |
}, |
||
"Joe Schmoe" |
"Joe Schmoe" |
||
);</ |
);</syntaxhighlight>Prints: |
||
<pre> |
<pre> |
||
Joe Schmoe called event() with the following named parameters: |
Joe Schmoe called event() with the following named parameters: |
||
Line 1,066: | Line 1,322: | ||
This is useful when you want your function to take both named (the hash) and positional (Joe Schmoe's $name) parameters. |
This is useful when you want your function to take both named (the hash) and positional (Joe Schmoe's $name) parameters. |
||
=={{header| |
=={{header|Phix}}== |
||
{{libheader|Phix/basics}} |
|||
{{works with|Rakudo|#22 "Thousand Oaks"}} |
|||
Phix supports named and optional parameters in a simple, natural, and intuitive way, erring on the side of caution when faced with potential ambiguity.<br> |
|||
Optional parameters are simply any with a default, and any non-defaulted parameters must occur before (to the left of) such.<br> |
|||
Named parameters can be provided in any order, but must be grouped together after (to the right of) any positional parameters.<br> |
|||
Note that low-level builtins (those defined using AutoAsm() in psym.e/syminit()) do not [yet] support named parameters, but everything else does. |
|||
The classic example (inspired by the standard Python equivalent) is that builtins\timedate.e defines: |
|||
Perl 6's support for optional parameters is much like Python's. Consider this declaration: |
|||
<!--<syntaxhighlight lang="phix">--> |
|||
<span style="color: #008080;">global</span> <span style="color: #008080;">function</span> <span style="color: #000000;">timedelta</span><span style="color: #0000FF;">(</span><span style="color: #004080;">atom</span> <span style="color: #000000;">weeks</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">days</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">hours</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">minutes</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">seconds</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">milliseconds</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">microseconds</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span><span style="color: #0000FF;">)</span> |
|||
<!--</syntaxhighlight>--> |
|||
which can be invoked as follows: |
|||
<lang perl6>sub funkshun ($a, $b?, $c = 15, :$d, *@e, *%f) { |
|||
... |
|||
}</lang> |
|||
<!--<syntaxhighlight lang="phix">(phixonline)--> |
|||
In the above signature: |
|||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span> |
|||
* <code>$a</code> is a mandatory parameter accepted by position (<code>funkshun 15, ...</code>). |
|||
<span style="color: #008080;">include</span> <span style="color: #004080;">timedate</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span> |
|||
* <code>$b</code> is an optional parameter that can be passed by position or by name. By default, it's undefined. |
|||
<span style="color: #008080;">constant</span> <span style="color: #000000;">days</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">hours</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">7</span><span style="color: #0000FF;">,</span> |
|||
* <code>$c</code> is an optional parameter that can be passed by position or by name. Its default value is <code>15</code>. |
|||
<span style="color: #000000;">fourdays</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">timedelta</span><span style="color: #0000FF;">(</span><span style="color: #000000;">days</span><span style="color: #0000FF;">:=</span><span style="color: #000000;">4</span><span style="color: #0000FF;">),</span> |
|||
* <code>$d</code> is an optional parameter that can only be passed by name. By default, it's undefined. |
|||
<span style="color: #000080;font-style:italic;">-- fourdays = timedelta(0,4) -- equivalent, **NB** a plain '=' is a very different thing:</span> |
|||
* <code>@e</code> is a slurpy array: it receives any leftover positional arguments. |
|||
<span style="color: #000000;">slipup</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">timedelta</span><span style="color: #0000FF;">(</span><span style="color: #000000;">days</span><span style="color: #0000FF;">=</span><span style="color: #000000;">4</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- === timedelta([weeks:=]iff(equal(days,4)?true:false)) |
|||
* <code>%f</code> is a slurpy hash: it receives any leftover named arguments. |
|||
-- with error if no local/in scope identifier days exists.</span> |
|||
<span style="color: #000000;">shift</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">timedelta</span><span style="color: #0000FF;">(</span><span style="color: #000000;">hours</span><span style="color: #0000FF;">:=</span><span style="color: #000000;">hours</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- perfectly valid (param hours:=local hours) |
|||
-- timedelta(0,hours:=15,3) -- illegal (not clear whether days:=3 or minutes:=3) |
|||
-- though of course the weeks:=0 part is fine</span> |
|||
<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;">"fourdays = %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #7060A8;">elapsed</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fourdays</span><span style="color: #0000FF;">)})</span> |
|||
<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;">"wrong = %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #7060A8;">elapsed</span><span style="color: #0000FF;">(</span><span style="color: #000000;">slipup</span><span style="color: #0000FF;">)})</span> |
|||
<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;">"shift = %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #7060A8;">elapsed</span><span style="color: #0000FF;">(</span><span style="color: #000000;">shift</span><span style="color: #0000FF;">)})</span> |
|||
<!--</syntaxhighlight>--> |
|||
Note that pwa/p2js automatically maps named parameters to positional parameters for you, since JavaScript does not support named parameters. |
|||
So, if we defined the function like this: |
|||
{{out}} |
|||
<pre> |
|||
<lang perl6>sub funkshun ($a, $b?, :$c = 15, :$d, *@e, *%f) { |
|||
fourdays = 4 days |
|||
say "$a $b $c $d"; |
|||
wrong = 0s |
|||
say join ' ', @e; |
|||
shift = 7 hours |
|||
say join ' ', keys %f; |
|||
</pre> |
|||
} |
|||
# this particularly thorny call: |
|||
funkshun |
|||
'Alfa', k1 => 'v1', c => 'Charlie', 'Bravo', 'e1', |
|||
d => 'Delta', 'e2', k2 => 'v2';</lang> |
|||
would print this: |
|||
<pre>Alfa Bravo Charlie Delta |
|||
e1 e2 |
|||
k1 k2</pre> |
|||
=={{header|Phix}}== |
|||
Phix supports named and optional parameters in a very simple, natural, and intuitive way, erring on the side of caution when faced with any potential ambiguity.<br> |
|||
Optional parameters are specified simply by providing a default, any non-defaulted parameters must occur before (to the left of) any defaulted parameters.<br> |
|||
Named parameters can be given (when invoking a routine) in any order, but must be grouped together after (to the right of) any non-named parameters.<br> |
|||
Note that low-level builtins (those defined using AutoAsm() in psym.e/syminit()) do not support named parameters (maybe one day..), but everything else does. |
|||
<lang Phix>global function timedelta(atom weeks=0, atom days=0, atom hours=0, atom minutes=0, atom seconds=0, atom milliseconds=0, atom microseconds=0) |
|||
-- can be invoked as: |
|||
constant fourdays = timedelta(days:=4) |
|||
-- fourdays = timedelta(0,4) -- equivalent |
|||
-- **NB** a plain '=' is a very different thing |
|||
constant oneday = timedelta(days=1) -- equivalent to timedelta([weeks:=]iff((equal(days,1)?true:false)) |
|||
-- - with an error if no local variable days exists. |
|||
constant shift = timedelta(hours:=hours) -- perfectly valid (param hours:=local hours) |
|||
-- timedelta(0,hours:=15,3) -- illegal (it is not clear whether you meant days:=3 or minutes:=3)</lang> |
|||
=={{header|PHP}}== |
=={{header|PHP}}== |
||
PHP doesn't support named parameters but you can simulate the behavior with PHP arrays. |
PHP doesn't support named parameters but you can simulate the behavior with PHP arrays. |
||
< |
<syntaxhighlight lang="php">function named($args) { |
||
$args += ["gbv" => 2, |
$args += ["gbv" => 2, |
||
"motor" => "away", |
"motor" => "away", |
||
Line 1,127: | Line 1,370: | ||
} |
} |
||
named(["teenage" => "cia", "gbv" => 10]);</ |
named(["teenage" => "cia", "gbv" => 10]);</syntaxhighlight> |
||
Output: |
Output: |
||
<pre>10 men running away from the cia</pre> |
<pre>10 men running away from the cia</pre> |
||
Line 1,136: | Line 1,379: | ||
to establish bindings to passed names. |
to establish bindings to passed names. |
||
===Passing symbol-value pairs=== |
===Passing symbol-value pairs=== |
||
< |
<syntaxhighlight lang="picolisp">(de foo @ |
||
(bind (rest) # Bind symbols in CARs to values in CDRs |
(bind (rest) # Bind symbols in CARs to values in CDRs |
||
(println 'Bar 'is Bar) |
(println 'Bar 'is Bar) |
||
(println 'Mumble 'is Mumble) ) ) |
(println 'Mumble 'is Mumble) ) ) |
||
(foo '(Bar . 123) '(Mumble . "def"))</ |
(foo '(Bar . 123) '(Mumble . "def"))</syntaxhighlight> |
||
===Passing a name list followed by values=== |
===Passing a name list followed by values=== |
||
< |
<syntaxhighlight lang="picolisp">(de foo @ |
||
(bind (next) # Save all symbols in first argument |
(bind (next) # Save all symbols in first argument |
||
(mapc set (arg) (rest)) # then bind them to remaining arguments |
(mapc set (arg) (rest)) # then bind them to remaining arguments |
||
Line 1,149: | Line 1,392: | ||
(println 'Mumble 'is Mumble) ) ) |
(println 'Mumble 'is Mumble) ) ) |
||
(foo '(Bar Mumble) 123 "def")</ |
(foo '(Bar Mumble) 123 "def")</syntaxhighlight> |
||
Output in both cases: |
Output in both cases: |
||
<pre>Bar is 123 |
<pre>Bar is 123 |
||
Line 1,157: | Line 1,400: | ||
===Positional parameters=== |
===Positional parameters=== |
||
When writing a function and not stating any parameters explicitly, such as the following function |
When writing a function and not stating any parameters explicitly, such as the following function |
||
< |
<syntaxhighlight lang="powershell">function Test { |
||
Write-Host Argument 1 is $args[0] |
Write-Host Argument 1 is $args[0] |
||
}</ |
}</syntaxhighlight> |
||
the only option are positional parameters using the <code>$args</code> array. |
the only option are positional parameters using the <code>$args</code> array. |
||
===Named parameters=== |
===Named parameters=== |
||
Stating any number of parameters directly in the function definition, such as |
Stating any number of parameters directly in the function definition, such as |
||
< |
<syntaxhighlight lang="powershell">function Test ($SomeArgument, $AnotherArgument, $ThirdArgument) { |
||
Write-Host "Some argument: $SomeArgument" |
Write-Host "Some argument: $SomeArgument" |
||
Write-Host "Another argument: $AnotherArgument" |
Write-Host "Another argument: $AnotherArgument" |
||
Write-Host "Third argument: $ThirdArgument" |
Write-Host "Third argument: $ThirdArgument" |
||
}</ |
}</syntaxhighlight> |
||
will cause them to be named automatically which enables the caller to state the arguments in any order. The syntax follows the convention used with cmdlets as well: |
will cause them to be named automatically which enables the caller to state the arguments in any order. The syntax follows the convention used with cmdlets as well: |
||
<pre>PS> Test -ThirdArgument foo -AnotherArgument bar -SomeArgument baz |
<pre>PS> Test -ThirdArgument foo -AnotherArgument bar -SomeArgument baz |
||
Line 1,183: | Line 1,426: | ||
===Switch parameters=== |
===Switch parameters=== |
||
Functions can have so-called ''switch parameters'' which are always boolean and either present or not. There is no need to give a value for them. |
Functions can have so-called ''switch parameters'' which are always boolean and either present or not. There is no need to give a value for them. |
||
< |
<syntaxhighlight lang="powershell">function SwitchTest ([switch] $on) { |
||
Write-Host Switched $(if ($on) { "on" } else { "off" }) |
Write-Host Switched $(if ($on) { "on" } else { "off" }) |
||
}</ |
}</syntaxhighlight> |
||
When calling a function with such a parameter the switch is simply given directly (which sets its value to ''true'') or omitted (which causes it to evaluate to ''false''): |
When calling a function with such a parameter the switch is simply given directly (which sets its value to ''true'') or omitted (which causes it to evaluate to ''false''): |
||
<pre>PS> SwitchTest |
<pre>PS> SwitchTest |
||
Line 1,193: | Line 1,436: | ||
===Optional parameters and default values=== |
===Optional parameters and default values=== |
||
Usually all parameters can be omitted. In the case of switch parameters this will cause them to assume the value ''false'', for normal parameters they will have the value <code>$null</code>. This is not always the desired value, though. Default values can be given too: |
Usually all parameters can be omitted. In the case of switch parameters this will cause them to assume the value ''false'', for normal parameters they will have the value <code>$null</code>. This is not always the desired value, though. Default values can be given too: |
||
< |
<syntaxhighlight lang="powershell">function Greeting ($Name = "Nobody") { |
||
Write-Host Hello, $Name! |
Write-Host Hello, $Name! |
||
}</ |
}</syntaxhighlight> |
||
If the <code>Name</code> argument is omitted now, its value will be <code>"Nobody"</code> instead of <code>$null</code>: |
If the <code>Name</code> argument is omitted now, its value will be <code>"Nobody"</code> instead of <code>$null</code>: |
||
<pre>PS> Greeting |
<pre>PS> Greeting |
||
Line 1,201: | Line 1,444: | ||
PS> Greeting John |
PS> Greeting John |
||
Hello John!</pre> |
Hello John!</pre> |
||
=={{header|Prolog}}== |
|||
{{works with|SWI Prolog}} |
|||
<syntaxhighlight lang="prolog">:- initialization(main). |
|||
main :- |
|||
sum(b=2,output=Output,a=1), |
|||
writeln(Output). |
|||
sum(A1,B1,C1) :- |
|||
named_args([A1,B1,C1],[a=A,b=B,output=Output]), |
|||
Output is A + B. |
|||
named_args([],_). |
|||
named_args([A|B],C) :- |
|||
member(A,C), |
|||
named_args(B,C). |
|||
</syntaxhighlight> |
|||
=={{header|Python}}== |
=={{header|Python}}== |
||
Line 1,208: | Line 1,469: | ||
In Python, a regular parameter of a function can be used as ''either a positional or a named'' parameter. The variable name that you use for the parameter when you declare the function becomes the "name" for the parameter, should you use it as a named parameter. When you call a function, you use the "name = value" syntax to provide the argument to a named parameter. The named arguments must come after all the positional arguments. |
In Python, a regular parameter of a function can be used as ''either a positional or a named'' parameter. The variable name that you use for the parameter when you declare the function becomes the "name" for the parameter, should you use it as a named parameter. When you call a function, you use the "name = value" syntax to provide the argument to a named parameter. The named arguments must come after all the positional arguments. |
||
< |
<syntaxhighlight lang="python">def subtract(x, y): |
||
return x - y |
return x - y |
||
subtract(5, 3) # used as positional parameters; evaluates to 2 |
subtract(5, 3) # used as positional parameters; evaluates to 2 |
||
subtract(y = 3, x = 5) # used as named parameters; evaluates to 2</ |
subtract(y = 3, x = 5) # used as named parameters; evaluates to 2</syntaxhighlight> |
||
Parameters can be made optional by providing a default argument, as described in the [[optional parameters]] article. |
Parameters can be made optional by providing a default argument, as described in the [[optional parameters]] article. |
||
Line 1,219: | Line 1,480: | ||
====Function Definition Parameters==== |
====Function Definition Parameters==== |
||
Function definitions in Python allow for the following ''parameter'' types: |
Function definitions in Python allow for the following ''parameter'' types: |
||
* Optional ''default parameter'' types which are explicitly specified by name, and may have an optional default value. |
* Optional ''default parameter'' types which are explicitly specified by name, and may have an optional default value. |
||
* An optional ''positional parameter'' which is an identifier preceded by <code>"*"</code>. |
* An optional ''positional parameter'' which is an identifier preceded by <code>"*"</code>. |
||
* And an optional ''keyword parameter'' which is an identifier preceded by <code>"**"</code>. |
* And an optional ''keyword parameter'' which is an identifier preceded by <code>"**"</code>. |
||
Line 1,244: | Line 1,505: | ||
* All positional arguments must appear before any keyword argument. |
* All positional arguments must appear before any keyword argument. |
||
* ''Keyword arguments'' of the form <code>parameter_name "=" value</code> will map the value to the <code>defparameter</code> in the definition of the same name. |
* ''Keyword arguments'' of the form <code>parameter_name "=" value</code> will map the value to the <code>defparameter</code> in the definition of the same name. |
||
* ''Mapping arguments'' that are the characters <code>"**"</code> followed by an expression evaluating to a mapping (such as a dict/hash). The key, value pairs from the mapping are unpacked and mapped like individual keyword arguments to <code>defparameter</code>s of the function definition. |
* ''Mapping arguments'' that are the characters <code>"**"</code> followed by an expression evaluating to a mapping (such as a dict/hash). The key, value pairs from the mapping are unpacked and mapped like individual keyword arguments to <code>defparameter</code>s of the function definition. |
||
* If the function ''definition'' includes a ''positional parameter'', then if the assignment of ''positional arguments'' and ''sequence arguments'' in the ''call'' gives more values than the <code>defparameters</code> of the definition, then these extra arguments are assembled, in order, into a tuple that is assigned to the <code>posparameter</code> of the definition. |
* If the function ''definition'' includes a ''positional parameter'', then if the assignment of ''positional arguments'' and ''sequence arguments'' in the ''call'' gives more values than the <code>defparameters</code> of the definition, then these extra arguments are assembled, in order, into a tuple that is assigned to the <code>posparameter</code> of the definition. |
||
* If the function ''definition'' includes a ''keyword parameter'', then if the parameter name of any ''keyword arguments'' and ''mapping arguments'' in the ''call'' is unknown in the <code>defparameters</code> of the function definition, then these extra keyword/value pairs are assembled into a dict that is assigned to the <code>keyparameter</code> of the definition. |
* If the function ''definition'' includes a ''keyword parameter'', then if the parameter name of any ''keyword arguments'' and ''mapping arguments'' in the ''call'' is unknown in the <code>defparameters</code> of the function definition, then these extra keyword/value pairs are assembled into a dict that is assigned to the <code>keyparameter</code> of the definition. |
||
* Any ''default parameter'' of the function ''definition'' that is not assigned a value at this point, but which has a default value, will be aassigned this default value, without re-evaluating the default value. |
* Any ''default parameter'' of the function ''definition'' that is not assigned a value at this point, but which has a default value, will be aassigned this default value, without re-evaluating the default value. |
||
* Any ''default parameter'' of the function ''definition'' that is still un-assigned will cause a <code>TypeError</code> exception to be raised. |
* Any ''default parameter'' of the function ''definition'' that is still un-assigned will cause a <code>TypeError</code> exception to be raised. |
||
* In addition, multiple mappings to any parameter will raise a <code>TypeError</code> exception. (This includes multiple mappings into a <code>keyparameter</code> or keyword arguments clashing with positional/sequence arguments). |
* In addition, multiple mappings to any parameter will raise a <code>TypeError</code> exception. (This includes multiple mappings into a <code>keyparameter</code> or keyword arguments clashing with positional/sequence arguments). |
||
Line 1,269: | Line 1,530: | ||
====Examples==== |
====Examples==== |
||
< |
<syntaxhighlight lang="python">>>> from __future__ import print_function |
||
>>> |
>>> |
||
>>> def show_args(defparam1, defparam2 = 'default value', *posparam, **keyparam): |
>>> def show_args(defparam1, defparam2 = 'default value', *posparam, **keyparam): |
||
"Straight-forward function to show its arguments" |
"Straight-forward function to show its arguments" |
||
Line 1,293: | Line 1,554: | ||
print (" <None>") |
print (" <None>") |
||
>>> show_args('POSITIONAL', 'ARGUMENTS') |
>>> show_args('POSITIONAL', 'ARGUMENTS') |
||
Default Parameters: |
Default Parameters: |
||
Line 1,334: | Line 1,595: | ||
Keyword Arguments (by sorted key name): |
Keyword Arguments (by sorted key name): |
||
<None> |
<None> |
||
>>> show_args('POSITIONAL', 'ARGUMENTS', |
>>> show_args('POSITIONAL', 'ARGUMENTS', |
||
'EXTRA', 'POSITIONAL', 'ARGUMENTS') |
'EXTRA', 'POSITIONAL', 'ARGUMENTS') |
||
Default Parameters: |
Default Parameters: |
||
Line 1,345: | Line 1,606: | ||
Keyword Arguments (by sorted key name): |
Keyword Arguments (by sorted key name): |
||
<None> |
<None> |
||
>>> show_args('POSITIONAL', 'ARGUMENTS', |
>>> show_args('POSITIONAL', 'ARGUMENTS', |
||
kwa1='EXTRA', kwa2='KEYWORD', kwa3='ARGUMENTS') |
kwa1='EXTRA', kwa2='KEYWORD', kwa3='ARGUMENTS') |
||
Default Parameters: |
Default Parameters: |
||
Line 1,356: | Line 1,617: | ||
keyword argument: kwa2 is: KEYWORD |
keyword argument: kwa2 is: KEYWORD |
||
keyword argument: kwa3 is: ARGUMENTS |
keyword argument: kwa3 is: ARGUMENTS |
||
>>> show_args('POSITIONAL', |
>>> show_args('POSITIONAL', |
||
'ARGUMENTS', 'EXTRA', 'POSITIONAL', 'ARGUMENTS', |
'ARGUMENTS', 'EXTRA', 'POSITIONAL', 'ARGUMENTS', |
||
kwa1='EXTRA', kwa2='KEYWORD', kwa3='ARGUMENTS') |
kwa1='EXTRA', kwa2='KEYWORD', kwa3='ARGUMENTS') |
||
Default Parameters: |
Default Parameters: |
||
Line 1,371: | Line 1,632: | ||
keyword argument: kwa3 is: ARGUMENTS |
keyword argument: kwa3 is: ARGUMENTS |
||
>>> # But note: |
>>> # But note: |
||
>>> show_args('POSITIONAL', 'ARGUMENTS', |
>>> show_args('POSITIONAL', 'ARGUMENTS', |
||
kwa1='EXTRA', kwa2='KEYWORD', kwa3='ARGUMENTS', |
kwa1='EXTRA', kwa2='KEYWORD', kwa3='ARGUMENTS', |
||
'EXTRA', 'POSITIONAL', 'ARGUMENTS') |
'EXTRA', 'POSITIONAL', 'ARGUMENTS') |
||
SyntaxError: non-keyword arg after keyword arg |
SyntaxError: non-keyword arg after keyword arg |
||
>>></ |
>>></syntaxhighlight> |
||
=={{header|Prolog}}== |
|||
{{works with|SWI Prolog}} |
|||
<lang prolog>:- initialization(main). |
|||
main :- |
|||
sum(b=2,output=Output,a=1), |
|||
writeln(Output). |
|||
sum(A1,B1,C1) :- |
|||
named_args([A1,B1,C1],[a=A,b=B,output=Output]), |
|||
Output is A + B. |
|||
named_args([],_). |
|||
named_args([A|B],C) :- |
|||
member(A,C), |
|||
named_args(B,C). |
|||
</lang> |
|||
=={{header|R}}== |
=={{header|R}}== |
||
Line 1,398: | Line 1,642: | ||
R parameters are all named; arguments can be passed either positionally or with explicit naming. The named arguments are matched to their parameters first, then the unnamed arguments fill in remaining slots. A parameter whose name begins with a period will not be matched to unnamed arguments. R allows abbreviated names to be used as long as they match uniquely to an argument. |
R parameters are all named; arguments can be passed either positionally or with explicit naming. The named arguments are matched to their parameters first, then the unnamed arguments fill in remaining slots. A parameter whose name begins with a period will not be matched to unnamed arguments. R allows abbreviated names to be used as long as they match uniquely to an argument. |
||
< |
<syntaxhighlight lang="rsplus">divide <- function(numerator, denominator) { |
||
numerator / denominator |
numerator / denominator |
||
} |
} |
||
Line 1,407: | Line 1,651: | ||
divide(den=3, num=2) # 0.66 |
divide(den=3, num=2) # 0.66 |
||
divide(den=3, 2) # 0.66 |
divide(den=3, 2) # 0.66 |
||
divide(3, num=2) # 0.66</ |
divide(3, num=2) # 0.66</syntaxhighlight> |
||
=={{header|Racket}}== |
=={{header|Racket}}== |
||
Line 1,413: | Line 1,657: | ||
Racket has built-in keyword and optional arguments: |
Racket has built-in keyword and optional arguments: |
||
< |
<syntaxhighlight lang="racket"> |
||
#lang racket |
#lang racket |
||
(define (pizza sauce |
(define (pizza sauce |
||
;; mandatory keyword argument |
;; mandatory keyword argument |
||
#:topping topping |
#:topping topping |
||
;; optional keyword argument with default |
;; optional keyword argument with default |
||
#:type [type "deep dish"]) |
#:type [type "deep dish"]) |
||
Line 1,426: | Line 1,670: | ||
(pizza "tomato" #:topping "onion") |
(pizza "tomato" #:topping "onion") |
||
(pizza #:topping "onion" "garlic" #:type "pan") |
(pizza #:topping "onion" "garlic" #:type "pan") |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Raku}}== |
|||
(formerly Perl 6) |
|||
{{works with|Rakudo|#22 "Thousand Oaks"}} |
|||
Raku's support for optional parameters is much like Python's. Consider this declaration: |
|||
<syntaxhighlight lang="raku" line>sub funkshun ($a, $b?, $c = 15, :$d, *@e, *%f) { |
|||
... |
|||
}</syntaxhighlight> |
|||
In the above signature: |
|||
* <code>$a</code> is a mandatory parameter accepted by position (<code>funkshun 15, ...</code>). |
|||
* <code>$b</code> is an optional parameter that can be passed by position or by name. By default, it's undefined. |
|||
* <code>$c</code> is an optional parameter that can be passed by position or by name. Its default value is <code>15</code>. |
|||
* <code>$d</code> is an optional parameter that can only be passed by name. By default, it's undefined. |
|||
* <code>@e</code> is a slurpy array: it receives any leftover positional arguments. |
|||
* <code>%f</code> is a slurpy hash: it receives any leftover named arguments. |
|||
So, if we defined the function like this: |
|||
<syntaxhighlight lang="raku" line>sub funkshun ($a, $b?, :$c = 15, :$d, *@e, *%f) { |
|||
say "$a $b $c $d"; |
|||
say join ' ', @e; |
|||
say join ' ', keys %f; |
|||
} |
|||
# this particularly thorny call: |
|||
funkshun |
|||
'Alfa', k1 => 'v1', c => 'Charlie', 'Bravo', 'e1', |
|||
d => 'Delta', 'e2', k2 => 'v2';</syntaxhighlight> |
|||
would print this: |
|||
<pre>Alfa Bravo Charlie Delta |
|||
e1 e2 |
|||
k1 k2</pre> |
|||
=={{header|REXX}}== |
=={{header|REXX}}== |
||
===version 1=== |
===version 1=== |
||
< |
<syntaxhighlight lang="rexx">/*REXX pgm shows named parameters when called as a subroutine/function*/ |
||
/*┌────────────────────────────────────────────────────────────────────┐ |
/*┌────────────────────────────────────────────────────────────────────┐ |
||
│ The syntax of: xxx = func1(parmName2=arg2, parmName1=arg1) │ |
│ The syntax of: xxx = func1(parmName2=arg2, parmName1=arg1) │ |
||
Line 1,505: | Line 1,787: | ||
return 'the final meaning of life, or 42 --- whichever is appropriate.' |
return 'the final meaning of life, or 42 --- whichever is appropriate.' |
||
/*stick a fork in it, we're done.*/</ |
/*stick a fork in it, we're done.*/</syntaxhighlight> |
||
===version 2=== |
===version 2=== |
||
< |
<syntaxhighlight lang="rexx">/* REXX --------------------------------------------------------------- |
||
* 01.07.2014 Walter Pachl |
* 01.07.2014 Walter Pachl |
||
* Argument values must not start with 'arg' |
* Argument values must not start with 'arg' |
||
Line 1,527: | Line 1,809: | ||
Say 'p.'i'='p.i |
Say 'p.'i'='p.i |
||
End |
End |
||
Return p.1**p.2</ |
Return p.1**p.2</syntaxhighlight> |
||
{{Out}} |
{{Out}} |
||
<pre>p.1=2 |
<pre>p.1=2 |
||
Line 1,542: | Line 1,824: | ||
{{trans|Tcl}} |
{{trans|Tcl}} |
||
{{works with|Ruby|2.0}} |
{{works with|Ruby|2.0}} |
||
< |
<syntaxhighlight lang="ruby">def example(foo: 0, bar: 1, grill: "pork chops") |
||
puts "foo is #{foo}, bar is #{bar}, and grill is #{grill}" |
puts "foo is #{foo}, bar is #{bar}, and grill is #{grill}" |
||
end |
end |
||
# Note that :foo is omitted and :grill precedes :bar |
# Note that :foo is omitted and :grill precedes :bar |
||
example(grill: "lamb kebab", bar: 3.14)</ |
example(grill: "lamb kebab", bar: 3.14)</syntaxhighlight> |
||
Ruby 1.9 can fake the effect with a Hash. If a caller passes <code>name: value</code> pairs, Ruby makes a Hash, and the called method sees this Hash in its last argument. To complete the effect, the method may declare an optional last argument that defaults to an empty Hash <code>{}</code>. In this version, <code>example(typo: 4)</code> causes no error. |
Ruby 1.9 can fake the effect with a Hash. If a caller passes <code>name: value</code> pairs, Ruby makes a Hash, and the called method sees this Hash in its last argument. To complete the effect, the method may declare an optional last argument that defaults to an empty Hash <code>{}</code>. In this version, <code>example(typo: 4)</code> causes no error. |
||
Line 1,553: | Line 1,835: | ||
{{works with|Ruby|1.9}} |
{{works with|Ruby|1.9}} |
||
< |
<syntaxhighlight lang="ruby">def example(opts = {}) |
||
# Hash#merge raises TypeError if _opts_ is not a Hash. |
# Hash#merge raises TypeError if _opts_ is not a Hash. |
||
# Nothing checks if _opts_ contains unknown keys. |
# Nothing checks if _opts_ contains unknown keys. |
||
Line 1,563: | Line 1,845: | ||
end |
end |
||
example(grill: "lamb kebab", bar: 3.14)</ |
example(grill: "lamb kebab", bar: 3.14)</syntaxhighlight> |
||
{{omit from|Rust}} |
|||
Ruby 1.8 and older versions can do the same, but must use the old syntax <code>:name => value</code>. |
|||
<lang ruby>def example(opts = {}) |
|||
defaults = {:foo => 0, :bar => 1, :grill => "pork chops"} |
|||
opts = defaults.merge(opts) |
|||
printf("foo is %s, bar is %s, and grill is %s\n", |
|||
opts[:foo], opts[:bar], opts[:grill]) |
|||
end |
|||
example(:grill => "lamb kebab", :bar => 3.14)</lang> |
|||
=={{header|Scala}}== |
=={{header|Scala}}== |
||
Line 1,580: | Line 1,853: | ||
Scala 2.8 utilizes named parameters and default values: |
Scala 2.8 utilizes named parameters and default values: |
||
< |
<syntaxhighlight lang="scala"> |
||
def add(x: Int, y: Int = 1) = x + y |
def add(x: Int, y: Int = 1) = x + y |
||
</syntaxhighlight> |
|||
</lang> |
|||
< |
<syntaxhighlight lang="scala"> |
||
scala> add(5) |
scala> add(5) |
||
6 |
6 |
||
Line 1,590: | Line 1,863: | ||
scala> add(y=10, x=4) |
scala> add(y=10, x=4) |
||
14 |
14 |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Scheme}}== |
=={{header|Scheme}}== |
||
< |
<syntaxhighlight lang="scheme"> |
||
(define (keyarg-parser argdefs args kont) |
(define (keyarg-parser argdefs args kont) |
||
(apply kont |
(apply kont |
||
Line 1,615: | Line 1,888: | ||
(display first))) |
(display first))) |
||
(newline)))) |
(newline)))) |
||
</syntaxhighlight> |
|||
</lang> |
|||
< |
<syntaxhighlight lang="scheme"> |
||
=> (print-name) |
=> (print-name) |
||
? |
? |
||
Line 1,626: | Line 1,899: | ||
=>(print-name 'last "Doe") |
=>(print-name 'last "Doe") |
||
Doe |
Doe |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|SenseTalk}}== |
|||
The <b>introduce</b> handler here includes a default value for <b>greeting</b>. Ordinarily, parameters are passed sequentially, but <code>by name</code> can be used to match values from a property list to the corresponding parameters of the handler that is being called.<syntaxhighlight lang="sensetalk">introduce "Mary" |
|||
introduce "Pablo", "Hola" |
|||
introduce greeting:"Bonjour", name:"Brigitte" by name |
|||
to introduce name, greeting:"Hello" |
|||
put greeting && name |
|||
end introduce |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
Hello Mary |
|||
Hola Pablo |
|||
Bonjour Brigitte |
|||
</pre> |
|||
=={{header|Sidef}}== |
=={{header|Sidef}}== |
||
< |
<syntaxhighlight lang="ruby">func example(foo: 0, bar: 1, grill: "pork chops") { |
||
say "foo is #{foo}, bar is #{bar}, and grill is #{grill}"; |
say "foo is #{foo}, bar is #{bar}, and grill is #{grill}"; |
||
} |
} |
||
# Note that :foo is omitted and :grill precedes :bar |
# Note that :foo is omitted and :grill precedes :bar |
||
example(grill: "lamb kebab", bar: 3.14);</ |
example(grill: "lamb kebab", bar: 3.14);</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>foo is 0, bar is 3.14, and grill is lamb kebab</pre> |
<pre>foo is 0, bar is 3.14, and grill is lamb kebab</pre> |
||
Line 1,644: | Line 1,933: | ||
{{works with|GNU Smalltalk}} |
{{works with|GNU Smalltalk}} |
||
< |
<syntaxhighlight lang="smalltalk">Object subclass: AnotherClass [ |
||
"..." |
"..." |
||
initWithArray: anArray [ "single argument" ] |
initWithArray: anArray [ "single argument" ] |
||
initWithArray: anArray andString: aString [ |
initWithArray: anArray andString: aString [ |
||
"two args; these two methods in usage resemble |
"two args; these two methods in usage resemble |
||
a named argument, with optional andString argument" |
a named argument, with optional andString argument" |
||
] |
] |
||
"..." |
"..." |
||
]</ |
]</syntaxhighlight> |
||
=={{header|Standard ML}}== |
=={{header|Standard ML}}== |
||
This example uses Standard ML "fields". |
This example uses Standard ML "fields". |
||
< |
<syntaxhighlight lang="sml">fun dosomething (a, b, c) = print ("a = " ^ a ^ "\nb = " ^ Real.toString b ^ "\nc = " ^ Int.toString c ^ "\n") |
||
fun example {a, b, c} = dosomething (a, b, c)</ |
fun example {a, b, c} = dosomething (a, b, c)</syntaxhighlight> |
||
To call the procedure ''example'', use: |
To call the procedure ''example'', use: |
||
< |
<syntaxhighlight lang="sml">example {a="Hello World!", b=3.14, c=42}</syntaxhighlight> |
||
However, this does not support optional parameters. To emulate them, we can process a parameter list: |
However, this does not support optional parameters. To emulate them, we can process a parameter list: |
||
< |
<syntaxhighlight lang="sml">datatype param = A of string | B of real | C of int |
||
fun args xs = |
fun args xs = |
||
Line 1,674: | Line 1,963: | ||
map (fn (A x) => a := x | (B x) => b := x | (C x) => c := x) xs; |
map (fn (A x) => a := x | (B x) => b := x | (C x) => c := x) xs; |
||
(!a, !b, !c) |
(!a, !b, !c) |
||
end</ |
end</syntaxhighlight> |
||
To process the argument list and call ''example'', use: |
To process the argument list and call ''example'', use: |
||
< |
<syntaxhighlight lang="sml">dosomething (args [A "tam", B 42.0]);</syntaxhighlight> |
||
=={{header|Suneido}}== |
=={{header|Suneido}}== |
||
Suneido can handle named and unnamed parameters. When using a combination, unnamed parameters must come before named ones and must be in the correct order. Named parameters can be in any order. Named parameters are given a default value so they are not mandatory. |
Suneido can handle named and unnamed parameters. When using a combination, unnamed parameters must come before named ones and must be in the correct order. Named parameters can be in any order. Named parameters are given a default value so they are not mandatory. |
||
<syntaxhighlight lang="suneido"> |
|||
<lang Suneido> |
|||
test = function (one, two, three = '', four = '', five = '') |
test = function (one, two, three = '', four = '', five = '') |
||
{ |
{ |
||
Print('one: ' $ one $ ', two: ' $ two $ ', three: ' $ three $ |
Print('one: ' $ one $ ', two: ' $ two $ ', three: ' $ three $ |
||
', four: ' $ four $ ', five: ' $ five) |
', four: ' $ four $ ', five: ' $ five) |
||
} |
} |
||
test('1', '2', five: '5', three: '3') |
test('1', '2', five: '5', three: '3') |
||
</syntaxhighlight> |
|||
</lang> |
|||
Output: |
Output: |
||
< |
<syntaxhighlight lang="suneido">one: 1, two: 2, three: 3, four: , five: 5</syntaxhighlight> |
||
=={{header|Swift}}== |
=={{header|Swift}}== |
||
Each function parameter has both an argument label and a parameter name. The argument label is used when calling the function; each argument is written in the function call with its argument label before it. The parameter name is used in the implementation of the function. By default, parameters use their parameter name as their argument label. |
Each function parameter has both an argument label and a parameter name. The argument label is used when calling the function; each argument is written in the function call with its argument label before it. The parameter name is used in the implementation of the function. By default, parameters use their parameter name as their argument label. |
||
< |
<syntaxhighlight lang="swift">func greet(person: String, hometown: String) -> String { |
||
return "Hello \(person)! Glad you could visit from \(hometown)." |
return "Hello \(person)! Glad you could visit from \(hometown)." |
||
} |
} |
||
print(greet(person: "Bill", hometown: "Cupertino"))</ |
print(greet(person: "Bill", hometown: "Cupertino"))</syntaxhighlight> |
||
You write an argument label before the parameter name, separated by a space: |
You write an argument label before the parameter name, separated by a space: |
||
< |
<syntaxhighlight lang="swift">func greet(person: String, from hometown: String) -> String { |
||
return "Hello \(person)! Glad you could visit from \(hometown)." |
return "Hello \(person)! Glad you could visit from \(hometown)." |
||
} |
} |
||
print(greet(person: "Bill", from: "Cupertino"))</ |
print(greet(person: "Bill", from: "Cupertino"))</syntaxhighlight> |
||
If you don’t want an argument label for a parameter, write an underscore (_) instead of an explicit argument label for that parameter. |
If you don’t want an argument label for a parameter, write an underscore (_) instead of an explicit argument label for that parameter. |
||
If a parameter has an argument label, the argument must be labeled when you call the function. |
If a parameter has an argument label, the argument must be labeled when you call the function. |
||
< |
<syntaxhighlight lang="swift">func greet(_ person: String, _ hometown: String) -> String { |
||
return "Hello \(person)! Glad you could visit from \(hometown)." |
return "Hello \(person)! Glad you could visit from \(hometown)." |
||
} |
} |
||
print(greet("Bill", "Cupertino"))</ |
print(greet("Bill", "Cupertino"))</syntaxhighlight> |
||
You can define a default value for any parameter in a function by assigning a value to the parameter after that parameter’s type. If a default value is defined, you can omit that parameter when calling the function. |
You can define a default value for any parameter in a function by assigning a value to the parameter after that parameter’s type. If a default value is defined, you can omit that parameter when calling the function. |
||
< |
<syntaxhighlight lang="swift">func greet(person: String, from hometown: String = "Cupertino") -> String { |
||
return "Hello \(person)! Glad you could visit from \(hometown)." |
return "Hello \(person)! Glad you could visit from \(hometown)." |
||
} |
} |
||
print(greet(person: "Bill"))</ |
print(greet(person: "Bill"))</syntaxhighlight> |
||
=={{header|Tcl}}== |
=={{header|Tcl}}== |
||
===Using arrays=== |
|||
The simplest way of passing named parameters is to use the Tcl language's strong support for [[Varargs#Tcl|variadic commands]] together with its arrays. By convention (originally from [[Tk]]) the named parameters names start with a hyphen (“<tt>-</tt>”) and are called options. |
The simplest way of passing named parameters is to use the Tcl language's strong support for [[Varargs#Tcl|variadic commands]] together with its arrays. By convention (originally from [[Tk]]) the named parameters names start with a hyphen (“<tt>-</tt>”) and are called options. |
||
< |
<syntaxhighlight lang="tcl">proc example args { |
||
# Set the defaults |
# Set the defaults |
||
array set opts {-foo 0 -bar 1 -grill "hamburger"} |
array set opts {-foo 0 -bar 1 -grill "hamburger"} |
||
Line 1,728: | Line 2,019: | ||
# Note that -foo is omitted and -grill precedes -bar |
# Note that -foo is omitted and -grill precedes -bar |
||
example -grill "lamb kebab" -bar 3.14 |
example -grill "lamb kebab" -bar 3.14 |
||
# => ‘foo is 0, bar is 3.14, and grill is lamb kebab’</ |
# => ‘foo is 0, bar is 3.14, and grill is lamb kebab’</syntaxhighlight> |
||
More complex option parsing is possible, e.g., with the <tt>opt</tt> package (of which only a small fraction of the functionality is shown here). This package also allows you to specify type constraints, though that is usually not necessary, and will generate a standard help message that can be obtained with the <tt>-help</tt> option: |
More complex option parsing is possible, e.g., with the <tt>opt</tt> package (of which only a small fraction of the functionality is shown here). This package also allows you to specify type constraints, though that is usually not necessary, and will generate a standard help message that can be obtained with the <tt>-help</tt> option: |
||
< |
<syntaxhighlight lang="tcl">package require opt |
||
tcl::OptProc example { |
tcl::OptProc example { |
||
{-foo -int 0 "The number of foos"} |
{-foo -int 0 "The number of foos"} |
||
Line 1,747: | Line 2,038: | ||
# -foo int (0) The number of foos |
# -foo int (0) The number of foos |
||
# -bar float (1.0) How much bar-ness |
# -bar float (1.0) How much bar-ness |
||
# -grill any (hamburger) What to cook on the grill</ |
# -grill any (hamburger) What to cook on the grill</syntaxhighlight> |
||
According to [http://wiki.tcl.tk/1730 wiki.tcl.tk discussions], '''::tcl::OptProc is deprecated.''' |
According to [http://wiki.tcl.tk/1730 wiki.tcl.tk discussions], '''::tcl::OptProc is deprecated.''' |
||
The recommended replacement is [http://tcllib.sourceforge.net/doc/cmdline.html cmdline] in [http://tcllib.sourceforge.net/doc/index.html tcllib]. "This is probably the most standard and widely-used of these packages." |
The recommended replacement is [http://tcllib.sourceforge.net/doc/cmdline.html cmdline] in [http://tcllib.sourceforge.net/doc/index.html tcllib]. "This is probably the most standard and widely-used of these packages." |
||
===Using dicts=== |
|||
Now (8.5) that dicts are here to replace arrays in most places, this can be achieved more cleanly as long as you do the authorized key checking yourself. Example of summary testing (to put in a nice uplevel wrapper): |
|||
<syntaxhighlight lang="tcl">proc example {x y args} { |
|||
set keyargs {arg1 default1 arg2 default2} |
|||
if {[llength $args] % 2 != 0} { |
|||
error "$args: invalid keyword arguments (spec: $keyargs)" |
|||
} |
|||
set margs [dict merge $keyargs $args] |
|||
if {[dict size $margs] != [dict size $keyargs]} { |
|||
error "$args: invalid keyword arguments (spec: $keyargs)" |
|||
} |
|||
lassign [dict values $margs] {*}[dict keys $margs] |
|||
puts "x: $x, y: $y, arg1: $arg1, arg2: $arg2" |
|||
} |
|||
example 1 2 # => x: 1, y: 2, arg1: default1, arg2: default2 |
|||
example 1 2 arg2 3 # => x: 1, y: 2, arg1: default1, arg2: 3 |
|||
example 1 2 test 3 # => test 3: invalid keyword arguments (spec: arg1 default1 arg2 default2) |
|||
example 1 2 test # => test: invalid keyword arguments (spec: arg1 default1 arg2 default2)</syntaxhighlight> |
|||
Of course, more work is required to reach the flexibility of something like Common Lisp's ordinary lambda list. |
|||
=={{header|VBA}}== |
|||
{{trans|Phix}}<syntaxhighlight lang="vb"> |
|||
Public Function timedelta(Optional weeks As Integer = 0, Optional days As Integer = 0, _ |
|||
Optional hours As Integer = 0, Optional minutes As Integer = 0, Optional seconds As Integer = 0, _ |
|||
Optional milliseconds As Integer = 0, Optional microseconds As Integer = 0) As Variant |
|||
End Function |
|||
Public Sub main() |
|||
'-- can be invoked as: |
|||
fourdays = timedelta(days:=4) |
|||
'-- fourdays = timedelta(0,4) '-- equivalent |
|||
'-- **NB** a plain '=' is a very different thing |
|||
oneday = timedelta(days = 1) '-- equivalent to timedelta([weeks:=]IIf((days=1,-1:0)) |
|||
'-- with NO error if no local variable days exists. |
|||
'VBA will assume local variable days=0 |
|||
Dim hours As Integer |
|||
shift = timedelta(hours:=hours) '-- perfectly valid (param hours:=local hours) |
|||
'-- timedelta(0,hours:=15,3) '-- illegal (it is not clear whether you meant days:=3 or minutes:=3) |
|||
'VBA expects a named parameter for 3 |
|||
End Sub</syntaxhighlight> |
|||
=={{header|Visual Basic}}== |
=={{header|Visual Basic}}== |
||
< |
<syntaxhighlight lang="vb">'the function |
||
Sub whatever(foo As Long, bar As Integer, baz As Byte, qux As String) |
Sub whatever(foo As Long, bar As Integer, baz As Byte, qux As String) |
||
'... |
'... |
||
Line 1,760: | Line 2,093: | ||
Sub crap() |
Sub crap() |
||
whatever bar:=1, baz:=2, foo:=-1, qux:="Why is ev'rybody always pickin' on me?" |
whatever bar:=1, baz:=2, foo:=-1, qux:="Why is ev'rybody always pickin' on me?" |
||
End Sub</ |
End Sub</syntaxhighlight> |
||
=={{header|V (Vlang)}}== |
|||
1) Vlang allows for a struct literal to be passed to the function, instead of named parameters. |
|||
2) Using this style, fields need not appear in the same order as they are declared. |
|||
3) If one or more fields are omitted, their default values will be used instead. |
|||
4) The named parameter feature was deliberately omitted, for greater code readability. |
|||
5) Depending on the situation, variadic and/or sum types can also be considered. |
|||
<syntaxhighlight lang="Zig"> |
|||
struct Params { |
|||
a int |
|||
b int |
|||
c int |
|||
} |
|||
fn a_fn(p Params) int { |
|||
return p.a + p.b + p.c |
|||
} |
|||
fn main() { |
|||
x := a_fn(Params{a: 1, b: 2, c: 3}) // same order |
|||
println("x = ${x}") |
|||
y := a_fn(Params{c: 3, b: 2, a: 1}) // different order |
|||
println("y = ${y}") |
|||
z := a_fn(Params{c: 2}) // only one field |
|||
println("z = ${z}") |
|||
} |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
x = 6 |
|||
y = 6 |
|||
z = 2 |
|||
</pre> |
|||
=={{header|Wren}}== |
|||
Wren doesn't support named parameters as such though they can be simulated using a map. |
|||
<syntaxhighlight lang="wren">var printName = Fn.new { |name| |
|||
if (!(name is Map && name["first"] != null && name["last"] != null)) { |
|||
Fiber.abort("Argument must be a map with keys \"first\" and \"last\"") |
|||
} |
|||
System.print("%(name["first"]) %(name["last"])") |
|||
} |
|||
printName.call({"first": "Abraham", "last": "Lincoln"}) // normal order |
|||
printName.call({"last": "Trump", "first": "Donald"}) // reverse order |
|||
printName.call({"forename": "Boris", "lastname": "Johnson"}) // wrong parameter names</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
Abraham Lincoln |
|||
Donald Trump |
|||
Argument must be a map with keys "first" and "last" |
|||
[./named_params line 3] in new(_) block argument |
|||
[./named_params line 10] in (script) |
|||
</pre> |
|||
=={{header|XSLT}}== |
=={{header|XSLT}}== |
||
XSLT only allows specification of template parameters by name, not position. |
XSLT only allows specification of template parameters by name, not position. |
||
< |
<syntaxhighlight lang="xml"><xsl:template name="table-header"> |
||
<xsl:param name="title"/> |
<xsl:param name="title"/> |
||
... |
... |
||
</xsl:template></ |
</xsl:template></syntaxhighlight> |
||
{{omit from|6502 Assembly|does not support named arguments without macros, which are entirely position-based}} |
|||
{{omit from|68000 Assembly|See above.}} |
|||
{{omit from|8086 Assembly|See above.}} |
|||
{{omit from|Axe}} |
{{omit from|Axe}} |
||
{{omit from|BASIC}} |
{{omit from|BASIC}} |
||
Line 1,774: | Line 2,170: | ||
{{omit from|bc}} |
{{omit from|bc}} |
||
{{omit from|dc}} |
{{omit from|dc}} |
||
{{omit from|F_sharp}} |
|||
{{omit from|GUISS}} |
{{omit from|GUISS}} |
||
{{omit from|Joy}} |
{{omit from|Joy}} |
||
Line 1,782: | Line 2,177: | ||
{{omit from|TI-89 BASIC}} |
{{omit from|TI-89 BASIC}} |
||
{{omit from|UNIX Shell}} |
{{omit from|UNIX Shell}} |
||
{{omit from|Z80 Assembly}} |
|||
{{omit from|zkl}} |
{{omit from|zkl}} |
||
{{omit from|ZX Spectrum Basic}} |
{{omit from|ZX Spectrum Basic}} |
||
Latest revision as of 09:18, 6 January 2024
![Task](http://static.miraheze.org/rosettacodewiki/thumb/b/ba/Rcode-button-task-crushed.png/64px-Rcode-button-task-crushed.png)
You are encouraged to solve this task according to the task description, using any language you may know.
Create a function which takes in a number of arguments which are specified by name rather than (necessarily) position, and show how to call the function. If the language supports reordering the arguments or optionally omitting some of them, note this.
Note:
- Named parameters relies on being able to use the names given to function parameters when the function is defined, when assigning arguments when the function is called.
- For example, if a function were to be defined as
define func1( paramname1, paramname2)
; then it could be called normally asfunc1(argument1, argument2)
and in the called function paramname1 would be associated with argument1 and paramname2 with argument2. func1
must also be able to be called in a way that visually binds each parameter to its respective argument, irrespective of argument order, for example:func1(paramname2=argument2, paramname1=argument1)
which explicitly makes the same parameter/argument bindings as before.- Named parameters are often a feature of languages used in safety critical areas such as Verilog and VHDL.
See also:
11l
F sqlen(x = 0, y = 0, z = 0)
R x*x + y*y + z*z
print(sqlen(z' 3)) // equivalent to print(sqlen(0, 0, 3))
Ada
All callable entities (procedures, functions, entries) require named arguments. All of them can be called using either positional or keyed association of the actual arguments. The arguments supplied with default values can be omitted.
procedure Foo (Arg_1 : Integer; Arg_2 : Float := 0.0);
It can be equivalently called as:
Foo (1, 0.0);
Foo (1);
Foo (Arg_2 => 0.0, Arg_1 => 1);
Foo (Arg_1 => 1);
ALGOL 68
BEGIN
MODE OPTNAME = STRUCT(STRING name),
OPTSPECIES = STRUCT(STRING species),
OPTBREED = STRUCT(STRING breed),
OWNER=STRUCT(STRING first name, middle name, last name);
# Version 2 of Algol 68G would not allow empty options to be specified as () so #
# VOID would need to be included in the MODEs for options and Empty option lists #
# would need to be written as (EMPTY) #
MODE OPTIONS = FLEX[1:0]UNION(OPTNAME,OPTSPECIES,OPTBREED,OWNER); # add ,VOID for Algol 68G version 2 #
# due to the Yoneda ambiguity simple arguments must have an unique operator defined #
# E.g. a string cannot be coerced to a structure with a single string field #
OP NAME = (STRING name)OPTNAME: (OPTNAME opt; name OF opt := name; opt),
SPECIES = (STRING species)OPTSPECIES: (OPTSPECIES opt; species OF opt := species; opt),
BREED = (STRING breed)OPTBREED: (OPTBREED opt; breed OF opt := breed; opt);
PROC print pet = (OPTIONS option)VOID: (
STRING name:="Rex", species:="Dinosaur", breed:="Tyrannosaurus"; # Defaults #
OWNER owner := ("George","W.","Bush");
FOR i TO UPB option DO
CASE option[i] IN
(OPTNAME option): name := name OF option,
(OPTSPECIES option): species := species OF option,
(OPTBREED option): breed := breed OF option,
(OWNER option): owner := option
ESAC
OD;
print(("Details: "
,IF CHAR c = breed[LWB breed]; char in string( c, NIL, "AaEeIiOoUu" ) THEN "an " ELSE "a " FI
,breed, " ", species, " named ",name," owned by ",owner, newline))
);
print pet((NAME "Mike", SPECIES "Dog", BREED "Irish Setter", OWNER("Harry", "S.", "Truman")));
print pet(()) # use print pet((EMPTY)) for Algol 68G version 2 #
END
Output:
Details: an Irish Setter Dog named Mike owned by HarryS.Truman Details: a Tyrannosaurus Dinosaur named Rex owned by GeorgeW.Bush
AppleScript
AppleScript does not implement default or optional parameters, but they can be simulated using records.
on getName(x)
set {firstName, lastName} to {"?", "?"}
try
set firstName to x's firstName
end try
try
set lastName to x's lastName
end try
return firstName & ", " & lastName
end getName
Examples:
getName({firstName:"John", lastName:"Doe"})
--> Returns: "John, Doe"
getName({lastName:"Doe"})
--> Returns: "?, Doe"
An easier way to achieve the above is by concatenating a record containing default values for the expected properties to the record actually passed. The result will contain the labels and values from both records, except that where the same label exists in both records, there'll only be one instance in the result and its value will be that from the first record:
on getName(x) -- x assumed to be a record for this demo.
set x to x & {firstName:"?", lastName:"?"}
return x's firstName & ", " & x's lastName
end getName
getName({lastName:"Doe"})
--> "?, Doe"
One of AppleScript's handler types has long been "handlers with labeled parameters". These haven't proved particularly popular as they have a limited set of AppleScript-defined labels, which can require some creativity when choosing one to make sense in the script narrative. However, labelled parameters can be given in any order in calls:
on getName from firstName beside lastName
return firstName & ", " & lastName
end getName
getName beside "Doe" from "John"
--> "John, Doe"
However, it's also possible to define user labels, with the same flexibility of order, using a slightly different syntax:
on getName given firstName:firstName, lastName:lastName
return firstName & ", " & lastName
end getName
getName given lastName:"Doe", firstName:"John"
--> "John, Doe"
AppleScript-defined and user labels can be combined, but the AppleScript ones must be given first if used. The given syntax also has a neat feature whereby if the value to be passed is a boolean, the keyword with or without can be used instead in the call. In fact the compiler imposes this anyway when a boolean is hard-coded into the call:
on getName given firstName:firstName, lastName:lastName, comma:comma
if (comma) then
return firstName & ", " & lastName
else
return firstName & space & lastName
end if
end getName
getName given lastName:"Doe", firstName:"John" comma:true -- compiles as: getName with comma given lastName:"Doe", firstName:"John"
--> "John, Doe"
getName without comma given lastName:"Doe", firstName:"John"
--> "John Doe"
Since Mac OS X 10.10, it has been possible to make labelled parameters optional by defining default values for them in the handler declarations. But at least one parameter must be provided in any call:
use AppleScript version "2.4" -- Mac OS X 10.10 (Yosemite) or later.
on getName under category : "Misc: " given firstName:firstName : "?", lastName:lastName : "?", comma:comma : true
if (comma) then
return category & firstName & ", " & lastName
else
return category & firstName & space & lastName
end if
end getName
getName given lastName:"Doe"
--> "Misc: ?, Doe"
Applesoft BASIC
Function definitions in Applesoft BASIC using the DEF FN statement can only have one parameter. Subroutines and functions with many parameters can be simulated using global variables which are effectively named parameters. Default or optional parameters can be simulated with a check in the subroutine.
100 IF LAST$ = "" THEN PRINT "?";
110 IF LAST$ < > "" THEN PRINT LAST$;
120 IF FIRST$ < > "" THEN PRINT ", "FIRST$;
200 FIRST$ = ""
210 LAST$ = ""
220 RETURN
]FIRST$ = "JOHN" : GOSUB 100"PRINT NAME ?, JOHN ]LAST$ = "DOE" : GOSUB 100"PRINT NAME DOE ]FIRST$ = "JOHN" : LAST$ = "DOE" : GOSUB 100"PRINT NAME DOE, JOHN
Arturo
func: function [x][
print ["argument x:" x]
print ["attribute foo:" attr 'foo]
print ["attribute bar:" attr 'bar]
print ""
]
func 1
func .foo:"foo" 2
func .bar:"bar" 3
func .foo:123 .bar:124 4
func .bar:124 .foo:123 5
- Output:
argument x: 1 attribute foo: null attribute bar: null argument x: 2 attribute foo: foo attribute bar: null argument x: 3 attribute foo: null attribute bar: bar argument x: 4 attribute foo: 123 attribute bar: 124 argument x: 5 attribute foo: 123 attribute bar: 124
AutoHotkey
AutoHotkey doesn't have named parameters, but they can be simulated as follows. ahk discussion
MyFunc( "Val=0, w=1024, Text=The Quick Brown Fox, newVar=I'm New" )
MyFunc( _overrides="" ) {
Static x=5, y=5, w=100, h=100, Count
Name:="AutoHotkey", Type:="Scripting", Text:="qwerty", Val:=True
Loop, Parse, _overrides,`,=, %A_Space% ; Override routine for Local/Static variables
A_Index & 1 ? (_:=A_LoopField) : (%_%:=A_LoopField)
Listvars
WinWaitClose, %A_ScriptFullPath%
}
Bracmat
In Bracmat, all functions have exactly one argument, called "arg". To split the argument and assign values to local variables, you always have to use pattern matching. In this task, the pattern is just made a bit more complex than would have been the case without explicit parameter names in the argument.
( ( testproc
= i x y z
. out$"Calling testproc"
& (=~):(=?i:?x:?y:?z) { initialise variables to 'failure' }
& !arg
: (? (i,?i) ?|?) { if "i" found, assign value to i. Otherwise just match with no side effect. }
: (? (x,?x) ?|?) { if "x" found, assign value to x. Otherwise just match with no side effect. }
: (? (y,?y) ?|?) { likewise }
: (? (z,?z) ?|?) { likewise }
& (~!i|put$(" i:=" !i)) { if variable doesn't fail, show its value }
& (~!x|put$(" x:=" !x))
& (~!y|put$(" y:=" !y))
& (~!z|put$(" z:=" !z))
& put$\n { add new line }
)
& testproc$((x,1) (y,2) (z,3))
& testproc$((x,3) (y,1) (z,2))
& testproc$((z,4) (x,2) (y,3)) { order is not important }
& testproc$((i,1) (y,2) (z,3))
);
Output:
Calling testproc x:= 1 y:= 2 z:= 3 Calling testproc x:= 3 y:= 1 z:= 2 Calling testproc x:= 2 y:= 3 z:= 4 Calling testproc i:= 1 y:= 2 z:= 3
C
C has no direct support for named parameters to functions, but it does permit named parameters to struct initializers. These can be used to simulate named function parameters:
#include <stdio.h>
// 1. Named parameters
typedef struct { int x, y, z; } FTest_args;
void FTest (FTest_args args) {
printf("x: %d, y: %d, z: %d\n", args.x, args.y, args.z);
}
#define FT(...) FTest((FTest_args){ __VA_ARGS__ })
// 2. Default parameters
#define DFT(...) FTest((FTest_args){ .x = 142, .y = 143, .z = 144, __VA_ARGS__ })
// 3. Convenience wrapper to avoid accessing args as "args.name"
void FTest2 (int x, int y, int z) {
printf("x: %d, y: %d, z: %d\n", x, y, z);
}
static inline void FTest2_default_wrapper (FTest_args args) {
return FTest2(args.x, args.y, args.z);
}
#define DF2(...) FTest2_default_wrapper((FTest_args){ .x = 142, .y = 143, .z = 144, __VA_ARGS__ })
int main(int argc, char **argv)
{
// Named parameters
FTest((FTest_args){ .y = 10 });
FTest((FTest_args){ .y = 10, .z = 42 });
FT( .z = 47, .y = 10, .x = 42 );
// Default parameters
DFT();
DFT( .z = 99 );
// Default parameters with wrapper
DF2();
DF2( .z = 99 );
return 0;
}
As a bonus, default values for the parameters left unspecified can be either implicitly set to zero by the struct initializer, or supplied in a wrapper-macro definition. But this is not idiomatic C by any stretch.
C#
Named parameters were added in C# 4.0. The examples below demonstrate how named parameters and optional parameters are a single concept in the language.
using System;
namespace NamedParams
{
class Program
{
static void AddWidget(string parent, float x = 0, float y = 0, string text = "Default")
{
Console.WriteLine("parent = {0}, x = {1}, y = {2}, text = {3}", parent, x, y, text);
}
static void Main(string[] args)
{
AddWidget("root", 320, 240, "First");
AddWidget("root", text: "Origin");
AddWidget("root", 500);
AddWidget("root", text: "Footer", y: 400);
}
}
}
Output:
parent = root, x = 320, y = 240, text = First parent = root, x = 0, y = 0, text = Origin parent = root, x = 500, y = 0, text = Default parent = root, x = 0, y = 400, text = Footer
C++
C++ does not support name parameters, but they can be simulated with the "Named Parameter Idiom" (http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.18).
You wrap the parameters in a class, and make the function a friend of the parameter class.
class foo_params{
friend void foo(foo_params p);
public:
foo_params(int r):
required_param_(r),
optional_x_(0),
optional_y_(1),
optional_z_(3.1415)
{}
foo_params& x(int i){
optional_x_=i;
return *this;
}
foo_params& y(int i){
optional_y_=i;
return *this;
}
foo_params& z(float f){
optional_z_=f;
return *this;
}
private:
int required_param_;
int optional_x_;
int optional_y_;
float optional_z_;
};
Declare the function to take the parameter class as its only parameter.
void foo(foo_params p){ . . .}
Call the function using the parameter object constructor with the required parameters and chaining the optional parameters.
foo(foo_params(42).x(7).z(23.54));
If you want real named parameters you can use The Boost Parameter Library.
#include <boost/parameter/name.hpp>
#include <boost/parameter/preprocessor.hpp>
#include <string>
BOOST_PARAMETER_NAME(foo)
BOOST_PARAMETER_NAME(bar)
BOOST_PARAMETER_NAME(baz)
BOOST_PARAMETER_NAME(bonk)
BOOST_PARAMETER_FUNCTION(
(int), // the return type of the function, the parentheses are required.
function_with_named_parameters, // the name of the function.
tag, // part of the deep magic. If you use BOOST_PARAMETER_NAME you need to put "tag" here.
(required // names and types of all required parameters, parentheses are required.
(foo, (int))
(bar, (float))
)
(optional // names, types, and default values of all optional parameters.
(baz, (bool) , false)
(bonk, (std::string), "default value")
)
)
{
if (baz && (bar > 1.0)) return foo;
return bonk.size();
}
Once the definition is written, using it is easy, by name or position.
function_with_named_parameters(1, 10.0);
function_with_named_parameters(7, _bar = 3.14);
function_with_named_parameters( _bar = 0.0, _foo = 42);
function_with_named_parameters( _bar = 2.5, _bonk= "Hello", _foo = 9);
function_with_named_parameters(9, 2.5, true, "Hello");
Clojure
Clojure doesn't have built-in support for named or keyword arguments, but you can use destructuring to achieve a similar effect.
(defn foo [& opts]
(let [opts (merge {:bar 1 :baz 2} (apply hash-map opts))
{:keys [bar baz]} opts]
[bar baz]))
Clojure 1.2 supports destructuring of trailing arguments as a map:
(defn foo [& {:keys [bar baz] :or {bar 1, baz 2}}]
[bar baz])
You can also use defnk
from clojure.contrib.def
, which is a macro that works similarly.
(use 'clojure.contrib.def)
(defnk foo [:bar 1 :baz 2]
[bar baz])
Sample output for all variants:
user> (foo :baz 123) [1 123] user> (foo :bar 456) [456 2]
Common Lisp
(defun print-name (&key first (last "?"))
(princ last)
(when first
(princ ", ")
(princ first))
(values))
&key
indicates that further parameters are named (keyword parameters); a bare symbol (e.g. first) has a default of NIL, whereas a list (e.g. (last "?")
) gives the variable name and the default value (which is evaluated when the function is called, unlike Python).
CL-USER> (print-name)
?
CL-USER> (print-name :first "John")
?, John
CL-USER> (print-name :first "John" :last "Doe")
Doe, John
CL-USER> (print-name :last "Doe")
Doe
In Common Lisp, the arguments to a function are always a simple list of values; the &key
facility merely defines an interpretation of that list by the function: alternating keys and values. (As a result of this, mixing varargs (&rest
) with named parameters is not recommended as it requires some additional means of distinguishing them. On the other hand, functions which pass their arguments on to other functions need not handle named arguments distinctly.)
Delphi
Delphi not support named params in any version, this is a uneficient, but functional, adaptation of c++ answer.
program Named_parameters;
{$APPTYPE CONSOLE}
uses
System.SysUtils;
type
TParams = record
fx, fy, fz: Integer;
function x(value: Integer): TParams;
function y(value: Integer): TParams;
function z(value: Integer): TParams;
class function _: TParams; static;
end;
function Sum(Param: TParams): Integer;
begin
Result := Param.fx + Param.fy + Param.fz;
end;
{ TParams }
function TParams.x(value: Integer): TParams;
begin
Result := Self;
Result.fx := value;
end;
function TParams.y(value: Integer): TParams;
begin
Result := Self;
Result.fy := value;
end;
function TParams.z(value: Integer): TParams;
begin
Result := Self;
Result.fz := value;
end;
class function TParams._: TParams;
begin
Result.fx := 0; // default x
Result.fy := 0; // default y
Result.fz := 0; // default z
end;
begin
writeln(sum(TParams._.x(2).y(3).z(4))); // 9
writeln(sum(TParams._.z(4).x(3).y(5))); // 12
{$IFNDEF UNIX} readln; {$ENDIF}
end.
Dyalect
Dyalect supports both named and optional parameters.
func fun(x, y = 0, z = 12.2, dsc = "Useless text") {
print("x=\(x), y=\(y), z=\(z), dsc=\(dsc)")
}
fun(12, z: 24.4, dsc: "Foo", y: 3)
fun(y: 42, x: 12)
- Output:
x=12, y=3, z=24.4, dsc=Foo x=12, y=42, z=12.2, dsc=Useless text
E
Since E supports arbitrary pattern matching (in the sense of Pattern Matching in parameter lists, a map-pattern can be used to provide named parameters, though the syntax is sufficiently noisy that this is not used casually.
def printName([=> first := null, => last := null]) {
if (last == null) {
print("?")
} else {
print(last)
}
if (first != null) {
print(", ")
print(first)
}
}
(Note: In map literals and map patterns, “=> x
” is shorthand for “"x" => x
”.)
? printName(["first" => "John"])
?, John
? printName(["last" => "Doe"])
Doe
? printName(["first" => "John", "last" => "Doe"])
Doe, John
Ecstasy
Method and function arguments are passed in order, unless argument names are specified by the caller. Both named arguments and default values for arguments are supported. Ordered and named arguments can both be used in the same invocation, but once a named argument is specified, all subsequent arguments in the invocation must also be named.
A common example of using named arguments is a "wither" method:
module NamedParams {
const Point(Int x, Int y) {
Point with(Int? x=Null, Int? y=Null) {
return new Point(x ?: this.x, y ?: this.y);
}
}
@Inject Console console;
void run() {
Point origin = new Point(0, 0);
console.print($"origin={origin}");
Point moveRight = origin.with(x=5);
console.print($"moveRight(x=5)={moveRight}");
Point moveUp = moveRight.with(y=3);
console.print($"moveUp(y=3)={moveUp}");
}
}
- Output:
origin=(x=0, y=0) moveRight(x=5)=(x=5, y=0) moveUp(y=3)=(x=5, y=3)
Elixir
The easiest and visually most appealing way to have named parameters is using a proplist as last parameter of the function.
def fun(bar: bar, baz: baz), do: IO.puts "#{bar}, #{baz}."
fun(bar: "bar", baz: "baz")
For this way to use them, order matters, as well as you can't define default values for arguments.
Erlang
At a guess "named parameters" are supposed to be used like proplists in Erlang.
Fun = fun( Proplists ) ->
Argument1 = proplists:get_value( argument1, Proplists, 1 ),
Kalle = proplists:get_value( kalle, Proplists, "hobbe" ),
io:fwrite( "~p ~s~n", [Argument1, Kalle] )
end.
The function can now be called like these examples.
25> Fun( [] ). 1 hobbe 26> Fun( [{argument1, 99}] ). 99 hobbe 27> Fun( [{kalle, "gustav"}, {argument1, 9}] ). 9 gustav
F#
F# supports named method arguments directly. However they are not supported for functions, function values, or lambda functions.
This example comes from the F# documentation:
type SpeedingTicket() =
member this.GetMPHOver(speed: int, limit: int) = speed - limit
let CalculateFine (ticket : SpeedingTicket) =
let delta = ticket.GetMPHOver(limit = 55, speed = 70)
if delta < 20 then 50.0 else 100.0
let ticket1 : SpeedingTicket = SpeedingTicket()
printfn "%f" (CalculateFine ticket1)
Factor
Named parameters in Factor are as simple as changing the :
word to ::
and using the variables defined in the stack effect declaration.
:: my-named-params ( a b -- c ) a b * ;
Forth
As with many of the other languages here, Forth does not have named parameters, but it does have practices that arise in situations where a Forth programmer might want named parameters. In Forth's case, these practices also arise when a more natural control language is wanted (e.g., LEFT ARM 36 DEGREES LIFT) or when a word would otherwise take excessively many arguments.
Two regrettably unnatural examples:
256 buffer: first-name
256 buffer: last-name
: is ( a "name" -- ) parse-name rot place ;
: greet ( -- )
cr ." Hello, " first-name count type space last-name count type ." !" ;
first-name is Bob last-name is Hall greet
require mini-oof2.fs
require string.fs
object class
field: given-name
field: surname
end-class Person
: hiya ( -- )
cr ." Hiya, " given-name $. space surname $. ." !" ;
Person new >o s" Bob" given-name $! s" Hall" surname $! hiya o>
- Output:
Hello, Bob Hall! Hiya, Bob Hall!
Fortran
Fortran accepts named parameter and optional parameter. Arguments are always named: if the name is omitted, the order used in the definition of the function / subroutine must be used.
subroutine a_sub(arg1, arg2, arg3)
integer, intent(in) :: arg1, arg2
integer, intent(out), optional :: arg3
! ...
end subroutine a_sub
! usage
integer :: r
call a_sub(1,2, r)
call a_sub(arg2=2, arg1=1)
The presence of an optional argument can be tested with PRESENT; if optional arguments come before a non optional argument, the usage of the name of the argument is mandatory.
subroutine b_sub(arg1, arg2)
integer, intent(in), optional :: arg1
integer, intent(in) :: arg2
!...
end subroutine b_sub
call b_sub(1) ! error: missing non optional arg2
call b_sub(arg2=1) ! ok
call b_sub(1, 2) ! ok: arg1 is 1, arg2 is 2
call b_sub(arg2=2, arg1=1) ! the same as the previous line
FreeBASIC
Dim Shared foo As Long, bar As Integer, baz As Byte, qux As String
'la función
Sub LoqueSea(foo As Long, bar As Integer, baz As Byte, qux As String)
'...
End Sub
'llamando a la función
Sub Algo()
LoqueSea(bar = 1, baz = 2, foo = -1, qux = "Probando")
End Sub
Go
Although Go doesn't support named parameters as such, they can be simulated using a struct with fields corresponding in name and type to the desired parameters.
A struct literal can then be passed to the function labelling the individual fields with their names. The fields need not appear in the same order as they are declared and, if one or more are omitted, they are given their 'zero' values.
Here's a simple example.
package main
import (
"fmt"
)
type params struct {x, y, z int}
func myFunc(p params) int {
return p.x + p.y + p.z
}
func main() {
r := myFunc(params{x: 1, y: 2, z: 3}) // all fields, same order
fmt.Println("r =", r)
s := myFunc(params{z: 3, y: 2, x: 1}) // all fields, different order
fmt.Println("s =", s)
t := myFunc(params{y: 2}) // only one field, others set to zero
fmt.Println("t =", t)
}
- Output:
r = 6 s = 6 t = 2
Haskell
We can simulate named, but not moveable arguments, with nullary data constructors:
data X = X
data Y = Y
data Point = Point Int Int deriving Show
createPointAt :: X -> Int -> Y -> Int -> Point
createPointAt X x Y y = Point x y
main = print $ createPointAt X 5 Y 3
We can also emulate named, moveable, optional arguments with record syntax:
data Point = Point {x, y :: Int} deriving Show
defaultPoint = Point {x = 0, y = 0}
createPointAt :: Point -> Point
createPointAt = id
main = print $ createPointAt (defaultPoint { y = 3, x = 5 })
Though this is cumbersome without using template Haskell, as the call site must supply the defaults.
Icon and Unicon
Icon and Unicon do not support named parameters. There are a couple of approaches that could be adapted to provide this kind of functionality. The basic considerations are:
- writing a string like "parm1=value" would be limiting as the value would have to be parsed and this form would be challenged to represent all data types
- using two parameters like this (...,"parm1:=",x,"parm2:=",y,...) removes this limitation
The test procedure below includes a list of valid parameter names to check against
Output:
Calling testproc x:=1 y:=2 z:=3 Calling testproc x:=3 y:=1 z:=2 Calling testproc x:=2 y:=3 z:=4 Calling testproc No parameter i:=
J
J is similar to Perl in that all arguments to functions come in as separate elements in an array. But it is possible to emulate more complex calling conventions. For example, using the calling convention J script, one could write:
NB. Strand notation
myFunc['c:\file.txt' 906 'blue' fs]
NB. Commas, like other langs
myFunc['c:\file.txt', 906, 'blue' fs]
NB. Unspecified args are defaulted ("optional")
myFunc['c:\file.txt' fs]
NB. Can use named arguments, like eg VB
myFunc[color='blue' fs]
NB. Often values needn't be quoted
myFunc[color= blue fs]
NB. Combination of comma syntax and name=value
myFunc[max=906, color=blue fs]
NB. Spelling of names is flexible
myFunc[MAX=906, COLOR=blue fs]
NB. Order of names is flexible
myFunc[COLOR=blue, MAX=906 fs]
NB. Even the delimiters are flexible...
myFunc<MAX=906, COLOR=blue fs>
For further discussion, see the corresponding thread in the J Forums.
Java
Like C++, Java also does not support named parameters. Named parameters can however be simulated simply with the "Builder pattern". (Joshua Bloch: Builder Pattern)
processNutritionFacts(new NutritionFacts.Builder(240, 8).calories(100).sodium(35).carbohydrate(27).build());
Follow the link for extra details about the 'NutritionFacts' class example.
JavaScript
JavaScript only has positional parameters, but named parameters can be emulated by passing an object with the appropriate properties:
function example(options) {
// assign some defaults where the user's has not provided a value
opts = {}
opts.foo = options.foo || 0;
opts.bar = options.bar || 1;
opts.grill = options.grill || 'pork chops'
alert("foo is " + opts.foo + ", bar is " + opts.bar + ", and grill is " + opts.grill);
}
example({grill: "lamb kebab", bar: 3.14});
// => "foo is 0, bar is 3.14, and grill is lamb kebab"
ECMAScript 2015 (ES6) variants
With this version, ECMAScript adds destrucuring assignments and destructuring in function parameters. Thus you could do something like this (this works in ES6 Fiddle, but is syntax error in Mozilla SpiderMonkey JS Shell, so uses console.log instead of print):
let
example = // The member name in the object can either be the same as the parameter (as in bar, grill),
// or a different parameter name as in the case of member foo being assigned to parameter a here.
({foo: a=0, bar=1, grill='pork chops'}={}) => (
console.log('foo is ',a,', bar is ',bar,', and grill is '+grill));
example();
// foo is 0 , bar is 1 , and grill is pork chops
example({grill: "lamb kebab", bar: 3.14});
// foo is 0 , bar is 3.14 , and grill is lamb kebab
example({foo:null});
// foo is , bar is 1 , and grill is pork chops
jq
jq does not strictly speaking support named function arguments, but since jq is JSON-oriented, it is possible to achieve the desired effect by using JSON objects.
For example, here is the jq analog of "print-name" defined in the Common Lisp section above. Here we format the full name and return it as a string:
def formatName(obj):
({ "name": "?"} + obj) as $obj # the default default value is null
| ($obj|.name) as $name
| ($obj|.first) as $first
| if ($first == null) then $name
else $name + ", " + $first
end;
Here are examples of how the function can be invoked:
formatName({"first": "George", "name": "Eliot"})
formatName({"name": "Eliot", "first": "George"})
formatName({"name": "Eliot"})
formatName({"first": "George"})
formatName({})
Julia
Julia supports arbitrary named keyword arguments, which are listed (with their default values) after a ;
in the function definition:
function surround(string ; border = :default, padding = 0)
ve, ho, ul, ur, dl, dr =
border == :round ? ("\u2502","\u2500","\u256d","\u256e","\u2570","\u256f") :
border == :bold ? ("\u2503","\u2501","\u250F","\u2513","\u2517","\u251b") :
border == :double ? ("\u2551","\u2550","\u2554","\u2557","\u255a","\u255d") :
border == :dotted ? ("\u254e","\u254c","\u250c","\u2510","\u2514","\u2518") :
border == :cross ? ("\u2502","\u2500","\u253c","\u253c","\u253c","\u253c") :
("\u2502","\u2500","\u250c","\u2510","\u2514","\u2518")
println(ul, ho^(length(string) + 2padding), ur, "\n",
ve, " "^padding, string," "^padding, ve, "\n",
dl, ho^(length(string) + 2padding), dr)
end
- Output:
julia> surround("♡", border = :round) ╭─╮ │♡│ ╰─╯ julia> surround("Julia", padding = 1, border = :double) ╔═══════╗ ║ Julia ║ ╚═══════╝
Kotlin
// version 1.0.6
fun someFunction(first: String, second: Int = 2, third: Double) {
println("First = ${first.padEnd(10)}, Second = $second, Third = $third")
}
fun main(args: Array<String>) {
// using positional parameters
someFunction("positional", 1, 2.0)
// using named parameters
someFunction(first = "named", second = 1, third = 2.0)
// omitting 2nd parameter which is optional because it has a default value
someFunction(first = "omitted", third = 2.0)
// using first and third parameters in reverse
someFunction(third = 2.0, first = "reversed")
}
- Output:
First = positional, Second = 1, Third = 2.0 First = named , Second = 1, Third = 2.0 First = omitted , Second = 2, Third = 2.0 First = reversed , Second = 2, Third = 2.0
LabVIEW
Function calls in LabVIEW are implemented as instantiated VIs, small icons representing the function to be called. All parameters are positional, by drawing wires to different points along the icon edge. By right-clicking on the VI icon and unchecking "View as Icon", the parameter names can be shown. The parameter names are mainly informational for the user.
This image shows a VI with "View as Icon" unchecked.
This image is a VI Snippet, an executable image of LabVIEW code. The LabVIEW version is shown on the top-right hand corner. You can download it, then drag-and-drop it onto the LabVIEW block diagram from a file browser, and it will appear as runnable, editable code.
Lasso
define mymethod(
-first::integer, // with no default value the param is required
-second::integer,
-delimiter::string = ':' // when given a default value the param becomes optional
) => #first + #delimiter + #second
mymethod(
-first = 54,
-second = 45
)
'<br />'
mymethod(
-second = 45, // named params can be given in any order
-first = 54,
-delimiter = '#'
)
-> 54:45
54#45
Lingo
Lingo does not support named function parameters. But this can be simulated by using a single property list (hash) with named properties as function argument. You can also create functions that support both calling methods, like e.g. this function that accepts either 3 integers or a single property list with such named properties:
-- accepts either 3 integers or a single property list
on foo (arg1, arg2, arg3)
if ilk(arg1)=#propList then
args = arg1
arg1 = args[#arg1]
arg2 = args[#arg2]
arg3 = args[#arg3]
end if
put "arg1="&arg1
put "arg2="&arg2
put "arg3="&arg3
end
foo(1,2) -- 3rd argument omitted
-- "arg1=1"
-- "arg2=2"
-- "arg3="
foo([#arg3:3]) -- only 3rd argument specified
-- "arg1="
-- "arg2="
-- "arg3=3"
Lua
function CreatePet(options)
local name=options.name
local species=options.species
local breed=options.breed
print('Created a '..breed..' '..species..' named '..name)
end
CreatePet{name='Rex',species='Dog',breed='Irish Setter'}
--position does not matter here.
M2000 Interpreter
We can use named parameters for modules only. Modules are like functions but can't be called from expressions. We can use current stack to return values using Push statement. Here we define type and we set values to make them optionals. Passing optionals in modules may cause problems if we have values in stack, so we can use Stack New {] to open an empty current stack (the old one is hidden until exit from that block), or using ? as "use standard value".
module namedparam (x as decimal=10, y as integer=50) {
Print type$(x), x
Print type$(y), y
}
namedparam 10, 20
namedparam ?, ?
Push 1, 2 : namedparam
Stack New {
\\ it is empty
namedparam
namedparam %y=500
namedparam %x=20
}
namedparam %x=1, %y=1
Maple
f := proc(a, {b:= 1, c:= 1})
print (a*(c+b));
end proc:
#a is a mandatory positional parameter, b and c are optional named parameters
f(1);#you must have a value for a for the procedure to work
2
f(1, c = 1, b = 2);
3
f(2, b = 5, c = 3);#b and c can be put in any order
16
Mathematica /Wolfram Language
Options[fn]={Add->False,Offset-> 0};
fn[x_,y_,OptionsPattern[]]:=If[OptionValue[Add]==True,x+y+OptionValue[Offset],{x,y,OptionValue[Offset]}]
fn[3,4,{Add->True,Offset->2}]
fn[3,4,{Offset->2,Add->True}]
- Output:
9 9
MATLAB / Octave
Named parameters are not natively supported. However, the following code can be used to implement them.
function foo(varargin)
for k= 1:2:length(varargin);
switch (varargin{k})
case {'param1'}
param1 = varargin{k+1};
case {'param2'}
param2 = varargin{k+1};
end;
end;
printf('param1: %s\n',param1);
printf('param2: %s\n',param2);
end;
foo('param1','a1','param2','b2');
foo('param2','b2','param1','a1');
Output:
>> foo('param1','a1','param2','b2'); param1: a1 param2: b2 >> foo('param2','b2','param1','a1'); param1: a1 param2: b2
Modula-3
Much like Ada, Modula-3 allows either positional or keyed association of actual parameters. Defaults can also be ignored.
PROCEDURE Foo(Arg1: INTEGER; Arg2: REAL := 0.0);
It can be equivalently called as:
Foo(1, 0.0);
Foo(1);
Foo(Arg2 := 0.0, Arg1 := 1);
Foo(Arg1 := 1);
Nemerle
Foo(number : int, word = "Default", option = true) : void // note type inference with default values
Foo(word = "Bird", number = 3) // an argument with a default value can be omitted from function call
Foo(3, option = false, word = "Bird") // unnamed arguments must be in same order as function definition and precede named arguments
Nim
In Nim, a regular parameter of a procedure can be used as either a positional or a named parameter.
proc subtract(x, y): auto = x - y
echo subtract(5, 3) # used as positional parameters
echo subtract(y = 3, x = 5) # used as named parameters
Parameters can be made optional by providing a default argument.
Objective-C
Objective-C, like Smalltalk, has a method call syntax that is visually identical to named arguments, but they are not optional and may not be reordered. (Optional arguments may be simulated by defining multiple methods with the same leading name part.)
@interface Demo : NSObject {
// Omitted ...
}
- (double) hypotenuseOfX: (double)x andY: (double)y;
- (double) hypotenuseOfX: (double)x andY: (double)y andZ: (double)z;
@end
@implementation Demo
- (double) hypotenuseOfX: (double)x andY: (double)y {
return hypot(x,y);
}
- (double) hypotenuseOfX: (double)x andY: (double)y andZ: (double)z {
return hypot(hypot(x, y), z);
}
@end
Demo *example = [[Demo alloc] init];
double h = [example hypotenuseOfX:1.23 andY:3.79];
Note in the example above that the name of the method, the selector; is actually “hypotenuseOfX:andY:
”.
OCaml
You can make a named argument (called labels in OCaml) by putting a tilde (~) before the name:
# let foo ~arg1 ~arg2 = arg1 + arg2;;
val foo : arg1:int -> arg2:int -> int = <fun>
# let foo ~arg1:x ~arg2:y = x + y;; (* you can also use different variable names internally if you want *)
val foo : arg1:int -> arg2:int -> int = <fun>
# foo ~arg2:17 ~arg1:42;;
- : int = 59
Named arguments can be re-ordered, but two arguments of the same label cannot be re-ordered relative to each other.
Named arguments can be curried. If you partially apply a function on a named argument (even if the named argument is not first in the function declaration), it will evaluate to a function of the remaining arguments.
Named arguments can be made optional, with the ?(arg = value)
syntax in the parameter declaration. See the optional parameters task for more details.
Oz
For methods, Oz does support named parameters with default values. The named parameters can be freely reordered.
declare
class Foo
meth init skip end
meth bar(PP %% positional parameter
named1:N1
named2:N2
namedWithDefault:NWD <= 42)
{System.showInfo "PP: "#PP#", N1: "#N1#", N2: "#N2#", NWD: "#NWD}
end
end
O = {New Foo init}
{O bar(1 named1:2 named2:3 namedWithDefault:4)} %% ok
{O bar(1 named2:2 named1:3)} %% ok
{O bar(1 named1:2)} %% not ok, "missing message feature in object application"
For procedures only positional parameters are supported. However, you can emulate named parameters by using records:
declare
proc {Foo PP Other=unit(named1:N1 named2:N2 ...)}
NWD = {CondSelect Other namedWithDefault 42}
in
{System.showInfo "PP: "#PP#", N1: "#N1#", N2: "#N2#", NWD: "#NWD}
end
{Foo 1 unit(named1:2 named2:3 namedWithDefault:4)}
{Foo 1 unit(named2:2 named1:3)}
{Foo 1 unit(named1:2)} %% not ok...
The procedure Foo is defined with pattern matching in the argument list. The ellipsis means that additional record fields are allowed. To access optional record fields, we have to explicitly try to select a field and provide a default value in case it is missing ("CondSelect").
Perl
Perl has no non-experimental formal parameters. Instead, Perl subroutines access all of their arguments through the special array @_
. You can easily implement named arguments by making your function interpret @_
(or part of it) as a hash.
sub funkshun {
my %h = @_;
# Print every argument and its value.
print qq(Argument "$_" has value "$h{$_}".\n)
foreach sort keys %h;
# If a 'verbosity' argument was passed in, print its value
# whatever that value may be.
print "Verbosity specified as $h{verbosity}.\n" if exists $h{verbosity};
# Say that safe mode is on if 'safe' is set to a true value.
# Otherwise, say that it's off.
print "Safe mode ", ($h{safe} ? 'on' : 'off'), ".\n";
}
The semantics of calling such a function follow directly from the semantics of using a hash. For instance, if you provide multiple values for the same named argument, only the last one will be used. An example call:
funkshun(
verbosity => 3,
password => 'foobie blech',
extra_lives => 3,
'42' => 'answer',
password => 'joshua'
);
Its output:
Argument "42" has value "answer". Argument "extra_lives" has value "3". Argument "password" has value "joshua". Argument "verbosity" has value "3". Verbosity specified as 3. Safe mode off.
Further flexibility can be obtained by using Pass by reference semantics:
sub event
{
my ($params_ref, $name) = @_;
my %params = %$params_ref;
my @known_params = qw(attendees event food time);
printf "%s called event() with the following named parameters:\n",
$name // 'Anonymous';
say sort map {
sprintf "%s: %s\n",
ucfirst $_,
ref $params{$_} eq ref []
? join ', ', @{ $params{$_} }
: $params{$_};
} grep exists $params{$_}, @known_params;
delete $params{$_} foreach @known_params;
say "But I didn't recognize these ones:";
while (my ($key, $val) = each %params)
{
say "$key: $val";
}
}
event(
{ # Curly braces with no label (e.g. 'sub' before it)
# create a reference to an anonymous hash
attendees => ['Bob', 'Betty', 'George', 'Bertha'],
event => 'birthday',
foo => 'bar',
food => 'cake',
frogblast => 'vent core',
time => 3,
},
"Joe Schmoe"
);
Prints:
Joe Schmoe called event() with the following named parameters: Attendees: Bob, Betty, George, Bertha Event: birthday Food: cake Time: 3 But I didn't recognize these ones: frogblast: vent core foo: bar
This is useful when you want your function to take both named (the hash) and positional (Joe Schmoe's $name) parameters.
Phix
Phix supports named and optional parameters in a simple, natural, and intuitive way, erring on the side of caution when faced with potential ambiguity.
Optional parameters are simply any with a default, and any non-defaulted parameters must occur before (to the left of) such.
Named parameters can be provided in any order, but must be grouped together after (to the right of) any positional parameters.
Note that low-level builtins (those defined using AutoAsm() in psym.e/syminit()) do not [yet] support named parameters, but everything else does.
The classic example (inspired by the standard Python equivalent) is that builtins\timedate.e defines:
global function timedelta(atom weeks=0, days=0, hours=0, minutes=0, seconds=0, milliseconds=0, microseconds=0)
which can be invoked as follows:
with javascript_semantics include timedate.e constant days = 1, hours = 7, fourdays = timedelta(days:=4), -- fourdays = timedelta(0,4) -- equivalent, **NB** a plain '=' is a very different thing: slipup = timedelta(days=4) -- === timedelta([weeks:=]iff(equal(days,4)?true:false)) -- with error if no local/in scope identifier days exists. shift = timedelta(hours:=hours) -- perfectly valid (param hours:=local hours) -- timedelta(0,hours:=15,3) -- illegal (not clear whether days:=3 or minutes:=3) -- though of course the weeks:=0 part is fine printf(1,"fourdays = %s\n",{elapsed(fourdays)}) printf(1,"wrong = %s\n",{elapsed(slipup)}) printf(1,"shift = %s\n",{elapsed(shift)})
Note that pwa/p2js automatically maps named parameters to positional parameters for you, since JavaScript does not support named parameters.
- Output:
fourdays = 4 days wrong = 0s shift = 7 hours
PHP
PHP doesn't support named parameters but you can simulate the behavior with PHP arrays.
function named($args) {
$args += ["gbv" => 2,
"motor" => "away",
"teenage" => "fbi"];
echo $args["gbv"] . " men running " . $args['motor'] . " from the " . $args['teenage'];
}
named(["teenage" => "cia", "gbv" => 10]);
Output:
10 men running away from the cia
PicoLisp
PicoLisp uses normally positional parameters, but 'bind' can be used to establish bindings to passed names.
Passing symbol-value pairs
(de foo @
(bind (rest) # Bind symbols in CARs to values in CDRs
(println 'Bar 'is Bar)
(println 'Mumble 'is Mumble) ) )
(foo '(Bar . 123) '(Mumble . "def"))
Passing a name list followed by values
(de foo @
(bind (next) # Save all symbols in first argument
(mapc set (arg) (rest)) # then bind them to remaining arguments
(println 'Bar 'is Bar)
(println 'Mumble 'is Mumble) ) )
(foo '(Bar Mumble) 123 "def")
Output in both cases:
Bar is 123 Mumble is "def"
PowerShell
Positional parameters
When writing a function and not stating any parameters explicitly, such as the following function
function Test {
Write-Host Argument 1 is $args[0]
}
the only option are positional parameters using the $args
array.
Named parameters
Stating any number of parameters directly in the function definition, such as
function Test ($SomeArgument, $AnotherArgument, $ThirdArgument) {
Write-Host "Some argument: $SomeArgument"
Write-Host "Another argument: $AnotherArgument"
Write-Host "Third argument: $ThirdArgument"
}
will cause them to be named automatically which enables the caller to state the arguments in any order. The syntax follows the convention used with cmdlets as well:
PS> Test -ThirdArgument foo -AnotherArgument bar -SomeArgument baz Some argument: baz Another argument: bar Third argument: foo
However, one can still just give the arguments in order without explicitly having to state the names of the parameters.
Arbitrary arguments can be omitted as well:
PS> Test -ThirdArgument foo -AnotherArgument bar Some argument: Another argument: bar Third argument: foo
This will cause the omitted arguments to have the value $null
Switch parameters
Functions can have so-called switch parameters which are always boolean and either present or not. There is no need to give a value for them.
function SwitchTest ([switch] $on) {
Write-Host Switched $(if ($on) { "on" } else { "off" })
}
When calling a function with such a parameter the switch is simply given directly (which sets its value to true) or omitted (which causes it to evaluate to false):
PS> SwitchTest Switched off PS> SwitchTest -on Switched on
Optional parameters and default values
Usually all parameters can be omitted. In the case of switch parameters this will cause them to assume the value false, for normal parameters they will have the value $null
. This is not always the desired value, though. Default values can be given too:
function Greeting ($Name = "Nobody") {
Write-Host Hello, $Name!
}
If the Name
argument is omitted now, its value will be "Nobody"
instead of $null
:
PS> Greeting Hello Nobody! PS> Greeting John Hello John!
Prolog
:- initialization(main).
main :-
sum(b=2,output=Output,a=1),
writeln(Output).
sum(A1,B1,C1) :-
named_args([A1,B1,C1],[a=A,b=B,output=Output]),
Output is A + B.
named_args([],_).
named_args([A|B],C) :-
member(A,C),
named_args(B,C).
Python
Basic explanation
A more detailed explanation of parameters, arguments, and how they are used is in the sections below. This is a simplified explanation:
In Python, a regular parameter of a function can be used as either a positional or a named parameter. The variable name that you use for the parameter when you declare the function becomes the "name" for the parameter, should you use it as a named parameter. When you call a function, you use the "name = value" syntax to provide the argument to a named parameter. The named arguments must come after all the positional arguments.
def subtract(x, y):
return x - y
subtract(5, 3) # used as positional parameters; evaluates to 2
subtract(y = 3, x = 5) # used as named parameters; evaluates to 2
Parameters can be made optional by providing a default argument, as described in the optional parameters article.
Detailed Explanation
Function Definition Parameters
Function definitions in Python allow for the following parameter types:
- Optional default parameter types which are explicitly specified by name, and may have an optional default value.
- An optional positional parameter which is an identifier preceded by
"*"
. - And an optional keyword parameter which is an identifier preceded by
"**"
.
If any of the parameter types are given then they must appear in the order specified above.
The syntax of function parameter declarations is more formally defined as:
funcdef ::= "def" funcname "(" [parameter_list] ")" ":" suite dotted_name ::= identifier ("." identifier)* parameter_list ::= (defparameter ",")* ( posparameter [, keyparameter] | keyparameter | defparameter [","] ) defparameter ::= parameter ["=" expression] posparameter ::= "*" identifier keyparameter ::= "**" identifier sublist ::= parameter ("," parameter)* [","] parameter ::= identifier | "(" sublist ")"
Function Call Arguments
The call of a function in python can use the following argument types:
- Positional arguments that are mapped by their position in the call argument list to the
defparameter
name in the corresponding position of the function definition. - Sequence arguments that are the character
"*"
followed by an expression evaluating to a sequence (such as a list or tuple). The values from the sequence are unpacked and mapped like individual positional arguments todefparameter
s of the function definition. Sequence arguments are “evaluated before any keyword argument, irrespecctive of their relative positions in an argument list”. - All positional arguments must appear before any keyword argument.
- Keyword arguments of the form
parameter_name "=" value
will map the value to thedefparameter
in the definition of the same name. - Mapping arguments that are the characters
"**"
followed by an expression evaluating to a mapping (such as a dict/hash). The key, value pairs from the mapping are unpacked and mapped like individual keyword arguments todefparameter
s of the function definition. - If the function definition includes a positional parameter, then if the assignment of positional arguments and sequence arguments in the call gives more values than the
defparameters
of the definition, then these extra arguments are assembled, in order, into a tuple that is assigned to theposparameter
of the definition. - If the function definition includes a keyword parameter, then if the parameter name of any keyword arguments and mapping arguments in the call is unknown in the
defparameters
of the function definition, then these extra keyword/value pairs are assembled into a dict that is assigned to thekeyparameter
of the definition. - Any default parameter of the function definition that is not assigned a value at this point, but which has a default value, will be aassigned this default value, without re-evaluating the default value.
- Any default parameter of the function definition that is still un-assigned will cause a
TypeError
exception to be raised. - In addition, multiple mappings to any parameter will raise a
TypeError
exception. (This includes multiple mappings into akeyparameter
or keyword arguments clashing with positional/sequence arguments).
The more formal definition of a function call's syntax is
call ::= primary "(" [argument_list [","] | expression genexpr_for] ")" argument_list ::= positional_arguments ["," keyword_arguments] ["," sequence_argument] ["," keyword_arguments] ["," mapping_argument] | keyword_arguments ["," sequence_argument] ["," mapping_argument] | sequence_argument ["," sequence_argument] ["," mapping_argument] | mapping_argument positional_arguments ::= expression ("," expression)* keyword_arguments ::= keyword_item ("," keyword_item)* sequence_argument ::= "*" expression mapping_argument ::= "**" expression keyword_item ::= identifier "=" expression
Examples
>>> from __future__ import print_function
>>>
>>> def show_args(defparam1, defparam2 = 'default value', *posparam, **keyparam):
"Straight-forward function to show its arguments"
print (" Default Parameters:")
print (" defparam1 value is:", defparam1)
print (" defparam2 value is:", defparam2)
print (" Positional Arguments:")
if posparam:
n = 0
for p in posparam:
print (" positional argument:", n, "is:", p)
n += 1
else:
print (" <None>")
print (" Keyword Arguments (by sorted key name):")
if keyparam:
for k,v in sorted(keyparam.items()):
print (" keyword argument:", k, "is:", v)
else:
print (" <None>")
>>> show_args('POSITIONAL', 'ARGUMENTS')
Default Parameters:
defparam1 value is: POSITIONAL
defparam2 value is: ARGUMENTS
Positional Arguments:
<None>
Keyword Arguments (by sorted key name):
<None>
>>> show_args(defparam2='ARGUMENT', defparam1='KEYWORD')
Default Parameters:
defparam1 value is: KEYWORD
defparam2 value is: ARGUMENT
Positional Arguments:
<None>
Keyword Arguments (by sorted key name):
<None>
>>> show_args( *('SEQUENCE', 'ARGUMENTS') )
Default Parameters:
defparam1 value is: SEQUENCE
defparam2 value is: ARGUMENTS
Positional Arguments:
<None>
Keyword Arguments (by sorted key name):
<None>
>>> show_args( **{'defparam2':'ARGUMENTS', 'defparam1':'MAPPING'} )
Default Parameters:
defparam1 value is: MAPPING
defparam2 value is: ARGUMENTS
Positional Arguments:
<None>
Keyword Arguments (by sorted key name):
<None>
>>> show_args('ONLY DEFINE defparam1 ARGUMENT')
Default Parameters:
defparam1 value is: ONLY DEFINE defparam1 ARGUMENT
defparam2 value is: default value
Positional Arguments:
<None>
Keyword Arguments (by sorted key name):
<None>
>>> show_args('POSITIONAL', 'ARGUMENTS',
'EXTRA', 'POSITIONAL', 'ARGUMENTS')
Default Parameters:
defparam1 value is: POSITIONAL
defparam2 value is: ARGUMENTS
Positional Arguments:
positional argument: 0 is: EXTRA
positional argument: 1 is: POSITIONAL
positional argument: 2 is: ARGUMENTS
Keyword Arguments (by sorted key name):
<None>
>>> show_args('POSITIONAL', 'ARGUMENTS',
kwa1='EXTRA', kwa2='KEYWORD', kwa3='ARGUMENTS')
Default Parameters:
defparam1 value is: POSITIONAL
defparam2 value is: ARGUMENTS
Positional Arguments:
<None>
Keyword Arguments (by sorted key name):
keyword argument: kwa1 is: EXTRA
keyword argument: kwa2 is: KEYWORD
keyword argument: kwa3 is: ARGUMENTS
>>> show_args('POSITIONAL',
'ARGUMENTS', 'EXTRA', 'POSITIONAL', 'ARGUMENTS',
kwa1='EXTRA', kwa2='KEYWORD', kwa3='ARGUMENTS')
Default Parameters:
defparam1 value is: POSITIONAL
defparam2 value is: ARGUMENTS
Positional Arguments:
positional argument: 0 is: EXTRA
positional argument: 1 is: POSITIONAL
positional argument: 2 is: ARGUMENTS
Keyword Arguments (by sorted key name):
keyword argument: kwa1 is: EXTRA
keyword argument: kwa2 is: KEYWORD
keyword argument: kwa3 is: ARGUMENTS
>>> # But note:
>>> show_args('POSITIONAL', 'ARGUMENTS',
kwa1='EXTRA', kwa2='KEYWORD', kwa3='ARGUMENTS',
'EXTRA', 'POSITIONAL', 'ARGUMENTS')
SyntaxError: non-keyword arg after keyword arg
>>>
R
R parameters are all named; arguments can be passed either positionally or with explicit naming. The named arguments are matched to their parameters first, then the unnamed arguments fill in remaining slots. A parameter whose name begins with a period will not be matched to unnamed arguments. R allows abbreviated names to be used as long as they match uniquely to an argument.
divide <- function(numerator, denominator) {
numerator / denominator
}
divide(3, 2) # 1.5
divide(numerator=3, denominator=2) # 1.5
divide(n=3, d=2) # 1.5
divide(den=3, num=2) # 0.66
divide(den=3, 2) # 0.66
divide(3, num=2) # 0.66
Racket
Racket has built-in keyword and optional arguments:
#lang racket
(define (pizza sauce
;; mandatory keyword argument
#:topping topping
;; optional keyword argument with default
#:type [type "deep dish"])
(printf "~a pizza with ~a sauce topped with ~a~n"
type sauce topping))
(pizza "tomato" #:topping "onion")
(pizza #:topping "onion" "garlic" #:type "pan")
Raku
(formerly Perl 6)
Raku's support for optional parameters is much like Python's. Consider this declaration:
sub funkshun ($a, $b?, $c = 15, :$d, *@e, *%f) {
...
}
In the above signature:
$a
is a mandatory parameter accepted by position (funkshun 15, ...
).$b
is an optional parameter that can be passed by position or by name. By default, it's undefined.$c
is an optional parameter that can be passed by position or by name. Its default value is15
.$d
is an optional parameter that can only be passed by name. By default, it's undefined.@e
is a slurpy array: it receives any leftover positional arguments.%f
is a slurpy hash: it receives any leftover named arguments.
So, if we defined the function like this:
sub funkshun ($a, $b?, :$c = 15, :$d, *@e, *%f) {
say "$a $b $c $d";
say join ' ', @e;
say join ' ', keys %f;
}
# this particularly thorny call:
funkshun
'Alfa', k1 => 'v1', c => 'Charlie', 'Bravo', 'e1',
d => 'Delta', 'e2', k2 => 'v2';
would print this:
Alfa Bravo Charlie Delta e1 e2 k1 k2
REXX
version 1
/*REXX pgm shows named parameters when called as a subroutine/function*/
/*┌────────────────────────────────────────────────────────────────────┐
│ The syntax of: xxx = func1(parmName2=arg2, parmName1=arg1) │
│ │
│ in the REXX language is interpreted specifically as: │
│ │
│ xxx = func1( yyy , zzz ) │
│ │
│ where yyy is the logical result of comparing (the REXX variables)│
│ │
│ parmName2 with arg2 and │
│ │
│ where zzz is the logical result of comparing (the REXX variables)│
│ │
│ parmName1 with arg1 │
│ │
│ (either as two strings, or arithmetically if both "parmName2" and │
│ "arg2" are both valid REXX numbers. In the REXX language, there │
│ is no way to declare (define) what a variable is [or its type], as │
│ each literal that can be a variable is assumed to be one. If it's │
│ not defined, then its uppercase name is used for the value. │
│ │
│ Consider the one-line REXX program: say Where are you? │
│ causes REXX to consider that four-word expression as a "SAY" │
│ statement, followed by three REXX variables, each of which aren't │
│ defined (that is, have a value), so REXX uses a value which is the │
│ uppercased value of the REXX variable name, namely three values in │
│ this case, so the following is displayed: WHERE ARE YOU? │
│ │
│ [There is a mechanism in REXX to catch this behavior and raise the │
│ NOVALUE condition.] │
│ │
│ To allow a solution to be used for this task's requirement, and │
│ and not get tangled up with the legal REXX syntactical expressions │
│ shown, this REXX programming example uses a variation of the │
│ task's illustration to allow a method in REXX of using named │
│ parameters: xxx = func1('parmName2=' arg2, "parmName1=" arg1) │
│ │
│ Also, REXX allows the omitting of arguments by just specifying a │
│ comma (or nothing at all, in the case of a single argument): │
│ │
│ xxx = func1(,zzz) │
│ │
│ would indicate that the 1st argument has been omitted. │
│ │
│ xxx = func1(yyy) │
│ │
│ would indicate that the 2nd argument (and all other subsequent │
│ arguments) has/have been omitted. │
└────────────────────────────────────────────────────────────────────┘*/
parse arg count,itemX /*assume 2 values have been used,*/
/*or whatever ... just to show...*/
do j=1 for arg(); _=arg(1) /*now, lets examine each argument*/
if arg(j,'Omitted') then iterate /*skip examining if argJ omitted.*/
/*(above) This is superfluous, */
/* but it demonstrates a method. */
if \arg(j,"Exists") then iterate /*exactly the same as previous. */
/*Only 1st char (2nd arg) is used*/
first=strip(word(_,1)) /*extract the 1st word in arg(j).*/
if right(first,1)\=='=' then iterate /*skip if 1st word isn't: xxx= */
parse var _ varname '= ' value /*parse the named variable &value*/
if varname=='' then iterate /*not the correct format, so skip*/
/*(above) fix this for real pgm. */
call value varname,value /*use BIF to set REXX variable. */
end /*j*/
/* ∙∙∙ perform some REXX magic here with specified parameters and stuff:*/
/* do this, do that, perform dis & dat, compute, gears whiz, cogs */
/* turn, wheels spin, belts move, things get assigned, stuff gets */
/* computed, wheels spin, belts move, things get assigned, motors*/
/* humm, engines roar, coal gets burned, water turns to steam, real */
/* work (some of it useful) gets done, and something is produced. */
return 'the final meaning of life, or 42 --- whichever is appropriate.'
/*stick a fork in it, we're done.*/
version 2
/* REXX ---------------------------------------------------------------
* 01.07.2014 Walter Pachl
* Argument values must not start with 'arg'
*--------------------------------------------------------------------*/
x=f(2,3)
Say x
Say ''
y=f('arg2='3,'arg1='2)
Say y
Exit
f: Procedure
Parse Arg p1,p2
Do i=1 to arg()
If left(arg(i),3)='arg' Then
Parse Value arg(i) With 'arg' j '=' p.j
Else p.i=arg(i)
End
Do i=1 To arg()
Say 'p.'i'='p.i
End
Return p.1**p.2
- Output:
p.1=2 p.2=3 8 p.1=2 p.2=3 8
Ruby
Ruby 2.0 adds keyword arguments to the language. All keyword arguments are optional, because they have default values. Ruby 2.0 rejects unknown keys; example(typo: 4)
raises ArgumentError. In Ruby 2.1 the mandatory default values were dropped.
def example(foo: 0, bar: 1, grill: "pork chops")
puts "foo is #{foo}, bar is #{bar}, and grill is #{grill}"
end
# Note that :foo is omitted and :grill precedes :bar
example(grill: "lamb kebab", bar: 3.14)
Ruby 1.9 can fake the effect with a Hash. If a caller passes name: value
pairs, Ruby makes a Hash, and the called method sees this Hash in its last argument. To complete the effect, the method may declare an optional last argument that defaults to an empty Hash {}
. In this version, example(typo: 4)
causes no error.
def example(opts = {})
# Hash#merge raises TypeError if _opts_ is not a Hash.
# Nothing checks if _opts_ contains unknown keys.
defaults = {foo: 0, bar: 1, grill: "pork chops"}
opts = defaults.merge(opts)
printf("foo is %s, bar is %s, and grill is %s\n",
opts[:foo], opts[:bar], opts[:grill])
end
example(grill: "lamb kebab", bar: 3.14)
Scala
Scala 2.8 utilizes named parameters and default values:
def add(x: Int, y: Int = 1) = x + y
scala> add(5)
6
scala> add(y=10, x=4)
14
Scheme
(define (keyarg-parser argdefs args kont)
(apply kont
(map (lambda (argdef)
(let loop ((args args))
(cond ((null? args)
(cadr argdef))
((eq? (car argdef) (car args))
(cadr args))
(else
(loop (cdr args))))))
argdefs)))
(define (print-name . args)
(keyarg-parser '((first #f)(last "?"))
args
(lambda (first last)
(display last)
(cond (first
(display ", ")
(display first)))
(newline))))
=> (print-name)
?
=> (print-name 'first "John")
?, John
=>(print-name 'first "John" 'last "Doe")
Doe, John
=>(print-name 'last "Doe")
Doe
SenseTalk
The introduce handler here includes a default value for greeting. Ordinarily, parameters are passed sequentially, but by name
can be used to match values from a property list to the corresponding parameters of the handler that is being called.
introduce "Mary"
introduce "Pablo", "Hola"
introduce greeting:"Bonjour", name:"Brigitte" by name
to introduce name, greeting:"Hello"
put greeting && name
end introduce
- Output:
Hello Mary Hola Pablo Bonjour Brigitte
Sidef
func example(foo: 0, bar: 1, grill: "pork chops") {
say "foo is #{foo}, bar is #{bar}, and grill is #{grill}";
}
# Note that :foo is omitted and :grill precedes :bar
example(grill: "lamb kebab", bar: 3.14);
- Output:
foo is 0, bar is 3.14, and grill is lamb kebab
Smalltalk
As for Objective-C the methods signature is made of "Symbol:[OtherSymbol:]*" (* stands for 0 or more repetition of the part in the brackets), without the possibility to reorder them (it would be another signature) or to make them optional.
Object subclass: AnotherClass [
"..."
initWithArray: anArray [ "single argument" ]
initWithArray: anArray andString: aString [
"two args; these two methods in usage resemble
a named argument, with optional andString argument"
]
"..."
]
Standard ML
This example uses Standard ML "fields".
fun dosomething (a, b, c) = print ("a = " ^ a ^ "\nb = " ^ Real.toString b ^ "\nc = " ^ Int.toString c ^ "\n")
fun example {a, b, c} = dosomething (a, b, c)
To call the procedure example, use:
example {a="Hello World!", b=3.14, c=42}
However, this does not support optional parameters. To emulate them, we can process a parameter list:
datatype param = A of string | B of real | C of int
fun args xs =
let
(* Default values *)
val a = ref "hello world"
val b = ref 3.14
val c = ref 42
in
map (fn (A x) => a := x | (B x) => b := x | (C x) => c := x) xs;
(!a, !b, !c)
end
To process the argument list and call example, use:
dosomething (args [A "tam", B 42.0]);
Suneido
Suneido can handle named and unnamed parameters. When using a combination, unnamed parameters must come before named ones and must be in the correct order. Named parameters can be in any order. Named parameters are given a default value so they are not mandatory.
test = function (one, two, three = '', four = '', five = '')
{
Print('one: ' $ one $ ', two: ' $ two $ ', three: ' $ three $
', four: ' $ four $ ', five: ' $ five)
}
test('1', '2', five: '5', three: '3')
Output:
one: 1, two: 2, three: 3, four: , five: 5
Swift
Each function parameter has both an argument label and a parameter name. The argument label is used when calling the function; each argument is written in the function call with its argument label before it. The parameter name is used in the implementation of the function. By default, parameters use their parameter name as their argument label.
func greet(person: String, hometown: String) -> String {
return "Hello \(person)! Glad you could visit from \(hometown)."
}
print(greet(person: "Bill", hometown: "Cupertino"))
You write an argument label before the parameter name, separated by a space:
func greet(person: String, from hometown: String) -> String {
return "Hello \(person)! Glad you could visit from \(hometown)."
}
print(greet(person: "Bill", from: "Cupertino"))
If you don’t want an argument label for a parameter, write an underscore (_) instead of an explicit argument label for that parameter. If a parameter has an argument label, the argument must be labeled when you call the function.
func greet(_ person: String, _ hometown: String) -> String {
return "Hello \(person)! Glad you could visit from \(hometown)."
}
print(greet("Bill", "Cupertino"))
You can define a default value for any parameter in a function by assigning a value to the parameter after that parameter’s type. If a default value is defined, you can omit that parameter when calling the function.
func greet(person: String, from hometown: String = "Cupertino") -> String {
return "Hello \(person)! Glad you could visit from \(hometown)."
}
print(greet(person: "Bill"))
Tcl
Using arrays
The simplest way of passing named parameters is to use the Tcl language's strong support for variadic commands together with its arrays. By convention (originally from Tk) the named parameters names start with a hyphen (“-”) and are called options.
proc example args {
# Set the defaults
array set opts {-foo 0 -bar 1 -grill "hamburger"}
# Merge in the values from the caller
array set opts $args
# Use the arguments
return "foo is $opts(-foo), bar is $opts(-bar), and grill is $opts(-grill)"
}
# Note that -foo is omitted and -grill precedes -bar
example -grill "lamb kebab" -bar 3.14
# => ‘foo is 0, bar is 3.14, and grill is lamb kebab’
More complex option parsing is possible, e.g., with the opt package (of which only a small fraction of the functionality is shown here). This package also allows you to specify type constraints, though that is usually not necessary, and will generate a standard help message that can be obtained with the -help option:
package require opt
tcl::OptProc example {
{-foo -int 0 "The number of foos"}
{-bar -float 1.0 "How much bar-ness"}
{-grill -any "hamburger" "What to cook on the grill"}
} {
return "foo is $foo, bar is $bar, and grill is $grill"
}
example -grill "lamb kebab" -bar 3.14
# => ‘foo is 0, bar is 3.14, and grill is lamb kebab’
example -help
# Usage information:
# Var/FlagName Type Value Help
# ------------ ---- ----- ----
# ( -help gives this help )
# -foo int (0) The number of foos
# -bar float (1.0) How much bar-ness
# -grill any (hamburger) What to cook on the grill
According to wiki.tcl.tk discussions, ::tcl::OptProc is deprecated. The recommended replacement is cmdline in tcllib. "This is probably the most standard and widely-used of these packages."
Using dicts
Now (8.5) that dicts are here to replace arrays in most places, this can be achieved more cleanly as long as you do the authorized key checking yourself. Example of summary testing (to put in a nice uplevel wrapper):
proc example {x y args} {
set keyargs {arg1 default1 arg2 default2}
if {[llength $args] % 2 != 0} {
error "$args: invalid keyword arguments (spec: $keyargs)"
}
set margs [dict merge $keyargs $args]
if {[dict size $margs] != [dict size $keyargs]} {
error "$args: invalid keyword arguments (spec: $keyargs)"
}
lassign [dict values $margs] {*}[dict keys $margs]
puts "x: $x, y: $y, arg1: $arg1, arg2: $arg2"
}
example 1 2 # => x: 1, y: 2, arg1: default1, arg2: default2
example 1 2 arg2 3 # => x: 1, y: 2, arg1: default1, arg2: 3
example 1 2 test 3 # => test 3: invalid keyword arguments (spec: arg1 default1 arg2 default2)
example 1 2 test # => test: invalid keyword arguments (spec: arg1 default1 arg2 default2)
Of course, more work is required to reach the flexibility of something like Common Lisp's ordinary lambda list.
VBA
Public Function timedelta(Optional weeks As Integer = 0, Optional days As Integer = 0, _
Optional hours As Integer = 0, Optional minutes As Integer = 0, Optional seconds As Integer = 0, _
Optional milliseconds As Integer = 0, Optional microseconds As Integer = 0) As Variant
End Function
Public Sub main()
'-- can be invoked as:
fourdays = timedelta(days:=4)
'-- fourdays = timedelta(0,4) '-- equivalent
'-- **NB** a plain '=' is a very different thing
oneday = timedelta(days = 1) '-- equivalent to timedelta([weeks:=]IIf((days=1,-1:0))
'-- with NO error if no local variable days exists.
'VBA will assume local variable days=0
Dim hours As Integer
shift = timedelta(hours:=hours) '-- perfectly valid (param hours:=local hours)
'-- timedelta(0,hours:=15,3) '-- illegal (it is not clear whether you meant days:=3 or minutes:=3)
'VBA expects a named parameter for 3
End Sub
Visual Basic
'the function
Sub whatever(foo As Long, bar As Integer, baz As Byte, qux As String)
'...
End Sub
'calling the function -- note the Pascal-style assignment operator
Sub crap()
whatever bar:=1, baz:=2, foo:=-1, qux:="Why is ev'rybody always pickin' on me?"
End Sub
V (Vlang)
1) Vlang allows for a struct literal to be passed to the function, instead of named parameters.
2) Using this style, fields need not appear in the same order as they are declared.
3) If one or more fields are omitted, their default values will be used instead.
4) The named parameter feature was deliberately omitted, for greater code readability.
5) Depending on the situation, variadic and/or sum types can also be considered.
struct Params {
a int
b int
c int
}
fn a_fn(p Params) int {
return p.a + p.b + p.c
}
fn main() {
x := a_fn(Params{a: 1, b: 2, c: 3}) // same order
println("x = ${x}")
y := a_fn(Params{c: 3, b: 2, a: 1}) // different order
println("y = ${y}")
z := a_fn(Params{c: 2}) // only one field
println("z = ${z}")
}
- Output:
x = 6 y = 6 z = 2
Wren
Wren doesn't support named parameters as such though they can be simulated using a map.
var printName = Fn.new { |name|
if (!(name is Map && name["first"] != null && name["last"] != null)) {
Fiber.abort("Argument must be a map with keys \"first\" and \"last\"")
}
System.print("%(name["first"]) %(name["last"])")
}
printName.call({"first": "Abraham", "last": "Lincoln"}) // normal order
printName.call({"last": "Trump", "first": "Donald"}) // reverse order
printName.call({"forename": "Boris", "lastname": "Johnson"}) // wrong parameter names
- Output:
Abraham Lincoln Donald Trump Argument must be a map with keys "first" and "last" [./named_params line 3] in new(_) block argument [./named_params line 10] in (script)
XSLT
XSLT only allows specification of template parameters by name, not position.
<xsl:template name="table-header">
<xsl:param name="title"/>
...
</xsl:template>
- Programming Tasks
- Basic language learning
- 11l
- Ada
- ALGOL 68
- AppleScript
- Applesoft BASIC
- Arturo
- AutoHotkey
- Bracmat
- C
- C sharp
- C++
- Boost
- Clojure
- COBOL/Omit
- Common Lisp
- D/Omit
- Delphi
- System.SysUtils
- Dyalect
- E
- Ecstasy
- Elixir
- Erlang
- F Sharp
- Factor
- Forth
- Fortran
- FreeBASIC
- Go
- Haskell
- Icon
- Unicon
- Icon examples needing attention
- Examples needing attention
- J
- Java
- JavaScript
- Jq
- Julia
- Kotlin
- LabVIEW
- Lasso
- Lingo
- Lua
- M2000 Interpreter
- Maple
- Mathematica
- Wolfram Language
- MATLAB
- Octave
- Modula-3
- Nemerle
- Nim
- Objective-C
- OCaml
- Oz
- Pascal/Omit
- Perl
- Phix
- Phix/basics
- PHP
- PicoLisp
- PowerShell
- Prolog
- Python
- R
- Racket
- Raku
- REXX
- Ruby
- Rust/Omit
- Scala
- Scheme
- SenseTalk
- Sidef
- Smalltalk
- Standard ML
- Suneido
- Swift
- Tcl
- VBA
- Visual Basic
- V (Vlang)
- Wren
- XSLT
- 6502 Assembly/Omit
- 68000 Assembly/Omit
- 8086 Assembly/Omit
- Axe/Omit
- BASIC/Omit
- BBC BASIC/Omit
- Bc/Omit
- Dc/Omit
- GUISS/Omit
- Joy/Omit
- PARI/GP/Omit
- PureBasic/Omit
- TI-83 BASIC/Omit
- TI-89 BASIC/Omit
- UNIX Shell/Omit
- Z80 Assembly/Omit
- Zkl/Omit
- ZX Spectrum Basic/Omit
- Functions and subroutines