--- /dev/null
+.. index::
+ single: 関数型プログラミング; はじめに
+
+====================
+関数型プログラミング
+====================
+
+以前の章では関数と再帰について学びました。
+
+関数型プログラミング (FP) の概念についてより詳しく学びます。
+
+* 純粋関数
+* 第一級関数
+* 高階関数
+* 無名関数と入れ子関数
+* 等式関数
+
+.. index::
+ pair: 関数型プログラミング; 純粋関数
+
+
+純粋関数
+========
+
+代入演算子により、関数への参照で渡される元データを処理する代わりに、
+変数の値 (リストとオブジェクト)をコピーして新しい変数を作成することで
+純粋関数 (状態を変更しない関数) を作成できます。
+
+
+用例:
+
+.. code-block:: ring
+
+ Func Main
+ aList = [1,2,3,4,5]
+ aList2 = square(aList)
+ see "aList" + nl
+ see aList
+ see "aList2" + nl
+ see aList2
+
+ Func Square aPara
+ a1 = aPara # リストのコピー
+ for x in a1
+ x *= x
+ next
+ return a1 # 新しいリストを返します。
+
+実行結果:
+
+.. code-block:: ring
+
+ aList
+ 1
+ 2
+ 3
+ 4
+ 5
+ aList2
+ 1
+ 4
+ 9
+ 16
+ 25
+
+
+.. index::
+ pair: 関数型プログラミング; 第一級関数
+
+第一級関数
+==========
+
+Ring の関数は第一級オブジェクトです。関数を仮引数として渡したり、
+変数として格納、または値を返せます。
+
+例えば、関数名を "関数名" または :関数名 のようにリテラルとして記述することで、関数の渡したり、返せます。
+
+関数名を有する変数を用いると、関数を渡したり返せます。
+
+Call 命令で関数名を有する変数から関数を呼び出します。
+
+文法:
+
+.. code-block:: ring
+
+ [関数の返値を代入するための変数] = Call 変数名([仮引数])
+
+用例:
+
+.. code-block:: ring
+
+ Func Main
+ see "before test2()" + nl
+ f = Test2(:Test)
+ see "after test2()" + nl
+ call f()
+
+ Func Test
+ see "Message from test!" + nl
+
+ Func Test2 f1
+ call f1()
+ See "Message from test2!" + nl
+ return f1
+
+実行結果:
+
+.. code-block:: ring
+
+ before test2()
+ Message from test!
+ Message from test2!
+ after test2()
+ Message from test!
+
+.. index::
+ pair: 関数型プログラミング; 高階関数
+
+高階関数
+========
+
+高階関数は、ほかの関数を仮引数として扱う関数です。
+
+用例:
+
+.. code-block:: ring
+
+ Func Main
+ times(5,:test)
+
+ Func Test
+ see "Message from the test function!" + nl
+
+ Func Times nCount,F
+
+ for x = 1 to nCount
+ Call F()
+ next
+
+実行結果:
+
+.. code-block:: ring
+
+ Message from the test function!
+ Message from the test function!
+ Message from the test function!
+ Message from the test function!
+ Message from the test function!
+
+.. index::
+ pair: 関数型プログラミング; 無名関数と入れ子関数
+
+無名関数と入れ子関数
+====================
+
+無名関数は、名前を持たない関数であり、ほかの関数へ仮引数として渡したり、変数へ格納できます。
+
+文法:
+
+.. code-block:: ring
+
+ Func [仮引数] { [ステートメント] }
+
+用例:
+
+.. code-block:: ring
+
+ test( func x,y {
+ see "hello" + nl
+ see "Sum : " + (x+y) + nl
+ } )
+
+ new great { f1() }
+
+ times(3, func { see "hello world" + nl } )
+
+ func test x
+ call x(3,3)
+ see "wow!" + nl
+
+ func times n,x
+ for t=1 to n
+ call x()
+ next
+
+ Class great
+ func f1
+ f2( func { see "Message from f1" + nl } )
+
+ func f2 x
+ call x()
+
+実行結果:
+
+.. code-block:: ring
+
+ hello
+ Sum : 6
+ wow!
+ Message from f1
+ hello world
+ hello world
+ hello world
+
+用例:
+
+.. code-block:: ring
+
+ Func Main
+ aList = [1,2,3,4]
+ Map (aList , func x {
+ return x*x
+ } )
+ see aList
+ aList = [4,9,14,25]
+ Map(aList, :myfilter )
+ see aList
+ aList = [11,12,13,14]
+ Map (aList , func x {
+ if x%2=0
+ return "even"
+ else
+ return "odd"
+ ok
+ })
+ see aList
+
+ Func myfilter x
+ if x = 9
+ return "True"
+ else
+ return "False"
+ ok
+
+ Func Map aList,cFunc
+ for x in aList
+ x = call cFunc(x)
+ next
+
+実行結果:
+
+.. code-block:: ring
+
+ 1
+ 4
+ 9
+ 16
+ False
+ True
+ False
+ False
+ odd
+ even
+ odd
+ even
+
+.. index::
+ pair: 関数型プログラミング; 等式関数
+
+等式関数
+========
+
+if 関数 = 関数、または演算子‘=’や‘!=’を用いずにテストできます (この機能は関数の等価性、あるいは Equality of functions とも言います)。
+
+用例:
+
+.. code-block:: ring
+
+ f1 = func { see "hello" + nl }
+
+ f2 = func { see "how are you?" + nl }
+
+ f3 = f1
+
+ call f1()
+ call f2()
+ call f3()
+
+ see (f1 = f2) + nl
+ see (f2 = f3) + nl
+ see (f1 = f3) + nl
+
+実行結果:
+
+.. code-block:: ring
+
+ hello
+ how are you?
+ hello
+ 0
+ 0
+ 1
+
+.. index::
+ pair: 関数型プログラミング; 参考文献
+
+参考文献
+========
+
+* How is the equality of functions defined? - Quora : https://www.quora.com/How-is-the-equality-of-functions-defined