第17回scala勉強会

プログラミング楽しいですねヽ(´ー`)ノ
第17回の勉強会が内容濃くて楽しかったのに、ustreamの配信ができなかったので、記録残しておきます。ust期待してた人はすいませんでした(´・ω・`)


ちょっと前にblogにも書きましたが、scalaでのSTM(software transactional memory)についてやりました。

で、

  • スライド用意してない
  • じゃあust用のパソコンにscalaとscalaSTM入れて動かしてデモしたいよね
  • けどインストールできないまま、数十分経過・・・
  • もうしょうがないからustなしで始めるかぁ・・・

っていう流れでなしになりましたすいません(´・ω・`)

前半の1時間20分くらい(?)は、scalaのSTMのサイトのサンプルのこのページと、このソースを、みんなで読んだり、実際に動かしてみました(・∀・)

scalaのSTM

ここの解説にあるように、この問題自体は結構有名だと思います。
5人が丸いテーブルに座っていて、それぞれ、食事が5つ、フォークが5つあって、食べるのにはフォークが2つ必要っていう話
wikipediaさんにあった説明の図↓

普通に放置するとデッドロックになるのでそれをどう防ぐか?っていうことで、wikipediaには数種類の解法と、実際のコード例が載ってます。

で、これをscalaのSTM使って解いてみるとどうなるのか!?(・∀・)

sampleのコードに自分でコメント入れたもの↓

    atomic { implicit txn => //このatmicというのが、おそらく関数をとる関数(?)
      if (left.inUse() || right.inUse())  //2つのフォークが使われてないか調べる
        retry // 使われてたらリトライ(?)
      left.inUse() = true // 左のフォークもつ
      right.inUse() = true // 右のフォークもつ
    }

このatmicというのが、STMのライブラリの関数です。(現状stmのpackage objectに定義されてるみたいですね)

scalaのSTM使うと、このatmicブロックで囲った部分での処理が必ず実行されるか、実行されないかのどちらかの状態にしかならないことが保証されるというものです。*1
database勉強してるとよく出て来る言葉で、ACIDという言葉がありますが、このAが、atmicブロック*2で囲った部分で実現できるというわけです。
例えばSTM使わずに、普通に以下のように書いただけでは

      if (left.inUse() || right.inUse())  //2つのフォークが使われてないか調べる
        retry // 使われてたらリトライ(?)
      //この間に他のスレッドにフォークの所有権を取得されてしまう可能性がある
      left.inUse() = true // 左のフォークもつ
      //同じくここでも
      right.inUse() = true // 右のフォークもつ

一度フォークが使われてないことを調べても、調べた後から実際に自分が取得するまでのちょっとの間*3に他のスレッドに取得されてしまう可能性があるわけです。

まぁ実際どういう場面で使うといいのか?とかパフォーマンスはどうなのか?とかまで考えるといろいろ難しい*4ですが、しかし選択肢としてこういうものがあるっていうのは素晴らしいですね。しかも前にも書きましたが、すべてライブラリとして実現されていて*5、しかもその実装を(ソースコードは変更せずに )切り替えられるようになるらしい*6っていうのは、結構大きな特徴ですね。

その次の話題↓

Scala Advent Calendar

みなさんScala Advent Calendar知ってますか?知ってますよね?Advent Calendar自体の説明はここ読んでもらうとして、先週に引き続き、1週間分のadvent calendarを読んでみよう(・∀・)というのが残りの数十分で行われました。

結論から言うと、みんなの内容が濃い*7 かつ 途中でscalaでの限定継続の話が盛り上がって、最後まで読み終わりませんでした(´・ω・`)

メモとか

ん〜継続の話も濃すぎたし、色々書きたいけど、書ききれないので、あとで追記 or 別エントリで書こうかなぁ

勉強会中に出た話題、調べてblogに書きたいこと、懇親会で話したこと のメモ↓

  • sampleのソースで、Array.tabulateって使われてたけど、使い方これであってるの?他のでもよくね?オーバーロードされてるけど、本当はどういうとき使うものなの?
  • okomokさんあどべ にでてきてる@suspendableアノテーションってなんだっけ?
  • okomokさんのコードとそれの感想をもとに書いたcooldaemonさんのblogとか(勉強会中に本人に解説してもらた(・∀・) )
  • okomokさんのコード自体は、継続の本来のつかいかたじゃないのか?
  • というかそもそも継続ってどういうとき使うと便利なの?
  • で、scalaでの限定継続って、どうやって実装されてんの?
  • stm自体のソースコードも読んでみたいよね
  • stmのソース中に出てくる、プリミティブ型に対しての重複している、DRYじゃないコードはどうにかならんのか・・・
  • actorとstm組み合わせて使うとか、stmと継続組み合わせてつかうとかするとさらに便利だったりする?そいうときのパターンってないのかなぁ?


あと、実際のSTMのsampleソースの実行結果を一部*8載せておきます。

  • 誰がいつフォークをとっているのか?
  • 現在のそれぞれの人の食べた進捗具合

がわかるようになってます。

fork 0 is owned by Some(Aristotle)
fork 1 is owned by Some(Aristotle)
fork 2 is owned by None
fork 3 is owned by None
fork 4 is owned by None
Aristotle is  0.13% done
Hippocrates is  0.01% done
Plato is  0.14% done
Pythagoras is  0.09% done
Socrates is  0.01% done

fork 0 is owned by Some(Socrates)
fork 1 is owned by None
fork 2 is owned by None
fork 3 is owned by None
fork 4 is owned by Some(Socrates)
Aristotle is  0.32% done
Hippocrates is  0.17% done
Plato is  0.30% done
Pythagoras is  0.28% done
Socrates is  0.22% done

fork 0 is owned by None
fork 1 is owned by None
fork 2 is owned by None
fork 3 is owned by Some(Pythagoras)
fork 4 is owned by Some(Pythagoras)
Aristotle is  1.90% done
Hippocrates is  0.35% done
Plato is  0.95% done
Pythagoras is  1.56% done
Socrates is  0.53% done

fork 0 is owned by None
fork 1 is owned by None
fork 2 is owned by None
fork 3 is owned by Some(Pythagoras)
fork 4 is owned by Some(Pythagoras)
Aristotle is 26.52% done
Hippocrates is  4.42% done
Plato is  0.95% done
Pythagoras is 30.26% done
Socrates is  1.78% done

fork 0 is owned by None
fork 1 is owned by Some(Hippocrates)
fork 2 is owned by Some(Hippocrates)
fork 3 is owned by Some(Pythagoras)
fork 4 is owned by Some(Pythagoras)
Aristotle is 36.97% done
Hippocrates is 10.92% done
Plato is 12.39% done
Pythagoras is 35.85% done
Socrates is 11.96% done

fork 0 is owned by None
fork 1 is owned by None
fork 2 is owned by Some(Plato)
fork 3 is owned by Some(Plato)
fork 4 is owned by None
Aristotle is 41.94% done
Hippocrates is 19.78% done
Plato is 18.96% done
Pythagoras is 45.75% done
Socrates is 28.96% done

fork 0 is owned by Some(Socrates)
fork 1 is owned by None
fork 2 is owned by Some(Plato)
fork 3 is owned by Some(Plato)
fork 4 is owned by Some(Socrates)
Aristotle is 68.19% done
Hippocrates is 26.67% done
Plato is 33.65% done
Pythagoras is 65.27% done
Socrates is 38.56% done

fork 0 is owned by Some(Socrates)
fork 1 is owned by None
fork 2 is owned by Some(Plato)
fork 3 is owned by Some(Plato)
fork 4 is owned by Some(Socrates)
Aristotle is 75.96% done
Hippocrates is 30.66% done
Plato is 45.09% done
Pythagoras is 71.65% done
Socrates is 48.12% done

fork 0 is owned by Some(Socrates)
fork 1 is owned by None
fork 2 is owned by None
fork 3 is owned by None
fork 4 is owned by Some(Socrates)
Aristotle is 83.99% done
Hippocrates is 35.62% done
Plato is 51.89% done
Pythagoras is 78.69% done
Socrates is 56.67% done

fork 0 is owned by None
fork 1 is owned by None
fork 2 is owned by None
fork 3 is owned by None
fork 4 is owned by None
Aristotle is 86.91% done
Hippocrates is 37.85% done
Plato is 58.26% done
Pythagoras is 81.23% done
Socrates is 61.13% done

fork 0 is owned by None
fork 1 is owned by Some(Hippocrates)
fork 2 is owned by Some(Hippocrates)
fork 3 is owned by Some(Pythagoras)
fork 4 is owned by Some(Pythagoras)
Aristotle is 91.02% done
Hippocrates is 43.15% done
Plato is 66.09% done
Pythagoras is 85.37% done
Socrates is 71.29% done

fork 0 is owned by Some(Aristotle)
fork 1 is owned by Some(Aristotle)
fork 2 is owned by Some(Plato)
fork 3 is owned by Some(Plato)
fork 4 is owned by None
Aristotle is 99.46% done
Hippocrates is 48.48% done
Plato is 74.33% done
Pythagoras is 92.28% done
Socrates is 79.13% done

fork 0 is owned by Some(Socrates)
fork 1 is owned by None
fork 2 is owned by Some(Plato)
fork 3 is owned by Some(Plato)
fork 4 is owned by Some(Socrates)
Aristotle is 100.00% done
Hippocrates is 56.02% done
Plato is 80.37% done
Pythagoras is 97.16% done
Socrates is 88.83% done

fork 0 is owned by None
fork 1 is owned by None
fork 2 is owned by None
fork 3 is owned by None
fork 4 is owned by None
Aristotle is 100.00% done
Hippocrates is 66.35% done
Plato is 90.02% done
Pythagoras is 100.00% done
Socrates is 100.00% done

fork 0 is owned by None
fork 1 is owned by None
fork 2 is owned by None
fork 3 is owned by None
fork 4 is owned by None
Aristotle is 100.00% done
Hippocrates is 75.73% done
Plato is 97.34% done
Pythagoras is 100.00% done
Socrates is 100.00% done

fork 0 is owned by None
fork 1 is owned by None
fork 2 is owned by None
fork 3 is owned by None
fork 4 is owned by None
Aristotle is 100.00% done
Hippocrates is 99.82% done
Plato is 100.00% done
Pythagoras is 100.00% done
Socrates is 100.00% done

fork 0 is owned by None
fork 1 is owned by None
fork 2 is owned by None
fork 3 is owned by None
fork 4 is owned by None
Aristotle is 100.00% done
Hippocrates is 100.00% done
Plato is 100.00% done
Pythagoras is 100.00% done
Socrates is 100.00% done

16.4 usec/meal

*1: Refというもので包んだデータについてのみです。cooldaemonさんいわく、これ結局モナドらしい( ゚д゚ )

*2:正確には関数をとる関数?いやメソッド?

*3:上記のコメントいれた場所

*4: っていうか自分もわからん(´・ω・`)

*5:新しい構文が導入されるのではないということ。結局ただのclassやmethodっていうこと。継続はコンパイラプラグインだけど、STMは純粋にライブラリ

*6: この認識であってるよね?

*7: これはいい意味で予想を裏切ってて素晴らしいヽ(´ー`)ノだれも5分で書いてる人いないだろっていうw

*8: sampleコードは3回同じこと実行してるけど、その中の一回分(全員が食べ終わるまで)