11. 手続きと関数
Modula-2 だと、結果を返しても返さなくても PROCEDURE
です。
11.1. 手続き (Procedures)
11.1.1. パラメータリスト (パラメータ並び / Parameter list)
・パラメータと引数
JIS X 3008:1994 ではパラメータの事を 引数
としていますが、元となった規格の ISO/IEC 7185:1990 では Parameter
となっています。
Pascal | 他言語 | 用語 | |
---|---|---|---|
定義で渡されるもの | 仮パラメータ | 仮引数 | パラメータ |
呼び出しで渡されるもの | 実パラメータ | 実引数 | 引数 |
次の x
は Pascal では 仮パラメータ
です。他言語では 仮引数
と呼ばれます。
function f(x: Integegr): Integer;
次の 2
は Pascal では 実パラメータ
です。他言語では 実引数
と呼ばれます。
v := f(2);
仮 (formal-)
とか 実 (actual-)
という言葉を使わない場合、前者が パラメータ
で、後者が 引数
となります。上のコードだと 「パラメータ x
に渡された、引数 2
」 という事になります。
See also:
・定数パラメータ
定数パラメータは Borland Pascal / Turbo Pascal 7.0 で導入されています。
11.1.2. 整合配列パラメータ (Conformant array parameters)
・ANSI Pascal
ANSI Pascal は 標準 Pascal (ISO 7185:1983) 水準 0 相当の規格です。
整合配列パラメータは名前等価の考え方から外れている気がして、個人的には好きではありません。
See also:
11.1.3. 再帰手続き (Recursive procedures)
11.1.4. 手続きパラメータ (Procedural parameters)
・手続きパラメータに標準手続きを渡せない根拠
ISO/IEC 7185 および JIS X 3008 には「標準手続きを実手続きパラメータとして渡す事は出来ない」とはどこにも書かれていないように思えるのですが、
6.6.3.4 Procedural parameters The actual-parameter (中略) shall be a procedure-identifier that has a defining-point contained by the program-block.
6.6.3.4 手続き引数 実引数 (中略) は,手続き名でなければならない。この手続き名の定義位置は,プログラムブロックに含まれていなければならない。
とあります 1。標準手続きはプログラムブロック内で定義されていないため、標準手続きを実手続きパラメータとして渡す事はできません。
名前等価の考え方で行くと Delphi の手続き型を使ったやり方の方がスマートに思えます。
(11.1.5.) オープン配列パラメータ (Open Array Parameters)
・オープン配列パラメータの由来
オープン配列パラメータは Modula-2 由来です。High() 関数も Modula-2 由来ですが、Modula-2 には LOW() 関数はありません。Modula-2 のオープン配列パラメータの配列は常に 0 から始まるため LOW() は不要なのです。
オープン配列パラメータは Borland Pascal / Turbo Pascal 7.0 で導入されています。
See also:
・Slice() 関数
Slice()
はオープン配列パラメータに直接渡す用途でのみ使える特殊な関数です。
program Solve;
var
SliceMe: array [1..200] of Integer;
procedure TakesArray(x: array of Integer);
begin
end;
begin
TakesArray(SLICE(SliceMe, 5));
end.
See also:
(11.1.6.) 型可変オープン配列パラメータ (Variant Open Array Parameters)
(11.1.7.) オープン配列コンストラクタ (Open Array Constructors)
(11.1.8.) 型なしパラメータ (Untyped Parameters)
型なしパラメータは Turbo Pascal で導入されています。
(11.1.9.) オープン文字列パラメータ (Open String Parameters)
(11.1.10.) デフォルトパラメータ (Default Parameters)
ルーチンのデフォルトパラメータは Delphi 4 以降で利用可能です。
(11.1.11.) ルーチンのオーバーロード (Overloading Routines)
ルーチンのオーバーロードは Delphi 4 以降で利用可能です。
(11.1.12.) Exit() 手続き
・Exit (Super Pascal の場合)
A.V. エイホらの『データ構造とアルゴリズム』で使われている疑似言語 Super Pascal では、同様の機能を持つ return() 文が使える事になっています。
・Exit (Modula-2 の場合)
Exit() 手続きは Modula-2 にもありますが、意味合いが異なります。
Pascal | Modula-2 | |
---|---|---|
Exit() / EXIT | ルーチンから抜ける | LOOP~END を抜ける |
RETURN() | N/A | ルーチンから抜ける |
See also:
(11.1.13.) Halt() 手続き
・Halt (Modula-2 の場合)
Halt() 手続きは Modula-2 にもありますが、Modula-2 の HALT() にはパラメータがありません。
See also:
11.2. 関数 (Functions)
結果型 (Result Type)
結果 (Result)
・Result 変数の由来
Result 変数は Eiffel 由来のようです。
・結果 (UCSD Pascal の場合)
パラメータを受け取る Exit() 手続き自体は UCSD Pascal でも実装されていましたが、受け取るパラメータはルーチンでした。逆にパラメータのない Exit() はありませんでした。
function Add(A, B: integer): Integer;
begin
Add := A + B;
Exit(Add);
end;
・結果 (拡張 Pascal の場合)
拡張 Pascal では結果を保持する変数名を指定できます。ユーザー定義の Result 変数のようなものです。
function Add(A, B: integer) = i: Integer;
begin
i := A + B;
end;
See also:
関数呼び出し (Function Call)
再帰関数 (Recursive functions)
11.2.1. 関数パラメータ (Functional parameters)
・関数パラメータに標準関数を渡せない根拠
ISO/IEC 7185 および JIS X 3008 には「標準関数を実関数パラメータとして渡す事は出来ない」とはどこにも書かれていないように思えるのですが、
6.6.3.5 Functional parameters The actual-parameter (中略) shall be a function-identifier that has a defining-point contained by the program-block.
6.6.3.5. 関数引数 実引数 (中略) は,関数名でなければならない。この関数の定義位置は,プログラムブロックに含まれていなければならない。
とあります 1。標準関数はプログラムブロック内で定義されていないため、標準関数を実関数パラメータとして渡す事はできません。
名前等価の考え方で行くと Delphi の手続き型を使ったやり方の方がスマートに思えます。
11.2.2. 副作用 (Side effect)
11.3. 前方宣言 (Forward declaration)
Turbo Pascal の forward は 1.0~5.5 までは予約語でした。6.0 で指令になったようです。
See also:
(11.4.) インライン展開 (Inline expansion)
(11.5.) 手続き型 (Procedural Types)
・手続き型の由来
手続き型 (Procedural Types) は Modula-2 の手続き型 (Procedure Type) 由来だと思われます。
・() の省略できないパラメータのない関数
11.1.1.節に次のような記述がありますが、例外があります。
パラメータのないルーチンの呼び出しでは ( ) を省略できます。
例えば次のような場合です。
program ProcTypes;
{$APPTYPE CONSOLE}
uses
SysUtils;
var
SW: Boolean;
Proc: TProcedure;
procedure ProcA;
begin
Writeln('A');
end;
procedure ProcB;
begin
Writeln('B');
end;
function Func: TProcedure;
begin
if SW then
result := ProcA
else
result := ProcB;
end;
begin
SW := True;
Proc := Func; // NG: 手続き型 Proc への Func の代入
Proc := Func(); // OK: Func の実行結果の代入
Proc;
end.
手続き型を返し、パラメータのない関数では ()
を省略できません。
(11.5.1.) 手続き型定数とグローバル手続き型変数の初期化
索引
[ ← 10. ポインタ型〔裏〕 ] [ ↑ 目次へ ] [ → 12. テキストファイルの入出力〔裏〕 ]