Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

第15章. 3つの関数カテゴリ

この章の目的

この章を読み終える頃には、Keleusmaが持つ3種類の関数と、それぞれの種類が何を許されているかが分かるようになります。この章を読み終える頃には、Keleusmaが持つ3種類の関数と、それぞれの種類が何を許されているかが分かるようになります。

3種類、3つの単語

Keleusmaのすべての関数は、ちょうど3種類のうちの一つです。種類は宣言の最初に置く単語 — fnyieldloop — で決まります。本ガイドのこれまでの関数はすべてfnでした。この章で3種類すべてを紹介し、続く章で残り2つをそれぞれ深く掘り下げます。Keleusmaのすべての関数は、ちょうど3種類のうちの一つです。種類は宣言の最初に置く単語 — fnyieldloop — で決まります。本ガイドのこれまでの関数はすべて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つのプログラムは見せただけで、実行はしませんでした。yieldloopのプログラムはホストと話すもので、keleusma runはホスト役を演じてはくれないからです。第16章から第18章で、こうしたプログラムをkeleusma compileで確認する方法を示します。第8部では、本物のloopプログラム — 1曲の楽曲 — をピアノロールというホストの中で実際に走らせます。上に挙げた2つのプログラムは見せただけで、実行はしませんでした。yieldloopのプログラムはホストと話すもので、keleusma runはホスト役を演じてはくれないからです。第16章から第18章で、こうしたプログラムをkeleusma compileで確認する方法を示します。第8部では、本物のloopプログラム — 1曲の楽曲 — をピアノロールというホストの中で実際に走らせます。

この章のまとめ

  • fnは原子的・全域な関数で、一気に最後まで走って終わります。
  • yieldは非原子的・全域な関数で、一時停止と再開ができ、必ず最後に終わります。yieldは非原子的・全域な関数で、一時停止と再開ができ、必ず最後に終わります。
  • loopは生産的・発散な関数で、決して終わらず、周回ごとに必ずyieldしなければなりません。loopは生産的・発散な関数で、決して終わらず、周回ごとに必ずyieldしなければなりません。
  • プログラムはloop関数を最大1つ持ち、それがエントリーポイントになります。プログラムはloop関数を最大1つ持ち、それがエントリーポイントになります。

次の章では、一時停止そのもの — yield — を見ていきます。