Call a function: Difference between revisions

From Rosetta Code
Content added Content deleted
(Z comes after P)
m ({{omit from|GUISS}})
Line 149: Line 149:
110 PRINT RND(): REM here we use a builtin function without parameters
110 PRINT RND(): REM here we use a builtin function without parameters
</lang>
</lang>

{{omit from|GUISS}}


[[Category:Functions and subroutines]]
[[Category:Functions and subroutines]]

Revision as of 18:59, 15 July 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 with a variable number of arguments (varargs)
  • Calling a function with named arguments
  • Using a function in command 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.

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

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>

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).

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 command context:

<lang perl6>foo(); bar(); # 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.

ZX Spectrum Basic

On the ZX Spectrum, functions and subroutines are separate entities. A function is limited to generating a return value. A subroutine can perform input and output.

<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 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 GOSUB 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>