2014年4月3日木曜日

Programming in Scala, First Edition: Chapter 1

1. A Scalable Language
  scalaは"scalable language"の意味。
    拡張性を重視。
    スクリプトから大規模プログラムまで幅広く使える。
  Javaとの親和性が高い。
    Javaの資産を簡単に使える。
  オブジェクト指向+関数型プログラミング+静的型付け
    関数型で単純パーツの組み合わせで素早く作れる。
    オブジェクト指向で大規模で拡張可能に作れる。

1.1 A language that grows on you
  scalaでは言語に機能を組み込み代わりにライブラリで実現している。
  自分に合うようにライブラリを作成、改造して自由に拡張できる。
  拡張可能な型
    scalaは言語に組み込み型を用意する代わりにライブラリで実装している。
    自分に合うように自由に作成、拡張できる。
    さらに自分の型を組み込み型の様に簡素で自然に表現出来る方法を用意。
  拡張可能な制御構造
    Scala's API for "actor-based" concurrent programmingに示されている。
      並列化のためにはErlangで採用されているactorsのアプローチ必要。
        共有メモリではなくてmessage passingの疎結合モデル。
      Javaのmulti thread modelも使えるがイマイチ。
      Erlangのactorsを実装している。
      actorもloopもreceiveもsend(!)も組み込み制御構造でなくて拡張。
      Erlangは同じようなものを持っているが組み込みで拡張できない。
    scalaでは制御構造も拡張出来て組み込み型の様に扱える。

1.2 What makes Scala scalable?
  scalaの拡張性はオブジェクト指向と関数型のハイブリットから来ている。
    スカラでは関数もオブジェクトで二つの考えが統合されている。
    これが学問的な意味だけではなく実際に拡張性を高める結果となっている。
    これがないと1.1のactorsの実装は出来ない。
  scalaのオブジェクト指向
    scalaはan object-oriented language in pure form
      全ての値がオブジェクトですべての関数がメソッド。
      smalltalk以外の他の言語は例外があり、それが仕様を複雑にしている。
    scalaはtraitというJavaのinterfaceを拡張したような機能がある。
      classよりもpluggable。
      これによって多重継承、ダイヤモンド継承の問題を回避できる。
  関数型言語としてのscala
    scalaは成熟した関数型言語
    1950年代にLisp、他にScheme, SML, Erlang, Haskell, OCaml, F#等
    関数がfirst-class values
      整数や文字列と同じようなに扱うことが出来る。
        関数の引数
        関数の戻り値
        変数に保存
        関数の中で定義できる。整数を定義するのと同じように。
        名前なしの関数表記をリテラルとして使える。整数の42等と同じように。
      これが操作の抽象化や新しい制御構造の作成を容易にする。
        これが拡張性を高める。
    参照透過性
      値が変更されない。immutable
      値を変えるのではなくて、入力から出力にマッピングする。
      副作用がないとも言える。
    scalaでは関数型でも命令型でも好きなスタイルでプログラミング出来る。

1.3 Why Scala?
  Javaとの互換性
    Javaの資産がそのまま使える。VMも使える。Javaの進化の恩栄も受けられる。
    Javaに機能がある。Javaより進んでいる。
      暗黙変換等。
  少ないコード量で書ける
    scalaのコードはJavaの半分程度で済む。
      不具合が少ない。
      読みやすい。理解しやすい。
      早く作れる。
    型推論
      型の記述を省略できる。
    既存ライブラリの再利用性の高さ
      沢山の既存ライブラリを再利用してあまり作らずに多くの事が出来る。
  抽象度が高い
    プログラムの複雑さとどう戦うか?
      自分の作っているコードがどう動くのか確実把握している必要がある。
      複雑さは、要求が複雑なのだから避けられない。
      複雑さを上手く扱う必要がある。
    scalaでは抽象化レベルを上げることで複雑さへの対処を助ける。
    制御の抽象化を行うことで簡素に書ける。
      簡素に書ければ理解しやすくなり間違いが減る。
      関数リテラルを使うと簡素に書ける。
      Javaでも制御の抽象化を出来るがscala程簡素に書けない
    関数型プログラミングで(論理学的な)推論原理(reasoning principles)が使える。
      参照透過に作られている必要ある。
      関数の適用順序を変えられる。
      コードを見やすく理解しやすくrefactoring出来る。
    参照透過や不変値を使う事でaliasing問題も回避できる。
      同一のリソースを複数から参照するaliasingは可変値だと扱うのが難しい。
      特に並列化するときは重要。
      ** 排他制御やデッドロックのもとになっている。
  静的型付け
    高機能な静的型システムを持っている
      generics, intersections, abstract types
    動的vs.静的
      動的の言語: Perl, Python, Ruby, or Groovy, SmallTalk
        「静的は書くのが煩雑で柔軟性が低い」と言っているが。
      scalaの型システムは型推論と型の定義、合成方法で補っている。
      静的のメリットは検証、リファクタリング、ドキュメント化しやすい事。
    検証可能
      型システムで「ある種」の問題がないことを「保証」出来る。
        演算における型の間違いだけではあるが。
        検出できる問題は少ないが有意義ではある。
          テストとは違った観点なので両方必要。
            「ある種」のテストは省略出来る。
    リファクタリング時の修正漏れを防げる。
    注釈(annotation)はコメントと違って更新不足になることがない。
      常にコンパイラによってチェックされるため。
    高機能な型推論で型の記述を最低限に出来る。
      有用なのはコードを読む人が理解するために必要な分だけ。
      ライブラリを使うだけのクラインとコードは殆ど型記述不要。
        時々動的型付けのスクリプト言語の様に見える。
      逆にライブラリは型記述が多くなる傾向にある。
        これはライブラリとクラインとのinterfaceを決めているのだから自然な事。

1.4 Scala's roots
  scalaは既存の言語や研究の成果を組み合わせることで出来ている。
    scala独自の特徴と言うのは少ない。
    記述方法はJava, C# <- C++ <- Cの流れ。
    全てをオブジェクトと捉えるのはRuby, SmallTalk
    全てがネスト可能はAlgol, Simula, Beta, gbeta
    関数型プログラミングはML, SML, OCaml, Haskell, F#
    他にErlang, Eifell等
  拡張性を強調しているところはlswimやSmallTalkと同じ。
  新しい概念としてはtraits, abstract types, extractors等がある。
  ** いろんな言語や概念があってそれぞれを勉強したくなる。どれも素晴らしい。

1.5 Conclusion
  Javaから来た人には型システムと関数型プログラミングが難しいかもしれない。

!! 時々hapter1を読み返して「scalaの長所は何か」を再認識したい。

0 件のコメント:

コメントを投稿