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

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

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

# この小技に関連するMind言語マニュアル

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

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


>構文＝ 
＜関数名＞とは　**関数　＜入力データ型＞ ・・ ＜入力データ型＞　＜出力データ型＞**
　　　　・・・・・し　　　　↑太字部は途中で改行してはならない
　　　　・・・・・すること。
>
>注：「関数」から末尾の＜出力データ型＞までを１行内に表記すること
注：「入力データ型」は１個～３個を書く。この個数が関数の引数個数となる
注：「入力データ型」が複数ある場合、すべて同一型であること
注：「入力データ型」が書かれない場合は１つの整数入力とみなされる
注：「出力データ型」が書かれない場合は整数出力とみなされる
>
>　　　　　　─── データ型に記述できる語 ───
　　　　　　整数入力、 小数入力　|  整数出力、 小数出力

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


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

Mind7では属性定義がいったん廃止されていますので、本記事の対象外となります。Mind7で関数形式の定義ができないという意味ではないのでご注意お願いします。

# 対応バージョン
□Mind７　■Mind８　■Mind９
■Windows版　□Linux版

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

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

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

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

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


# Mindプログラムソース

```mind:function.src
一つの引数を受け取り１つの戻り値を返す関数とは　関数　整数入力　整数出力（c　→　c）
        cは　変数
    cに　入れ
    cを　一つ増加し
    cを　返す。

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

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

メインとは    　（・　→　・）
        C1は　数値　１０
        C2は　数値　５
        C3は　変数
        C4は　変数

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

    [C3 := 二つの引数を受け取り１つの戻り値を返す関数（C1、C2）]
    C3を　数値表示し　改行し
    
    [C3 := 二つの引数を受け取り２つの戻り値を返す関数（C1、C2）]
    C3を　数値表示し　改行し
    C4に　入れ　C4を　数値表示し　改行すること。
```
関数形式で定義したので、代入の数式表現でサンプルソースを書いておりますが、通常の日本語表現で書くこともできます。

> C3に　 一つの引数を受け取り１つの戻り値を返す関数（C1）を　入れ

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

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

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

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

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

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


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

## Mind９
下図はMind９βです。
```cmd:
C:\developments\vscode\mind9>mind function file   

日本語プログラミング言語 Ｍｉｎｄ Version 8.11 for Windows
          Copyright(C) 1985 Scripts Lab. Inc.
コンパイル中 .. 終了
Coping.. C:\mind9-beta\mind9-beta\bin\mindex.exe --> function.exe
```
## Mind8
```cmd:
C:\developments\vscode\mind9>mind function file

日本語プログラミング言語 Ｍｉｎｄ Version 8.07 for Windows
          Copyright(C) 1985 Scripts Lab. Inc.
コンパイル中 .. 終了
Coping.. c:\pmind\bin\mindex.exe --> function.exe
```

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

```cmd:
C:\developments\vscode\mind9>function
11
5
15
5
```

# Mindプログラムソース（出力属性を２つ定義）
二つの引数を受け取り２つの戻り値を返す関数の定義部で、整数出力の宣言を２つにするとコンパイルエラーとなります。

```mind:function2.src
※２つの関数定義はfunction.srcと同一のため略

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

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


## コンパイル結果

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

```cmd:
C:\developments\vscode\mind9>mind function2 file

C:\developments\vscode\mind9>mind function2 file 

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

C:\developments\vscode\mind9>function2
```

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

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

# Mindプログラムソース（２つ返して１つしか処理しない場合）
二つの引数を受け取り２つの戻り値を返す関数の定義部で、整数出力の宣言を１つにしてコンパイラを通し、関数実行時の後に２つ目の戻り値を処理しないで終了すると実行時にスタックずれが発生します。

```mind:function3.src
※３つの関数定義はfunction.srcと同一のため略

メインとは    　（・　→　・）
        C1は　数値　１０
        C2は　数値　５
        C3は　変数
        C4は　変数

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

    [C3 := 二つの引数を受け取り１つの戻り値を返す関数（C1、C2）]
    C3を　数値表示し　改行し
    
    [C3 := 二つの引数を受け取り２つの戻り値を返す関数（C1、C2）]
    C3を　数値表示し　改行し
    スタック検査すること。
```
このサンプルでは、スタック検査を実行してチェックしています。

## コンパイル・実行結果

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

```cmd:
C:\developments\vscode\mind9>mind function3 file

日本語プログラミング言語 Ｍｉｎｄ Version 8.11 for Windows
          Copyright(C) 1985 Scripts Lab. Inc.
コンパイル中 .. 終了
Coping.. c:\mind9-beta\mind9-beta\bin\mindex.exe --> function3.exe

C:\developments\vscode\mind9>function3
11
5
15
スタックがずれています。
C:\developments\vscode\mind9>
```

# 参考情報
この小技「関数」を使った記述例の記事です。

https://qiita.com/mylifewithviolin/items/dda7f481891f2ae1e1d6

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

https://qiita.com/mylifewithviolin/items/07a750ffb370591815ba


# おわりに
いかがでしたでしょうか？なにかの参考になれば幸いです。2025年は日本語プログラミング言語Mind生誕４０周年です。

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

興味を持たれた方は[日本語プログラミング言語Mind公式サイト](https://www.scripts-lab.co.jp/mind8download/download.html)にアクセスすると、Mindコンパイラをダウンロードできます。

[Mindプログラミングマニュアル（基本文法）](https://www.scripts-lab.co.jp/mind/ver8/doc/index.html)ページから気になるお題の構文を選んで、この記事のようにサンプル実装実行してQiitaにアウトプットしてみましょう！

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

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