関数型プログラミング

以前に関数と再帰を説明させていただきました。

ここでは関数型プログラミング (FP) の概念を詳説します。

  • 純粋関数

  • 第一級関数

  • 高階関数

  • 無名関数と多重関数

  • 等式関数

純粋関数

純粋関数 (状態不変関数) を定義するには、 オリジナルデータを参照渡しで関数に与えて処理するのではなく、 変数 (リストとオブジェクト) の値を代入演算子で新しい変数にコピーします。

用例:

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               # 新しいリストを返します。

実行結果:

aList
1
2
3
4
5
aList2
1
4
9
16
25

第一級関数

Ring の関数は第一級オブジェクトです。関数を仮引数として渡したり、 変数として代入、または値を返せます。

例えば、関数名を "関数名" や :関数名 のようにリテラルにすると関数を渡したり返せます。

関数名を代入した変数は関数に渡したり、返値として返せます。

Call 命令は関数名を代入した変数から関数を呼び出します。

文法:

[関数の返値を代入するための変数] = Call 変数名([仮引数])

用例:

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

実行結果:

before test2()
Message from test!
Message from test2!
after test2()
Message from test!

高階関数

高階関数は関数を仮引数として扱えます。

用例:

Func Main
        times(5,:test)

Func Test
        see "test 関数のメッセージ!" + nl

Func Times nCount,F

        for x = 1 to nCount
                Call F()
        next

実行結果:

test 関数のメッセージ!
test 関数のメッセージ!
test 関数のメッセージ!
test 関数のメッセージ!
test 関数のメッセージ!

無名関数と多重関数

無名関数は、固有名のない関数です。ほかの関数へ仮引数として渡したり、変数へ代入できます。

文法:

Func [仮引数] { [ステートメント] }

用例:

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()

実行結果:

hello
Sum : 6
wow!
Message from f1
hello world
hello world
hello world

用例:

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

実行結果:

1
4
9
16
False
True
False
False
odd
even
odd
even

等式関数

if 関数 = 関数、または演算子‘=’や‘!=’ を用いずにテストできます (この機能は関数の等価性、あるいは Equality of functions とも言います)。

用例:

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

実行結果:

hello
how are you?
hello
0
0
1

参考文献