Initializing help system before first use

forward

A subroutine has to be `known' at the place where it is called in a program. In the preceding examples we have defined all subroutines at the start of the programs but this may not always be feasible or desirable. Mosel therefore enables the user to declare a subroutine separately from its definition by using the keyword forward. The declaration of of a subroutine states its name, the parameters (type and name) and, in the case of a function, the type of the return value. The definition that must follow later in the program contains the body of the subroutine, that is, the actions to be executed by the subroutine.

The following example (model qsort1.mos) implements a quick sort algorithm for sorting a randomly generated array of numbers into ascending order—please note that the implementation discussed here is merely provided as a programming example, we would generally recommend that you use the qsort routine of the Mosel module mmsystem in your Mosel programs. The procedure qsort that starts the sorting algorithm is defined at the very end of the program, it therefore needs to be declared at the beginning, before it is called. Procedure qsort_start calls the main sorting routine, qsort. Since the definition of this procedure precedes the place where it is called there is no need to declare it (but it still could be done). Procedure qsort calls yet again another subroutine, swap.

The idea of the quick sort algorithm is to partition the array that is to be sorted into two parts. The `left' part containing all values smaller than the partitioning value and the `right' part all the values that are larger than this value. The partitioning is then applied to the two subarrays, and so on, until all values are sorted.

model "Quick sort 1"

 parameters
  LIM=50
 end-parameters

 forward procedure qsort_start(L:array(range) of integer)

 declarations
  T:array(1..LIM) of integer
 end-declarations

 forall(i in 1..LIM) T(i):=round(.5+random*LIM)
 writeln(T)
 qsort_start(T)
 writeln(T)

! Swap the positions of two numbers in an array
 procedure swap(L:array(range) of integer,i,j:integer)
  k:=L(i)
  L(i):=L(j)
  L(j):=k
 end-procedure

! Main sorting routine
 procedure qsort(L:array(range) of integer,s,e:integer)
  v:=L((s+e) div 2)              ! Determine the partitioning value
  i:=s; j:=e
  repeat                         ! Partition into two subarrays
   while(L(i)<v) i+=1
   while(L(j)>v) j-=1
   if i<j  then
    swap(L,i,j)
    i+=1; j-=1
   end-if
  until i>=j
                                 ! Recursively sort the two subarrays
  if j<e and s<j then qsort(L,s,j); end-if
  if i>s and i<e then qsort(L,i,e); end-if
 end-procedure

! Start of the sorting process
 procedure qsort_start(L:array(r:range) of integer)
  qsort(L,getfirst(r),getlast(r))
 end-procedure

end-model

The quick sort example above demonstrates typical uses of subroutines, namely grouping actions that are executed repeatedly (qsort) and isolating subtasks (swap) in order to structure a program and increase its readability.

The calls to the procedures in this example are nested (procedure swap is called from qsort which is called from qsort_start): in Mosel there is no limit as to the number of nested calls to subroutines (it is not possible, though, to define subroutines within a subroutine).

© 2001-2020 Fair Isaac Corporation. All rights reserved. This documentation is the property of Fair Isaac Corporation (“FICO”). Receipt or possession of this documentation does not convey rights to disclose, reproduce, make derivative works, use, or allow others to use it except solely for internal evaluation purposes to determine whether to purchase a license to the software described in this documentation, or as otherwise set forth in a written software license agreement between you and FICO (or a FICO affiliate). Use of this documentation and the software described in it must conform strictly to the foregoing permitted uses, and no other use is permitted.