2.08 Procedures and Functions

Procedures and Functions

A procedure is identified by starting with the word procedure(proc) and a function is similarly identified by starting with the word function(func).

In each case they stop with the word end followed by procedure or function.

The essential difference between a procedure and a function is that a function always returns a value. A procedure does not normally return a value although it is possible to do so. In this case the returned value is an integer. By default a procedure always returns a value of zero. Currently there is no way of retrieving the value from outside the procedure.

In functions you either use the name of the function as a target variable to return the value or, alternatively, you can specify the return value in a return statement. If a return statement is specified without a value, the return variable is used. The same applies to procedures, even though currently there is no way of retrieving the value.

Although a function is normally called to return a value, a function may be called as procedure, where the returned value is not important.

Procedure(Proc)

Description:

Defines a procedure.

Syntax:

{procedure|proc} name [([@] par1 [, …[@] parN)]]
[{var|local var[, var[, …]]]
[{static var[, var[, …]]]

[return]
end [{procedure|proc}]

where:

name
the procedure name
par1…parN
parameters passed to the procedure
var
local variables

Example:

Implementation Status:

LynPlex Interpreter
LynPlexC Compiler
LynPlexS Compiler

Function(Func)

Description:

Defines a function.

The essential difference between a procedure and a function is that a function returns a value.

In functions you use the name of the function as a target variable to return the value. In fact the same applies to procedures, but currently there is no way of retrieving the value from outside the procedure.

The return statement can also be used to assign the return value and then exit the function.

Syntax:

{function|func} [as] return-type name [([@] par1 [, …[@] parN)]]
{function|func} name [([@] par1 [, …[@] parN)]] as return-type
[{var|local var[, var[, …]]]
[{static var[, var[, …]]]

[return [return-value]]

name=return-value
end [{function|func}]

where:

name
the function name
par1…parN
parameters passed to the function
var
local variables
return-type
the type of value to be returned from the function
return-value
the value to be returned from the function

Example:

Implementation Status:

LynPlex Interpreter
Return type is not supported.
LynPlexC Compiler
LynPlexS Compiler

Passing Parameters

Parameters can be passed by value or by reference. By default strings, types and arrays are passed by reference, all other types are passed by value. This may be changed in a procedure or function declaration.

Passing parameters by value means the executor makes a copy of the parameter and this is passed to the procedure or function. The passed variable may be changed by the called procedure or function, but the value in the caller's code will not be changed.

Passing parameters by reference means the executor passes the pointer of variable rather than a copy. The value in caller's code may well be the changed after the call.

Normally you would use the reference indicator (@) character for passing parameters by reference. This is only necessary where the parameter would otherwise by passed by value.

// Passing 'x' by value
proc f(x)
  x = 1
  end proc f(x)

x = 2
f x
put x; // displays 2
// Passing 'x' by reference
proc f(@x)
  x = 1
  end proc f(@x)

x = 2
f x
put x; // displays 1

You can use the word byref instead of the reference indicator (@). There is no difference between the two methods other than byref must be followed by a space as it is a separate word.

proc f(byref x)
  x = 1
  end proc f(byref x)

Similarly, where a parameter would normally be passed by reference, you can use the word byval to pass it by value.

(To be implemented) Parameters may be omitted by the calling statement. A null variable will be passed instead. Alternatively a default value can be specified on the proc/func statement.

Passing Arrays

You can pass arrays as parameters. When using arrays as parameters they are always passed by reference. This avoids the need to duplicate the array.

Passing & returning arrays, using local arrays.

func fill(a)
  local b, i

  range b(16)
  for i = 0 to 16 
    b(i) = 16-a(i)
  fill = b
  end func fill(a)

range v()
v = fill(v)

Single-line Functions

Where a function is very simple it is possible to define it in a single line.

Syntax:

func name[(par1[,...])] = expression

(To be implemented) Functions declared in this form are actually macros and are included in line to avoid the call overhead.

Nested Procedures and Functions

Procedures and functions may be nested. The nested procedures/functions are visible only inside the “parent” procedure/function.

func f(x)
  // Function: f.f1()
  func f1(x)
    // Function: f.f1.f2()
    func f2(x)
      f2 = cos(x)
      end
    f1 = f2(x)/4
    end

  // Function: f.f3()
  func f3
    f3 = f1(pi/2)
    end

  put f1(pi); // OK
  put f2(pi); // ERROR
  f = x + f1(pi) + f3; // OK
  end

There is no way to access a global procedure with the same name as a local procedure… Then again, why would you want to? …

Subroutines

A subroutine may be defined within a procedure or function, to execute some code out of line.

A subroutine is identified by starting with the word subroutine(sub) and stopping with the word end followed by subroutine.

A subroutine is invoked by the call statement.

A subroutine may also be defined just by a label. In this case the code must always end with a return statement.

There are no parameters passed to a subroutine. The subroutine will use the same variables as the parent routine.

The USE keyword

This keyword is used on specific commands to passing a user-defined expression.

Example:

split str, words, " " use trim

In that example, every element of words will be 'trimmed'.

Declare

//To be provided//

Local, Static, Shared, External and Common

A variable that is declared (either explicitly or implicitly) and used only within a procedure is local to that procedure and is not the same as any other variable of the same name used elsewhere. The value of a local variable is reset each time the procedure is called.

A variable that is declared as static is also local to the procedure. Unlike a local variable its value does not change across calls to the function or subroutine. When the procedure is called, the value of a static variable will be the same as it was on the previous call.

A variable that is declared as shared in the root segment of a source module is available to all functions and procedures at all levels within the same source module. Unless a variable is explicitly declared as local within a procedure, all references to that variable are taken to refer the shared variable of that name.

Where an object is declared as external it may or may not be defined within the current source module. It must be defined once before use in any of the modules that reference it. Within a source module the external variable can be accessed within any function or procedure in the same way as a shared variable.

If a variable is declared as common, the same variable is available at all levels of the program and across all modules. The use of common is dependent on the linker that is being used. If the linker does not support common storage, then common is effectively the same as shared.

See 2.03 Data Scope for details.

See Also


lynplex/lp0208.txt · Last modified: 2012/07/10 22:10 (external edit)