LoginSignup
0
0

<11> 手続きと関数 (標準 Pascal 範囲内での Delphi 入門)〔裏〕

Last updated at Posted at 2021-02-16

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:

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() は不要なのです。

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.) デフォルトパラメータ (Default Parameters)

ルーチンのデフォルトパラメータは Delphi 4 以降で利用可能です。

(11.1.9.) ルーチンのオーバーロード (Overloading Routines)

ルーチンのオーバーロードは Delphi 4 以降で利用可能です。

(11.1.10.) オープン文字列パラメータ (Open String Parameters)

(11.1.11.) 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.12.) 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.) 手続き型 (Procedural Types)

・手続き型の由来

手続き型 (Procedural Types) は Modula-2 の手続き型 (Procedure Type) 由来だと思われます。

・() の省略できないパラメータのない関数

11.1.1.節に次のような記述がありますが、例外があります。

パラメータのないルーチンの呼び出しでは ( ) を省略できます。

例えば次のような場合です。

ProcTypes.dpr
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.4.1.) 手続き型定数とグローバル手続き型変数の初期化

索引

:ramen: [ ← 10. ポインタ型〔裏〕 ] [ ↑ 目次へ ] [ → 12. テキストファイルの入出力〔裏〕 ]

  1. 『ISO/IEC 7185:1990』および『JIS X 3008:1994』より引用。 2

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0