読書会のスタイル別・メリット/デメリットを考える

自分でも読書会を開催する日が遠からず来た時に、自分ならどんなスタイルで運営するだろうか?と考えあぐねた。 今まで参加した読書会にはいくつかスタイルがあり、それぞれにメリデメがあると想像できたので、考えてみることにする。

今までに参加した読書会のスタイル

プレゼン式

章ごとに担当者を割り当てて、担当者がその章の内容とプラスアルファの内容をプレゼン形式で発表する。 また、会によってはディスカッションの議題が提示されてグループワークを行うこともある。

音読式

1, 2ページくらいの文章を指定して、その場で決まった担当者が音読する。その後、気になったことを議論する。これを繰り返す。

黙読式

1, 2ページくらいの文章を指定して黙読する。その後、その部分の論理構造や内容について議論する。これを繰り返す。

メリデメ

表にしてみた。

評価点 プレゼン式 音読式 黙読式
時間あたりの進みが速い ⭐⭐⭐ ⭐⭐
1回休んだあとの参加しやすさ ⭐⭐⭐ ⭐⭐
メンバーの負担が低い ⭐⭐ ⭐⭐
議論の粒度が細かい ⭐⭐ ⭐⭐
大人数でやりやすい ⭐⭐⭐ ⭐⭐

総合的にどの場面でも適した読書会の形式はなくて、これらのパラメータのうちどれを重視するかだと思う。

プレゼン式を採用すると良さそうなケース

  • 部屋を取りにくいなど、回数を重ねること自体が負担になる場合。
  • 読むスピードの足並みを揃えるのが難しい大人数の場合。

音読式を採用すると良さそうなケース

  • ライト層に「とりあえず出てみるか」と思ってもらいたい場合。
  • メンバーが集まるコストが低い場合。
  • まとまった時間が取れない場合。

黙読式を採用すると良さそうなケース

  • 少人数で少しずつ議論をして認識をあわせながら進みたい時。
  • メンバーが集まるコストが低い場合。(音読式と同じ)

現場で役立つシステム設計の原則のデータソース層とドメインモデルのつなぎこみに感動した

f:id:blackawa:20171010152910j:plain

www.amazon.co.jp

会社の同僚と読み合わせをしているのだけど、面白い本。 Java(というかSpringBoot)を使って、ドメイン駆動設計の考えに従って変更に強いアプリケーションを設計・実装していく方法がまとめられている。

レイヤードアーキテクチャドメインモデル

増田さんは以下のような3層 + ドメインモデルの構造を示している。

(わかりやすい絵)

が、読んでいると実際にはPresentation層、Presntation層と結びついたApplication層、Application内部の小さな業務ロジックを担当するApplication層、ドメインモデル、ドメインモデルの一部としてのDatasource層、実際にSQLAPIで情報を取得したり登録したりするDatasource層、くらいには層が分かれているねという理解になった。

(わかりやすい絵)

こういう暗黙の了解とか言い換えはそこそこ本著に入ってる気がした。

Datasource層とDBのコミュニケーションどうするの?

レイヤードアーキテクチャの章で感動したのは、データソース層とDBのコミュニケーション方法。 本著では、アプリケーションのシステム的構成と業務ロジックを「レイヤードアーキテクチャ」と「ドメインモデル」に分離しようとしているが、読み進めていて「いやそれはわかるけど、結局データソースとつながないといけないじゃん」と思っていた。

そしたらサンプルコードと共に解説されていた。

DataSourceのInterfaceはドメインとして定義して、それを実装する @Repository アノテーションがついたDatasource層を用意する。 Datasource層は内部でORマッパーを持っていて、そいつがDBとコミュニケーションして、結果をドメインモデルに詰めて返してくれる。

たしかにこれなら、Datasource層にアクセスしたらあたかもドメインが取得できているように振る舞える。

言いたいことはわかるけどどうやるの?と、言葉にできないレベルでモヤモヤしていたことの実装例を見られてスッキリした。

ゴツいCSVファイルをなんとかしてINSERT文に書き換える

Spacemacsに取り込めない50万行くらいあるCSVを、SQLに書き換えてDBに適用する必要があった。

こういう時、毎回コマンドラインを調べてる気がするのでまとめる。

改行コードCRLF -> LF

元データがExcelのシートで来たので。

cat data.csv | sed -e 's/\r\n/\n/g'

重複行削除

データに重複が混じっていたので。

sort data.csv > sort.csv
# 件数が変わっていないことを確認
wc -l *.csv

uniq sort.csv > data.csv

1行目にinsert文を書く

echo 'insert into xxx (...) values' > insert.sql

各行をSQLのパーツに使えるようにフォーマットして2行目以降に配置する

cat unique.csv | sed -e 's/^/(/g' | sed -e 's/$/),/g' >> insert.sql

最終行だけ ,; にする

sed -e '$s/,$/;/g' insert.sql > complete.sql

これで source すればok。 これ絶対また忘れるわ。

Spacemacsデビューした

f:id:blackawa:20171003215304p:plain

久しぶりにEmacs触り始めたんだけど、ふと思い立ってSpacemacsデビューしてみた。 なんかあっても既存のEmacs用の.emacs.dはdotfileに残ってるし、と思って。

インストール

github.com

のREADME.mdを見るのが良さそう。

僕は今入ってるEmacsを一度アンインストールして、READMEどおりにemacs-plusを入れ直した。

Clojureを書く

最初に起動するとVimライクなキーバインドにするかEmacsライクなキーバインドにするかとか聞かれる。

qiita.com

でオススメされたとおりにVim(Evil)を選ぶ。

最初にインストールが終わった状態では全然キーボードが動かなかったから一回再起動したら動き出した。

elnodeでweb serverを起動してみる

Emacsといえばweb serverなのでelnodeを入れる。が、layerはなさそう。 いろいろあがいた挙句、結局<list-packages>からのelnodeを選んでインストールしてしまった。負けた。

適当な.elファイルを開いてサンプルコードをコピペすれば動く。

additional-packageにgithubを指定したりもしてみたけど思ったとおりに動かない。負けた感ある。

ハマりどころ

これはMacEmacs触る人はよくぶつかるのかもだけど、MacにはもともとEmacsがインストールされている。( /usr/bin/emacs ) ので、PATHで /usr/local/bin/emacs を最初に評価させて、brewで入れたEmacsが起動するように設定する。

マイナーなライブラリを入れるには少しlayerの学習が必要そう。

JVMツールの簡単インストーラー、sdkmanのことを紹介させてくれ

f:id:blackawa:20171003133129p:plain

SDKMAN! the Software Development Kit Manager

この完全に他のツールとかぶりそうな名前、かつアメコミみたいなアイコンのツールが、まー便利。 わりと前からあるから、みんな知ってるかもしれないし、そもそもこのツールについて人と話したことがあんまりない。けど、個人的に紹介したいからさせてもらう。

sdkmanとは

インストールすると、sdk install xxx みたいな感じでJVM系の各種ツールをインストールできるツール。

なんとJavaもインストールできる。

もうこれで良くない?

使い方

Installation - SDKMAN!を読んでくれ。 brewのインストールと同じでインストールスクリプトbashで実行するだけ。ちょう簡単。 .bashrcとか.zshrcの末尾にちょっと勝手に追記されるから、それだけ確認しておいて。

試してみる

手元のMacはすでに環境構築済みなのでVagrantで建てたubuntuで試す。

vagrant init ubuntu/xenial64
vagrant up
vagrant ssh

# ここからubuntu
curl -s "https://get.sdkman.io" | bash
# unzipコマンドがないよって怒られる。実はunzipを入れても次はzipがないよって言われるので入れておく
sudo apt-get install unzip zip
curl -s "https://get.sdkman.io" | bash
# インストール成功して.bashrcと.zshrcの末尾にちょびっと追記される。
source "/home/ubuntu/.sdkman/bin/sdkman-init.sh"

# インストールできたか調べる
sdk version

# Javaをインストールしてみる
which java # -> 何も返ってこない
sdk install java 9.0.0-zulu
which java # -> /home/ubuntu/.sdkman/candidates/java/current/bin/java
java --version
# openjdk 9.0.0.15
# OpenJDK Runtime Environment (Zulu build 9.0.0.15+181)
# OpenJDK 64-Bit Server VM (Zulu build 9.0.0.15+181, mixed mode)

# Mavenもインストールしてみる
which mvn # -> 何も返ってこない
sdk install maven
which mvn # -> /home/ubuntu/.sdkman/candidates/maven/current/bin/mvn

# 動く
mvn archetype:generate # 当たり前だけどすごい

簡単すぎ。Javaインストールできるってすごい。

既存のツールが入っちゃってる人へ

消して。

brewで入れたなら brew uninstall xxx しよう。 Windowsならバイナリを消して環境変数PATHに入れた設定とかを消せばいいんじゃないかな。

Macならbrewとかportとかあるから、こういうのは特にWindows勢にとってめちゃめちゃ強力なツールになると思うな。

Overtone始めたらClojureのシーケンス操作の哲学にマッチしすぎててスゲー!ってなった話

とうとうライブができるプログラマーになることにしたので、Overtoneを始めた。

目標

  • (SHOULD)音作りを雰囲気だけかじる(ここは今回重要でない)
  • ドラムで軽やかなリズムを奏でる
  • ドラムに合わせてメロディが流れるようにする
  • だんだん音を足していく
  • (SHOULD)フィルターをかける

これくらいできればなんかそれっぽい感じになるでしょ。

始め方

github.com

を読んで頑張ろう。変化に耐えられる心を持てってwikiに書いてあったから、変化に耐えられない日記はポインタと化します。

使い方メモ

definst

楽器(というか音色)を定義できるっぽい。デフォルトでもいろいろあるけど。

ctl

今鳴っている音に対して変更をかけられる。なんかライブっぽくてかっこいい。 フィルターをだんだんかけていく、みたいなのもこれを使えるのかな。

(definst quux [freq 440] (* 0.3 (saw freq)))
(quux)
(ctl quux :freq 660)
;; => 1オクターブ上がる
(stop)

sample

サンプリング音源を鳴らす。 freesoundっていう無料音源サイト?からダウンロードすることもできるみたい。 コマンド叩いたらブラウザが開いて、ログインを求められた。面白い。

(def water-drops (freesound 50623))
(water-drops)
;; => 水音が鳴る
(stop)

この音を加工したりもできるんだろうな。

play-chord

コードを鳴らす。

(defn play-chord [a-chord]
  (doseq [note a-chord] (saw2 note)))
(play-chord (chord :C4 :major))

すごい。 chordはdoseqできるみたいだから、多分 chord 関数はシーケンス生成してるんだな。 実装見たら実際そうだった。すごい。こんなところでClojure likeなシーケンス操作が出てくるなんて!

ってことは、chordはシーケンスだから複数のコードを合成する、みたいなこともできるのか。 たとえばCmM7を鳴らしたい時は、

(let [minor7 (chord :C4 :m7)
      major7 (chord :C4 :M7)]
  (-> (concat minor7 major7)
       distinct
       play-chord))
;; =>  不穏な音

play-chordされる前の Set シーケンスの中身を見てみたら合ってそう。 こんなに簡単に複雑なコードを鳴らせるなら、ジャズが捗りますな(雑な偏見)。

metronome

ビートを定義する。

(defonce metro (metronome 120))

(metro) すると今のビートが取れるようになる。これを渡して、at関数で任意のタイミングでビートが鳴らせるようになる。

(defn chord-progression-beat [m beat-num]
   (at (m (+ 0 beat-num)) (play-chord (chord :C4 :major)))
   (at (m (+ 4 beat-num)) (play-chord (chord :G3 :major)))
   (at (m (+ 8 beat-num)) (play-chord (chord :A3 :minor)))
   (at (m (+ 14 beat-num)) (play-chord (chord :F3 :major)))
   (apply-at (m (+ 16 beat-num)) chord-progression-beat m (+ 16 beat-num) []))

けっこう冗長だから、もっとシンプルに書けそうだな。

とはいえ、これを実行すると延々けっこうきれいなコード進行が鳴り続ける。プログラミングで実現してるなんて。すごい。 しかもこれはシーケンスを解釈してるだけ。なんてこった!シーケンスすげぇな。

これの実行中は、関数を再定義すると apply-at された時に定義が書き換えられて新しいコード進行が始まる。

さらに別の、たとえばドラムトラックを書いて評価すれば、それがメトロノームに合わせて演奏される。

metro-npm

metronomeの内容を書き換える。つまりテンポを変えられる。

そういえば小節の概念がないな。 多分、ループを作った時のapply-atするタイミング次第で変拍子でもなんでもいいんだろうな。

わからないこと

sc-ugenっていうオブジェクトを足し算したり掛け算したりするサンプルコードの意味がわからない。 SuperCollider Unit Generatorのことらしいから、SuperColliderをちょっとさわってみないといけないのかな。

あとは、そもそもオシレーターってなんだっけ??SAWって波の形だよね?みたいなレベルで音楽用語がわからない。 DAWさわっててもギター弾いてても曲書いてても、わからないことだらけだぁ。

https://github.com/overtone/overtone/blob/master/docs/ugens.mdを見てる限りは、サンプルコードに出てきて宣言元を辿れないやつはこのsc-ugenオブジェクトだったから、ugensのページに対応するものがありそう。

Clojureを書く時についつい忘れがちなキーバインドまとめ

最近2ヶ月ぶりくらいにClojureを書き始めたら、手癖で覚えてるキーバインドもありつつ、なんかここらへん押せばいいって手が勝手に動くけどちょっと違うらしくて動かない、ってやつもあり。

毎回思い出すのつらいからまとめることにした。

キー 起こること
<C-c><M-j> REPL起動
<C-c><C-q> REPL停止
<C-c><M-n> 今カーソルが開いているnamespaceに、REPLを移動させる
<M-.> 宣言に飛ぶか聞かれる
<M-,> <M-.>で飛んだ元に戻る
<M-s> 今カーソルがある位置から見て直上のカッコを消す