第15章. 3つの関数カテゴリ
この章の目的
この章を読み終える頃には、Keleusmaが持つ3種類の関数と、それぞれの種類が何を許されているかが分かるようになります。この章を読み終える頃には、Keleusmaが持つ3種類の関数と、それぞれの種類が何を許されているかが分かるようになります。
3種類、3つの単語
Keleusmaのすべての関数は、ちょうど3種類のうちの一つです。種類は宣言の最初に置く単語 — fn、yield、loop — で決まります。本ガイドのこれまでの関数はすべてfnでした。この章で3種類すべてを紹介し、続く章で残り2つをそれぞれ深く掘り下げます。Keleusmaのすべての関数は、ちょうど3種類のうちの一つです。種類は宣言の最初に置く単語 — fn、yield、loop — で決まります。本ガイドのこれまでの関数はすべてfnでした。この章で3種類すべてを紹介し、続く章で残り2つをそれぞれ深く掘り下げます。
fn — 完了する計算
fnで宣言された関数は「原子的・全域(atomic total)」な関数です。原子的というのは、途中で止まらず一気に最後まで走る、という意味です。全域というのは、必ず終わる、という意味です。fnの関数は入力を取り、計算し、結果を返して、終わります。ホストと話すために止まることはできず、永遠に走り続けることもできず、自分自身を呼ぶこともできません。fnで宣言された関数は「原子的・全域(atomic total)」な関数です。原子的というのは、途中で止まらず一気に最後まで走る、という意味です。全域というのは、必ず終わる、という意味です。fnの関数は入力を取り、計算し、結果を返して、終わります。ホストと話すために止まることはできず、永遠に走り続けることもできず、自分自身を呼ぶこともできません。
fn perfect_fifth(root: Word) -> Word {
root + 7
}
fn main() -> Word {
perfect_fifth(60)
}
keleusma runで実行します。出力は67です。fnの関数は和音の音を計算するようなものです — 質問が明確で、答えが明確で、それで終わりです。keleusma runで実行します。出力は67です。fnの関数は和音の音を計算するようなものです — 質問が明確で、答えが明確で、それで終わりです。
yield — 一時停止するフレーズ
yieldで宣言された関数は「非原子的・全域(non-atomic total)」な関数です。非原子的というのは、途中で一時停止できるということです。yield関数はホストに値を渡して一時停止でき、あとで再開できます。何度でも一時停止できますが、最後には必ず終わらなければなりません。yieldで宣言された関数は「非原子的・全域(non-atomic total)」な関数です。非原子的というのは、途中で一時停止できるということです。yield関数はホストに値を渡して一時停止でき、あとで再開できます。何度でも一時停止できますが、最後には必ず終わらなければなりません。
yield main(input: Word) -> Word {
let reply = yield input;
reply
}
yield関数は、指揮者のキューで一時停止して、合図のたびに進み、何回かのキューのあとに最後にはきちんと終わる演奏フレーズのようなものです。第16章で一時停止そのものについて扱います。yield関数は、指揮者のキューで一時停止して、合図のたびに進み、何回かのキューのあとに最後にはきちんと終わる演奏フレーズのようなものです。第16章で一時停止そのものについて扱います。
loop — 終わらない楽曲
loopで宣言された関数は「生産的・発散(productive divergent)」な関数です。発散というのは、決して終わらない、ということです。loop関数は永遠に繰り返します。「生産的」というのは付いている条件で — 周回ごとに必ずホストに値を渡さなければならない、ということです。loopで宣言された関数は「生産的・発散(productive divergent)」な関数です。発散というのは、決して終わらない、ということです。loop関数は永遠に繰り返します。「生産的」というのは付いている条件で — 周回ごとに必ずホストに値を渡さなければならない、ということです。
loop main(input: Word) -> Word {
let _ = yield input;
0
}
loop関数は楽曲そのもの、オスティナート(繰り返しモチーフ)で、ホストが回し続ける限りいつまでもうねり続けます。第17章で扱います。loop関数は楽曲そのもの、オスティナート(繰り返しモチーフ)で、ホストが回し続ける限りいつまでもうねり続けます。第17章で扱います。
3つの間のルール
- プログラムは
loop関数を最大で1つしか持てません。1つあれば、それがプログラムのエントリーポイントになります。プログラムはloop関数を最大で1つしか持てません。1つあれば、それがプログラムのエントリーポイントになります。 yield関数はエントリーポイントにもなれますし、ヘルパーにもなれます。fn関数は純粋な計算で、3種類のどの関数からも使えます。
関数の種類は、最初の単語に書かれた約束です。fnは必ず終わる、loopは何かを出し続ける。言語はこれらの約束に依拠して第1章の保証を成り立たせています。関数の種類は、最初の単語に書かれた約束です。fnは必ず終わる、loopは何かを出し続ける。言語はこれらの約束に依拠して第1章の保証を成り立たせています。
yield と loop の実行について
上に挙げた2つのプログラムは見せただけで、実行はしませんでした。yieldやloopのプログラムはホストと話すもので、keleusma runはホスト役を演じてはくれないからです。第16章から第18章で、こうしたプログラムをkeleusma compileで確認する方法を示します。第8部では、本物のloopプログラム — 1曲の楽曲 — をピアノロールというホストの中で実際に走らせます。上に挙げた2つのプログラムは見せただけで、実行はしませんでした。yieldやloopのプログラムはホストと話すもので、keleusma runはホスト役を演じてはくれないからです。第16章から第18章で、こうしたプログラムをkeleusma compileで確認する方法を示します。第8部では、本物のloopプログラム — 1曲の楽曲 — をピアノロールというホストの中で実際に走らせます。
この章のまとめ
fnは原子的・全域な関数で、一気に最後まで走って終わります。yieldは非原子的・全域な関数で、一時停止と再開ができ、必ず最後に終わります。yieldは非原子的・全域な関数で、一時停止と再開ができ、必ず最後に終わります。loopは生産的・発散な関数で、決して終わらず、周回ごとに必ずyieldしなければなりません。loopは生産的・発散な関数で、決して終わらず、周回ごとに必ずyieldしなければなりません。- プログラムは
loop関数を最大1つ持ち、それがエントリーポイントになります。プログラムはloop関数を最大1つ持ち、それがエントリーポイントになります。
次の章では、一時停止そのもの — yield — を見ていきます。