Asymptote
functions are treated as variables with a signature
(non-function variables have null signatures). Variables with the
same name are allowed, so long as they have distinct signatures.
Function arguments are passed by value. To pass an argument by reference, simply enclose it in a structure (see Structures).
Here are some significant features of Asymptote
functions:
int x, x(); x=5; x=new int() {return 17;}; x=x(); // calls x() and puts the result, 17, in the scalar x
int sqr(int x) { return x*x; } sqr=null; // but the function is still just a variable.
int a, a(), b, b(); // Valid: creates four variables. a=b; // Invalid: assignment is ambiguous. a=(int) b; // Valid: resolves ambiguity. (int) (a=b); // Valid: resolves ambiguity. (int) a=b; // Invalid: cast expressions cannot be L-values. int c(); c=a; // Valid: only one possible assignment.
typedef int intop(int); intop adder(int m) { return new int(int n) {return m+n;}; } intop addby7=adder(7); write(addby7(1)); // Writes 8.
f
, even for calls to f
in previously
declared functions, by assigning another (anonymous or named)
function to it. However, if f
is overloaded by a
new function definition, previous calls will still access the original
version of f
, as illustrated in this example:
void f() { write("hi"); } void g() { f(); } g(); // writes "hi" f=new void() {write("bye");}; g(); // writes "bye" void f() {write("overloaded");}; f(); // writes "overloaded" g(); // writes "bye"
void f(bool b); void g(bool b) { if(b) f(b); else write(b); } f=new void(bool b) { write(b); g(false); }; g(true); // Writes true, then writes false.
Asymptote
is the only language we know of that treats functions
as variables, but allows overloading by distinguishing variables
based on their signatures.
Functions are allowed to call themselves recursively. As in C++, infinite
nested recursion will generate a stack overflow (reported as a
segmentation fault, unless a fully working version of the GNU
library libsigsegv
(e.g. 2.4 or later) is installed at
configuration time).