Call a function: Difference between revisions

Content added Content deleted
m (→‎{{header|Phix}}: added syntax colouring the hard way, phix/basics)
Line 3,931:
 
=={{header|Phix}}==
{{libheader|Phix/basics}}
Phix has three kinds of routines: procedure, function, and type. A procedure does not return a value, whereas a function does.
A type is a specialised kind of function that permits declarations of instances which are automatically validated whenever they are changed, further a type routine always returns either true or false.
* Phix does not allow implicit discard of function results. The explicit discard statement takes the form
 
<lang Phix>{} = myfunction()</lang>
<!--<lang Phix>-->
<span style="color: #0000FF;">{<span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">myfunction<span style="color: #0000FF;">(<span style="color: #0000FF;">)
<!--</lang>-->
 
* This is in fact a simple contraction of standard multiple assigment (which can be nested as deeply as you like):
 
<lang Phix>{cities,populations} = columize(muncipalities)
<!--<lang Phix>-->
{{},populations} = columize(muncipalities) -- discard result[1]
<span style="color: #0000FF;">{<span style="color: #000000;">cities<span style="color: #0000FF;">,<span style="color: #000000;">populations<span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">columnize<span style="color: #0000FF;">(<span style="color: #000000;">muncipalities<span style="color: #0000FF;">)</span>
{cities,{}} = columize(muncipalities) -- discard result[2]
<span style="color: #0000FF;">{<span style="color: #0000FF;">{<span style="color: #0000FF;">}<span style="color: #0000FF;">,<span style="color: #000000;">populations<span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">columnize<span style="color: #0000FF;">(<span style="color: #000000;">muncipalities<span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- discard result[1]</span>
{cities} = columize(muncipalities) -- ""</lang>
<span style="color: #0000FF;">{<span style="color: #000000;">cities<span style="color: #0000FF;">,<span style="color: #0000FF;">{<span style="color: #0000FF;">}<span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">columnize<span style="color: #0000FF;">(<span style="color: #000000;">muncipalities<span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- discard result[2]</span>
<span style="color: #0000FF;">{<span style="color: #000000;">cities<span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">columnize<span style="color: #0000FF;">(<span style="color: #000000;">muncipalities<span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- ""
<!--</lang>-->
* Calling a function with no parameters still requires the "()" empty argument list.
* Optional arguments are denoted simply by the presence of a default, and must be grouped on the right:
 
<lang Phix>function myfunction(integer a, string b="default")
<!--<lang Phix>-->
return {a,b}
<span style="color: #008080;">function</span> <span style="color: #000000;">myfunction<span style="color: #0000FF;">(<span style="color: #004080;">integer</span> <span style="color: #000000;">a<span style="color: #0000FF;">,</span> <span style="color: #004080;">string</span> <span style="color: #000000;">b<span style="color: #0000FF;">=<span style="color: #008000;">"default"<span style="color: #0000FF;">)</span>
end function
<span style="color: #008080;">return</span> <span style="color: #0000FF;">{<span style="color: #000000;">a<span style="color: #0000FF;">,<span style="color: #000000;">b<span style="color: #0000FF;">}</span>
--? myfunction() -- illegal, compile-time error
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
?myfunction(1) -- displays {1,"default"}
<span style="color: #000080;font-style:italic;">--? myfunction() -- illegal, compile-time error</span>
?myfunction(2,"that") -- displays {2,"that"}</lang>
<span style="color: #0000FF;">?<span style="color: #000000;">myfunction<span style="color: #0000FF;">(<span style="color: #000000;">1<span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- displays {1,"default"}</span>
<span style="color: #0000FF;">?<span style="color: #000000;">myfunction<span style="color: #0000FF;">(<span style="color: #000000;">2<span style="color: #0000FF;">,<span style="color: #008000;">"that"<span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- displays {2,"that"}
<!--</lang>-->
 
* Sequence parameters can be of any length, which is another way to implement optional/variable number of arguments.
* Named arguments can be specified in any order, with an error if any non-optional parameters are missing:
 
<lang Phix>?myfunction(b:="then",a:=3) -- displays {3,"then"}
<!--<lang Phix>-->
--?myfunction(b:="though") -- compile-time error</lang>
<span style="color: #0000FF;">?<span style="color: #000000;">myfunction<span style="color: #0000FF;">(<span style="color: #000000;">b<span style="color: #0000FF;">:=<span style="color: #008000;">"then"<span style="color: #0000FF;">,<span style="color: #000000;">a<span style="color: #0000FF;">:=<span style="color: #000000;">3<span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- displays {3,"then"}
--? myfunction(b:="though") -- illegal, compile-time error
<!--</lang>-->
 
* The programmer is free to use either positional parameters or named parameters, or a mixture of both (with positional parameters first).
* Phix does not support first-class functions directly, butas insteadintegers, usesalong with an integerolder routine_id mechanism (and obviously integers are first-class):
 
<lang Phix>constant integer r_my_func = routine_id("myroutine")
<!--<lang Phix>-->
?call_func(r_my_func,{1}) -- displays {1,"default"}</lang>
<span style="color: #008080;">constant</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">r_myfunction</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">routine_id<span style="color: #0000FF;">(<span style="color: #008000;">"myfunction"<span style="color: #0000FF;">)<span style="color: #0000FF;">,</span>
<span style="color: #000000;">first_class</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">myfunction</span>
<span style="color: #0000FF;">?<span style="color: #7060A8;">call_func<span style="color: #0000FF;">(<span style="color: #000000;">r_myfunction<span style="color: #0000FF;">,<span style="color: #0000FF;">{<span style="color: #000000;">1<span style="color: #0000FF;">}<span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- displays {1,"default"}</span>
<span style="color: #0000FF;">?<span style="color: #7060A8;">call_func<span style="color: #0000FF;">(<span style="color: #000000;">myfunction<span style="color: #0000FF;">,<span style="color: #0000FF;">{<span style="color: #000000;">1<span style="color: #0000FF;">}<span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- ""</span>
<span style="color: #0000FF;">?<span style="color: #7060A8;">call_func<span style="color: #0000FF;">(<span style="color: #000000;">first_class<span style="color: #0000FF;">,<span style="color: #0000FF;">{<span style="color: #000000;">1<span style="color: #0000FF;">}<span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- ""</span>
<span style="color: #0000FF;">?<span style="color: #000000;">first_class<span style="color: #0000FF;">(<span style="color: #000000;">1<span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- ""
<!--</lang>-->
 
The value of r_my_func can be passed as an argument to any routine, or stored in a table, and invoked in a similar fashion.<br>
Note however that for performance reasons some builtins do not have a proper routine_id; if you need one you must write a trivial one-line wrapper.<br>
Line 3,963 ⟶ 3,987:
* Partial application is usually achieved through a single variable-length "user_data" parameter within a call_func() expression.
* All arguments are passed by reference with copy-on-write semantics: to modify the value of a parameter you must both return and assign it, as in:
 
<lang Phix>s = append(s,item)</lang>
<!--<lang Phix>-->
<span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append<span style="color: #0000FF;">(<span style="color: #000000;">s<span style="color: #0000FF;">,<span style="color: #000000;">item<span style="color: #0000FF;">)
<!--</lang>-->
 
* Implicit forward calls are supported, as are optional explicit forward declarations, which can occasionally cure compilation error messages.