HEXA BLOG

プログラム

HEXA BLOGプログラム2014.8.18

関数型プログラミングを始めてみよう ! Func.1

お久しぶりです、サッカーワールドカップも終わり
平常モードに戻ったコウスケです。

今回から、関数型プログラミングの紹介をしたいと思います。
想定する読者はプログラミングに関して最低限の知識がある方になります。

 

20131203_separater

 

なぜ関数型プログラミング?
 「悟りを開けるから」です(プログラマとして)!
 ・・というのは冗談めかしてよく言われるのですが・・
 実際どういうことなのか、悟りを開いてない私にはわかりません。
 ただ・・関数型プログラミングはめちゃくちゃ便利!
 新しい考え方が学べる!といったメリットがあります。
 
そもそも関数型プログラミングってなに?
 「関数」が主人公のプログラミングです!
 オブジェクト指向言語における「オブジェクト」でも
 手続き型言語における「手続き」でもありません。
 今回はこの部分を紹介したいと思います。
 
なぜpythonなの?
 私が使い慣れていること・・は実際の所あるのですが、
 関数型プログラミングのために作られた関数型言語でなくても、
 普段のプログラミングでもそのエッセンスを取り込むことができる
 ということを紹介したいからです。

 

 関数型プログラミングにはhakelllispなど関数型言語というものがあります。
 純粋な関数型プログラミングをするならばそういったものを使うのが最適なのですが、
 なかなか敷居が高いです。
 pythonは、普通に使えばC言語ライクで初心者にも使いやすい言語なのですが、
 関数型プログラミングのエッセンスも取り入れられている所もあります。

 

 pythonを知らない方でも、
 擬似コードっぽく読んでいけばなんとなくやっていることは
 わかると思います^^。
 興味を持ったら、公式チュートリアルなどを読んでみてください。
 

20131203_separater

 

さて、本題ですが関数型言語であるためには何が必要なのか?
・・それは、関数がファーストクラスオブジェクトであることです!

ファーストクラスオブジェクトとは、すごく簡単にいえば

 

変数に代入できる
引数や返り値として使用することのできる

 

オブジェクトのことです。
例えば、C言語などでの基本型であるintやfloat、
Javaなどオブジェクト指向言語におけるクラスは
ファーストクラスオブジェクトです。
(※ここでのオブジェクトはプログラミングにおける部品・要素的な意味で、
オブジェクト指向のオブジェクトとは異なります)。

つまり、関数型言語では関数そのものを変数に代入でき、
引数や返り値として扱えます!

このことが、プログラミングにおいてとっても便利なのです!
それもただ便利なのでなく、新たな次元での考え方をもたらしてくれます!

 

以下、関数を変数として使う例を示します。

例えば、ゲームプログラミングでの状態遷移などによく使う、
関数テーブルによる実行制御をシンプルに書けます。

 

# -*- coding: sjis -*-<br /><br />#<br /># 標準入力からコマンド入力を受け付け、<br /># それに応じて行動(関数を実行)します<br />#<br /><br />#------------------------------<br /># 実行関数<br />#------------------------------<br />def walk():<br />    print "walkを実行"<br /><br />def stop():<br />    print "stopを実行"<br /><br />def attack():<br />    print "attackを実行"<br /><br />def sleep():<br />    print "sleepを実行"<br /><br />#------------------------------<br /># メイン関数<br />#------------------------------<br />def main():<br />    # 関数テーブル<br />    command_actions = {"walk":walk, <br />                "stop":stop, <br />                "attack":attack, <br />                "sleep":sleep}<br /><br />    while(True):<br />        print "-"*10<br />        print "コマンドを入力(walk/stop/attack/sleep):",<br />        command = raw_input() # 標準入力からコマンドを取得<br />        <br />        if command_actions.has_key(command):<br />            # コマンドに応じて行動<br />            action = command_actions[command] # 関数を取得<br />            action()<br />        else:<br />            print "!! 無効なコマンドです"<br />        <br /><br />if __name__ == '__main__':<br />    main()
実行例<br />---------------------------------------------------<br />d:\work\python&gt;python test.py<br />----------<br />コマンドを入力(walk/stop/attack/sleep): walk<br />walkを実行<br />----------<br />コマンドを入力(walk/stop/attack/sleep): stop<br />stopを実行<br />----------<br />コマンドを入力(walk/stop/attack/sleep): hoge<br />!! 無効なコマンドです<br />----------<br />コマンドを入力(walk/stop/attack/sleep): sleep<br />sleepを実行<br />----------<br />コマンドを入力(walk/stop/attack/sleep):

他の例といえばGUIのボタンなどの挙動を記述するときに使う
コールバック関数でしょうか。
直接関数を代入できるのでスッキリします。

# -*- coding: sjis -*-<br /><br />#<br /># GUI表示の代わりとして標準入力を受け付け、<br /># それに応じたコールバック関数を呼び出します。<br />#<br /><br /># ダイアログを表すクラス<br />class Dialog:<br />    # コンストラクタ<br />    def __init__(self):<br />        self.okPressed = None<br />        self.cancelPressed = None<br /><br />    def show(self):<br />        while True:<br />            # GUI表示の代わりとして標準入力を受け付けます<br />            input = raw_input("ボタンを押してください(ok/cancel)") <br />            # 入力に応じて登録された関数を呼ぶ<br />            if input == 'ok':<br />                if self.okPressed:<br />                    self.okPressed()<br />            elif input == 'cancel':<br />                if self.cancelPressed:<br />                    self.cancelPressed()<br />            else:<br />                print "無効な入力です"<br />    <br />#------------------------------<br /># コールバック登録関数<br />#------------------------------<br />def myOkPressed():<br />    print "OKが押されました"<br /><br />def myCancelPressed():<br />    print "キャンセルが押されました"<br /><br />#------------------------------<br /># メイン関数<br />#------------------------------<br />def main():<br />    # ダイアログを作成<br />    d = Dialog()<br />    # ボタン押下に対してコールバック関数を登録<br />    d.okPressed = myOkPressed<br />    d.cancelPressed = myCancelPressed<br />    # 表示<br />    d.show()<br /><br />if __name__ == '__main__':<br />    main()<br />

今回のまとめ
・関数型プログラミングで悟りが開ける!
・関数型プログラミングは関数が主人公だ。
・関数型言語では、関数をファーストクラスオブジェクトとして使用できる。

次回は関数を引数や返り値として取れることの便利さを
説明したいと思います。

数回に分けてネタが続く限り続けていきたいと思います
のでお楽しみに!

 

RECRUIT

大阪・東京共にスタッフを募集しています。
特にキャリア採用のプログラマー・アーティストに興味がある方は下のボタンをクリックしてください

RECRUIT SITE