Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

関数型言語とオブジェクト指向言語(序章)

5,975 views

Published on

関数型言語とオブジェクト指向型言語について社内で勉強会を開いたときの資料です。第一回。

Published in: Software
  • Sex in your area is here: ♥♥♥ http://bit.ly/39sFWPG ♥♥♥
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Dating for everyone is here: ❶❶❶ http://bit.ly/39sFWPG ❶❶❶
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

関数型言語とオブジェクト指向言語(序章)

  1. 1. 関数型言語とオブジェクト指向言語 序章?
  2. 2. 一応、開発者向きのお話です。 開発者以外には難しいかも。 聞く人のレベルがよくわからなかったので、 「いってることがよくわからない」 「そんなことは知っている」 などとあるかもしれませんが。 ちなみにアニメもありません。 (`・ω・´)わかんなかったら質問しいや。
  3. 3. とりあえず プログラミング言語の歴史でも。。。
  4. 4. プログラミング言語 本格的にプログラミング言語が作られ始めたのは1950年代になります。 1954:FORTRAN 科学技術計算を得意分野とし、学術系大規模分野で使われます。 1958:LISP 最古であろう関数型言語です。ここから派生した言語もたくさんあります。 1959:COBOL 事務処理言語として作られ、いまでも金融機関などの大型コンピュータで 動いています。完全になくなることはないでしょう。 1964:BASIC 初心者向けの言語という思想で作られました。その後マイクロソフトがMS BASICを 1970年代につくり、いろいろなパソコンで使われることとなりました。 1966:PL/I ぴーえるわんとよみます。IBMがFORTRANとCOBOLの両方の特性を併せ持つ 言語を目指してつくったらしいです。いまでもあります。
  5. 5. プログラミング言語 1969~:SmallTalk オブジェクト指向という言葉を作った、最古の言語になります。Simulaというこれ より前のオブジェクトを持った言語と、LISPの影響を受けています。 1971~:Pascal フランスの数学者の名前をとったらしい言語です。ALGOLというさらに古い言語の 流れを汲みます。Delphi(製品名)という、昔はやりかけた開発環境ではこれに オブジェクト指向を組み合わせて、ObjectPascalという言語が作られました。 1972~:C 最も有名な言語でしょうか。もともとはUNIXというOSを作るための言語として 開発されました。いまでもあらゆるところで使われています。 1972~:Prolog 人工知能研究にかかわることの多い、論理型言語であり手続き型でもオブジェクト指 向でもなく、関数型言語に影響を与えています。
  6. 6. プログラミング言語 1983:C++ C言語にオブジェクト指向を取り入れた言語です。仕様の取り込みすぎでかなり複雑 化した言語ですが、今でも進化し続けており近年のコーディングスタイルも取り込ん でいます。 1983:Objective-C C++と同時期に同じようにCと互換性のあるオブジェクト指向言語として作られ、 のちにMacOSXの公式開発言語となりました。だれもが知っているIPhoneアプリは 基本的にこの言語で作ります。IPhone人気もあり最近人気急上昇です。 1987:Perl 昔はこれでWebアプリがよく作られました。いまでも使われ続けていますが、もう 人気はありません。 1990:Python、Haskell すべてがオブジェクトで関数型の特徴もあるPython、関数型言語として有名な Haskellがこの頃には出始めます。普及はしていません。
  7. 7. そこ、寝てないの。 (*_ _)Zzz...
  8. 8. プログラミング言語 1991:VisualBasic(VB) クライアントサーバー型システム全盛の頃、世の中にはVB技術者があふれかえるほど いました。Basicの流れを汲み、初心者にも簡単に作れることが売りの言語でした。 この当時のVBは今現在のVB.netとはまったくの別物です。 1995:Ruby スクリプト系の言語でありながら、オブジェクト指向言語として作られました。C 言語で作られた拡張ライブラリを利用できたりします。遅いイメージの強い言語です が、1.9系でJITコンパイラが導入され高速化されました。それでもまだ遅かったりし ますが、実装系によります。RubyOnRailsで有名になりました。 1995:Java Oracleに買収されたSunが作ったオブジェクト指向言語です。JVMという仮想マシ ン上で動きます。進化がとまりかけていましたがやっと、動き出しました。大規模~ 小規模、Web・バッチなんでもこなせる、技術者が多く、C言語の次に広く使われて いる言語です。
  9. 9. プログラミング言語 1995:PHP Perl、Ruby同様スクリプト系言語で、コンパイルが不要、初心者も使いやすいなど 主にWebサイト、ソーシャルゲームなど世界中で広く使われています。もともと名 前の由来が、「Personal Home Page」でもありWeb専用言語です。バージョンが あがるにつれオブジェクト指向ぽい要素も取り入れてきましたが、速度が遅い、セキ ュリティが弱い、旧バージョンにひきずられるなど、欠点も目立ちます。 1996:OCaml 関数型言語のMLにオブジェクト指向の要素を取り入れた、関数型とオブジェクト指向 の両方の特性を持つ言語ですが、関数型に位置づけられます。 1997:JavaScript Javaと名前が似ていますが、まったく違います。Javaが注目をあびていることに目 をつけて名前がつけられたという話もあります。パソコンのブラウザ上で動作し、 ホームページに動きをつける、サーバーと通信をするなどといった用途で広く使われ ています。実は何でもできるかなり柔軟なオブジェクト指向言語です。
  10. 10. プログラミング言語 1998:Erlang 関数型言語の部類に含まれますが、並行処理や分散処理、耐障害性に重点をおいて 作られています。その為、比較的大規模分散環境に特化した形となっています。 2001:C#(.NET) マイクロソフトがJavaやObjectPascalなど既存の言語のいいとこどりをしつつ作っ たオブジェクト指向言語です。昔はJavaと同じような書き方をしましたが今では バージョンも5.0となり、だいぶ別物です。逆にJava8(最新バージョン)は C#が3.0の時代から持っている機能をまねていたりします。 2002:F#(.NET) マイクロソフトがOCamlをベースに作った関数型言語ですが、オブジェクト指向言語 の特性も持っています。.NETの豊富なライブラリも利用できます。 2003:Scala JVM上で動く、オブジェクト指向言語と関数型言語の両方の特性をもつ言語です。 Javaの豊富なライブラリを使うことができ、関数型言語的な記述もでき、比較的 関数型を知らない人でも入りやすい部類の言語です。
  11. 11. ...。 まだありますが、きりがないので。 さて。関数型言語とオブジェクト指向言語はいくつあっ たでしょう?
  12. 12. こんな感じに分類できます。 関数型言語 LISP Haskell OCaml Erlang Scala F# etc... COBOL?しらね。(手続き型です) PHP?いらね。(手続き型です) オブジェクト指向型言語 SmallTalk ObjectPascal C++ Objective-C Ruby Java C#(VB.NET,C++/CLI含む) etc...
  13. 13. じゃあ、実際つかわれているのは? 現状、商用として使われるのは CやCOBOLなどの手続き型言語、 JavaやC#などのオブジェクト指向型言語、 どちらかといえば別のあつかいとなるPHP、Perl、Ruby、Pythonなどの スクリプト系言語などに分類されます。 PythonやRubyは一応オブジェクト指向、PHPはなんちゃってオブジェクト 指向(もともと手続き型言語) そもそも、人がコンピュータにあれしてこれして、という命令をすること自体 が、一連の手続きなのです。 オブジェクト指向といっても、メソッドの中身は手続き型の書き方(処理を上 から順番に実行していく)の集まりになります。
  14. 14. あれ? 関数型は? |/// |・ω・)ノ
  15. 15. 一部では使われています。 たとえばScala。 ・Twitterの後ろのシステム ・パテントビューロのastamuse (知的財産・技術情報のデータベースWebシステム) たとえばF#。 ・証券システムのデリバティブ取引(高速計算ロジック・アルゴリズム) ・さまざまなジャンルの格付けエンジン(アルゴリズム) たとえばOCaml。 ・金融向けアプリケーション ・XenServerのツール群
  16. 16. つまり。 関数型言語は、一般的な業務システムやらWebサイト・コンテンツなどに 向いている言語ではなく、「ニッチな専門分野に向いている言語」 ということになります。 関数型言語も昔からあります。 なのになぜ普及していないか。 なぜ普及しないのか。 一部で普及はしています。ただ、分野が違うということです。 関数型言語の得意分野はもともと「定理の証明」や「数学の難題を解く」など といった分野で効力を発揮します。
  17. 17. 2014年5月時点の言語別検索ランキング(TIOBE調査)
  18. 18. 関数型とオブ(略)の特徴 ざっくりと。
  19. 19. オブジェクト指向言語(1) オブジェクトと呼ばれる機能の集まりの部品を使ってプログラムを構成します。 オブジェクトはカプセル化という隠蔽工作がされていて、使う人は中身を知らなくても いいようになっています。 例えば、車のエンジンをかける人はキーを入れて回すとか、ボタンを押すとかで エンジンがかかります。エンジンにライターで自分で点火するわけじゃありません。 エンジンの仕組みを知っているわけでもありません。 それぞれのオブジェクトは自分自身の振る舞い(どういう動きをするか)をメソッド として持っています。オブジェクトは「キーを入れてまわす」メソッドを呼ばれたら、 自分で「エンジンをかける」メソッドを呼び出すなどして処理を行います。 「エンジンをかける振る舞い(メソッド)」 「走る振る舞い(メソッド)」 「止まる振る舞い(メソッド)」など。
  20. 20. オブジェクト指向言語(1) 例えば、キーをまわすメソッドが公開されていて、引数が車のキーで、エンジンをかけるメソッド が非公開だったら。(Javaのばあい) public class Car { private static final String KEY_NUMBER = 1111; public String toggleKey(String key) { if (key != null && KEY_NUMBER.equals(key)){ int result = startEngine(); if (result == 0) { return "エンジンかかった!"; }else{ return "エンジンかかんないよ。。。"; } } return "キーちがうよ"; } private int startEngine(){ // エンジンをかける処理 } }
  21. 21. オブジェクト指向言語(2) そして車の操作でハンドルやアクセル、ブレーキを使うのはトヨタだろうが日産だろ うが同じです。 これをオブジェクト指向では「インターフェース」のメソッドで表現します。 車のメーカーによって操作の仕方が違ったら困りますよね。 オブジェクト指向言語のインタフェースも同じで、 インタフェースを実装したオブジェクトは使う側が意識しなくても 同じ使い方ができるわけです。 ハンドルがなかったりアクセルがなかったり ブレーキがなかったりしたら 運転の仕方がわかりませんよね。
  22. 22. オブジェクト指向言語(2) 例えば、キーをまわすメソッド、アクセルを踏むメソッド、ブレーキを踏むメソッドを定義したい 場合、インターフェースで表現できます。(Javaの場合) public interface ICar { // 車インタフェース void toggleKey(String key); void pressAcceleratorPedal(); void pressBrakePedal(); } public class ToyotaCar implements ICar { // トヨタ車クラスは車インタフェースを実装します public void toggleKey(String key) { startEngine(); } public void pressAcceleratorPedal() { run(); } public void pressBrakePedal() { stop(); } } public class NissanCar implements ICar ~でも中身をおなじように書いたとして。
  23. 23. オブジェクト指向言語(3) ICar toyota86 = new ToyotaCar(); //トヨタ車クラスの86インスタンス(オブジェクト)を作ります。 toyota86.toggleKey("1234"); // startEngine()が実行され、エンジンがかかります。 toyota86.pressAcceleratorPedal() // run()が実行され、車が走ります。 ICar fairLadyZ32 = new NissanCar(); //日産車クラスのZ32インスタンス(オブジェクト)を作ります。 fairLadyZ32.toggleKey("1234"); // startEngine()が実行され、エンジンがかかります。 fairLadyZ32.pressAcceleratorPedal() // run()が実行され、車が走ります ICarは車インタフェースなので、操作方法だけを定義します。 その中身はトヨタも日産もホンダも、みんな独自に作っていて、構造も違うわけですが、 運転する人はそんなことは知らなくてもどの車も運転できます。 ハンドルやアクセル、ブレーキなどの操作方法が同じだからです。 「インタフェース」はなぜ必要なのか、それは使っていくうちにわかっていくと思います。
  24. 24. オブジェクト指向言語(4) クラス、継承、オーバーライド、ポリモーフィズム、オブジェクト指向ならではの いろいろな言語機能の要素があります。 話がながくなるので、 詳細な説明が必要であれば、別途機会を設けます。。。 めんどくさいわけではありません! つぎ、関数型いきます!
  25. 25. 関数型言語(1) ・関数型言語で言う「関数」とは、ほかの言語で言うメソッド、ファンクション、 C言語の関数とは違います。 ・関数型言語で言う「関数」とは、数学における関数とおなじような意味であり、 f(x) = x + 2 のような式、あるいは関数を意味します。 ・関数型言語はラムダ計算の概念を使ってプログラムを記述します。 ラムダ式による表現では上記の式を、 λ x, x + 2 と表現します。これは引数をxとし、x+2の計算を行うという表記になります。 ・関数は値であり、関数型言語では同列に扱います。つまり関数は変数に代入でき、 ・関数の引数として関数を渡す ・関数の戻り値として関数を返す といった使い方をします。 また、このような関数のことを、高階関数と呼びます。
  26. 26. 関数型言語(2) ・関数型言語では、副作用のないプログラミングを基本とします。 「副作用のない」とは、たとえば f(x) = x + 2 この関数を使うとして、f(2) は常に結果が4になります。 つまりどういうことかというと、 「同じ値を引数で渡した場合には必ず同じ結果が返る」 ということです。 ・たとえば、データベースにアクセスするメソッドがあったとして、同じ条件でデータ ベースからレコードを検索して取得するメソッドの結果はそのときのデータベースの 状態によって変わります。 C言語の関数mallocなどにしても、確保されるメモリアドレスの値は毎回変わります。 これを、「副作用がある」状態といいます。 ・関数型では副作用のない関数を細かい粒度で作成し、それらを組み合わせてプログラ ムを作っていきます。
  27. 27. 関数型言語(3) 関数型言語では、副作用のないプログラミングをするというのは前述のとおり。 これは関数だけでなく、変数にも当てはまります。 変数も、一度設定したら後から変更はできないということです。 当然、グローバル変数なども使いません。 これらの特長により、 ・関数呼び出しの結果が引数のみに依存する ・関数呼び出しがほかの機能の動作に影響を与えない この副作用がない関数や式の状態を、「参照透過性(参照透明性)」といいます。 ですが、はたして「副作用のない」処理がどれだけあるのでしょう。 プログラムを作ったことのある人は自分のソースコードを見てみてください。 おそらく副作用だらけだと思います。
  28. 28. じゃあ、 関数型はやっぱりつかえない? (´・ω・`)ショボーン
  29. 29. 副作用がないメリット 参照透過性は以下のメリットをもたらします。 1)並列実行が可能 同じ値を渡せば同じ結果が返り、外部要素の状態によらないため、 複数の細かい処理に分けて同時に実行しても、結果が変わりません。 つまり、並列実行が可能ということです。 これは近年増えてきたマルチコアCPUを効率的に利用できることを意味します。 当然、分散コンピューティングにも適しています。 ※並列:複数のCPU(コア)で別々の処理を同時に行うこと。 並行:1つのCPU(コア)で複数の処理を一定時間毎に切り替えながら 同時に実行しているように見せる、擬似並列処理。普通のスレッドはこちら。 2)遅延評価・実行が可能 いつ実行しても結果が変わらないため、結果が必要な時点で初めて実行する など、遅らせて実行することが可能です。(待ち時間がなくなります)
  30. 30. ハードウェアの話 パソコンでもスマホでも、CPU(中央演算処理装置)というものがのっかってます。 人間で言えば、頭脳にあたる機械です。 最近はスマホでもデュアルコア(コア2つ) とか、クアッドコア(コア4つ)とか でてます。これは、1つのCPUの中に 複数のCPUが入っているということです。 昔はCPUの動作する周波数(クロック周波数)をあげ、使っているトランジスタの数を増 やしていくだけでも性能が上がっていきました。 昔僕が使っていたパソコンのCPUは16MHzでした。今じゃ2GHz、3GHzは普通。 2GHzは2048MHzですから、128倍。 なぜ複数のコアがのるようになったかといえば、それだけでは処理速度が上げられなくなっ たからです。
  31. 31. ハードウェアの話 本来はCMOS回路の0と1を切り替える時にだけエネルギー、つまり電気を 消費するのですが、それ以外にリーク電流での電力消費が無視できない規模に なってしまっていました。 クロック周波数をあげ、トランジスタの数を増やしていくと、処理速度も上がり ますが消費電力も増大していきます。 多数のトランジスタを限られたスペースに詰め込むために、回路を微細化しすぎ て絶縁体の壁が薄くなると、それをすり抜ける電子(リーク電流)が増えすぎて しまいその結果、消費電力がさらに上がりすぎて、高熱や誤動作の原因にもなり、 頭打ちになってしまったということです。
  32. 32. 意味不明ですね。 (´・ω・`)ショボーン まあ、あまり気にしないでください。興味のある人は CPU、リーク電流、半導体、トンネル効果なんかでググってください。
  33. 33. マルチプロセッサとマルチコア さて。処理速度UPができなくなりました。 この問題を解決するためにいろいろな改善策が とられ、複数のCPUをのせて、作業を分担する ようにしました。 4人でやれば早く終わるよね、って感じ。 サーバー用のXeon(ジーオン)というCPUだ とハイエンドクラスではマルチプロセッサ+マ ルチコアの構成になっています。 でも、何も考えずに作ったプログラムはコアが 4つあっても1つしか使われません。 3人は遊んでいるわけですよ。
  34. 34. だから? (ヾ(´・ω・`)ネェネェ
  35. 35. 関数型言語は並列化しやすい 参照透過性に以下のメリットがあることは前述のとおり。 1)並列実行が可能 2)遅延評価・実行が可能 これらの特長により、複数CPU(コア)を使った並列処理が実行しやすくな ります。言語レベルで分散化・処理速度の向上、CPUの有効活用がしやすい ということです。 所詮、スレッドを使ったところで、タイムスライスでしかないので1つしか CPUが使われません。(タイムスライスというのは時間を10~20ns間隔程 度に区切って複数の処理を1つのCPUで切り替えながら行うこと)
  36. 36. 関数型言語は並列化しやすい 関数型言語が見直されてきているのは、ハードウェアの環境が関数型の特性に 向いてきたからでもあります。 また、GoogleやHadoopのようなMapReduce(大量データ集計処理)も、 もともとは関数型言語が起源になります。つまりはそういうことです。 ※Map:集合に対して処理を行い集合を返す。 Reduce:Mapの結果集合に処理を行い、その結果を返す(合計値など)
  37. 37. ただし。 オブジェクト指向型言語ではマルチコアが生かせないのか? 並列化できないのか?というと、 そんなことはありません。 C++などはOpenMPやTBB(インテル スレッディング ビルディング ブロック)など もあるし、C#などにもTaskやらParallel.ForやらPLINQやら、マルチコアを生かせる 機能はいろいろあります。Javaもバージョン8からC#と同じようなことがやっとでき るようになりました。 また、オブジェクト指向型言語も関数型の利点を取り入れてきています。 PHP?もちろんできません。
  38. 38. そんなわけで 次回は関数型の特徴の1つでもある ラムダ式について オブジェクト指向言語もあわせて 説明します。
  39. 39. ご清聴ありがとうございました。

×