Call a function: Difference between revisions

From Rosetta Code
Content added Content deleted
(Added PicoLisp)
Line 271: Line 271:


By default, arguments are passed readonly, which allows the implementation to decide whether pass-by-reference or pass-by-value is more efficient on a case-by-case basis. Explicit lvalue, reference, or copy semantics may be requested on a parameter-by-parameter basis, and the entire argument list may be processed raw if that level of control is needed.
By default, arguments are passed readonly, which allows the implementation to decide whether pass-by-reference or pass-by-value is more efficient on a case-by-case basis. Explicit lvalue, reference, or copy semantics may be requested on a parameter-by-parameter basis, and the entire argument list may be processed raw if that level of control is needed.

=={{header|PicoLisp}}==
When calling a funcion in PicoLisp directly (does this mean "in a statement context"?), it is always surrounded by parentheses, with or without arguments, and for any kind of arguments (evaluated or not):
<lang PicoLisp>(foo)
(bar 1 'arg 2 'mumble)</lang>
When a function is used in a "first class context" (e.g. passed to another function), then it is not yet '''called'''. It is simply '''used'''. Technically, a function can be either a '''number''' (a built-in function) or a '''list''' (a Lisp-level function) in PicoLisp):
<lang PicoLisp>(mapc println Lst) # The value of 'printlin' is a number
(apply '((A B C) (foo (+ A (* B C)))) (3 5 7)) # A list is passed</lang>
Any argument to a function may be evaluated or not, depending on the function. For example, 'setq' evaluates every second argument
<lang PicoLisp>(setq A (+ 3 4) B (* 3 4))</lang>
i.e. the first argument 'A' is not evaluated, the second evaluates to 7, 'B' is not evaluated, then the fourth evaluates to 12.


=={{header|Tcl}}==
=={{header|Tcl}}==

Revision as of 14:35, 19 August 2011

Call a function is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

The task is to demonstrate the different syntax and semantics that the language may provide for calling a function. This may include:

  • Calling a function that requires no arguments
  • Calling a function with a fixed number of arguments
  • Calling a function that utilizes optional arguments
  • Calling a function with a variable number of arguments (varargs)
  • Calling a function with named arguments
  • Using a function in statement context
  • Using a function in first class context within an expression
  • Obtaining the return value of a function
  • Demonstrating any differences that apply to calling builtin functions rather than user defined functions
  • Demonstrating differences between calling subroutines and functions, if these are separate cases within the language.
  • State whether arguments are passed by value or by reference

Note this task is about methods of calling functions, not methods of defining functions, which is a separate topic.

Ada

  • Ada provides two kinds of subroutines: procedures, without return values, and functions, with return values. The return values of procedures must be used by the callers. If you don't want do deal with the return value, call a procedure instead.
  • As a rule of thumb, an Ada compiler is free to pass arguments either by value or by reference. Parameters have a mode, however: either 'in' or 'out' or 'in out'. It is prohibited to write somthing to an 'in' parameter. The next language Standard, Ada 2012, will support functions with 'out' and 'in out' mode parameters, so far, only procedures could have parameters with non-'in' modes. So any of the following statements for Ada functions holds for Ada procedures as well.
  • There are no differences between between calling built-in vs. user defined functions.
  • Functions without parameters can be called by omitting the parameter list (no empty brackets!):<lang Ada>S: String := Ada.Text_IO.Get_Line;</lang>
  • Ada supports functions with optional parameters:<lang Ada>function F(X: Integer; Y: Integer := 0) return Integer; -- Y is optional

... A : Integer := F(12); B : Integer := F(12, 0); -- the same as A C : Integer := F(12, 1); -- something different</lang>

  • If the number of parameters of F where fixed to two (by omitting the ":= 0" in the specification), then B and C would be OK but A wouldn't.
  • Ada does not support functions with a variable number of arguments. But a function argument can be an unconstrained array with as many values as you want:<lang Ada>type Integer_Array is array (Positive range <>) of Integer;

function Sum(A: Integer_Array) return Integer is

  S: Integer := 0;

begin

  for I in A'Range loop
     S := S + A(I);
  end loop;
  return S;

end Sum; ... A := Sum((1,2,3)); -- A = 6 B := Sum((1,2,3,4)); -- B = 10</lang>

  • One can realize first-class functions by defining an access to a function as a parameter:<lang Ada>function H (Int: Integer;
           Fun: not null access function (X: Integer; Y: Integer)
             return Integer);
          return Integer;

...

X := H(A, F'Access) -- assuming X and A are Integers, and F is a function

                    -- taking two Integers and returning an Integer.</lang>
  • The caller is free to use either a positional parameters or named parameters, or a mixture of both (with positional parameters first) <lang Ada>Positional := H(A, F'Access);

Named  := H(Int => A, Fun => F'Access); Mixed  := H(A, Fun=>F'Access); </lang>

Icon and Unicon

Icon and Unicon have generalized procedures and syntax that are used to implement functions, subroutines and generators.

  • Procedures can return values or not and callers may use the returned values or not.
  • Procedures in Icon and Unicon are first class values and can be assigned to variables which can then be used to call procedures. This also facilitates some additional calling syntax.
  • Additionally, co-expressions are supported which allow for co-routine like transfers of control between two or more procedures. There are some differences in syntax for co-expression calls.
  • There are no differences between calling built-in vs. user defined functions
  • Named arguments is not natively supported; however, they can be supported using a user defined procedure as shown in Named parameters
  • Method calling is similar with some extended syntax
  • Arguments are basically passed by value or reference based on their type. Immutable values like strings, and numbers are passed by value. Mutable data types like structures are essentially references and although these are passed by value the effective behavior is like a call by reference.

For more information see Icon and Unicon Introduction on Rosetta

<lang Icon>procedure main() # demonstrate and describe function calling syntax and semantics

  # normal procedure/function calling
  f()                      # no arguments, also command context
  f(x)                     # fixed number of arguments
  f(x,h,w)                 # variable number of arguments (varargs)
  y := f(x)                # Obtaining the returned value of a function
  
  # procedures as first class values and string invocation 
  f!L                      # Alternate calling syntax using a list as args   
  (if \x then f else g)()  # call (f or g)()
  f := write               # assign a procedure
  f("Write is now called") # ... and call it
  "f"()                    # string invocation, procedure
  "-"(1)                   # string invocation, operator
  # Co-expressions
  
  f{e1,e2}                 # parallel evaluation co-expression call  
                           # equivalent to f([create e1, create e2]) 
  expr @ coexp             # transmission of a single value to a coexpression
  [e1,e2]@coexp            # ... of multiple values (list) to a coexpression 
  coexp(e1,e2)             # ... same as above but only in Unicon 
  # Other
  
  f("x:=",1,"y:=",2)       # named parameters (user defined)

end</lang>

J

A function that requires no arguments can be simulated by calling a function with an empty list for an argument: <lang j>f</lang>

A function with a fixed number of arguments gets special treatment in J when the fixed number is 1 or 2. <lang j>f 'one argument'</lang>and <lang j>'this example has two arguments' f 'the other argument'</lang> Alternatively, you can add something that enforces a constraint on length for the varargs case.

Note also that J offers special syntactic forms that take extra arguments. For example, here is a three argument case: <lang j>1 'special left arg' adverb 2</lang> and here is a four argument case <lang j>1 'special left arg' conjunction 'special right arg' 2</lang>Adverbs and conjuctions have an optional left argument (which is the far left value, which was 1 in the above two examples).


A function with a variable number of arguments (varargs): When you need to deal with more than four arguments (or more than two arguments in a context which demands a verb) or when you need to deal with a variable number of arguments, you can pass them in a list. If argument types conflict they will need to be put in boxes and the function will have to take its arguments out of the boxes. Here's an unboxed example with five arguments: <lang j> f 1,2,3,4,5</lang> and here's a boxed example with five arguments: <lang j>f (<1),(<2),(<3),(<4),(<5) </lang> Note that the last set of parenthesis is unnecessary <lang j>f (<1),(<2),(<3),(<4),<5</lang> Note also that J offers some syntactic sugar for this kind of list <lang j>f 1; 2; 3; 4; <5</lang>. Note also that if the last argument in a semicolon list is not boxed there is no need to explicitly box it, since that is unambiguous (it must be boxed so that it conforms with the other members of the list). <lang j>f 1; 2; 3; 4; 5</lang>

A function with named arguments can be accomplished by calling a function with the names of the arguments. <lang j>f 'george';'tom';'howard'</lang> Other interpretations of this concept are also possible, for example a function which requires an object could be thought of as a function with named arguments since an object's members have names:<lang j> obj=: conew'blank'

  george__obj=: 1
  tom__obj=: 2
  howard__obj=: 3
  f obj
  coerase obj</lang>  Name/value pairs can be achieved by in various ways, including passing names followed by values <lang j>f 'george';1;'tom';2;'howard';3</lang> and passing names and values in the same order <lang j>1 2 3 f 'george';'tom';'howard'</lang> and passing a structure of pairs <lang j>f ('george';1),('tom';2),:(howard';3)</lang>  Or, for example, the pairs could be individually boxed:  <lang j>f ('george';1);('tom';2);<howard';3</lang>

Using a function in command context is no different from using a function in any other context, in J. Using a function in first class context within an expression is no different from using a function in any other context, in J.

Obtaining the return value of a function is no different from using a function in j. For example, here we add 1 to the result of a function: <lang j>1 + f 2</lang>

The only differences that apply to calling builtin functions rather than user defined functions is spelling of the function names.

There are no differences between calling subroutines and functions because J defines neither subroutines nor functions. Instead, J defines verbs, adverbs, and conjunctions which for the purpose of this task are treated as functions.

PARI/GP

Calling a function is done in GP by writing the name of the function and the arguments, if any, in parentheses. As of version 2.5.0, function calls must use parentheses; some earlier versions allowed functions with an arity of 0 to be called without parentheses. However built-in constants (which are implicit functions of the current precision) can still be called without parentheses.

Optional arguments can be skipped, leaving commas in place. Trailing commas can be dropped.

Functions can be used when statements would be expected without change. <lang parigp>f(); \\ zero arguments sin(Pi/2); \\ fixed number of arguments Str("gg", 1, "hh"); \\ variable number of arguments (x->x^2)(3); \\ first-class x = sin(0); \\ get function value</lang>

Built-in functions are like user-defined functions in current versions. In older versions built-in functions cannot be passed as closures.

Most arguments are passed by reference. Some built-in functions accept arguments (e.g., flags) that are not GENs; these are passed by value or reference depending on their C type. See the User's Guide to the PARI Library section 5.7.3, "Parser Codes".

Perl 6

Fundamentally, nearly everything you do in Perl 6 is a function call if you look hard enough. At the lowest level, a function call merely requires a reference to any kind of invokable object, and a call to its postcircumfix:<( )> method. However, there are various forms of sugar and indirection that you can use to express these function calls differently. In particular, operators are all just sugar for function calls.

Calling a function that requires no arguments:

<lang perl6>foo # as list operator foo() # as function foo.() # as function, explicit postfix form $ref() # as object invocation $ref.() # as object invocation, explicit postfix &foo() # as object invocation &foo.() # as object invocation, explicit postfix

($name)() # as symbolic ref</lang>

Calling a function with exactly one argument:

<lang perl6>foo 1 # as list operator foo(1) # as named function foo.(1) # as named function, explicit postfix $ref(1) # as object invocation (must be hard ref) $ref.(1) # as object invocation, explicit postfix 1.$foo # as pseudo-method meaning $foo(1) (hard ref only) 1.$foo() # as pseudo-method meaning $foo(1) (hard ref only) 1.&foo # as pseudo-method meaning &foo(1) (is hard foo) 1.&foo() # as pseudo-method meaning &foo(1) (is hard foo) 1.foo # as method via dispatcher 1.foo() # as method via dispatcher 1."$name"() # as method via dispatcher, symbolic +1 # as operator to prefix:<+> function</lang>

Method calls are included here because they do eventually dispatch to a true function via a dispatcher. However, the dispatcher in question is not going to dispatch to the same set of functions that a function call of that name would invoke. That's why there's a dispatcher, after all. Methods are declared with a different keyword, method, in Perl 6, but all that does is install the actual function into a metaclass. Once it's there, it's merely a function that expects its first argument to be the invocant object. Hence we feel justified in including method call syntax as a form of indirect function call.

Operators like + also go through a dispatcher, but in this case it is multiply dispatched to all lexically scoped candidates for the function. Hence the candidate list is bound early, and the function itself can be bound early if the type is known. Perl 6 maintains a clear distinction between early-bound linguistic constructs that force Perlish semantics, and late-bound OO dispatch that puts the objects and/or classes in charge of semantics. (In any case, &foo, though being a hard ref to the function named "foo", may actually be a ref to a dispatcher to a list of candidates that, when called, makes all the candidates behave as a single unit.)

Calling a function with exactly two arguments:

<lang perl6>foo 1,2 # as list operator foo(1,2) # as named function foo.(1,2) # as named function, explicit postfix $ref(1,2) # as object invocation (must be hard ref) $ref.(1,2) # as object invocation, explicit postfix 1.$foo: 2 # as pseudo-method meaning $foo(1,2) (hard ref only) 1.$foo(2) # as pseudo-method meaning $foo(1,2) (hard ref only) 1.&foo: 2 # as pseudo-method meaning &foo(1,2) (is hard foo) 1.&foo(2) # as pseudo-method meaning &foo(1,2) (is hard foo) 1.foo: 2 # as method via dispatcher 1.foo(2) # as method via dispatcher 1."$name"(2) # as method via dispatcher, symbolic 1 + 2 # as operator to infix:<+> function</lang>

Optional arguments don't look any different from normal arguments. The optionality is all on the binding end.

Calling a function with a variable number of arguments (varargs):

<lang perl6>foo @args # as list operator foo(@args) # as named function foo.(@args) # as named function, explicit postfix $ref(@args) # as object invocation (must be hard ref) $ref.(@args) # as object invocation, explicit postfix 1.$foo: @args # as pseudo-method meaning $foo(1,@args) (hard ref) 1.$foo(@args) # as pseudo-method meaning $foo(1,@args) (hard ref) 1.&foo: @args # as pseudo-method meaning &foo(1,@args) 1.&foo(@args) # as pseudo-method meaning &foo(1,@args) 1.foo: @args # as method via dispatcher 1.foo(@args) # as method via dispatcher 1."$name"(@args) # as method via dispatcher, symbolic @args X @blargs # as list infix operator to infix:<X></lang> Note: whether a function may actually be called with a variable number of arguments depends entirely on whether a signature accepts a list at that position in the argument list, but describing that is not the purpose of this task. Suffice to say that we assume here that the foo function is declared with a signature of the form (*@params). The calls above might be interpreted as having a single array argument if the signature indicates a normal parameter instead of a variadic one. What you cannot do in Perl 6 (unlike Perl 5) is pass an array as several fixed arguments. By default it must either represent a single argument, or be part of a variadic list. You can force the extra level of argument list interpolation using a prefix | however:

<lang perl6>my @args = 1,2,3; foo(|@args); # equivalent to foo(1,2,3)</lang>

Calling a function with named arguments:

<lang perl6>foo :a, :b(4), :!c, d => "stuff" foo(:a, :b(4), :!c, d => "stuff")</lang>

...and so on. Operators may also be called with named arguments, but only colon adverbials are allowed:

<lang perl6>1 + 1 :a :b(4) :!c :d("stuff") # calls infix:<+>(1,1,:a, :b(4), :!c, d => "stuff")</lang>

Using a function in statement context:

<lang perl6>foo(); bar(); baz(); # evaluate for side effects</lang>

Using a function in first class context within an expression:

<lang perl6>1 / find-a-func(1,2,3)(4,5,6) ** 2;</lang>

Obtaining the return value of a function:

<lang perl6>my $result = somefunc(1,2,3) + 2;</lang>

There is no difference between calling builtins and user-defined functions and operators (or even control stuctures). This was a major design goal of Perl 6, and apart from a very few low-level primitives, all of Perl 6 can be written in Perl 6.

There is no difference between calling subroutines and functions in Perl 6, other than that calling a function in void context that has no side effects is likely to get you a "Useless use of..." warning. And, of course, the fact that pure functions can participate in more optimizations such as constant folding.

By default, arguments are passed readonly, which allows the implementation to decide whether pass-by-reference or pass-by-value is more efficient on a case-by-case basis. Explicit lvalue, reference, or copy semantics may be requested on a parameter-by-parameter basis, and the entire argument list may be processed raw if that level of control is needed.

PicoLisp

When calling a funcion in PicoLisp directly (does this mean "in a statement context"?), it is always surrounded by parentheses, with or without arguments, and for any kind of arguments (evaluated or not): <lang PicoLisp>(foo) (bar 1 'arg 2 'mumble)</lang> When a function is used in a "first class context" (e.g. passed to another function), then it is not yet called. It is simply used. Technically, a function can be either a number (a built-in function) or a list (a Lisp-level function) in PicoLisp): <lang PicoLisp>(mapc println Lst) # The value of 'printlin' is a number (apply '((A B C) (foo (+ A (* B C)))) (3 5 7)) # A list is passed</lang> Any argument to a function may be evaluated or not, depending on the function. For example, 'setq' evaluates every second argument <lang PicoLisp>(setq A (+ 3 4) B (* 3 4))</lang> i.e. the first argument 'A' is not evaluated, the second evaluates to 7, 'B' is not evaluated, then the fourth evaluates to 12.

Tcl

<lang tcl>aCallToACommandWithNoArguments aCallToACommandWithOne argument aCallToACommandWith arbitrarily many arguments aCallToACommandWith {*}$manyArgumentsComingFromAListInAVariable aCallToACommandWith -oneNamed argument -andAnother namedArgument aCallToACommandWith theNameOfAnotherCommand aCallToOneCommand [withTheResultOfAnother]</lang> Tcl does differentiate between functions and other types of commands in expressions: <lang tcl>expr {func() + [cmd]} expr {func(1,2,3} + [cmd a b c]}</lang> However, there are no deep differences between the two: functions are translated into commands that are called in a particular namespace (thus foo() becomes tcl::mathfunc::foo). There are no differences in usage between built-in commands and user-defined ones, and parameters are passed to commands by value conceptually (and read-only reference in the implementation).

ZX Spectrum Basic

On the ZX Spectrum, functions and subroutines are separate entities. A function is limited to being a single expression that generates a return value. Statements are not allowed within a function. A subroutine can perform input and output and can contain statements.

<lang zxbasic>10 REM functions cannot be called in statement context 20 PRINT FN a(5): REM The function is used in first class context. Arguments are not named 30 PRINT FN b(): REM Here we call a function that has no arguments 40 REM parameters cannot be passed parameters, however variables are global 50 LET n=1: REM This variable will be visible to the called subroutine 60 GO SUB 1000: REM subroutines are called by line number and do not have names 70 REM subroutines do not return a value, but we can see any variables it defined 80 REM subroutines cannot be used in first class context 90 REM builtin functions are used in first class context, and do not need the FN keyword prefix 100 PRINT SIN(50): REM here we pass a parameter to a builtin function 110 PRINT RND(): REM here we use a builtin function without parameters</lang> 120 RANDOMIZE: REM statements are not functions and cannot be used in first class context.