日本語プログラミング言語Mindの小技 「関数」~戻り値を複数返せる~ #mind - Qiita

日本語プログラミング言語Mindの小技「関数」について説明したいと思います。

日本語プログラミング言語Mindのユーザー、または日本語プログラミング言語に興味のある方

この小技に関連するMind言語仕様の記述はMind8プログラミングマニュアルに記載があります。
2 プログラム表記の基本
関数

一般的なプログラム言語と同じような「関数」も定義できる。基本的には内部動作は通常の処理単語と同じで、コンパイラによる属性の認識と、上位から呼び出す際の表記が主な違いである。
 以下が定義ルールである。

構文= <関数名>とは 関数 <入力データ型> ・・ <入力データ型> <出力データ型>
    ・・・・・し          ↑太字部は途中で改行してはならない
    ・・・・・すること。

  注:「関数」から末尾の<出力データ型>までを1行内に表記すること
  注:「入力データ型」は1個~3個を書く。この個数が関数の引数個数となる
  注:「入力データ型」が複数ある場合、すべて同一型であること
  注:「入力データ型」が書かれない場合は1つの整数入力とみなされる
  注:「出力データ型」が書かれない場合は整数出力とみなされる

          ─── データ型に記述できる語 ───
          整数入力、 小数入力 | 整数出力、 小数出力

 上の構文は前項「処理単語の属性を指定する」(○○は 処理単語 ・・・・・)のそれと似ているが、属性が省略された場合の扱いが異なる。関数では<入力データ型>が省略されると1つの整数を引数とすると解釈され、<出力データ型>を省略すると整数を結果として返すものとされる。

本機能(本記事)は、下記のバージョンに対応しています。Mind8のLinux版も対応していると思いますが、本記事では特に検証を行っておりません。

Mind7では属性定義がいったん廃止されていますので、本記事の対象外となります。

□Mind7 ■Mind8 ■Mind9
■Windows版 □Linux版

「関数」はプログラミング言語Mindの処理単語の定義形式で、他のプログラミング言語の関数定義に近いものとなります。関数形式の定義文の形式は関数っぽくなく、引用時に関数ぽっくなるイメージです。

Mindでも関数形式の定義では、引数としてのスタックの想定状態をわかりやすくすることができます。処理単語形式でも実は属性定義をしておくと同じ効果があります。

Mindの通常からなる処理単語定義においては、物理的にはスタックに置かれた情報を処理単語側が先入れ後出しで処理していくので、スタックに置かれているどのような状態を引数としているかは、ソースコードだけでみるとぱっと見にはわかりにく面があります。(このあたりは静的型付けの関数形式のプログラミング言語に慣れきっている側の感想です。)

その点を補完するMindの別のしくみとしては、通常処理単語の定義においてもスタックの入りと戻りを注釈表記で表現するようになっています。この点の詳しい説明は別の機会にゆずります。

関数形式で処理単語を定義した場合でも、Mindの特徴としては戻り値を複数返せるという、通常1つの戻り値を定義する関数形式言語では少ない範疇の定義を行うことができます。ただし、後述しますがこれは若干裏技的となります:relaxed:

function.src

一つの引数を受け取り1つの戻り値を返す関数とは 関数 整数入力 整数出力(c → c)
        cは 変数
    cに 入れ
    cを 一つ増加し
    cを 返す。

二つの引数を受け取り1つの戻り値を返す関数とは 関数 整数入力 整数入力 整数出力(c1 c2 → c)
        c1は 変数
        c2は 変数
    c2に 入れ
    c1に 入れ
    c1から c2を 引いて 返す。

二つの引数を受け取り2つの戻り値を返す関数とは 関数 整数入力 整数入力 整数出力(c1 c2 → c3 c4)
        c1は 変数
        c2は 変数
    c2に 入れ
    c1に 入れ
    c1から c2を 引いて 返し
    c1に c2を 加えて 返す。

メインとは     (・ → ・)
        C1は 数値 10
        C2は 数値 5
        C3は 変数
        C4は 変数

    [C3 := 一つの引数を受け取り1つの戻り値を返す関数(C1)]
    C3を 数値表示し 改行し

    [C3 := 二つの引数を受け取り1つの戻り値を返す関数(C1、C2)]
    C3を 数値表示し 改行し
    
    [C3 := 二つの引数を受け取り2つの戻り値を返す関数(C1、C2)]
    C3を 数値表示し 改行し
    C4に 入れ C4を 数値表示し 改行すること。

関数形式で定義したので、代入の数式表現でサンプルソースを書いておりますが、通常の日本語表現で書くこともできます。

C3に  一つの引数を受け取り1つの戻り値を返す関数(C1)を 入れ

Mindの関数定義において、引数名という概念はなく、上記のサンプルソースコードのC1,C2はあくまで関数内のローカル変数であって、2つの引数相当のスタック値を代入しているにすぎません。

関数名で先頭の全角数字を漢数字としているのは、先頭1文字が全角数字の場合それに続く漢字が数助詞として解決されるのを避けているためです。

関数名の末尾の「~関数」にコンパイラ上の意味はありません。そのように命名しているだけです。

関数名の後の、空白のつぎに出現する「関数」はシステムトークンです。これにより関数形式の定義を強制しています。

二つの引数を受け取り2つの戻り値を返す関数の定義部で、整数出力の宣言が1つであるのはMindの関数宣言の仕様です。これはこのサンプルソースのように代入形式で実行した場合に1つ以上の戻り値を想定しずらいためと思われます。

実際には関数定義内で2つの戻り値をスタックに返しても、スタックずれしない限りは、代入の後にスタックから値を拾うことができます。

ではコンパイルしてみます。下位ライブラリはfileを指定します。

Mind9

下図はMind9βです。

C:developmentsvscodemind9>mind function file   

日本語プログラミング言語 Mind Version 8.11 for Windows
          Copyright(C) 1985 Scripts Lab. Inc.
コンパイル中 .. 終了
Coping.. C:mind9-betamind9-betabinmindex.exe --> function.exe

Mind8

C:developmentsvscodemind9>mind function file

日本語プログラミング言語 Mind Version 8.07 for Windows
          Copyright(C) 1985 Scripts Lab. Inc.
コンパイル中 .. 終了
Coping.. c:pmindbinmindex.exe --> function.exe

つづいて実行してみます。
Mind8の結果です。記述は割愛していますがMind9βも同じです。

C:developmentsvscodemind9>function
11
5
15
5

二つの引数を受け取り2つの戻り値を返す関数の定義部で、整数出力の宣言を2つにするとコンパイルエラーとなります。

function2.src

※2つの関数定義はfunction.srcと同一のため略

二つの引数を受け取り2つの戻り値を返す関数とは 関数 整数入力 整数入力 整数出力 整数出力(c1 c2 → c3 c4)
        c1は 変数
        c2は 変数
    c2に 入れ
    c1に 入れ
    c1から c2を 引いて 返し
    c1に c2を 加えて 返す。

※メインの定義はfunction.srcと同一のため略

コンパイル結果

Mind8の結果です。記述は割愛していますがMind9βも同じです。

C:developmentsvscodemind9>mind function2 file

C:developmentsvscodemind9>mind function2 file 

日本語プログラミング言語 Mind Version 8.07 for Windows
          Copyright(C) 1985 Scripts Lab. Inc.
コンパイル中 .. 終了
1 個のエラーが有ります。

C:developmentsvscodemind9>function2

function2.inf

function2.src 14 行目でエラー。行内容は、
二つの引数を受け取り2つの戻り値を返す関数とは 関数 整数入力 整数入力 整数出力 整数出力(c1 c2 → c3 c4)
      要因1:出力型の指定が多すぎます。

1 個のエラーが有ります。

二つの引数を受け取り2つの戻り値を返す関数の定義部で、整数出力の宣言を1つにしてコンパイラを通し、関数実行時の後に2つ目の戻り値を処理しないで終了すると実行時にスタックずれが発生します。

function3.src

※3つの関数定義はfunction.srcと同一のため略

メインとは     (・ → ・)
        C1は 数値 10
        C2は 数値 5
        C3は 変数
        C4は 変数

    [C3 := 一つの引数を受け取り1つの戻り値を返す関数(C1)]
    C3を 数値表示し 改行し

    [C3 := 二つの引数を受け取り1つの戻り値を返す関数(C1、C2)]
    C3を 数値表示し 改行し
    
    [C3 := 二つの引数を受け取り2つの戻り値を返す関数(C1、C2)]
    C3を 数値表示し 改行し
    スタック検査すること。

このサンプルでは、スタック検査を実行してチェックしています。

コンパイル・実行結果

Mind9βの結果です。記述は割愛していますがMind8も同じです。

C:developmentsvscodemind9>mind function3 file

日本語プログラミング言語 Mind Version 8.11 for Windows
          Copyright(C) 1985 Scripts Lab. Inc.
コンパイル中 .. 終了
Coping.. c:mind9-betamind9-betabinmindex.exe --> function3.exe

C:developmentsvscodemind9>function3
11
5
15
スタックがずれています。
C:developmentsvscodemind9>

この小技「関数」を使った記述例の記事です。

Mind7での関数定義の注意事項はこちらの記事が詳しいです。

いかがでしたでしょうか?なにかの参考になれば幸いです。2025年は日本語プログラミング言語Mind生誕40周年です。

本記事シリーズのご紹介

本記事シリーズ「日本語プログラミング言語Mindの小技」は「日本語プログラミング言語Mind生誕40周年プロジェクト」の一環です。

興味を持たれた方は日本語プログラミング言語Mind公式サイトにアクセスすると、Mindコンパイラをダウンロードできます。

Mindプログラミングマニュアル(基本文法)ページから気になるお題の構文を選んで、この記事のようにサンプル実装実行してQiitaにアウトプットしてみましょう!

筆者はMind7/8/9βで検証しておりますが、もちろんMind8だけでもじゅうぶんです。またお題が既存記事とかぶるのはまったく問題ありません。同じお題でみなさまの多様斬新なサンプルをお待ちしております:grinning:

面白い!、楽しい、カンタン、難しいのも書ける!みんなでやってみよう:relaxed:



フラッグシティパートナーズ海外不動産投資セミナー 【DMM FX】入金

Source link