(define -ayalog '())

括弧に魅せられて道を外した名前のないプログラマ

社会人 2 年目の女の子から相談された話

昨晩、久しぶりに高校の頃から付き合いのある女の子と話していた。その時間なんと 4 時間程…。

昨年の春から彼女*1は某 SIer な会社で働いていて、就活の頃からちょいちょい相談に乗ったりしていたんだけど今は社会人 2 年目ということでまぁぼちぼちやっているみたいだった。

「最近どうしてんのー」なんて話から始めて、色々とお仕事のお話とかしていたんだけどだいたい以下のような話をしていた。

  • 最近、プログラミングしてなくて今は見積もりとかやってるんだけど、やっぱりプログラミングしたい
  • 本読んで勉強していると途中で読むの飽きたりしちゃって最後まで読めない
  • プログラミングとかプログラミング言語の何が面白くて好きなの
  • コードを人に見てもらうの恥ずかしい
  • 一緒に仕事しているベテランパートナーさんが自分を認めてくれない

みたいな。

話の半分以上は結局悩み相談だったんじゃないかな。僕は社会人 6 年目にして転職も 2 回経験していてだいたい同じ業界にいるので、キャリアとかステップアップとかの相談相手としてはちょうど良かったんだと思う。さて、このお悩み相談室聞きながら、僕自身「どうだったけなー」と思うことが結構あったので、とりあえず記録としてどういう回答したのかとか僕自身のことをちょろっと振り返りつつ書いてみようかなーと思う。

最近、プログラミングしてなくて今は見積もりとかやってるんだけど、やっぱりプログラミングしたい

この辺、「プログラミング」との距離のとり方で変わるから一概にどうこうってないんだけど、プログラミングしたいだけなら余暇にコード書くなりして OSS にコントリビュートするとか、自分で Android/iPhone アプリ作るなり、 Web アプリ作るなりすればいいと思うんです。で、この「プログラミングしたい」が自分でプロダクトコードを書いて、「お客さんに喜んで欲しい」みたいなのを目的としていたり、なんかそういう感じの考え方でとにかく自分で会社の仕事としてプロダクトコードを書きたいんだってなると話がめんどくさくなる。 SIer の特にプロパーにいてコードを書いてられる人って僕は少ないと思っていて、それは環境とその人の性格にかなり左右されるものではあると思うんだけど、やっぱりどうしても年数を重ねるごとにコード書く機会は減りがちなのかなぁと思う*2。なので後者なら部署の異動願い出すなり、転職するなりしたほうがいいのかなと思う。前者ならとりあえず、時間をとってコード書いたらいいんじゃないかな。
彼女の場合は、今の現状に多少なり不満はあるけど、別に今すぐ転職とか考える必要もないかなーと言っていたので、勉強しようぜって話をして終わった。

本読んで勉強していると途中で読むの飽きたりしちゃって最後まで読めない

これよく分かるなーと。僕も勉強を始めたばかりの頃*3、右も左も分からなくてとりあえずいろんな本を買ったけど、なかなか最後まで読めなかったなーと。僕なりに思い当たる最後まで読み終わらない理由は以下の通り。

  • 本の頭にある面白くない話が長すぎて本題になかなか入らない
  • 自分のレベルにあってないので何書いてあるかよく分からない
  • その本を読んで自分が何を出来るようになるのかイメージできない
  • 抽象的な話ばっかりで意味が結局何が言いたいのかよく分からない

一つ目は「読み飛ばす」という選択肢ももちろんありつつ、小説好きとかだと「本を頭からお尻まで綺麗に読まないといけない」って思い込みがあったりして読み飛ばすことをしないのかなって、昨日女の子と話していて思った。なので、冒頭で著者のうんちくを延々と書いてあるような本はなかなかそれだけで損しているのではと。
二つ目、これは「あるある」だと思うんだけどどうなんでしょう。僕も結構分からないところとかあってそこで躓いたままになってる本とかある( SICP とか)。なので一回で読みきって理解しようとするんじゃなくて、一旦理解することを諦めて全体像を掴んで 2 週目するとかした方がいいんじゃないのかなと。もしくは A を理解するための前提に B があるので B を先に理解してないと理解できないとか。そういう場合は諦めて、 B を先に勉強して理解するのも手なのかなと。
三つ目は単純に飽きがくるので仕方ない。 JavaScript のサイ本とか頭から読もうとしても、わりと辛いですよね*4。あと RoR だと「手を動かして作っていきましょう」みたいな本がわりとあるイメージ*5なんだけど、 Java だとそういうのよりリファレンスよりの初心者向けの本が多かったりして何かものを作るに至る本って少ないなーと*6。入門はさせてやるけど、ここから先には進ませないぞ!!みたいな。つらい。あとこれ RoR の場合、会社で使われている技術と自分で勉強する技術が一致しやすいけど、 Java だと*7会社で使っているフレームワークStruts 魔改造版なのに、自分で勉強しようとすると生の Servlet/JSP みたいになってなかなか自分の勉強とお仕事とか結びつきにくい*8というのもこの辺の原因なのかなーとか。最近は Spring Boot が流行ってきている空気あるし、 Spring Boot の入門本とかあるのでいい流れになってきているんでしょうか。
四つ目に該当する本は今読むべきではない可能性があるので一旦本を閉じて違う本を読みましょう。もしくは価値がない本かもしれないのでいずれにしても読むのをやめようという感じ。

とまぁそういう話をしながらとりあえず、「リーダブルコード」、「リファクタリングウェットウェア」、「達人プログラマ」みたいな読み物に近い本をとりあえず勧めてみた。彼女の場合は特に二つ目、三つ目の理由が大きいみたいだったのであわせて先に書いたようなアドバイスをしてみた。

プログラミングとかプログラミング言語の何が面白くて好きなの

これね答え難いというか、説明し難いなぁと。元々プログラミングを始めたきっかけは厨ニ病こじらせた「ゲーム作りたい」というありきたりな理由だったし、それをこじらせ続けた結果 Emacs やターミナルで作業するのを比較的好むような人間になってしまった。「黒い画面でカタカタするのカッコイイと思ってしまう」病である。
それはさておき、プログラミングというのはやっぱり見えるものが出来たときに達成感がある。前々職/前職ともに Java を書くお仕事のときって、プロジェクトが最悪だったからあまりコード書いてるっていう時間って多くなかったし、オフショアな感じで自分で書いたっていう実感を得ることは少なかったんだけど、 Scheme でプロジェクトオイラーをほそぼそとやっているときはパズルが解けたときの楽しさがあってそれは良かった。 Rails を触るようになって「自分で動くものを作れるんだ」って実感するようになったし、徐々に Linux のコマンドとか多少は使えるようになって、そこでようやく「モノを作る楽しさ」みたいなのを実感出来るようになった気がする。なので僕にとってプログラミングはふたつの側面があってひとつはパズル、もうひとつはモノ作りとしての側面。どちらの側面も好きだし、モノ作りをしているときに、難問が出てきてパズルしている瞬間とかも好き。
プログラミング言語それそのものは勉強してて、言語として「こんなこと出来るの!?」みたいな発見とかがやっぱり楽しいのかなと思う。あとは元々そういう言語に対する興味が人より少しばかり強いんだと思う。それは Scheme という素敵なものに出会ってから特に強くなったのかなと。自分の考え方をどれだけ綺麗にコードに出来るか、あるいは言語としてのパワーをどれだけ自分が活かせるのか。元々レースゲーやってると自分のゴーストと戦って一喜一憂するようなことをずっとしてたりするので、その延長線で過去の自分に比べて綺麗なコードを書くことを楽しんでる節がある。そのまだ見ぬ綺麗なコードを書くために色んな事を勉強しようと思うわけで、その過程も僕は楽しんでいるんでしょうね、きっと。

コードを人に見てもらうの恥ずかしい

分かる。「そんなダサいコード書くんだ」って思われたくない、から見せ
るのを躊躇う。だけど、隠したところで「今の自分が書ける精一杯」がそれのはずで、「ダサいコード」を書いている自覚があったとしても開き直って見てもらうしかないと思う。自分じゃそれ以上どうしようもないから「ダサいコード」になってしまっているわけで、それじゃあ誰かに見てもらってレビューしてもらおうよと。

一緒に仕事しているベテランパートナーさんが自分を認めてくれない

ベテランパートナー*9さんが話聞いている感じだと 30,40 代のおっちゃんぽいんだけど、まぁ技術の人って感じらしくてわりと言動がキツイらしく、「そんなのも知らないのか」「勉強してんのか」みたいなことを言われるのがつらいとのこと。もはや人生相談。
まぁ彼女曰く「私は私なりに頑張っているのに」とのことだったんだけど、そりゃ人によって人の評価の仕方って違うし、技術面だけ見る人に「私、開発以外のことも頑張ってますよ」とか「まだ一年目なので」なんて言っても仕方ないと思うわけです。それにあなたが本来評価してもらうべき人は自分の「上司」であって、「パートナー」さんではないですよねと。なので、ひとつの方法としてはその人が何を言っても気にしないというのがある。
ただ、話を聞くとどうも「自分が頑張っていることをその人に認めて欲しい」というのがあるみたいだった。それじゃあもう勉強して見返してやるくらいの気持ちで頑張るしかないんじゃないかなと。勉強して逆に「あなたの書くコード加齢臭がしますね」くらい言えるくらいになればいいだけの話*10。ただ、どんなに頑張ったとしても「認めてもらう/褒めてもらう」って機会は大人になるとなかなかないのは理解しておくべきかな。怒るほうが簡単だからね。勿論、意識してちゃんと褒めたり/認めたりが出来るような人も中にはいますが、そう多くはないでしょう。
あと、これは気持ちが楽になるおまじない的なあれだけど、やっぱり 3,40 くらいの人とかそれ以上の人って結構な年数仕事してきてて、インターネット黎明期くらいからやってる人もいたりして、そういう人たちはある程度広く浅くなんでも知ってたりする*11。で、ここ数年で仕事をするようになって社会に出て初めてプログラミング始めましたみたいな人が、そういう人からみたら「そんなことも知らないのか」になるのはわりと仕方ない部分もあるんじゃないかなーと思っている。ので、一種の諦めだけど、あまり深く考えて鬱々するくらいならそうやってちょっと割り切ってしまえば楽になることもあると思う。

余談だけど、やっぱりこういうのってなんだかんだで人間関係をうまく構築出来ていないというのが根幹にある気がしてて、ある程度は「コミュニケーションをしっかり取る」ことで解消される気がしている。「パートナー」「プロパー」として仕事をするんじゃなくて、同じチームの人間として対等に接する努力が大事なんじゃないかなーと。お昼ごはんに誘うなり、普段から雑談してみたりすれば多少はそういう刺々しいこともなくなるんじゃないかなって気がします。何やっても無駄なこともあるけど、そういう基礎部分がおろそかになるとそもそもチームとして仕事するのも難しいですしね。コミュニケーション大事。

最後に

若かった頃に比べるとやっぱり歳をくったなと感じることが多いのが最近です。今回の子は僕と同い年なわけだけど、社会に出て長い分僕の方がなんとなく相談される側になってしまうなーと。まぁ社会人 6 年目っていうと長く感じるけど、プログラマとしてはまだまだペーペーのひよっ子同然なので、今後も精進していきたいですね。

余談

完全に余談になるんだけど、プログラミング楽しいっていう話をしているときに思わず Scheme を勧めてしまった。ちなみに環境は Emacs/Gauche な環境構築の仕方を教えてしまった。将来、立派な Lisper になってほしいと思う。

*1:記事中の"彼女"は全て三人称の人代名詞としての"彼女"であり、恋人のことではありません

*2:これに当てはまらない人もそこそこいるのは知ってるけどね

*3:4,5 年くらい前?

*4:僕はつらいので読んでませんが

*5:列車本とか

*6:分かんない、僕が知らないだけというのは十分にありうる

*7:Java dis じゃないけど経験上引き合いに出せるのがこいつしかいない…

*8:もちろんこの場合 Servlet/JSP を勉強する意味はあるんだけど、慣れてない初心者だと全く違うものに見えるし会社で使っている環境と全然違ったりするのでそのへん含めて色々と乖離がある気がしている

*9:ここでいう「パートナー」はプロパーの対になる言葉ですね

*10:そんなこと言ったらダメだけど

*11:逆にココ最近のことを全く知らない人もいつつ

(Boolean. false) の Clojure での扱い

Lisp: Common Lisp, Racket, Clojure, Emacs Lisp - Hyperpolyglot
にあるように Clojure の中で false として扱われるのは nil と false それ自身だけ。驚くことに全くもってその通りで、 (Boolean. false) は false じゃないんだ。

user=> (if (Boolean. false) 1 2)
1
user=> (not (Boolean. false))
false
user=> (false? (Boolean. false))
false

かたや、こちらではどういうわけか false になる。

user=> (class false)
java.lang.Boolean
user=> (= false (Boolean. false))
true

これはとても直感に反している。こういう振る舞いをするのは何か深いわけがあるのか、それとも何か見落としている?という感じの質問。

これに対する回答ではココに説明が書いてあると書いてあります。全部読むべきだけど、大事なところを抜粋すると。

[...] All [...] conditionals in Clojure are based upon the same logic, that is, nil and false constitute logical falsity, and everything else constitutes logical truth, and those meanings apply throughout. [...] Note that if does not test for arbitrary values of java.lang.Boolean, only the singular value false (Java's Boolean.FALSE), so if you are creating your own boxed Booleans make sure to use Boolean/valueOf and not the Boolean constructors.

JavaClojure を比較してみます。

System.out.println(Boolean.valueOf(false) ? true : false);  // false
System.out.println(new Boolean(false)     ? true : false);  // false
user=> (if (Boolean/valueOf false) true false)
false
user=> (if (Boolean. false) true false)
true

(Boolean. false) は nil でも false でもなくて、ただの (Object.) なので nil でも false でもないです。
(= false (Boolean. false)) が true になるのは = が Java の equals メソッドに依存しているからじゃないかな。

というように回答がなされていて、なるほどーなーと思いました。まぁ回答の原文にありましたが、 (Boolean. false) は使うべきではないってところで気をつけましょう。

あなたの Slack にも Clojure bot どうですか?

こんな感じです。

f:id:ayato0211:20150523115945p:plain

Clojure bot を導入してみる

使うのはこれです。

便利なことに README に Deploy to Heroku というボタンがあるので押してしまって Heroku のデプロイ画面に行きましょう。
(ログインしてなければログイン画面が出るのでログインしましょう)

f:id:ayato0211:20150523122224p:plain

デプロイ画面ではアプリケーションの名前を入力して、環境変数をセットします。
f:id:ayato0211:20150523122228p:plain
f:id:ayato0211:20150523122232p:plain

前後しますが、このアプリは Slack の Incoming WebHooks と Slash Commands のふたつを利用します。
Slash Commands の方を登録して取得出来る Token を Heroku の COMMAND_TOKEN 変数に入力し、 Incoming WebHooks の方を登録して取得出来る Webhook URL を POST_URL 変数に入力して Deploy ボタンを押してデプロイが成功すれば OK です*1

デプロイに成功したら、 Slash Commands の URL に https://your-app-name.herokuapp.com/clj と入力して適当な Command を設定*2すればお終いです。後は適当に Clojure bot と戯れましょう。

f:id:ayato0211:20150523123219p:plain
誰が発言したのか分からないので闇発言が捗りますね!!

*1:僕は不備がないのにデプロイに数回失敗したので、失敗したら何度か試行してみるといいかも

*2:例えば /clj とか

Emacs の上の方にファイルのパスを表示したかった

f:id:ayato0211:20150521193130p:plain

ずっと前からしたいなーって思ってたけど、思いの外簡単に出来たので満足している。

(setq-default
 header-line-format
 '(""
   (:propertize (:eval (shorten-directory default-directory 30))
                face mode-line-folder-face)
   (:propertize "%b"
                face mode-line-filename-face)))

(defun shorten-directory (dir max-length)
  "Show up to `max-length' characters of a directory name `dir'."
  (let ((path (reverse (split-string (abbreviate-file-name dir) "/")))
        (output ""))
    (when (and path (equal "" (car path)))
      (setq path (cdr path)))
    (while (and path (< (length output) (- max-length 4)))
      (setq output (concat (car path) "/" output))
      (setq path (cdr path)))
    (when path
      (setq output (concat ".../" output)))
    output))

ついでなのでモードラインの表示も少し弄ってスッキリさせてある。