Kotlin のコルーチン入門

この記事は何か? Kotlin のコルーチンライブラリに kotlinx.coroutines がある。このライブラリには丁寧なドキュメント が付随しており、それを一歩ずつ写経しながら訳していく。なお、全文を訳してはいないし、自分で書き足した部分もある。興味を持っていただけたのであれば、原文にあたることをお勧めする。 はじめの一歩を踏み出す import kotlinx.coroutines.* fun main() { GlobalScope.launch { // 新しいコルーチンを作りバックグラウンドで動作させる delay(1000L) // 1秒待つ (non-blocking) println("World!") } println("Hello, ") // コルーチンが待っている間メインスレッドが動き続ける Thread.sleep(2000L) // メインスレッドを止めないように sleep する } これの出力結果: Hello, World! コルーチンは軽量なスレッドであり、CoroutineScope の launch で作成できる。このサンプルでは GlobalScope.launch {} でコルーチンを作っており、これはアプリケーションそのものと同じライフサイクルを持つ。 なお、これと同じことは普通の thread でも実現できる。 import kotlin.concurrent.thread fun main() { thread { Thread.sleep(1000L) println("World!") } println("Hello, ") Thread.sleep(2000L) } ブロックする箇所を明示する non-blocking な delay() と blocking な Thread. [Read More]

Structured Concurrency

import kotlinx.coroutines.* fun main() { printThreadName("start") runBlocking { val job = launch { val result = computeResult() printThreadName("$result") } delay(500) job.cancel() } Thread.sleep(500) printThreadName("end") } suspend fun computeResult(): Int { return coroutineScope { val one = async { computeOne() } val two = async { computeTwo() } one.await() + two.await() } } suspend fun computeOne(): Int { printThreadName("start computeOne") delay(1000) printThreadName("end computeOne") return 10 } suspend fun computeTwo(): Int { printThreadName("start computeTwo") delay(1000) printThreadName("end computeTwo") return 22 } import kotlinx. [Read More]

【書評】自閉症・発達障害を疑われたとき・疑ったとき

この記事は『自閉症・発達障害を疑われたとき・疑ったとき』の書評です。

何を期待してこの本を読んだのか?

まだ幼い息子が一般的でない育ち方をしており、どうすれば彼の人生が良いものになるのか知りたくて手にとりました。息子には次のような特徴があります。

  • 2才を超えても一語も発しない (「パパ」「ママ」とすら言わない)
  • 呼びかけに応えない
  • 指差しではなく、親の手を動かすことで意思を伝える (いわゆる「クレーン現象」)
  • よく泣く (たとえば保育園のお遊戯会などで歌がやむと泣く)

一方で、知的な問題を抱えているようには思えません。たとえば子ども向けの辞典を開いて「X はどれ?」と聞くと、それを指差すことができます。このことから、言葉は発しないものの耳は聞こえていることがわかります。

これらを総合して「我が子には自閉傾向があるのかもしれない」と思い、この本を読みました。

期待に応える本であったのか?

医療に関わる本は批判的に読むことが重要だと考えています。医学は再現性の低い事象を扱う学問だし、根拠のないカルトのような情報も多いからです。

本書の第一章には次のような節があります。

情報は藁にもすがって見るのではなく、批判的、客観的に見ることが大切です。

薬が効いたという話だけが強調され、「効かなかったという話はない」場合は要注意です。どんな薬でも効く場合もあれば効かない場合もあり、副作用のために中断せざるを得ないこともあります。どんな治療でも「100パーセント」有効ということはまずありません。 ですから効いたということだけを宣伝している情報は、とくに体の負担になるような処置や検査をする場合には、保険外診療、保険診療にかかわらず要注意です。

著者のスタンスはわたしには望ましく思えるものです。この本ではエビデンスレベルの高い情報と著者の意見は分けて書かれています (「エビデンスレベルとはそもそも何か」という記述も本書に含まれています)。

あえて不満をあげれば、巻末リファレンスが書籍のみであるところが気になりました。エビデンスレベルの高いものについては、論文そのものも載せておいてもらえればと思いましたが、一般書にそのようなニーズはほとんどないのかもしれません。

参考になった内容

「ほめる」や「目を合わせる」などベーシックなところをのぞいて、次のようなところが参考になりました。

親が主導権を持ちながらも、子どもに「自己決定」させる

たとえば、食事のときに「準備ができたからご飯を食べなさい」ではなく、「おなかが空いていたらご飯を食べる?」「うん」「じゃあ食べよう」のように会話を進めます。

別な例では、遊び食べに対して「さっさと食べないと片付けるよ」ではなく、「もっと食べる人?」に「はい」と返事をさせたうえで「食べようね」とする方がうまくいくともありました。

指差しの練習

前述の通り、息子は指差しができません。しかし「指差し」も練習できるとのこと。子どもの手を取って人差し指を開き、指差しを補助する方法などがあるそうです。

補充代替療法 (CAM)

このような記述があります。

ASD においても実にさまざまな CAM (Complementary and Alternative Medicine: 補充代替療法) が提唱されています。共通する問題点は、成功例は紹介するが失敗例の報告はないことと、明らかなエビデンスを持った論文がないことです。

また医療であれば何を目標に行うか、という前提がありますが、CAM の場合にはそれも漠然としています。なかなか改善しない状況に藁をもつかみたい保護者の気持ちがわからないわけではありませんが、いわば障害ビジネスではないかと考えられるものも残念ながらあります。

これに続いて、「サプリメント、ビタミン」「除去食」「キレート療法 (キレート剤を水銀などの金属と結合させて体外に排出しようとする治療法)」のすべてについて、根拠が乏しいと結論づけています。「有効性が確立している…はありません」などのように書かれており、真摯な印象を受けました。

小学校における「通常学級」と「特別支援学級」

そもそも ASD であることを学校に告げるかどうか、そのメリット・デメリットについての記述があります。学校に話すことで、なかば脅迫のように「問題があるから相談に来たのですよね?」などと言われるケースがあることも紹介されています。

また、特別支援学級からはじめても「伸びたら通常学級に替わることができますよ」と教育委員会で言われることがあるそうです。これについては「過去5年間で実際に何人が替わったか?」と聞いてみることが勧められています。特別支援学級から通常学級に替わるのは実際にはかなりハードルが高いことのようです。

おわりに

息子の発育は遅れているけれど「いつかは人並みになるだろう」と楽観的に考えていました。しかし、本書を手にとって「やるべきことはたくさんある」と認識を改めました。また「小学校入学などのイベントをひかえて、悩ましいことがたくさんある」とも思いました。

自閉症や発達障害については調べ始めたばかりなので、より多角的に情報を仕入れて知見を深めていきたいと思います。

【書評】エンジニアの知的生産術 ―効率的に学び、整理し、アウトプットする

この記事は『エンジニアの知的生産術 ―効率的に学び、整理し、アウトプットする』の書評として書いています。

先に書いておくと、この本を周囲の人間に強く勧められるかと問われれば No です。一方、無碍に「この本を読むのは時間の無駄である」と切って捨てられるようなものでもないと思いました。

何を期待してこの本を読んだのか?

タイトルの通り、ソフトウェアエンジニアとしての生産性を高める術はないものかと思い、本書を手に取りました。著者の西尾さんの文章をウェブでよく拝見しており、学ぶことも多かったので期待値は高めでした。

期待に応える本であったのか?

「期待に応える本であったのか?」という問いに対する短い返答は「いいえ」になります。この本を読むことで、わたしの知的生産性が高まったかといえば、そんなことはないと思います。一方で「この本を読むことは時間の無駄であったか?」と問われれば、それにも「いいえ」と答えます。

この本が参照している『難解な本を読む技術』には「開いている本」と「閉じている本」という概念が登場するそうです。

開いている本は、読者が自分で考えることを期待して、著者が自分の意見を言っていない本です。閉じている本は、著者が自分の結論を持っており、そこへ向けて論を進める本です。 世の中の多くの本が閉じているのに対して、哲学書には開いている本が比較的たくさんあります。本書『エンジニアの知的生産術』は、私が「情報収集・モデル化・応用」のサイクルなどいくつかの結論を持っていて、それを構築していっているという点では「閉じている本」です。しかし、その私の結論の1つが「具体的にどういう方法でやるかは読者の置かれた状況によって決まるので、読者は自分でそれを構築しなければならない」なので、具体的な方法論に関してはかなり「開いている本」の立場をとっています。

著者の言う通り、『エンジニアの知的生産術』はかなり「開いている本」だと思います。

たとえば、本の読み方について扱った章では、「速読 (フォトリーディング) する技がある」「繰り返し読むという方法もある」「完全に理解できるまで先に読み進めないという方法もある」「完全に理解することをあきらめてどんどん読み進めるという手もある」のように語られます。どういう本に対してどういう選択肢を取るかは読者にゆだねられます。

これに対して、わたしは「何も言っていないのに等しいのでは」と感じました。

一事が万事、このような感じで議論が進められており、よく言えば「多方面からの意見を拾っている」ものの、読者としては「結局のところ、どうすればいいんだ?」と思わされました。

「はじめに」の節には次のようにあります。

私は … 業務の一環として、京都大学サマーデザインスクールで、考えを整理してアウトプットする方法のワークショップを行ったり、首都大学東京の非常勤講師として、大学生に研究によって新たな知識を生み出すことについて教えたりしてきました。しかし、限られた時間では伝えたいことが伝えきれません。参考書を紹介しても、たくさん紹介したのでは全部は読んでもらえません。私の伝えたいことが1冊にまとまった本が欲しいです。

この取り組みは、ある種の成功を収めていると言えます。つまり、本書の中では「Getting Things Done」や「ポモドーロ・テクニック」、「フォトリーディング」や「KJ 法」など、それだけで一冊の本が書ける (実際に書かれている) 内容がごった煮されています。

一方、どの内容も浅くしか触れられておらず、たとえば「明日からはこういう方法を試してみよう」と思えることはありませんでした。

まとめ

『エンジニアの知的生産術 ―効率的に学び、整理し、アウトプットする』を読むことで知的生産性を向上できる人は限られているように感じました。

なお、この本のレビュワーの方からも 「で、どうしたらよいの?」がわからない という意見があったそうです。これに対して、著者は次のように答えています。

材料がそろっていないと、結合は起きません。「地」は経験です。本書を読んでしっくりこなかったなら、今回は残念ながら材料が足りなかったようです。でも大丈夫です。経験は日々あなたの中に蓄積されていくので、いつか「あ、これか」とつながるときが来るでしょう。半年経ってからまた読みなおしてみてください。きっと何かが変わるでしょう。

わたしの経験不足で本書の内容を噛みしめられなかった可能性は十分にあるものの、半年後にまた読み直す気持ちになるかといえば怪しい、というのが偽らざる気持ちです。

なぜ Go では何百万もの Goroutine を作れるのに Java は数千のスレッドしか作れないのか?

(この記事は Why you can have millions of Goroutines but only thousands of Java Threads の翻訳です) 経験のあるエンジニアならば JVM 言語で次のようなエラーを見たことがあるでしょう。 [error] (run-main-0) java.lang.OutOfMemoryError: unable to create native thread: [error] java.lang.OutOfMemoryError: unable to create native thread: [error] at java.base/java.lang.Thread.start0(Native Method) [error] at java.base/java.lang.Thread.start(Thread.java:813) ... [error] at java.base/java.lang.Thread.run(Thread.java:844) OutOfMemory …スレッド作成の失敗。Linux が動いている私のノート PC では、だいたい 11,500 スレッドを作成した辺りでこのエラーが発生します。 Go で無限に sleep する Goroutine を作成すると、これとは大きく違う結果になります。私のノート PC では 70,000,000 の Goroutine を作れましたが、飽きたのでそこでやめてしまいました。なぜ Goroutine はスレッドよりもたくさん作れるのでしょう? この答えを探るためには OS を理解する必要があります。また、これは学術的な問題ではなく、実際に使われるソフトウェアをデザインするための問題です。私は本番環境で JVM スレッドの限界にぶつかった経験が何度もあります。問題のあるコードがスレッドを解放させ損ねたこともあるし、単にエンジニアが JVM スレッドの限界について認知していなかったこともあります。 [Read More]

circleci コマンド悲喜こもごも

CircleCI に導入された circleci コマンドでローカルでも CircleCI の挙動を確認できるようになった。 …というのは嘘である。 気づいただけで、ふたつ不満がある。たとえば CircleCI の cron は、システムレベルの cron がサポートする */x (x: 整数) のような記法をサポートしていない。つまり、5分おきにジョブを走らせたいときに */5 * * * * と 書けない 。かわりに 5,10,15,20,25,30,35,40,45,50,55 * * * * と書かなければならない。しかし、この問題は circleci コマンドの文法チェックでは検知できない。わたしは、これをリモートに push したあとで「うーん、動かないなぁ」と思いながら色々とぐぐって問題を発見した。つらい。 また、ローカル環境で次のように .circleci/config.yml を書くと Error: error authentication with ECR: AWS Credentials not found と怒られる。 version: 2 jobs: build: docker: - image: 00000000000.dkr.ecr.ap-northeast-1.amazonaws.com/my-image:latest aws_auth: aws_access_key_id: $AWS_ACCESS_KEY_ID aws_secret_access_key: $AWS_SECRET_ACCESS steps: - run: name: Greeting command: echo Hello, world. [Read More]

こんにちは、世界

こんにちは、GitLab

日本語のブログを広告のないスペースで書いていきたいと思いたち、GitLab にたどり着きました。GitHub はすでに英語の記事を書くために使っていたので。言語が混ざるのはよくないと思っている派です。

なお、「広告のある場所で記事を書くと想いがゆがむ」と考えるにいたった経緯についてはリンク先の記事をご参照ください。