Mastodon の電脳考古学、あるいは不在の中心としての Twitter について
突然ですが、5月始めに出る「マストドン本」に寄稿させて頂くことになりました。後半の技術パートの導入として、Mastodon の技術的な基盤である OStatus の章を担当しています。
本書の執筆には、mstdn.jp のぬるかるさんや pawoo.net の中の人に加えて、界隈では誰でも名前を知ってるような面々が勢ぞろいで、まさに Mastodon オールスターといった趣であり、わし本当にこんな所に混ざっていいのか…。まぁ、ともかく現在予約受付中です、買ってね!
これがマストドンだ! 使い方からインスタンスの作り方まで (NextPublishing)
- 作者: マストドン研究会
- 出版社/メーカー: インプレスR&D
- 発売日: 2017/05/12
- メディア: オンデマンド (ペーパーバック)
- この商品を含むブログ (1件) を見る
思い返すになかなかの急展開ですが、最初、降って湧いた Mastodon ブームに第二次 P2P ブームの面影を見て手を出したくなり、じゃあ Akka Streams で OStatus プロトコルを実装してみようかなと、さっそく OStatus API の挙動を調べるために Pawoo を curl
でつつき回したり、gist にまとめ記事を書いたりしていたところ、それを見ていた知人の紹介でインプレスさんから依頼を頂いたという次第です。
それが先週の中頃で、一昨日には校了したのでたった一週間で作られたことになります。当然、リアルで紙をやり取りしていては間に合わないので、原稿は Google Drive でやり取りし、著者同士の連絡調整は Facebook Messenger、書き上がったらその場で組版システムに突っ込んで出力結果を見ながら校正、という具合。出版に関わったのは初めてなんですが、最近はこんなスピード感なんですねぇ、いやはや。
担当編集者さん、さすがにこういう進行だと本当に大変そうで、時間が限られてる中で著者10人を相手に原稿集めて組版して校正してと大車輪でヒイヒイ言っておられました。おつかれさまです…。
Mastodon の電脳考古学
ところで、手元に作業時間と紙幅の関係で原稿に入れられなかった謎の図があるのですが、もったいないのでここに置いておきます。
これは、記事を書くにあたって OStatus の背景にある技術思想の歴史を押さえておいた方が良かろうと思い、関連するプロダクトや仕様書の日付を整理してみたものです。まぁ、これだけでは何のこっちゃという感じだと思うので詳しくは書籍をお買い求めください(宣伝)。
この辺の歴史は掘ってみるとなかなか面白いのですが、一つ問題があって、こうした経緯を語る資料が今まさに失われかけているってことですね。OStatus 関連、公式サイトどころか、仕様書自体がネットから消失しかけているものが多く、それを探し出すべくネットを徘徊していると「電脳考古学」という言葉を思い浮かべてしまう。たった十年前の話だというのに。
この辺、興味がある人は今のうちに資料を収集して保全しておくと良いんじゃないかしら。もう十年も経ったら何もかも電子の海の向こうへと消え去りそう。
「不在の中心」としての Twitter
最初に「今の Mastodon ブームを見ると過去の P2P ブームを思い出す」と書きましたが、ただ、ブームを駆動する動機は十年前とは大きく異なっているように思います。その根源は、ネットやそれを取り巻く社会のありようがこの十年で大きく変わったことにありそうだ、というのが僕の意見です。
ゼロ年代前半までのネットは、まだまだ社会の外部であるという意識を強く持っていたと思います。「ネットの自由」と「社会の規範」との間にある緊張関係は今よりもはるかに強く、またネット側の立場を強力に代表する人間や組織もなく、このままでは権威が介入して自由が全てスポイルされる日が来るのでは、という懸念が真剣に語られていた頃です。
そんな時代に分散システムが要請された理由は、一言で言えば「単一障害点をなくす」ということでした。責任主体の分散化、つまり責務を数多くの個人(が所有するコンピュータ)に「分権」して薄めることでシステムと参加者を守ろう、という動機があったわけです。
そして現在。今や、ネットは社会そのものとなりつつあり、また我々は Google や Twitter という中央集権的なシステムを信頼してネットを使うようになりました。そして、彼らは社会の一部に入り込んで「ネットの利益」を代表する存在となり、少なくとも民主主義陣営の国々の多くで、突然ネットに強力な規制がかけられる可能性は下がっています*1。
こうして、十年前と比べれば中央集権的な構造に対する警戒は(良くも悪くも)薄まっており、そういう切迫感が動機付けとなる状況ではなくなっています。例えば、GNU social 陣営と Mastodon 陣営の議論における微妙な温度差は、「自由」について常に危機感を持って活動してきた旧世代と、それをリスペクトしつつも切実さが薄い現行世代の違い…というまとめ方はいささか乱暴かもしれないですが、まぁそんなことも感じます。
では、こうした状況においてなお、我々が分権的なコミュニティを求める動機って何でしょうか?
僕は、「社会そのものと化したネットから一歩引く」という話なのだろうと思っています。全てがグローバルでフラットな場から撤退して、参加者や管理者の「顔」が見えやすい場を求めて移動し、ノイズが少なく心理的な安全性が高い少しだけ閉じたコミュニティを作る。この Mastodon ブームがどこまで続くかは不透明ですが、少なくとも、そういうバランスを取りたいという欲求の現れとして見ることはできそうな。
かと言って、これは Twitter の役割が終わったことを意味しないでしょう。なぜなら、今や Twitter とは概念であり、具体的に OStatus 互換実装たちが「連合」できるのはそのおかげだろうと思うからです。
記事にも少し書きましたが、僕は OStatus を構成する仕様のうち最も重要なのは、インスタンス間の通信プロトコルである PubSubHubbub や Salmon ではなく Atom フィードとその「語彙」だろうと思います。例えば、我々は「フォロー」という語彙が何を指すのか知っており、インスタンス間で「AはBをフォローする」というメッセージが伝えられた時に、利用者や異なる OStatus 実装がその意図を誤解する余地はありません*2。それに対して、そのペイロードを運ぶプロトコルはいくらでも取り換え可能だろうし、むしろもっと良い選択肢がありそうに思います。
思うに、OStatus は Twitter からの「脱出」を目指して作られたものですが、これらは不在の中心である Twitter の周りを巡っているが故に、バラバラにならずに済んでいるのだと思います。Twitter はマイクロブログの語彙を象徴する「バベルの塔」であり、仮に将来それが崩壊するようなことが起きれば、きっとまた、連合も維持できなくなるでしょう。
世界最小級のキーボード The Planck Keyboard を作ってみた
海外の自作キーボード (DIY keyboard) コミュニティで生まれ、近年は日本でもすっかり有名になった ErgoDox ですが、その ErgoDox と並ぶ人気を誇る "The Planck Keyboard" の DIY キットを手に入れて組み立ててみました。
どれくらい人気かというと、現在募集中の共同購入(後述)には開始から一週間で世界中から 1,700 件を超える応募があり、新しいカスタムキーキャップのメニューには大抵 Planck 専用セットが用意されるくらい。
過去の記事でも紹介してきた通り、僕は ErgoDox EZ キーボードを使っています。ErgoDox には大変満足していますが、一方でそれなりに細かい不満があるのも確かです。
ただ、普段使いの道具に対するこだわりというものは、突き詰めていくと極めて個人的なモノにならざるを得ません。必然的に、自分が真に求めるものと、汎用性への目配りが必要な完成品 *1 との間には埋めがたい齟齬が出てきます。
そんなわけで、将来的に自作キーボードの制作に手を出していくことを想定して、比較的に制作が簡単で入手の容易なコレを一個作ってみようと思った次第。噂の "40% keyboard" を試してもみたかったし。
Planck Keyboard できたー。半田付けスキルが上がったので、ひとまず所期の目標は達成。 pic.twitter.com/bT9L342xsN
— Yuta Okamoto (@okapies) 2017年3月11日
あとは、少し電子工作っぽいことをやってみたかったのもあります。IoT だなんだと言っているこのご時世に、物理レイヤから距離を取って出来合いのソフトウェアスタックの世界に引きこもっているのも如何なものかと思っていたので、少し自分の芸風を広げてみましょうと。
で、はんだ付けと聞くと一気に敷居が高く聞こえると思いますが、実際はきちんとした道具を揃えればそんなに難しくないですね。この記事では、はんだ付けの道具の揃え方やコツなどについても紹介していこうと思います。
Planck キーボードとは?
Planck は Jack Humbert 氏が開発・販売している DIY キーボードキットです。ErgoDox 使いには QMK firmware の作者と紹介するのが通りがいいでしょうか。いわゆる 40% keyboard プロジェクトの代表格で、その特異な格子状のキートップとミニマルな外観で有名です。姉妹プロジェクトに、サイズ違いの Preonic というものもあります。
Planck の特徴は公式サイトの "a DIY compact 40% ortholinear keyboard" という紹介で言い尽くされてますが、一つずつ見ていきましょう。以下、画像は氏が制作した販促ポスターより。
"ortholinear"
Planck はキーを格子状に配置するレイアウトになっています。"ortholinear" はこのようなキー配置を指す Jack さんの造語で、Planck キーボードの最大の特徴となっています。
一見すると奇抜に感じますが、そもそも論として「一般的なキーボードのキーが互い違い (staggered) に配置されてるのは、かつてのタイプライターの機構上の都合 *2 でしかない」ということらしい。実際、格子状の配置とすることでレイアウトが左右対称になりフットプリントを最小に抑えられるわけで、なかなか興味深いコンセプトと言えます。
"compact 40%"
お気付きかと思いますが、Planck にはキーが 47~48 個しかありません。これは通常のキーボードの約 40 % で、特に数字キーの列が影も形もありません。これは、主要なキーをホームポジションの隣のみに限定することで、指の移動 (finger travel) を最小限にすることを狙った配置になっているからです。
けれど、76 キーの ErgoDox でさえ「右側のキーが足りない」という声が聞かれるくらいなのに、こんなにバッサリと削ってしまっては実用に耐えないのでは?
心配ご無用。最下段のスペースキーの隣にある "Raise" と "Lower" はファンクション (Fn) キーになっていて、これと組み合わせればホームポジションを崩さずに物理キーの2倍以上のキーにアクセスできます。二つの Fn キーが親指位置に置かれているのもポイントで、直線的でエルゴノミクス性をガン無視しているかのような外観なのに、実は「親指活用」を重視したキーボードなのです。
"DIY"
ErgoDox と同様に、自分でプログラムした QMK firmware を書き込むことでキー割り当てを自分好みにカスタマイズできます。また、LED の取り付けに対応しているので、バックライト仕様に変更してファームウェアで光り方を制御できます。あと、基板にスピーカーが組み込まれているので、キーボードで音楽を演奏するなんてことも可能。
購入方法
3/26 現在、Massdrop で DIY キットの共同購入 (group buy) を実施中です。海外からの輸入になりますが、販売者や工場との間に Massdrop が入ってくれるので比較的安心ですし、日本への配送も問題なく行ってくれます。締め切りが3月末なのであと一週間もないですが、必要なパーツがまとめて安く揃う貴重な機会なので興味のある方はお見逃しなく(次の募集はおそらく三か月~半年後かと)。
いろいろなオプションがありますが、Plate は MX compatible、Switch は純正の Cherry MX か互換品の Gateron を選んでおくのが無難でしょう(Matias スイッチを買ってもいいですが、カスタムキーキャップの入手性が低いのでお勧めしません)。軸色による押下感の違いはこちらの記事が参考になります。
また、キーキャップについては、同時開催の別枠の drop で文字入りのセットが安価に提供されています。
今回は、昨年末に作者のサイトから直接購入したものを使いました。現時点では、Massdrop に出品されているものより古いバージョンの plate しか買えないようなので注意。
また、キーキャップとスイッチは OLKB では Matias スイッチしか提供してない ので、Cherry 互換を使いたい場合は別に調達する必要があります。スイッチは日本でも純正の Cherry MX スイッチを売ってくれる所がありますが、意外にも一番手に入れにくいのはキーキャップです。これらの入手方法については以前の ErgoDox の記事を参考にしてください。
道具を揃える
前述のとおり、Planck は DIY キットなので基本的に完成品の販売はありません。とはいえ、必要な部品は全て加工済みで売ってくれるし、組み立ても簡単なので苦労する所はほぼないです。唯一の問題は、基板にキースイッチを取り付けるのにはんだ付けが必要なところで、そこを敷居が高いと感じる人も多いでしょう。
半田付けの道具が揃った(※半田ごて以外 pic.twitter.com/Vt8zK1aa9X
— Yuta Okamoto (@okapies) 2017年3月4日
ただ、今回やってみたところ「まともな道具さえ揃えれば非常に簡単」という感想でした。最低限、以下のものがあればいいでしょう:
- 糸はんだ(すず 60%/鉛 40%、Φ 0.8~1.0 mm、やに入り)
- はんだごて(温度調整機能付き)と 2C 型のこて先
- こて台(簡易型ではない重いやつ)
- クリーニングワイヤ(こて台に付属している場合もある)
- 工作マット(机を汚れや高温から保護する)
この中で特に重要なのがはんだごてです。千円以下で買える安いものもありますが、断然「温度調整機能付き」のものをお勧めします。少し値が張るものの、作業のやり易さとはんだの品質が天と地ほど違います。学校で安いはんだごてで実習をやらされてトラウマになってる人も多かろうと思いますが、能力不足は全てカネが解決します。ぜひお試しあれ。
また、はんだごてを買うと標準で付いてくる円錐形のこて先(B 型)は実は使いにくいので、別途 2C (or 3C) 型 *3 のこて先を入手して付け替えましょう。C 型のこて先の特徴については以下のページなど:
はんだは、あまり太いと融けにくいので Φ 0.8 mm 程度が良いようです。環境に優しい「無鉛はんだ」というものが売っていると思いますが、融点が高くて扱いにくいので初心者はやめておいた方が無難。
こて台は、ひっくり返ってケガをしないように重いやつにしましょう。また、こて先を掃除するために水を含ませたスポンジを使うのが一般的ですが、温度調整機能付きのこてを使う場合は温度が下がらないようにクリーニングワイヤを使う方が良いようです。こて台とセットの製品があるので、入手できるならそれを。
購入方法ですが、この辺の道具はホームセンターや家電量販店では品揃えが悪く、困った時の Amazon もイマイチだったので、ヨドバシドットコムで買うのが一番早いと思います。ブランドは HAKKO(白光)と goot(太洋電機産業)がメジャーみたいなので好きな方を。今回は基本的に HAKKO 製で統一しました。
組み立てる
組み立て方については、基本的には公式サイトのドキュメントを熟読してください。ここでは、作業の進め方のイメージ作りの一助として、僕が実際にやった作業を簡単に紹介します。
概要
以下の手順で組み立てていきます:
- 基板の動作確認
- プレートにキースイッチを組み込む
- スイッチを基板にはんだ付けする
- スイッチの動作確認
- 基板をケースに取り付けてキーキャップをはめる
- 完成!
1. 基板の動作確認
組み立て終わっていざ電源投入したら認識しませんでした…は悲しすぎるので、念のために動作確認しておきましょう。基板には初期ファームウェアが書き込まれているので、PC に USB ケーブルで接続すれば認識してくれます。成功すれば、表面に実装された LED が緑に点灯してスピーカーからビープ音が出るはずです。
2. キースイッチの組み込み
次にキースイッチをプレートに取り付けていきますが、公式の手順ではまず数個だけ取り付けて確認することを推奨しています。スイッチを取り付けた後に基板を裏からはめてケースに納めてみて、基板の向きが正しいこと、スイッチのピンが基板の穴からまっすぐ出ていることを確認しましょう。
確認が終わったらケースから取り出し、残りのスイッチを全てプレートにはめ込みます。
全てはめ込んだら、基板をプレート側へ軽く押し込み、全てのピンが基板の穴から同じ長さだけ飛び出していることを確認しましょう。ピンを曲げてしまわないように注意。
3. スイッチのはんだ付け
さァ、一番楽しいスーパーはんだ付けタイムです。安全にはくれぐれも気を付けましょう。例えば、こての電気コードを蹴っ飛ばす等の事故を起こさないように、コードの長さには余裕を持ち、作業机の周りはよく整頓しておきましょう。あと、煙は有害物質なのできちんと換気しましょう。
こての温度は 340~360 ℃に調節するのが良いようです。これより高くても低くても良くありません。以下の動画のように、こて先をスイッチのピンとランド(基板の金色の部分)に押し当てて何秒か加熱したら、はんだをピンとランドの間へ送り込みます。この際、量は多くても少なくても良くないとか…。
いい道具(温度調節機能付き)を使うとここまで楽だとは…。中学校の頃の自分に教えてやりたい。 pic.twitter.com/39xD8J4Tib
— Yuta Okamoto (@okapies) 2017年3月11日
注意点は、「はんだをこて先へ直接押し付けない」「こて先との接触面積が大きいほど熱を伝えやすい」の二点です。もし C 型のこて先を使っているなら、こて先の面の部分を加熱する部分に押し当てて使うことになります。また、こて先に黒い汚れが付着してきたらワイヤーにグサグサ刺して拭き取りましょう。
その他のはんだ付けのコツについては、色々なサイトで紹介されているので探してみてください。まぁ、十年こてを触ってなかった僕でも何とかなったので、あまり細かいことを気にする必要はないかも。それよりも、繰り返しになりますが安全に気を使ってください。
4. スイッチの動作確認
はんだ付けが終わったら PC に繋いでスイッチの動作をテストしてみましょう。
至極当然ながらこの状態でも動く。 pic.twitter.com/0WYfpKF7ah
— Yuta Okamoto (@okapies) 2017年3月11日
5. ケースに取り付ける
動作確認が済んだら、プレートと基板をケースにねじ止めします。
あとは好きなキーキャップをはめて完成!
ファームウェアのカスタマイズ
現時点ではファームウェアの書き換えまではやれていないので、書き換え手順を示したページだけご紹介します(Easy AVR は GUI でファームウェアをカスタマイズできるソフトなのかな)。
また、ErgoDox EZ と同じ QMK firmware を使うので、ビルド方法については下記の記事が参考になると思います:
まとめ
QMK firmware の対応キーボードを見たことがある人は分かると思いますが、DIY キーボードコミュニティでは、Planck 以外にも実に様々なプロジェクトが活動しています。この記事が、自作キーボードに関心を持つ人が一歩を踏み出す助けになれば幸いです。
実は、キット自体は昨年末に発注していて1月には届いていたんだけど、道具の入手や場所の確保はどうしようか…と色々と悩んでいるうちにズルズルと時が過ぎ、完成までだいぶ時間がかかってしまったのでした。今回、電子工作の初歩中の初歩的な内容とはいえ、実際にキーボードを一つ組み上げたことでだいぶ自信がつきました。次は、「左右分割型 Planck」とも言える Let's Split に手を出してみようかと思案中(4月中旬に在庫が復活するらしい)。
「関数型プログラミングって何?」日本語訳
この記事は、技術翻訳 Advent Calendar 2016 の15日目です(枠が空いてたので勝手にお邪魔してます)。前回(6日目)は、id:msyksphinz さんの「個人が趣味で技術書を翻訳するという意義について」でした。
今回ご紹介するのは、昨年末に公開された Kris Jenkins さん (@krisajenkins) の "What Is Functional Programming?" です。日本語訳の公開については著者から承諾済みです。また、London Functional Programmers meetup での同タイトルの講演動画が公開されています。
関数型プログラミングの考え方は、世間ではどうも小難しい話だと思われている節があります。その理由の一つに、議論の抽象度が(比較的)高いことが挙げられるでしょう。例えば、以前このブログで紹介した「なぜ関数プログラミングは重要か」も、関数型プログラミングの本質をコンパクトに抽出した優れた論文なのですが、いかんせん数学的な考え方に慣れていない方にはとっつきにくい面がありました。
しかし、この記事では、我々が日々の仕事をこなしていく上で、関数型プログラミングがいかに実践的な方法論であるかを平易かつ具体的に説いています。特に、数学は一切出てこないのでご安心ください。
(いちおう技術翻訳ネタにも触れておくと、この記事、読む分にはスルスル読めたので楽勝かなーと思ってたんだけどそんなことは無かった…。以前 ScalaMatsuri ブログでも検証した通り、Google 翻訳の精度が上がってるので併用したら少しは楽になるかと思ったけど、こういう口語的な言い回しを多用する文章にはまるで無力でした。まる。)
関数型プログラミングって何? (What Is Functional Programming?)
これは、関数型プログラミングの本質は何なのかってことについての僕の見解で、とにかく目先の仕事を片づけたいと思っている職業プログラマ (jobbing programmer) に向けて書いたものだ。
この記事で僕が伝えたいのは、君が書くあらゆる関数には二組の入力と二組の出力があるってことだ。
二つ? え、一つだけでしょ?
いいや、二つ。間違いなく二つだ。一つ目のペアについて例を見てみよう:
public int square(int x) { return x * x; } // 補足: これが何の言語かは重要じゃないけど、入力と出力の型を強調するために明示的に宣言する言語を選んだ。
これを見た君は、この関数の入力は int x
で出力は int
だと考えるんじゃないか。
それが入力と出力の一組目で、言うなれば従来の捉え方だ。では続いて、入力と出力の二組目の例を見てみよう:
public void processNext() { Message message = InboxQueue.popMessage(); if (message != null) { process(message); } }
この関数は、構文を見るかぎりは何も入力を取らず何も出力を返さないように見えるが、何かに対して明らかに依存しているし、明らかに何かをしている。実は、この関数には入力と出力の組が隠れている。その隠れた入力とは popMessage()
を呼び出す前の InboxQueue
の状態だ。そして、隠れた出力とは process
が引き起こしたあらゆる結果と、それに加えて、処理が終わった後の InboxQueue
の状態だ。
間違いなく、InboxQueue
の状態はこの関数の本物の入力だ。その値を知らなければ processNext
の挙動も分からない。そして、出力の方も本物だ。processNext
を呼び出した結果は、InboxQueue
の新たな状態を考慮しないと完全に理解することはできない。
このように、二番目のコード片には入力と出力が隠れている。それは何かを必要として、そして何かを引き起こすが、API を見ただけではそれが何なのかは決して推測できない。
この隠れた入出力にはちゃんとした名前があって、その名を「副作用」という。さまざまな種類の副作用があるけど、それらは全て同じコンセプトの下でまとめられる。「引数リストに含まれないけど、この関数の呼び出しに必要なものは? そして、戻り値に含まれないけど行うことは?」
(僕は実のところ、隠れた出力を表す「副作用 (side-effect)」という語だけでなく、隠れた入力を表す「副原因 (side-cause)」という語も必要だと思う。これ以降の記事では、ほとんどの場所では簡潔に「副作用」とだけ書くが、その場合は間違いなく副原因の話もしている。僕は、あらゆる隠れた入出力についての話をしている。)
副作用は複雑性の氷山だ
関数が副作用(と副原因)を持つとき、こう見立てることができる:
public boolean processMessage(Channel channel) {...}
…で、これを見た君は、これが何をしているのか理解したと思うかもしれないが、それは全くの誤りだ。関数の中身を見なければ、その関数に何が必要なのか、あるいはその関数が何を行うのかを知る方法はない。チャンネルからメッセージを取り出して処理する? たぶん。何かの条件を満たしたらチャンネルを閉じる? おそらく。どこかのデータベースのカウンタを更新するのかな? ひょっとすると。期待したログディレクトリのパスを見つけられなかったら爆発するの? かもしれない。
副作用は複雑性の氷山だ。関数のシグネチャを、そして名前を見たとき、君はそれが何物なのかを何となく分かった気になる。しかし、関数シグネチャの表層の下には、本当にあらゆるものが隠れている可能性がある。あらゆる要件、あらゆる変更、そうしたものが隠れている。実際に何が関わっているかは、関数の実装を見なければ知る由もない。API の表層の下には、さらなる複雑性の膨大な塊があるかもしれない。それを把握する方法は三つしかない: 関数の定義に飛び込むか、複雑性を表層に持ってくるか、無視を決め込んでうまくいくことを祈るか。そして、無視すると、たいてい結局はタイタニック号と同じ過ちを犯すことになる。
これってカプセル化の話じゃないの?
違うよ。
カプセル化とは、実装の詳細を隠蔽することだ。呼び出し元がコードの内部のことを心配しなくても済むように隠そうって話だ。これは変わらず良い方針だけど、この記事で話してることじゃない。
副作用に注目するのは「実装の詳細を隠蔽したい」からではなく、コードとその外側の世界との関係を隠蔽したいからだ。副原因を伴う関数には、その関数が外部のどんな要素に依存しているかについて文書化されていない仮定がある。副作用を伴う関数には、その関数が外部のどんな要素を変化させるかについて文書化されていない仮定がある。
副作用は悪なのか?
いや、それがプログラムの元々の作者が期待した通りに動作するならおそらく大丈夫だ。ただ、副作用の難しいところは、僕らは元のプログラマが暗黙に期待していたことが正しいと、そしていくら時間が経っても変わることなく正しいと信じる必要があるってことだ。
僕らは、この関数を書いた際に期待していた通りに世界の状態を設定しただろうか? さもなくば、世界がどこかで変更された? それはおそらく、一見して繋がりのないコード片が変更されたせいだ。そうでなければ、そのソフトウェアを新しい環境にインストールしたからだ。世界の状態について隠された仮定があるとき、僕らは、世界の状態と、その関数が十分に動作する状態とが似ていると暗に期待していることになる。
このコードはテストできるだろうか? 単独では無理だ。回路基板と違って、僕らは入力にそのままプラグを差し込んだり出力を確認したりできない。僕らはコードをこじ開け、その隠れた原因や作用を把握し、それが存在するはずの世界をシミュレートする必要がある。僕は、テスト駆動開発に取り組んでいる人々が、テストをブラックボックスでやるべきかホワイトボックスでやるべきかについて堂々巡りしているのを見てきた。答えはブラックボックスでやるべきで、実装の詳細を無視できるはずだけど、副作用を許してしまえばそれはできない。副作用はブラックボックステストへの扉を閉ざしてしまう。なぜなら、箱をこじ開けて中身を調べなければ入出力へ到達できなくなるからだ。
これは、デバッグにおいてさらに問題になる。関数が副作用(や副原因)を許さなければ、その関数が正しいかどうか理解するには、単にいくつか入力を与えて出力を確認するだけでいい。だが、副作用を伴う関数だったら? システムの他の部分に対する影響を際限なく考慮しなきゃいけなくなる。関数が何かに対して依存したり影響を引き起こしたりするのを許容すると、あらゆる場所にバグが存在するようになる。
副作用は常に表層に移せる
僕らは、この複雑性に対して何かできるだろうか? うん、始めるのは実のところかなり簡単だ: 関数が何か入力を持つなら、そう言おう。何かを出力として返すなら、そう宣言しよう。それだけだ。
例を試してみよう。この関数には入力が隠れている。素早く見つけられたらボーナスポイントだ:
/** * 訳注: 指定したチャンネルで現在放映しているテレビ番組を返す関数。 */ public Program getCurrentProgram(TVGuide guide, int channel) { Schedule schedule = guide.getSchedule(channel); Program current = schedule.programAt(new Date()); return current; }
この関数には現在時刻 (new Date()
) という入力が隠れている。この複雑性を表層に移すには、こういう追加の入力があるってことをシグネチャの中で正直に表すだけでいい:
/** * 訳注: 第三引数に when を追加して programAt(Date) に与えている。 */ public Program getProgramAt(TVGuide guide, int channel, Date when) { Schedule schedule = guide.getSchedule(channel); Program program = schedule.programAt(when); return program; }
これで、この関数は入力(や出力)を隠し持たなくなった。
この新バージョンの良い点と悪い点を見てみよう:
悪い点
より複雑になったように見える。関数の引数が二つから三つに増えたし。
良い点
複雑にはなっていない。依存関係を隠してもシンプルにはならないし、それを正直に表したらより複雑になるってこともない。
テストははるかに簡単になっている。一日の異なる時刻、時計の変化、うるう年といったすべてのテストがそのまま書ける。なぜなら、好きな時刻を渡せるからだ。僕は、最初のバージョンのような本番コードをテストするために、あらゆる種類の巧妙なトリックで現在のシステムクロックを偽装するのを見てきた。これをパラメータ化するだけで、そんな苦労をしなくて済むんだ!
推論もより簡単になっている。いまや、関数は単に入力と出力の関係を記述しているだけだ。入力が分かれば出力がどうなっているべきか分かるし、そして結果についてあらゆることが分かる。これはすごいことだ。このコードは単独で検証できる。入力と出力の関係さえテストすれば関数全体をテストしたことになる。
(そして余談だけど、便利なのはこれだけじゃない。「一時間後に始まる番組」を返すようなコードがタダで手に入る。)
「純粋関数」って何?
ドラムロールをどうぞ。
これで隠れた入力と出力について把握したので、ついに「職業プログラマ向けの純粋関数の定義」を説明できる:
関数が〈純粋〉であるとは、全ての入力が入力として包み隠さず宣言されていて、同様に出力が出力として宣言されていることだ。
逆に、入力や出力を隠し持っている関数は〈純粋〉ではない。非純粋な関数にとっては、僕らが「関数が提供する契約」だと思っているものは全体のうちの半分に過ぎない。複雑性の氷山が迫っている。純粋でないコードは決して「単独」では使えないし、単独でテストすることもできない。テストやデバッグをしたいときはいつも、そのコードが依存する他のコードを追跡しなければならなくなる。
「関数型プログラミング」って何?
純粋関数と非純粋関数について把握したので、これで「職業プログラマ向けの関数型プログラミングの定義」を説明できる:
関数型プログラミングとは、純粋な関数を書いて隠れた入出力をなるべく取り除き、できるだけ多くのコードを入力と出力の関係だけで記述することだ。
ほとんどのプログラムは何かを返すというより何かを行うために実行されるので、どうしたっていくらかの副作用は避けられないけど、プログラムの中は厳格に制御しよう。副作用(と副原因)を可能な限り排除して、それでも取り除けない場合は厳重に管理するんだ。
別の言い方をするなら、「コード片に必要なものや、コード片が生成する結果を隠蔽するのはやめよう」ってことだ。コード片を正しく実行するのに必要なものがあるなら、そう言おう。コード片が何か有益なことをするなら、それを出力として宣言しよう。そうすれば、僕らのコードはよりクリーンになる。複雑性を表層に移せば、それをかみ砕いて対処することができる。
「関数型プログラミング言語」って何?
あらゆる言語は純粋関数をサポートしている ― 例えば add(x, y)
を非純粋関数にするのは難しい。*1そして多くの場合、非純粋関数を純粋関数に変換するには、関数の入力と出力をすべてシグネチャに持ち上げるだけでいい。そうすれば、シグネチャは関数の挙動を完全に記述するようになる。じゃあ、あらゆるプログラミング言語は「関数型」なのか?
そんなことはない。もしそうなら、「関数型プログラミング言語」なんて言葉は無意味だってことになる。
それじゃあ、「職業プログラマ向けの関数型プログラミング言語の定義」はなんて説明すればいいんだろう?
関数型プログラミング言語とは、副作用なしでプログラミングすることをサポートしたり奨励したりするような言語だ。
より具体的には、関数型言語は副作用の積極的な排除を可能な限り助け、それができない場合は厳重に制御するのに役立つ。
より過激な言い方をするなら、関数型言語は副作用に対して積極的に敵対する。副作用は複雑で、複雑さはバグで、バグは悪魔だ。関数型言語は君が副作用に敵対することも助け、君と共に副作用を力で屈服させるだろう。
それで全部?
そうだ。きっとこれまで、君はそれが隠れた入力であると考えたことがないような微妙なものもいくつかあるだろうけど、それが本質だ。「副作用が第一の敵である」という観点でソフトウェアを構築し始めると、君がプログラミングについて知っているあらゆることが変化するだろう。この記事のパート 2 では、副作用と関数型プログラミングについて把握した上で、プログラミングの現状に散弾銃をブッ放すことにしたい。
謝辞
この記事は、関数型プログラミングの性質について何回か議論したことが元になっている。特に Sleepyfox との「適切なライブラリを組み合わせれば JavaScript は関数型プログラミング言語とみなせるか」を巡る議論からは大いに刺激を受けた。僕の答えは直感的にはノーだけど、それがなぜかを考えることを通じて、非常に実りの多い思索に誘われるきっかけになった。
James Henderson に敬意を。今年は、彼のおかげで関数型について多くの実りあるアイデアに触れることができた。
そして、Malcolm Sparks, Ivan Uemlianin、Joel Clermont、Katy Moe、そして僕のドッペルゲンガー Chris Jenkins。皆の校正と提言に感謝する。
おまけ: Part 2 の概要
パート 2 を翻訳する元気が残ってないので概要だけ紹介しておきます。
関数型プログラミングは何ではないか
関数型言語は副作用(副原因)と戦うための道具であって、つまり:
関数型言語はどれ?
設計の臭い
- 引数なしは副原因のシグナル
public Int foo() {}
- 戻り値なしは副作用のシグナル
public void foo(...) {...}
ErgoDox の壊れたキースイッチを交換する
この記事は ErgoDox Advent Calendar 2016 の3日目です。今日は、皆さんのご家庭でもできる「簡単、Cherry スイッチの分解手順!」をご紹介したいと思います。
近況
突然の ErgoDox ブームから早9か月、皆さんのキーボードライフはいかがでしょうか? 僕もブームに乗って、当時からこんな記事を書いて情報収集やパーツ集めに勤しんでおります。
あと、meetup で LT もやりましたね。
https://eventdots.jp/report/20160610_588645eventdots.jp
正直なところ、使いこなしに情熱と労力が必要な部類のガジェットですし、商業ベースの分割キーボードが登場し始めた昨今、あえてコレを選ぶ理由も少しずつ減ってきている気もしますが、しかし、我が家にやって来た ErgoDox 君は今日も元気に活躍中です。
現在は、新たに Massdrop で調達した GMK 製キーキャップと O-Ring を組み込んで使っています。段差付きの Cherry profile のキーキャップに取り換えたことで打ちやすさが向上したほか、僕は打鍵が強い方(カチャカチャ、ッターン!)なので、ゴム製の O-Ring を装備して打鍵の衝撃を吸収することで指にかかる負荷を軽減しています。
僕は元々は HHKB Pro Type-S ユーザなのですが、スイッチに赤軸をチョイスしていることもあって、むしろ以前よりも軽快なタイピング環境を実現できています。あのスコスコした打ち心地も捨てがたいんですけどね…。
キースイッチのチャタリング問題
というわけで、一番の目的であった肩凝りも改善されて(最近はむしろ腰痛が…)快適な ErgoDox ライフを送っています。万歳!
…ところが、秋に入った頃から、次第にキーのチャタリング現象 (Contact bounce) に悩まされるようになってきました。
ErgoDox EZ は、キースイッチとして Gateron を採用しています。これは、その名の通り Gateron という会社が供給している Cherry MX クローンのスイッチで、自作キーボード界隈のデファクト的なパーツなのですが、どうもこいつの調子が良くない。
具体的には、特定のキーで打鍵しても入力されなかったり、一回の打鍵で何文字も入力されてしまいます。典型的なチャタリングですね。これ自体は、メカニカルスイッチである以上は避けようがないのですが、数か月で現象が出るのはひどい…。*1
普通の市販のキーボードなら、泣く泣く「買いなおす」の一択ですが、そこは我らの DIY キーボード ErgoDox。この場合、解決策は二つあります。一つはファームウェアでの debouncing 設定の調整、もう一つはスイッチ部品の交換です。
ファームウェアで debouncing する
一つ目は、ファームウェアの debouncing 設定を調整する方法です。
そもそもチャタリングはなぜ起きるのでしょうか? キースイッチは、下記の図のようにキーを押し込んだ時に電極が接触したり離れたりすることで、電圧を変化させる機構になっています。
(from The Keyboard Company's blog)
ファームウェアは、一定間隔でスイッチの電圧をスキャンすることでキーの押下を判定するのですが、スイッチが機械的にヘタってくると電圧の変化が不安定になって、短時間で何回もスイッチを上げ下げしたかのように判定されてしまうことがあります。
これを回避するには、ファームウェア側で「スイッチの押下状態が一定期間(5 ms とか)継続された場合のみ有効な打鍵と判定する」と処理してやるのが有効です。これを debouncing といいます。ErgoDox のファームウェアには DEBOUNCE 定数 が用意されており、これを調整すると問題を軽減できるようです(デフォルト値は 5
)。以下で紹介するキースイッチの交換が難しい場合は試してみると良いかもしれません。ファームウェアをビルドして書き込む方法については前回の記事を参照してください。
(DEBOUNCE 定数の調整については、あまり大きな値を設定すると弊害があります。識者が技術的な解説を GitHub にコメントして下さっていますので、英語ですがご参考までに。)
キースイッチの交換
もう一つは、今回の記事の本題であるキースイッチの物理的な交換です。チャタリングの原因がスイッチの上側の部分(バネ、軸、カバー)にある場合は、これで問題が改善します。
補足(12/17): スイッチのメンテナンスについて「接点復活剤でも改善するのでは?」というご指摘を受けました。下側の電極部分の問題の場合は、こちらを試してみるのも手かもしれません。化学物質なので、例えばプラスティックが溶けるような成分が入ってないか注意しましょう(参考)。直に吹き付けるのもやめた方がいいかも。
補足(2017/10/29): 以下で説明するスイッチ交換ではどうしてもチャタリングが直らなかったスイッチの電極部分に、KURE の エレクトロニッククリーナーとコンタクトスプレーを試したところ改善しました。半年程度の時点では不具合も出ていないので、スイッチ交換の前にこちらを試してみるのも手かもしれません。
僕の場合、メカニカルキーボードの ErgoDox を入手した時点でチャタリングの発生は予見していた *2 ので、Massdrop で Gateron スイッチ単品の出品を見つけた際に予め確保していました。後述するように、EZ に付いてくるものと完全に同じものではないようで、後から入手した方がハウジングが若干タイトでガタツキが少ない気がします(気のせいかもしれないけど。
Massdrop の Gateron は定期的に再出品されるようなので、今は問題がない人でも予備を確保する意味で出品をチェックしておくことをお勧めします(購入確定後1ヵ月くらいで届く。120 個入りで $25 くらい)。また、少し割高ですが、すぐに入手したい場合は Mechanical Keyboards や 1Up Keyboards、Clueboard などの EC サイトで買う手もあります(補足: 国内でオリジナルの Cherry MX スイッチを入手する方法について、記事の最後に追記しました。)(補足2: PCB mount か Plate mount か選べ、と言われる場合がありますが、基本は Plate mount で問題ないです。PCB mount は固定用の追加の出っ張りがあるバージョン)。
あと、チャタリング以外にも、ドイツの GMK electronic design 製のキーキャップは Gateron スイッチと相性問題(下側に力を入れて押下した際にひっかかりがある)がありますが、これもスイッチの交換で直る場合があります。
僕の場合は、実際にスイッチを交換したら問題が解消したので、ロット固有の問題なのか製造時期の問題なのかもよく分からない(製造番号とか書いてないので)のですが、同様の問題に当たった方は試してみる価値はあるかと思います。
工具の準備
では、交換用のスイッチの在庫を確保している前提で話を進めていきます。まず、交換にあたってはいくつか工具を準備する必要があります。
- キーキャップ引き抜き工具
- ピンセット(or マイナスドライバー)
- キースイッチ分解工具
キーキャップ(キートップ)引き抜き工具は、キーボードの清掃用として国内でも容易に入手できます。僕はダイヤテックの販売している FILCO 製のやつを使っていますが、類似の製品はいくつかあるので、どれかを入手すればよいでしょう。
FILCO Keypuller キーボードメンテナンス用キーキャップ引き抜き工具 ブラック FKP01
- メディア: Personal Computers
ピンセットは、あれば便利というレベルで必須ではありません。ホームセンターとかで適当に買ってきましょう。マイナスドライバーとかでもよいですが、先が曲がっているものが使いやすいかもしれません。
問題は、キースイッチの分解 (disassembly) 工具です。Cherry MX 系のスイッチはハウジングが上下で分かれていて、四か所のツメで固定する構造になっています。つまり、このツメを外側に持ち上げてやれば上側のカバーを取り外せます。
ただ、この写真では下からピンセットで持ち上げていますが、実際にはスイッチはキーボードの基盤に半田付けされていて下側からのアクセスは難しいので、上側からカバーの両端の穴から何かを差し込む形になります。ドライバーでこじ開けてもいいんですが、二か所ないし四か所を同時に持ち上げないといけないので、そこそこ面倒です。専用の工具も売ってるんですが、日本在住だと $7 の工具を手に入れるのに国際輸送でプラス $35 とかさすがにちょっと…。
というわけで、自分で分解工具を作ってしまいましょう。幸い、身近な材料で簡単に自作できます。
はい、そこら辺に転がってるふつーのバインダークリップですね。大きさは、あまり太いものを選ぶと加工しにくいし何より穴に入らないので、15 mm くらいの小さめのやつで十分です。
加工も簡単です。クリップを分解して針金の部分を取り外し、曲がっている部分が少しだけ外側を向くようにペンチなどで捻じ曲げてやります。
これだけ。実際に穴に差し込んでみると、こんな感じで先端部分でツメを外側へ持ち上げられます。
交換作業
工具さえ揃えば、あとはお茶の子サイサイ(死語)です。やってみましょう。(言うまでもありませんが、以下の作業は自己責任でお願いします)
まず、引き抜き工具でキーキャップを取り外して、交換対象のキースイッチを露出させます。作業性を考えて、周りのキーキャップも一緒に取り外すとよいです。
次に、先ほどの分解工具を写真のように穴に突き差して、グッと真ん中に引き寄せながら持ち上げると…
このようにパカッと開いて、スイッチの下側の電極だけが残ります。この部分は基盤にはんだ付けされていて、壊すと面倒なので気を付けましょう。
ちなみに、写真のように一気に開けるのが難しい場合は片側ずつ持ち上げても大丈夫。ピンセットで押さえながら持ち上げるとやりやすいです。
最後に、新しいスイッチを分解してバネ、軸、カバーを取り出し、それら三つを元通りに穴へはめ込めば交換完了です。
ね、簡単でしょう?
まとめ
というわけで、キーボードの中で一番故障しやすいスイッチが壊れても自分で直せるようになったので、愛用の ErgoDox をメーカーの供給状態に左右されずに末永くメンテできるようになりました。
まぁ、ここまでの手順を確立するのにかなり時間を費やしたのは確かで、改めて一般人向けのガジェットではないなと思うものの、気になる部分を一つ一つ自分で直したり改良したりできるのは、やはり DIY キーボードの魅力かと。「手がかかるほどかわいい」は真理ですね。…誰だ、沼とか言ったの!
そんなわけで、PFU さんがセパレート式 HHKB を出すまでは当面コレで頑張ってみたいと思います。
追記: Cherry MX の入手方法について
互換品ではない正規の Cherry MX スイッチを国内で入手するルートがあるようです(10 個 770 円)。在庫が不足する場合もあるようですが、売っていたら確保しておくと良いかも。
Cherryの青軸とかはここで買ってるけど、これだとErgoDoxには組み込めないのかな?国内だし3日くらいで届く。→https://t.co/ZO0joMd4fb
— タケダハチオ (@takedahachio) 2016年12月3日
ErgoDox EZ は Gateron ですが、互換性があるので Gateron を分解して Cherry を取り付けることは問題なくできるようです。実際に試した方によると「違和感なし」とのこと。
お分かりいただけただろうか(見づらい
— O.J.I. (@re_OJI) 2016年12月5日
Gateron→CherryMX換装できました。
ErgoDox の壊れたキースイッチを交換する - Okapies' Archive https://t.co/nw5De5Lox5 pic.twitter.com/IgxopjXC2N
@okapies 無事出来ました。Gateron→Cherry全く問題&違和感なしです。https://t.co/mgEN4RUB2U
— 中途半端er (@ChootHumper) 2016年12月5日
ただ、互換品とはいえ異なるメーカーの製品を組み合わせることになるので、あくまで自己責任でお願いします。また、軸によっては色が同じでも荷重が違う場合があるのでご注意。
ErgoDox EZ カスタマイズ情報のまとめ
先日買った ErgoDox EZ が届いたのでカスタマイズ中。GW に発注して一週間くらいで届いたので、かなり流通体制が整ってきている様子。
いぢりがいがあるのは良いのだけれど、正直なところ「素人お断り」感がすごいですね*1。というわけで、調べたことをまとめていこうかと。随時更新予定。
※記事中でリンクしているドキュメント類はかなり頻繁に場所が変わっているので、リンク切れの場合は頑張って探してください…。
ファームウェアのカスタマイズ
追記 (11/27): EZ 公式の GUI 設定ツールが登場しています。日本語キーの割り当てとかは部分的にしかサポートしてないっぽいですが…。
ErgoDox のキーマップを変更するには、本体ファームウェアの更新が必要。ファームウェアをカスタマイズするには、Massdrop の Ergodox Configurator を使うか qmk_firmware を自分でカスタマイズしてビルドする。Ergodox Configurator だと日本語キーやマクロなどが使えないので、その場合はファームウェアのビルドが必須になる。
ビルド手順はプラットフォームごとに整備されているので、詳細はドキュメントを参照してほしい。手順自体は、依存ライブラリをインストールしたら keyboards/ergodox/ に行って make
するだけなので、そこまで難しくないはず…。
キーマップの定数の意味
keymap.c に出てくる KC_XXXX
という定数は、様々なキーコードに対応している。キーをカスタマイズする際は、これを所望のキーコードに書き換えてやる。
公式のドキュメントは以下にある:
- https://github.com/jackhumbert/qmk_firmware/blob/master/doc/keymap.md(キーマップの説明)
- https://github.com/jackhumbert/qmk_firmware/blob/master/doc/keycode.txt(キーコード一覧)
ファームウェアのインストール
Teensy を使ったファームウェアの書き換え手順。リセットスイッチを押すのに細長いものが必要なので、手元にゼムクリップを用意しておくとよい。
Hyper キーと Meh キー
デフォルトレイアウトにある Hyper キーと Meh キーってなんやねん、と思って調べてみた。これは、通常の方法では入力できない修飾キー (Alt + Ctrl + Shift + Cmd) を組み合わせることで、起動中のアプリケーションと被らない、どのタイミングでも使用できるホットキーを設定できる、というものなんだそうだ(追加でキーボードショートカットを設定するユーティリティアプリが必要)。例えば、エディタを操作してる最中に Hyper + S で Slack アプリを呼び出す、みたいなことができる。Meh キーは Cmd キーを削った Windows 向けのバージョン(Windows に Cmd キーはないから)。
元々、OS X で疑似的に Hyper キーを実現するというテクニックがあって、それをキーボード自体に組み込んだものらしい:
- A Modern Space Cadet / Steve Losh
- A useful Caps Lock key - BrettTerpstra.com
- Using Slate: A Hacker's Window Manager for Macs - Tristan Hume
JIS(日本語)レイアウト固有のキーについて
ErgoDox の初期設定は US レイアウトを前提にしているので、JIS レイアウトで使うには、例えば「半角/全角」キーは自分で割り当てる必要がある。
JIS レイアウトでの定数とキーの対応関係は、下記の記事にまとまっている:
仕様とかの解説は以下:
- USキーボードと日本のキーボードの違い(US レイアウトにあって JIS レイアウトにないキー等の解説)
- USB キーボードのキーコード仕様 (pp.53-60)
- USBキーボードのキーコード
OS X で日本語関連のキーが動作しない問題があるようだ(正確には、OS X で動くように修正すると逆に Windows や Ubuntu で動かなくなる)。解決してメインラインにマージされたっぽい(255
が signed
で -1
だったぜとか書いてあってマジかってなった)。
ファームウェアの CI 環境
自宅以外の環境でも調整できるようにしたかったので、id:ymotongpoo さんのブログ記事を参考にして CI 環境を構築した。qmk_firmware のビルド手順は頻繁に変わっていていちいち対応するのも大変なので、普通はここまでする必要はないと思う。
QMK の公式レポジトリに追随したかったので、直接 fork して develop
ブランチを切った。
僕が使っているファームウェアは以下からダウンロードできる(キーマップ):
やっていることは、依存ライブラリをインストールした Docker コンテナで make
しているだけ。最新バージョンに対応した wercker.yml は GitHub に置いてあるので、もし自分で CI 環境を組む際はどうぞ(wercker 側で $TARGET_KEYMAP
環境変数の設定が必要)。Docker Image を自分で用意する場合はこの Dockerfile を使ってください。
キーキャップ
ErgoDox EZ は Cherry MX キースイッチなので、Cherry 用のキーキャップを流用できる。ただし、ErgoDox は親指キーや周辺キーのサイズが通常のキーボードと異なるので、この部位に対応する特殊なキーキャップの入手が課題になる。必然的に特注品になってしまうので高価なことが多い。
ErgoDox 用キーキャップ
前述の通り、ErgoDox のキーキャップをカスタマイズする場合は、特殊なサイズのキーキャップを揃える必要がある。必要数は以下の通り(参考1、参考2):
- 1x: 60 個(普通のキーと同じサイズ)
- 1.5x: 12 個(Tab キー程度のサイズ。両脇に配置)
- 2x: 4 個(シフトキー程度のサイズ。親指部分に配置)
また、段差付き(=各段で形状が異なる)の sculptured のキーキャップの場合は、各段 (row) ごとに個数を合わせる必要がある。以下は一例(参考):
- 16 - Row 1 - 1u
- 14 - Row 2 - 1u
- 10 - Row 3 - 1u
- 20 - Row 4 - 1u
- 2 - Row 1 - 1.5u
- 2 - Row 2 - 1.5u
- 6 - Row 3 - 1.5u
- 2 - Row 4 - 1.5u
- 4 - Row 2 - 2u
段数の数え方はキーキャップのメーカーによって異なるので注意してほしい。
プロファイル
市場に出回っているキーキャップには様々な形状があり、形状ごとに「○○プロファイル (profile)」という名前で呼ばれている。プロファイルの詳細については、Reddit の Wiki や Geekhack のスレッドなどが詳しい。代表的なものには以下がある:
ErgoDox EZ 公式で買えるのは、文字なしで段ごとに形状の異なる (sculptured) の DCS プロファイルと、文字入りで上面が真っ平な代わりにキャップ同士の入れ替えが可能な DSA プロファイルの二つ。
- Our Keycaps | ErgoDox EZ
- Finishing up the ErgoDox - adereth(各プロファイルの断面図が載ってる)
11月頃?からキーキャップの単品売りもしてくれるようになったが、かなりいいお値段 ($90) なので本体とセットで買った方が良い(これでも相場的には安い方だったり…)。
JIS 配列の文字刻印が入っているキャップは、現状では下記の FILCO が販売している製品しか入手できない。
FILCO Majestouchシリーズ専用交換用キーキャップセット 日本語108キー(91キー兼用) カナなしモデル ブラック FKCS108NB
- 発売日: 2014/12/18
- メディア: Personal Computers
当然、ErgoDox 用の 1.5x や 2x のキャップは含まれていないので EZ 付属のキャップと組み合わせる必要がある。しかし、これは OEM プロファイルというかなり背丈が高いプロファイルで DSA プロファイルとは組み合わせにくい(DCS もおそらく同様)。そこを我慢して使うならアリか。
材質
ABS 樹脂製と PBT 樹脂製の二種類がある。基本的には PBT の方が高級で、耐久性が高く摩耗によるテカリが出にくいが、加工しにくいという難点がある。そのため、特にデザイン性の高いキーキャップには ABS 製が多く、PBT 製は刻印のない無地のキーキャップに多い。
また、キートップに印刷されている刻印が摩耗で消えてしまう問題があるが、"double-shot" と呼ばれる二色成形のキーキャップなら回避できる。
入手方法
国内ではほぼ入手できないので、海外からの輸入が基本になる。
キーキャップメーカーの詳細は下記の記事が詳しい:
キーキャップをバラ売りで欲しい場合は、Pimpmykeyboard.com や WASD Keyboards などのオンラインショップから購入できる*2。色や形をカスタマイズしたい場合は利用することになるだろう。その他の取り扱い店の情報はこちら。
自作キーボード界隈では、Massdrop に代表される共同購入 (group buy) サイトで不定期に募集される特注品のキーキャップを購入することも一般的に行われている。普通は通常のキーボード用ばかりだが、稀にオプションで ErgoDox 用セットが提供される場合がある。いずれの募集 (drop) も一週間程度で募集が締め切りになるので、定期的にチェックしておくとよい。2ch のキーキャップ総合スレでは Massdrop 以外の共同購入の情報も共有されている(物によっては品質が怪しい場合もあるようなので注意)。
WASD Keyboards では、キーキャップに好きな文字をプリントできるオプションを提供している(1個あたり7ドル)。お金があるなら JIS 配列を刻印したものを作ってもらう手も…?
ケーブル
この項については ErgoDox users meet up で発表した。
仕様
ErgoDox は、マシン本体との接続に使う Mini USB の他に、セパレートしたキーボード同士を接続するための 直径 3.5mm の TRRS ケーブルが必要。これは、国内では「4極ステレオミニプラグ」と呼ばれてオーディオ用で流通しているものと同じもの。
2極や3極との見分け方は、コネクタ部分が3本の線で4つに分かれているかを調べる。
市販品
ErgoDox EZ に付属してくる TRRS ケーブルは長めで無骨な感じのものであり、できればもっといい感じのものに買い替えたい。が、4極のオス/オスでケーブル長が短めのもの、という製品は数が限られる。
現状では、ダイヤテックが販売している Matias Ergo Pro 用のケーブルを流用するのがおすすめ。巻き取り式なので長さの調節が容易なのが良い。
あと、こういうのもあるが、買ってみたところかなり短いので広げて配置したい人には厳しそう。
エスエスエーサービス [ 3.5mm4極ステレオミニケーブル ] オス - オス [10cm] ST35-AM01R4
- 発売日: 2016/03/03
- メディア: エレクトロニクス
オーダーメイド
ErgoDox 向きの素敵な TRRS ケーブルが不足しているのは海の向こうでも事情は同じらしく、自作しちゃう人もいるようだ。
そんな需要に応えてなのか、ケーブルをオーダーメイドで作ってくれるサービスがあり、色とか長さとかを自由に選べる。日本への配送もやってくれるっぽいが、送料込みで四~五千円くらいするのが難点。
CPU 切替器(KVM スイッチ)
今までサンワサプライ製の CPU 切替器を使っていたんだけど、どうやら ErgoDox とキーボードエミュレーション機能の相性が悪いらしく、差しても Windows で認識されない。*3
以下、手に入る範囲でいくつか試したので紹介する(6/10 現在)。現在は ATEN の製品を使っていて、マウスキーが使えない以外は切り替え時のラグもなく満足している。
メーカー | 製品名 | Linux (Ubuntu) | Windows | マウスキー | 備考 |
---|---|---|---|---|---|
サンワサプライ | SW-KVM2LU | ◯(即時) | × | ? | ディスコン。後継機は SW-KVM2LUN |
バッファロー | BSKMRA201 | ◯(ラグ小) | △(ラグ大) | ◯ | - |
RATOC | REX-430UDA | ◯(ラグ小) | △(ラグ大) | ◯ | - |
ATEN | CS692 | ◯(即時) | ◯(即時) | × | - |
ATEN は国内メーカーに OEM 供給しており、中身は ATEN 製というものがけっこうある。ATEN 自身のブランドで販売されているものは、ファームウェアの更新に対応している点がメリット。サンワサプライ製品も ATEN OEM が多いので、最近の製品でファームウェアが最新になっているなら使えるかもしれない。
ScalaMatsuri 2016 でスタッフ&発表やりました
だいぶ出遅れましたが、ScalaMatsuri 2016 の参加報告です。
発表者として
今回、CFP に応募して当選した「なぜリアクティブは重要か (Why Reactive Matters)」というタイトルで発表をさせていただきました。投票してくださった皆様、聞きにきてくださった皆様、ありがとうございます。
発表に使ったスライドは以下になります(発表は英語スライドでしたが日本語化しました):
www.slideshare.net
今回はプログラミングの話題に重点を置きつつ、〈リアクティブ・コンポーネント+データフロー〉という構図が、非同期プログラムのコードから分散システムのアーキテクチャまで、様々なスケールで出現する様子をご紹介しました。
最後でチラリと触れた「イミュータブル・インフラストラクチャ (Immutable Infrastructure) みたいなキーワードが流行ったわりには、DevOps のツールチェインって命令型ばっかで関数型の知見が全然入ってないよね」という話は、そのうちどこかで改めて扱いたいと思っています。
あと、タイトルの元ネタである「なぜ関数プログラミングは重要か」自体についてはあまりちゃんと紹介できませんでしたが、先日、解説記事を書きましたのでご興味があればぜひ。
81 枚分の内容を 40 分の時間内に収めて話すという所はクリアしたものの、「内容が頭に入ってこなかった」というご意見も頂いており、そこは反省点ですね。精進します。
そろそろ、怒涛のスライドストリームをバックプレッシャー無しで叩きつけるスタイルは何とかした方が良い感はある。
— Yuta Okamoto (@okapies) February 1, 2016
参加者として
当日はスタッフとしてバタバタしてたので頻繁に中座してましたが、聞きたかった発表については翻訳チーム内でローテーションを調整してもらったのでガッツリ聞けました。ありがとうございます。
- 1日目:
- リアクティブ・マイクロサービス (Christopher Hunt)
- レジリエンスが無ければ、他は無いも同じ (Jonas Bonér)
- The Zen of Akka (Konrad Malawski)
- 実戦Scalaz-Stream: 既存のバッチシステムを置き換える (Mathias Sulser)
- 2日目:
- アンカンファレンス朝会
- Kafka Tuning (@xuwei_k)
- Async Testing in ScalaTest 3.0 (Bill Venners)
- Typesafeの人にリアクティブについて聞こう(パネルディスカッション)
- パネルディスカッション:Scala社内教育
一日目は、とにかく Jonas Bonér さんの発表が圧巻でした。スライドだけ見ていると「???」という所が多いのですが、実際に聞くと本当に分かりやすい。あと、スライドは字幕付け作業の一環で事前に目を通していたのですが、まさか冒頭で「○ッキー」のテーマをブッ込んでくるとは思わなかった(笑。
〈レジリエンス〉というキーワードについては、今回、翻訳チーム内でもどう訳すかについて散々議論したのですが、日本語にピッタリと対応する言葉がない、なかなか奥深い概念です。リアクティブ・マニフェストの翻訳では〈耐障害性〉としたのですが、そのまま〈レジリエンス〉と訳すより仕方がないという結論になったので、マニフェストの方も変更するかもしれません。そのうち講演動画もアップする予定なので、その際に私も解説記事とか書きたいですね。
二日目は、朝会に始まり Typesafe メンバーのパネルと Scala 社内教育のパネルと、一日に三回も司会に登壇するという自分でも謎の大車輪をやっていました。貴重な経験ができたと思います(笑。
来日中の Typesafe メンバー全員に参加していただいたパネルディスカッションについては、まぁぶっちゃけると私がどうしても話を聞きたかったので、麻植さんに出演交渉の仲介をお願いしたり、TIS の前出さんと根来さんにも加わって頂いて作戦会議したりして、なんとか形になりました。皆様、本当にありがとうございます。
内容としては、Typesafe 社の技術開発やビジネスの方針について、今までドキュメントやプレスリリースから憶測していた部分のニュアンスがかなり明確になったので、個人的には大満足でした。今までウェブ上で明言されてなかった話とかも飛び出したし…。
社内教育パネルについては、そもそもの「何を、どういう順で教えるべきか」という点が人によって意見に隔たりがあることが確認できたものの、できればもう少し深堀りできると良かったですね。司会として、事前にインタビューとかしておくべきでした。
スタッフとして
今回、準備委員会では「翻訳チーム」のリーダーを任せていただきました。仕事内容はこんな感じですか:
- 同時通訳者の派遣の手配と、当日の対応
- メールやリリースの文面の翻訳・レビュー
- CFP の英訳・日本語訳とウェブサイト掲載
- 発表スライドの CoC compliance レビュー、英文レビュー、字幕作成、etc..
- 海外参加者の渡航に関するフォロー
今回、同時通訳はケイワイトレードさんにお願いしました。PyCon の方から良い評判を伺っていたことが決め手になって依頼したのですが、当日ご来場頂いた方はお分かりの通り、非常に質の高い通訳を提供して頂けました。
これは、通訳者の皆さんがプログラミングについての知識をしっかりとお持ちであったことが大きいです。また、発表者に対するインタビューなどの事前準備もしっかりしていました(自分がインタビューを受けた際も、「アクターは、オブジェクト指向で言うところのオブジェクトと同じものですか?」という的確な質問を受けて感心しました)。今回の ScalaMatsuri は、関数型プログラミングの専門用語が飛び交うたいへん難しい依頼だったと思いますが、期待以上の仕事をして頂けたと思います。
翻訳の実務については、今年も横田さん (@eed3si9n_ja) に大きく依存してしまい申し訳ありませんでした…。ただ、今年は皆様のご協力のおかげで、去年よりもワークロードが分散化できたかなと思っています。竹井さん (@taketon_)、木村さん (@kimutansk)、田中豪さん (@tan_go238)、田中翔さん (@tshowis)、岡田さん (@ocadaruma)、大村さん (@everpeace)、青山さん (@aoiroaoino)、河内さん (@kawachi)、その他ご協力頂いたスタッフの皆さん、ありがとうございました(順不同)。
行動規範 (CoC) について
昨年から始めた行動規範の文面の見直しや、マナー動画のアイデア出し、各種資料の compliance レビューに参加しました。
行動規範のあり方についてはスタッフ内にも色々な考え方がありますが、個人的には規範的な面より啓発的な面を重視すべきという考え方で意見をしていました。要は、ルールを定めるのは「開かれたカンファレンス」の実現が目的であって、違反者の断罪が目的ではないということです。
Scala Matsuri は、様々な地域やコミュニティから集う技術者に対して開かれたカンファレンスを目指しています。特に、性別や人種など、多様な背景を持つ人々が互いに敬意を払って楽しい時間を過ごせるよう、当カンファレンスでは、発表者や参加者、スポンサーの皆様に以下の行動規範を守っていただくようにお願いしています。
また、こうした取り組みは我々だけがやっても意味がないので、他のカンファレンスにも輪を広げていきたいと思っています。今回の行動規範の文面やマナー動画は、皆さんのカンファレンスでどんどんパクって頂くことを前提に作っています。ご自由にお使いください。
一方で、行動規範を真面目に運用しようとすると、資料のレビューやクレーム対応等に少なからずコストをかける必要があるのも確かです。技術カンファレンスの多くがボランティアで運営されている以上、いきなり完全なサポートは難しい場合も多いと思います。
私は、段階的な導入で構わないと思います。行動規範は、先ほども書いたように、「正義の実現のため」というよりも「参加者の間口を広げるため」にあると考えるからです。また参加者の方も、自分が参加するカンファレンスに行動規範がない場合に、そのことを責めるのではなく、自分から手を挙げて仕組みの整備に協力するくらいの心構えを持って頂けると良いのではないかと思います。
まとめ
2013 年の Scala Conference in Japan 以来、3回ほどスタッフとして関わってきましたが、国内外の濃い面子がここまで一堂に会する機会を実現できたのは始めてだと思います。個人的には、他の技術カンファレンスを通して考えても例がありません。例えば、吉田さん(Scalaz コミッター)と Bill Venners さん(Scalatest 作者)の対話が実現した件は、その最良の成果の一つだと思います。
また、同時通訳については導入して本当に良かったと思います。私も含めて、数年前よりも英語スキルが上がってきている面子が増えているものの、双方向に議論をするとなると、まだブ厚い壁が存在します。その垣根が取り払われることで、日本語話者と英語話者が同時に登壇してパネルディスカッションをやる、といったことも実現できるようになりました。「Scala の国際カンファレンスをやる」という目標に対して、大きく近づいたと思います。
参加者の皆さん、発表者の皆さん、そしてスタッフの皆さんの貢献に感謝します。ありがとうございました。
聞きたかった話が全部聞けたし、自分の意見を人に聞いてもらう機会も貰えたし、今まで参加した中で一番密度の濃いカンファレンスだったと思う。皆さんの参加とか貢献があってこそ実現した機会だと思うので、とにかく感謝感謝ですね。 #ScalaMatsuri
— Yuta Okamoto (@okapies) January 31, 2016
ReactiveSocket について
この記事は、Java Advent Calendar 2015 の 22 日目です。前日は、n_slender さんの「PlayFramework 2.4 Java Ebeanでのアプリ開発」でした。
今日の記事では、この半年くらいで仕様と実装が出てきている ReactiveSocket というプロトコル仕様についてお話したいと思います。
なぜ Java Advent Calendar でプロトコルの話を? と訝しがっている方も多いと思いますが、基本的には以下の二つの理由です。
- JEP 266 として JDK 9 に追加される予定の Reactive Streams と密接に関わっている
- Java 製のサーバサイド向けライブラリを多数 OSS 化している Netflix が中心になって仕様策定を行っており、参照実装も JVM 向けが中心
予定ではプロトコルレベルの話にも踏み込んで解説したいと思っていたのですが、プライベートが色々と立て込んでいるため、概要レベルのご紹介になることをお許しください。
ReactiveSocket って何?
ReactiveSocket is an application protocol providing Reactive Streams semantics over an asynchronous, binary boundary.
(ReactiveSocket とは、非同期バイナリ境界をまたいで Reactive Streams のセマンティクスを提供するアプリケーションプロトコルである。)
ざっくり言うと Reactive Streams の考え方をアプリケーションプロトコルのレイヤで実現するための仕様。
そもそもの Reactive Streams とは何か、については以前に書いた記事でも解説しているのでご参照ください。
要点としては、メッセージ駆動のコンポーネント間でメッセージをやり取りするシステムを組んだ際のフロー制御の方法を定めている。
具体的には、送信側が受信側の処理能力を超える量のメッセージを送信してバッファを溢れさせることのないように、受信側から送信側に対して「次は◯個送っていいよ」というフィードバック (back-pressure) を通知することで、過負荷の際に処理能力を超えるメッセージを受信してシステムがクラッシュする事態を回避することを狙っている。詳細な動作については、以下のスライドの図も参考にしてほしい:
特徴
ReactiveSocket の特徴は以下の通り:
メッセージ駆動
(HTTP2 と同様の)非同期なメッセージ駆動であり、全ての通信は、単一のコネクション上に多重化されたメッセージストリームを介して行う。また、これによってレスポンス待ちでブロックすることがなくなる。
相互作用モデル
ReactiveSocket は複数の相互作用 (interaction) モデルをサポートしている。ユースケースごとに適切なモデルを選んで使用することで、性能やユーザ体験に与える影響を向上できる。
また、後述するようにトランスポートに何を使うか (TCP, WebSocket, Aeron, ...) に依存しないので、これらを使ってアプリケーションを実装すれば、性能特性に合わせてトランスポートを入れ替えることもできる。
- Fire-and-Forget(撃ちっぱなし)
- レスポンスが必要ない場合は、これを使うのが一番効率的
Future<Void> completionSignalOfSend = socketClient.fireAndForget(message);
- Request/Response(単一レスポンス)
- 普通のリクエストレスポンス。「レスポンス1個のストリーム」を最適化したものと考えることができる
Future<Payload> response = socketClient.requestResponse(requestPayload);
- Request/Stream(有限個の複数レスポンス)
- 「コレクション」や「リスト」に相当
Publisher<Payload> response = socketClient.requestStream(requestPayload);
- Topic Subscription(無限個の複数レスポンス)
- 「プッシュ通知」や「イベントストリーム」に相当
Publisher<Payload> response = socketClient.requestSubscription(topicSubscription);
- Channel(双方向ストリーム)
- クライアント側から途中でリクエストの条件を変更したりするような場合に用いる
Publisher<Payload> output = socketClient.requestChannel(Publisher<Payload> input);
フロー制御
二つのフロー制御方式をサポートしている。どちらも、トランスポートレイヤではなくアプリケーションレベルの流量制御に焦点を置いている。
一つは、Reactive Streams が仕様化しているような request(n)
の非同期プル。こちらは、リクエスト発行側 (requester) から応答側 (responder) へのキャパシティの通知に使う。
もう一つは ReactiveSocket 独自のリース (leasing) という仕組みで、応答側から発行側へのキャパシティ通知に用いられる。リースは、「規定時間 (TTL) までに◯個まで送ってよし」という形式でリクエストを発行する。これによって、データセンター内のサーバ間通信のようなユースケースで、アプリケーションレベルの負荷分散(クライアント側で、各サーバから通知されたリースの情報を使ってリクエストを分散する)がやりやすくなる。
多言語 (polyglot) サポート
相互作用モデルとフロー制御を言語非依存なプロトコルとして定義しているので、言語を跨いだインタラクションに利用できる(Reactive Streams は JVM 上で動作するミドルウェア同士でしか利用できない)。
様々なトランスポートレイヤをサポート
ReactiveSocket 自体は OSI Layer 5/6 相当のアプリケーションプロトコルであり、TCP 以外にも WebSocket や Aeron (*)、Quic といった様々なトランスポートプロトコルの上に実装できる。
また、ReactiveSocket が定義するアプリケーションレイヤはトランスポートの差異を隠蔽するので、ユースケースに合わせて最適なトランスポートを選ぶことができる。
*: Reactive Manifesto の執筆者の一人である Martin Thompson の会社 Real Logic が開発しているトランスポートプロトコル。元 LMAX の CTO で Disruptor を開発していた御仁、といえば分かる方もいるのでは。
性能
コネクションを使い回すので、コネクションを何度も張り直すような余計な処理を回避できる。また、バイナリプロトコルなので CPU 負荷を削減できる。さらに、フロー制御が組み込まれているので、相手先システムがスローダウンしている時にリトライ地獄を仕掛けてさらに負荷をかけるようなことがない。
同様の課題を解決する仕組みとして、Netflix が自身のマイクロサービス同士のフロー制御に使っている Hystrix があるが、オーバヘッドや複雑さが増すという問題点があった。
なんで HTTP/2 を使わないの?
大雑把に言うと、HTTP/2 は一義的にウェブサイトからドキュメントを取得するブラウザのためのプロトコルで、ReactiveSocket が想定するユースケースに合わないから。
- リクエスト/レスポンスのみで、それ以外の相互作用モデルをうまくサポートできない
- アプリケーションレベルのフロー制御の仕組みがない
- REST は非常に普及しているが、アプリケーションのセマンティクスを定義するのに使うのは非効率で不適切である
対応実装と今後について
コアライブラリとして reactivesocket-java が公開されている。これ自体はプロトコル実装を Reactive Streams API でアクセスできるようにしたもので、実際には以下のような具体的なトランスポートプロトコルの実装でラップして使う:
また、ブラウザや Node.js から使える JavaScript 版の実装も作られている:
- reactivesocket-js
- reactivesocket-js-ws(今のところ空っぽ)
今後…については最近あまり追いかけられてないので分からないです。すいません。とりあえず、Netflix 内部のフロー制御を Hystrix から置き換えていきたいのだとは思われる。具体的な進捗を知ってる人がいたら教えて下さい。あとは、Reactive Streams に参加してる他のベンダー(Typesafe とか)が乗っかるのかどうか(いちおう呼びかけはなされていて、Typesafe の人も関心はあるみたい)。
既に見たように、Reactive Streams 自体は JVM に閉じた仕組みだったところを、アプリケーションレイヤープロトコルとして仕様化することで多言語で活用できる可能性が出てきたわけで、個人的には注目しています。