kmizuの日記

プログラミングや形式言語に関係のあることを書いたり書かなかったり。

Kyoto.Mokumoku Vol.1開催しました

 新型コロナ禍による自粛もだいぶ緩和されてきた昨今、リモートワーク続きで人と会えてないなあ……などと思いながらいつものように三条通りを散歩していた時でした。

 副業のプログラミング教育でTypeScriptを教えている 荘子万能さんにばったりローソンに遭遇。後ろから「水島さん?」と声をかけられて、ビクンと振り返るとそこには何度もお会いした見慣れた顔があったのでした。それをきっかけに、荘子さんの会社であるBonBon株式会社のオフィスが自宅から徒歩10分くらいの古民家にあることが判明。

 オフィスを案内してもらった後に、荘子さんから「せっかくですし、会社のオフィスを使って何かイベントやりません?」というお誘いがあり、それならもくもく会とか良いんじゃないでしょうかと私が提案して、もくもく会の開催が決まったのでした。そういういい加減にも程がある経緯で開催することになったのが、

kyoto-mokumoku.connpass.com

 でした。そのKyoto.Mokumoku Vol.1 が昨夜、京都市内のBonBon株式会社のオフィスで行われました。

 参加者は(敬称略)総勢9名。経緯が経緯だけに何名くらい参加してくれるか少々不安でしたが、予想以上の参加者数でした。

 当日は、20分前に私が会場に到着して荘子さんと相談しながら会場設営。リモート参加の方のための準備をすっかり忘れていたため、ちょっとヒヤヒヤでしたが19:20にはなんとか開始できる状態が整いました。

 最初はせっかく京都に集まったのだからということで全員で軽く自己紹介。驚いたのが、プログラミング言語関係の人(研究者含む)の参加者が数名おられたことですね。おかげで、もくもく会開催中は、秋津早苗さんが作っておられる篩型付き自作言語の話を聞いたり、私が構文解析について語ったり、RyosukeKojimaさんがProlog機械学習の話について語ったりと妙な盛り上がり(?)を見せました。

 21時過ぎにもくもく会はいったんお開きで、懇親会は二条駅近くの鳥貴族。二テーブルに別れて色々なことを話したのですが、私も含めて対面に飢えている(?)部分もあるのか、かなり盛り上がりました。

 会場を提供してくださった荘子さん、それと参加者の皆様、ありがとうございました!

 来月以降も引き続きKyoto.Mokumokuは開催していきたいと思いますので、よろしくお願いします。次回は7/27(水)19:00頃の予定です。詳細が決まりましたらconnpassで告知する予定です。

Play Frameworkに寄付始めました

 こういうのは個人でやるなら黙ってやる方がカッケーみたいな美学がないこともないですが、私のブログでも多少なりとも見てくれている人がいて、それをきっかけに支援したいプロジェクトに寄付をするきっかけにもなるかなと思い、あえて書いてみることにしました。

 元々のきっかけは上記ツイートでした。Play FrameworkがLightbendの手を離れてコミュニティベースのメンテナンスになることは私も知っていたのですが、Play Frameworkには色々な意味でお世話になっているのでこの機会に何か恩返しくらいは出来ないかなと、$5.00 USD / monthでサポートすることにしました。

 最近は寄付を募るにもするにも、open collectiveという支援しやすい環境が整って来たのはだいぶいい感じですね。今までも支援したいけどどう支援していいかわからなかった人も多いと思うので、別にPlay Frameworkでなくとも、何か自分が推しのOSSがあって、直接プロジェクトには関われないけど支援したいと思うのなら、別に継続でなく、単発でもやってみるのはありなのではないかなと感じる今日この頃です。

 なお、支援の元手は私が個人事業主(屋号はParsing Technologies)としてやっているプログラミング教育とかでいただいている報酬だったりします。

 ところで、幸福の研究で「自分は誰かにいいことをしてあげられた」と思えた時の方が幸福感が増すというのを読んだことがある(要出典)のですが、実際のところたぶん正しいんだろうなあと実感しています。 元々Scalaに関わり始めた動機もそういうものだったので、気質の問題というのもあるのかもしれませんが。

 欧米(主語でか)の大富豪がよく慈善事業をしたがるのも、社会からの要請や税制面での問題だけでなく、ひょっとしたら慈善事業しないと落ち着かないとかいうことも一因としてはあるのかもなーとか思ったり。

「第一回プログラミング教育について話し合う会」を3/25(金)に開催します

 Twitter@kmizuアカウントでも多少宣伝しましたが、こちらの方でも改めて。趣旨は

opt.connpass.com

に書いてある通りですが、お堅いことを言わずにプログラミングを教える、教えられる側の知見を持ち寄ることで楽しい集まりに出来ればと思っています。参加者は技術者でなくても良くて、たとえば「プログラミング」を教えることになりそうだけど、どうすればいいのかわからないという小学校/中学校/高校の先生方でもウェルカムです。あるいは「プログラミング」を今まさに学んでいるけども、教え方にピンと来ないという側(学生でも社会人でも)の参加も歓迎したいです。現状ではどちらかというと「教える側」のためのイベントになりそうな気はしますが、たとえば懇親会で教える側、教えられる側の交流が持てれば面白いことになりそうだとも思っています。

 私的な目玉はアベ先生による、普段あまり知られていない小学校でのプログラミング教育の実態のお話です。小学校でのプログラミング教育の実態についてはまだまだ知らないので、どのようなお話がうかがえるのかとても楽しみにしています。

 また、その他にもDDD等で有名な増田 亨さんきしだなおきさんなど,色々な方が発表やLTをしてくださる予定です。今後は賛否両論あれどプログラミング教育が一般的になっていくのは間違いありません。その過渡期にある現在、それぞれの視点を持ち寄ってみませんか?

 発表枠は埋まっていますが参加枠はまだまだあるので、がんがん宣伝していただけると嬉しいです。

書籍のサンプルコードと違う言語で写経することの意義

 こんばんは、みずしまです。最近は主に強化学習の勉強をしているのですが、読み進めていく過程で少し悩みの種がありました。それは、サンプルコードの扱いです。サンプルコードはPythonで書かれていて、実際に書き写すことが私にとって理解の助けになるのは確かなように思えましたが、一方で過去の経験から、そのまま写経すると「スルスルと動いてしまってフィードバックとして不十分そうだな」と感じたので、Scalaで書いてみることにしました。

 別にScalaでなくて、JavaでもRubyでもあるいはJuliaでも良かったのですがそれはともかくとして、元のサンプルコードと違う言語で書くことで得られる利点も結構あるものだなというのが正直に感じた点です。たとえば、np.mean(...)というコードが書籍では出て来るわけですが、「そういえばScalaでmeanと同じことをするにはどうしたらいいんだっけ?」と考えることになりますし、グラフをプロットするライブラリでいいのあったっけ……と考えたところから、Plotyを見つけることにもつながりました。

 Scalaは典型的なオブジェクト指向言語でもあるため、サンプルコードをScalaに移すのはさほど難しくはありません。しかし、やはり違う言語ですから移植する時には相応に色々なことを考える必要があります。たとえば、Pythonはリストも辞書もデフォルトで可変ですがScalaではデフォルトでは不変です。なので、可変なコレクションを見つけたときには「うーん。ここは、scala.collection.mutabe.Bufferで表現すべきだろうか」とか、あるいは「varで不変コレクションを扱うべきだろうか」とか考えるわけです。

 また、ごく一部のコードを除いてPythonコードのほとんどには型注釈がついていないので「rewardsの型は明示されていないけど、文脈的にSeq[Double]が相当するな」など考えながら移植する必要があります。

 移植するにはコードの意味をより深く理解しなければならないため、単なる写経よりも理解度が深まったというのが正直な感想です。単に忠実に元のコードを書き写していただけでは(コードの意味を考えずとも動いてしまうため)このような効果は得られなかっただろうことが予測されるので、人によっては「違う言語で写経」は学習のために役立つかもしれません(既に実践している方も多いかとは思いますが)。

 あんまり生産的でないですがそんなことを感じた今日一日でした。なお、元の本はこちら

https://www.amazon.co.jp/dp/B082HNNGQG/

 です。サンプルコードの一部をScala化したのがこんな感じです。

package com.github.kmizu.scala_ml
import scala.math.random

case class CoinToss(var headProbs: Seq[Double], var maxEpisodeSteps: Int = 30) {
  private var tossCount: Int = 0

  def length: Int = headProbs.length

  def reset(): Unit = {
    tossCount = 0
  }

  def step(action: Int): (Double, Boolean) = {
    val `final`= maxEpisodeSteps - 1
    if(tossCount > `final`) {
      throw new RuntimeException(
        """The step count exceeded maximum.
          |Please reset env.""".stripMargin
      )
    }
    val done = tossCount == `final`

    if(action >= headProbs.length) {
      throw new Exception(s"The No.${action} coin doesn't exist")
    }
    val headProb = headProbs(action)
    val reward = if(random() < headProb) 1.0 else 0.0
    tossCount += 1
    (reward, done)
  }
}

 

動的型付き言語は素早くプロジェクトを立ち上げるのに向いており、静的型付き言語は長期間の保守にむいているという仮説

 :誤解されないように最初にこの記事の意図を書いておくと、古典的な静的型付き言語VS.動的型付き言語の論争をするつもりはありません。これまで色々なプロジェクトを観察(風聞も含む)して来たところ、そういう傾向があるのではないかという仮説です。それと、文脈として主にWebアプリケーション開発する時のことを想定しており、それ以外のケースはいったん脇に置いています。WebアプリケーションだとPHP(動的型付き言語)の方が圧倒的に事例多いのではという感想もありそうですが、その辺りを考え出すと話がこんがらがるので、これもいったん脇においています。

 たとえば、色々な事例を見聞きするに、スタートアップ企業において動的型付き言語であるRubyのWebアプリケーションフレームワークであるRuby on RailsRoR)は好まれる傾向にあります。近年のPythonの動向はさておき、未だにRoRの求人がかなり多いのも間違いない。で、何故だろうと考えた時に色々な人から聞くのが「とにかく最低限のアプリケーションを素早く作ることができる」ということなんですね。RoRが出た当初にあった、テンプレートエンジンとの手軽な連携というメリットが今どのくらいあるかはともかく、Webアプリケーションを立ち上げる時、ほとんどのプロジェクトはまずRDBを使うでしょうから、ActiveRecordが標準で備わっているRoRには独特の強みがあるように思います。

 そして、ActiveRecordのような、一見メソッド呼び出しに見えるものがDBアクセスになるような柔軟なライブラリを作りやすいのは、メタプログラミングが容易という部分があるにせよ、動的な型付き言語ならでは(あるいは静的な型が「ない」から)というのがあります。実際、ActiveRecordガリガリに使われたRubyコードに静的な型をつけようとしても(たとえば、Ruby 3のRBSにのっとった型注釈を使っても)かなり苦しい。他にも色々ありますが、静的な型がない言語というよりそれを前提に作られたライブラリやフレームワークは、「短期間にとりあえず成果物を作る」ことに向いているように思えます。

 また、特にそういうプロジェクトの立ち上げ期にはありがちですが、非常に短期間の試行錯誤が必要とされるので、その度に型が変わっていたら(少なくとも現状の(強力な)静的型システムを持つ言語では、都度都度違う型を割り当てる必要がある場面もある)面倒くさくて仕方がない。また、静的型付き言語では実行前に型チェックが走る以上、(傾向として)「ちょっと変えて再実行」はより時間がかかります。つまり、試行錯誤の回数が滅茶苦茶多いような状況では、静的型付き言語は時間がかかりがちと言えそうです。もちろん、立ち上げ期でも静的型付き言語の方が向いている事例(たとえば、金銭のような「厳密な扱い」がとりわけ重要視されるものをよく扱う場合とか、そもそも最初期でもそこまで試行錯誤しなくていい場合は、妙な計算をあらかじめはじくことが出来る静的型付き言語の方が向いている)もあります。

 というわけで、(あくまでも仮説ですが)動的型付き言語は素早く最低限の成果物を作るという点においては静的型付き言語よりは向いているのではないかと。もちろん、プロジェクトメンバーのスキルセットが違ったり、あらかじめ問題の性質がわかっているとか、状況によって揺らぐ部分はいくらでもありますが。

 しかし、RoRを採用した事例で同時に聞くのが「保守するのがとても辛い」という声です。もちろん、どんなプロジェクトであろうとコードを長期間保守するのはしんどいものですが、自分が見たコードでも、「長期間の保守のしんどさ」はRoRを採用した事例でとても多い。繰り返しますが、あくまで例でRoRが悪いといったことを書きたいわけではありません。

 で、なんでRoRのプロジェクトを長期間保守するのがしんどいかと言うと、自分が見た事例も含めると「とにかく、コードを読む手掛かりが少ない」んですよ。たとえば、これは一見メソッド呼び出しに見えるけど、実はDBアクセスじゃないだろうか、とか、このメソッドは状況からするとクラスAのものぽいけど、実は無関係のクラスBのものを呼び出していた、とか、とにかくコードをぱっと見しただけだと手がかりが非常に少ない。

 こういう時に「ドキュメントをきちんと書くべきである」とか「テストをきちんと書くべきである」という反論をよく耳にします。確かに正論ですし、苦しい状況に陥った現場での解決策としては、それしかないとも思います。

 しかし、優秀なプログラマですら納期などの時間制約があればドキュメントをさぼったりあるいは書いても最低限なことはあります。テストだって「きちんとしたテスト」を常に書けるほど人間は完璧じゃないはずです。テスト駆動開発はそういう事を回避するための方法論かもしれませんが、じゃあ「きっちり」テスト駆動開発を実行し続けることは果たして可能なのだろうかと言う疑問は持ちます。テスト駆動開発が悪いといかいう話ではなくて、やっぱり人間はそこまで完璧ではない。

 一方、静的型付き言語であれば*1、少なくとも「引数の型と返り値の型」は明記しなければなりません。もしサボろうものならそもそもプログラムを実行できませんから、いわば「最低限のドキュメント」を強制的に書かされることに近い。この「最低限のドキュメント」がどのくらい役に立つかは立ち位置によって別れると思いますが、DropboxがPythonにほぼ100%型注釈をつけた事例などを考えると、現実的には役に立つと考えざるを得ない。ちなみに、このようなことが可能だったのは、型注釈が機械によってチェックされるという性質によるものであって、「書いた型が間違っている可能性が高い」状況では到底達成ができなかったのではと感じます。

 以上、私の経験に基づく仮説にはなりますが、動的型付き言語はすばやい立ち上げに向くが長期間の保守に向いておらず、静的型付き言語はすばやい立ち上げには向かないものの、長期間の保守にむいているように思えます。

 ただ、くどくはなりますが、論じたいのはあくまで傾向の話です。Rubyを採用している現場でもテストやドキュメントを「きっちり」書いた結果として、保守性の問題が起こっていない現場はあるでしょうし、Javaを採用している現場でもメンバーのスキルセットや性格の問題で「型があるからテストもドキュメントもテキトーでいいや」とばかりに、テストや(型以外の)ドキュメント書きを軽視した結果、悲惨なことになった現場は山ほどあるはずです。個別の言語戦争を煽るのは意図していないことは改めて書いておきます*2

 しかし、人間は本来的に面倒くさい作業を後回しにしがちだし、(本来の意味で)怠惰な人が多いという現実を踏まえると、「素早くプロジェクトを立ち上げたい」時は「型を頻繁に変える」作業は面倒くさいから、結果として動的型付き言語の方が楽な部分はある一方で、その後にきっちりとしたドキュメントを書く必要性が生じても「緊急じゃないしなあ」と面倒くさがるものじゃないかなと。そういう「面倒くさがりな人間の現実」を踏まえて言語を選定することが必要ではないか、と最近は思うようになりました。

 ちなみに、そういう現実を踏まえた時に思うのが、最初から「言語をいずれ置き換える」ことを見越すことです。ただ、「一度作った資産を放棄する」のはやはり人間心理として難しいものです(サンクコストバイアスによるものと言えるかも)。そういった現実まで考えると、「最初は型をつけない」けど「徐々に型をつけることができる」漸進的型付け*3というアプローチはより重要になってくるのかもしれません。特に、サーバーサイド用言語としては「最初から漸進的型付け」な言語はほぼ無い状況ですが、TypeScriptとはまた違った「漸進的型付け」な言語を作るのがいい解のようにも思えます(TypeScriptはJavaScriptとの互換性をある程度維持しなければいけないという制限がある故にデザインがやや歪になってますが、一から設計するのならもっと良い漸進的型付けの言語が作れそうです)。

*1:明示的な型注釈が重要である、がより正確ですが、引数や返り値の型をほぼ完璧に推論してくれる言語であっても、推論結果をファイルに出力する事は可能なので、脇に置いておきます

*2:私も過去にそういう言語戦争に参加していたのだろうという批判はあるでしょう。私が未熟であった故としか言えないですが、今はそういう立場ではないとだけ書いておきます

*3:追記:TSは漸進的型付き言語のひとつですし、Pythonにおけるmypyも広義にはそう言えます。PHPのtype hintがそう言えるかはやや微妙ですが、「漸進的型付けっぽい」くらいは言えるかもしれません。なんでこれを追記したかというと、メジャーな動的型付き言語は部分的に静的型を追加していて既に漸進的型付けに近いアプローチを採用しているというのを当然の前提としてたのですが、多くの人にとって普通の前提ではないことに気づいたからです。なお、Ruby 3に限って言えば漸進的型付けの方向かはやや微妙です。というのは、.rbsという形で型シグネチャを別ファイルに分離する、つまり.rbには変更を加えないという路線がまずあって、その上にsoutaroさん作のsteepのように.rbsとか見て漸進的型付けをするツールがあり、他方でmameさんの型プロファイラのような独特なアプローチもある感じだからです。個人的に型プロファイラがどうなるかは興味深く見守っていますが他の動的型付き言語とは違う方向に舵を切っているのは確かなようです

人前である行動習慣を宣言することの効果

 さて、先日、Twitterの使い方のマイルールを定めたわけですが、あれは別に凄い苦悩してたわけでもなくて、そもそも兼ねてから日常で「つい」Twitterに手が伸びてしまいがちな自分の習慣を是正しようと思っての荒療治という側面がありました。健康に悪いとわかりつつも、ついカロリーの高いものを食べてしまうんだけどどうしようみたいな。

 以前から「もうちょっとツイートをする頻度を減らそう」と思ったことはあって、その時々で一定の効果を挙げていました。しかし、結局「頻度を減らす」が習慣化できずにいたのが悩みの種でした。ただ、数か月前から社内で読書会をしている

予想どおりに不合理 行動経済学が明かす「あなたがそれを選ぶわけ」 | ダン アリエリー, 熊谷 淳子 | 産業研究 | Kindleストア | Amazon

 で、締め切りに遅れがちな学生が、「自分はこれこれの締め切りを守ります」と宣言することで一定の効果を挙げたというエピソードを思い出したのです。これ自体は「公衆の面前で宣言する」ことによって、「先延ばし癖」を防ぐという文脈ですが、この「公衆の面前で宣言する」ことの効果は「先延ばし癖」に限ったことではなく日常で行う行動全般について有効なのではないかと考えたわけです。

 ただ、「ツイートをする時に非難をしないように注意する」といった宣言は履行出来ているかの判定が難しいので、より自己判定が簡単なマイルールにしたという経緯があります。さらに、「ピン止め」することによって、「宣言の内容を自分が忘れない」という意図と「(少なくとも)私のツイートをよく見てくださる方は見ているだろう」という方向に意識を向ける意図がありました。

 結果として、「ツイートをする」ことについてかなり「腰が重い」という心理状態を作り出すことが出来、あまりツイートをしなくなったわけで宣言の効果は大きかったようです。

 あくまでN=1であって、一般に通用するかは全くもって不明ですが、ある習慣を止めたい(逆に習慣づける)時に「人前で(なるべく曖昧さがない)宣言をする」というのはかなり有効なのではと個人的に思っています。

私は(もはや)国内Scalaコミュニティの偉い人ではありません

 このことはいい加減はっきり書いておかないとなあということで、ちょっと記事にしてみることにしました。

 もちろん、英語圏Scalaコミュニティで私が強い影響力を持ったことはそもそもありません(日本でそれに一番ふさわしいのは@xuwei_kさんだと思います。恐ろしい数のcontributionという点で)。日本語圏でもScalaコミュニティ内で意義のある活動をしていたのは5年以上も前の事です。「外側」からみるとまた違って見えるかもしれませんが、それが正直な自己認識です。

 色々な経緯があるにせよ、私が日本でScalaコミュニティに関する活動を始めたのは、Scalaが良い言語なので広めたいという本当に純粋な動機でした。Scala Conference in Japan 2013を最初に企画したのは私ですが、あれもまあ起爆剤として誰かがやらないとなあと思っていたのを勢いでやったことですし、そもそも私自身が組織運営に本質的に向いてないこともあって、後継であるScalaMatsuriについては徐々に麻植さんや他のスタッフの方々へバトンタッチをしていきました。現在のScalaMatsuriについては、多少情報を伝え聞いていますが、ほとんどノータッチです。

 特に去年や今年辺りで、私が国内のScalaコミュニティに関して何かやったと言えるのは、「Scalaスケーラブルプログラミング第4版」の監訳に関する活動くらいです。

 それにも関わらず、国内だと未だに私がなんか日本Scalaコミュニティのボスみたいな見方をしている方が(悪意ではないにせよ)いらっしゃるみたいなので、それはもう違うんだということをここではっきりと宣言しておきます。まあ、そもそも初期からでもボスだったことは一度もないんですけどね。技術的批判やその他批判に関しては全面的にウェルカムですし、技術コミュニティでボスだのなんだの考える方が不健全です。

 まあ、実際に私がボスで周りに取り巻きがいるとか悪意ある見方をしてあまつさえ動画にした方を目にしたときは正直なところ、辛いなんてものではなかったです。同時に、取り巻きとかボスという視点でしかボランティアコミュニティのことをとらえられない悲しい人なんだなあと思ったことも書いておきます。

 初期の国内Scalaコミュニティの成立にあたって私が一定の役割を果たしたくらいの自負はありますが、特に2016以降のなにがしかの「成果」はほとんどが他の人によるものです。

 未だに私がScalaの、特に言語仕様について詳しいのはたぶん事実でしょうけど、それですらあくまで日本国内でのことで、海外だと私より詳しい人なんてざらにいます。

 だから、もしこれまで私のことをそう認識していた方がいたとしたら、これからは「Scalaが好きなただのプログラマー」として扱ってもらえたらなあと望むばかりです。

 数年以上前から、国内でScalaというと私にやたら注目が集まる(国内のScalaコミュニティ内では私が別にそんなに貢献してないのは周知ですが、「外野からみた認識」としてですね)状況は色々な意味で不健全だと感じていましたし、望んでもいないのに成果を横取りしたように思われたり、関係ないことで風評被害を流されたりなどがあり、一年以上前から今後どうしようかと色々考えていました。純粋なボランティアとしてやっていた部分が多いのでそういう風評被害に反応するのも正直疲れています。

 もちろん、Scala研修テキストは主要メンテナとして(最近更新が滞り気味ですが)責任をもってメンテナンスしていこうと思いますし、それ以外でも出来る範囲で貢献はしてくつもりです。ただ、そもそも私のライフワークは構文解析プログラミング言語自体に関して作ったり考えたりすることですし、さらにいうなら現在はプログラミング教育や物事の認知といった方向にシフトしてきてもいます。

 もし自意識過剰だったのなら笑っていただければいいのですが、そうでないのなら、どうか「日本のScalaの偉い人」などと扱わないで欲しいというメッセージが届けばいいなと思います。