分123この章では,命令プログラミングと関数プログラミングのパラダイムの違いを理解するために,簡単な計算問題を取り上げます。命令プログラミングと関数プログラミング当たり前過ぎて意識されていないかもしれませんが,改めて命令プログラミングのパラダイム(以下「命令型」と略記)を説明すると,次のようになります。命令を列挙する(典型的には命令である文をセミコロンで区切って並べる)状態がある(状態とは再代入可能な変数のこと)再代入を使って状態を変化させる一方,関数プログラミングのパラダイム(以下「関数型」と略記)は次のようになります。関数を引数に適用する状態はない(値を破壊したくなったら)新たな値を作る状態がないので,変数の値は変わりません。これが関数プログラミングを永続データプログラミングと定義した理由です。関数型で本当に問題が解けるのか疑問だと思います。これから簡単な計算問題を使って,両パラダイムの違いを浮き彫りにします。次のような問題を解く関数calcを定義することを考えます。入力として整数の配列あるいはリストが与えられる(たとえば[10,20,30,40,50])0から数えてn番目の要素にはnを掛けるそれらすべてを足し合わせて出力として返すつまり,次のような計算をします。命令プログラマであれば,この問題をfor文か類似のループで解くでしょう。実際にJavaScriptで関数calcを書いてみます。for文を使うと,次のように実装できます。ret;}このcalcは,命令型の特徴を備えています。セミコロンで区切って命令を列挙している状態retとiがあるretとiはループが回るたびに再代入されている実際に動かしてみましょう。次のコードはRhinoを使い,入力として配列[10,20,30,40,50]を与える例です。calc([10,20,30,40,50]);400正しい答え400が出てきました。命令プログラマであれば,これとはまったく異なる解決方法があるとは想像もできないかもしれません。このプログラムは十分に簡潔で,これ以上分割はできないと思うでしょう。関数プログラマから見ると,この関数は仕事のやり過ぎに見えます。Crockford氏のエッセイをよく読んでいました。エッセイの一つに「JavaScript:世界で最も誤解されたプログラミング言語」があります。このエッセイで筆者が衝撃を受けたのは,「⁠不格好なforステートメント」という言葉でした。この疑問は,関数プログラミングを習得することでようやく氷解しました。関数プログラミングでは,MapReduceという方法で解きます。MapReduceと言うと,Googleの分散処理フレームワークが有名ですが,このシステムのアイデアの根源は関数型のmapとreduceを使う手法です。対話環境でMapReduceを試してみましょう。リストをまとめるHaskellでは,リストのリテラルが用意されており,角括弧の中に要素をカンマで区切って書きます。同じ表記がJavaScriptでは配列でしたが,Haskellではリストを意味します。整数のリストのリテラルを評価してみましょう(プロンプトPrelude>は>と略記します⁠)⁠。[10,20,30,40,50][10,20,30,40,50]整数のリストそのものが返ってきました。次に,このリストの要素と掛け合わせるカウンタを用意しなくてはいけません。Haskellでは,[はじめ..おわり]と書くと,値を増やしながら列挙してくれます。[0..4][0,1,2,3,4]リストが2つあると扱いづらいので,常套手段である関数zipで1つにまとめましょう。Haskellでは,関数を呼び出す際に,関数のあとの引数を丸括弧で囲む必要はありません。引数はカンマではなく,空白で区切って列挙します。[10,20,30,40,50][(0,10),(1,20),(2,30),(3,40),(4,50)]リストが1つ新たに生成されました。この要素は(0,10)のように,カウンタと整数の組になっています。このように表記される組は,無名の構造体であると理解するとよいでしょう。zipの第一引数であるリストには「おわり」が指定されていません。この場合,必要なだけ生成することを意味します。zipは,短いほうのリストに合わせて組のリストを生成しますので,実際に第一引数は第二引数の長さ分だけカウンタを生成します。あとで利用しやすいように,上記の結果にret1という名前を付けておきましょう。対話環境では,変数を定義する場合にletを使います。[10,20,30,40,50]念のため,ret1自体を評価することで,ret1の中身を調べてみましょう。ret1[(0,10),(1,20),(2,30),(3,40),(4,50)]mapを使ういよいよmapを使ってみましょう。mapとは,第一引数に関数を,第二引数にリストを取ります。その関数をリストの要素それぞれに適用します。関数を引数に取る関数は,高階関数と呼ばれるのでした。mapは,最も基本的で最も有名な高階関数です。今やりたいことは,カウンタと整数を掛け合わせることです。そこでまず,カウンタと整数の組を取り,互いを掛け合わせる関数mulを定義してみましょう。対話環境では,関数を定義する場合もletを使います(注1⁠)⁠。iこの定義には,第3章で説明するパターンマッチが使われています。今は単にこのように書くと思って進んでください。mapを使ってmulをret1の各要素に適用してみます。ret1[0,20,60,120,200]整数のリストが新たに生成されました。答えに近づいてきましたね。これにもret2という名前を付けておきましょう。i」と順番が逆なのは,zipにカウンタ[1..]を部分適用(後述)して簡潔に書くためです。開発した代表的なオープンソフトにMew,Firemacs,Mightyがある。『プログラミングHaskell』や『Haskellによる並列・並行プログラミング』の翻訳者。職場ではHaskell,家庭では3人の子供と格闘する日々を送っている。2019」を開催しました。DAY1・DAY2の様子を注目セッションとともにお伝えします。LINEのエンジニア3名がイベントに先駆けて見どころを紹介します。業務を改善する情報共有の仕掛け~DevOpsの実現,RPAの導入に向けて~ソフトウェア開発の業務改善をテーマに,DevOps実現の手順やそれを助けるツールとの連携,RPAによる社内ドキュメントの管理や効率化について解説します。若者世代から圧倒的な人気を誇るライブ配信&動画投稿コミュニティアプリ「MixChannel」(ミクチャ)の裏側(レコメンドシステムやサーバサイド開発など)について解説していきます。その他の連載CSS3アニメーションでつくるインターフェイス表現CSS3によるアニメーション表現を紹介していきます。その中でも,幅広い読者に応用してもらえるだろうインターフェイスを主なお題とします。MySQL道普請便り本連載では,MySQLを使ったアプリ開発・運用に関するノウハウをご紹介していきます。RecipeUbuntuの強力なデスクトップ機能を活用するための,いろいろなレシピをお届けします。JavaScriptセキュリティの基礎知識JavaScriptに関するセキュリティ上の問題はどこで発生し,どうすれば防ぐことができるのか?について解説していきます。〜システムをきちんと運用するための基礎知識システムは「作って終わり」ではなく,運用の中でさまざまな問題が発生します。問題の発生に備えて事前にどのような対応をしておくべきなのか,問題発生時に何をしなければならないのか,ポイントを解説していきます。きたみりゅうじの聞かせて珍プレーソフトウェア開発の現場で体験したトホホな失敗,思わずうなる珍プレーをきたみりゅうじ氏が四コママンガで紹介。Linuxのメンテナンスの傍ら,Linuxやオープンソースソフトと日々を過ごす著者が,その魅力とつきあい方を,エッセイ風味でお届けします。PRESS特別編集部員,さわやか笑顔のスーパーハカーはまちちゃんとネット大好き14歳わかばちゃんが,毎号,読者の皆さんから寄せられたおたよりを紹介します。皆さんの日頃の悩みにも答えちゃいますよ。]メールでのお知らせメールで次の案内をお送りしております。メールの配信を希望する方は,利用したい項目をチェックしてメールアドレスを入力し,[登録]ボタンをクリックしてください。UPDATES[ほぼ週間に1回]新刊メールマガジン[ほぼ週間に1回]電脳会議の各号案内[ほぼ1ヵ月半に1回]※変更する場合や停止する場合は,登録情報変更ページをご覧ください。※登録いただいたメールアドレスには,そのお知らせ以外,配信いたしません。Ltd.ページ内容の全部あるいは一部を無断で利用することを禁止します。個別にライセンスが設定されている記事等はそのライセンスに従います。