はじめに
株式会社テンクーの新人エンジニアのtmatsudaと申します。
弊社の開発では、Clojureがメインの言語として使われており、私も選考・入社に伴ってClojureをゼロから学習しました。
これまでの学習歴は半年と少しという程度で、まだまだ学ぶことの多い身ですが、ここまでのClojure入門の経験・感想を語っていきたいと思います。
強いClojureプログラマの方は、入門者がこんな点に苦労した、くらいの話として見て頂ければと思います。
これからClojureに入門したい!という方がここに辿り着いていましたら、何かしらの足しになれば幸いです
ちなみに、Clojure入門前の自分のプログラミング経験を簡単に紹介すると以下のような状態でした。Clojureだけでなく、エンジニアとしても駆け出しです。
- 新卒でSIerに入社し、1年ほど経験を積んだ後、現職に転職。仕事で開発をした経験は乏しい。
- Pythonの経験年数は5年ほどあったが趣味レベル。前職の業務でC#とVBAを数か月程度だけ使った。
- 関数型言語でコードを書いた経験は全くない。
入門期の勉強
Clojureを全く知らない状態から、まずは以下のようなことから始めました。
Replitでhello world!したりFizz Bazzを作ったりする
最初は手軽にちょっと体験してみたかったため、webページだけで様々なコードが実行できるサービス、Replitを使って触ってみました。簡単に体験してみるのが目的なら良いと思いますが、括弧の管理が大変でした。(VSCode + Calvaの開発環境に慣れた今は、この環境に戻れませんね...。)
プログラミングClojure 第2版 (Amazonリンク)
貴重な日本語のClojure本で、良本だと感じますが、入門者にやさしい方ではないかと思います...。入門レベルから一気に最後まで理解するのは大変そうなので、最初は4章までの理解度を高めることを優先するのがよさそうに思いました。
私も実務を経験した今、ちょくちょく読み返して理解を深めて行きたいですね。
公式ウェブサイト https://clojure.org のコンテンツを読む
英語ですが、REFERENCEやGUIDESでの説明が分かりやすく、大変役立ちました。
⏬特に、以下の内容は開発中もよく目にするものでありながら、本だけでは理解が浅い部分だったために助かりました。
https://clojure.org/guides/weird_characters
https://clojure.org/reference/special_forms
https://clojure.org/reference/metadata
https://clojure.org/reference/java_interop
https://clojure.org/reference/datatypes
👇日本語訳プロジェクトもあるようです。
https://github.com/japan-clojurians/clojure-site-ja
問題を通してClojureが学べるサイト
- Codewars
-
4ever-clojure
上記2つは、競プロのような感覚でプログラミング問題に挑戦できるサイトです。問題を通して、どのように関数を組み合わせれば良いのかを考えたり、他の良さそうな解答を見たりすることが、Clojureに頭を慣らすための良いトレーニングになったと感じます。
現場で教えて頂いたこと
自学だけでは辿り着かず、教えてもらって助かったというトピックをいくつか紹介します。
エディタのslurp, barfを使って括弧を動かしてコーディングをする
今までこれほど括弧を扱った経験が無く、括弧の位置をslurp, barfの操作で動かしながらコーディングをするということを知りませんでした。
👇slurp, barfでどのように括弧が動くかは以下の説明が分かりやすいです。
https://calva.io/paredit/#editing
スタイルガイド(bbatsov/clojure-style-guide)を参考にしてコーディングする
当初はこちらのスタイルガイドの存在を知りませんでした。また、cljfmtやclj-kondoで書き方に問題が無いかを確認することも習慣付けました。
自分が扱っているデータ型の性質を掴むためにlist?
seq?
vector?
map?
などの関数を活用する
私が学び始めの頃は、処理したいデータの形式を毎回type
関数で調べようとしていましたが、プロダクトのコードでは、様々なクラスが使われていることもあり、type
の出力を見ても結局良く分からないということがありました。
データ型を厳密に把握する必要が無い場合では、例えばseq?
などを使って、true
ならseq
の性質を持つものとして扱っていくというのが実用的な方法のようです。
JVMとの関わり
ClojureはJVM上で動く言語のため、実行時のパフォーマンスを向上させるために、JVM上でどのように実行されるかを意識すべき場合があります。
私もこの点の知識は乏しいですが、JVMのガベージコレクションの仕組みを知っておくと良いよと助言頂いたり、Java Flight Recorderを活用して実行を記録することで、メモリを消費しているオブジェクトを特定できることなどを教えて頂きました。
let
に含まれる暗黙のdo
例えば、一つのブロックとして、複数の式を順番に評価したい場合にdo
が使われるということは知っていました。
(do
(println 1)
(println (inc 1)))
しかし、以下のようコードではdo
が不要になっていることが不思議でした。
(let [x 1]
(println x)
(println (inc x)))
これは、公式ドキュメント: https://clojure.org/reference/special_forms#let の記述によると、let
のバインディングに続く式は、暗黙のdo
(英語原文では 'implicit do
')があるものとして処理されることが理由のようです。
fn
, defn
, doseq
など、let
以外にも暗黙のdo
を含むマクロやスペシャルフォームがあります。
学んでいて感じたこと
- 最初は括弧の多さに面食らっていたが、エディタにサポートしてもらえば、そこまで大変ではないと分かった。
- より人気の言語に比べると、どうしてもコンテンツが少ない。本格的に学ぶためには英語ドキュメントを読めるようになることが必須。また、困った時に教えて頂ける環境があると非常に心強い。
- 前職のSIerの業務では英語ドキュメントを読む機会が乏しかったため、日常的に英語ドキュメントを読むことは少しカルチャーショックを受けました。
- Clojureの関数の実装は簡潔なものも多く、初心者でも案外読める。
- 知らない関数があった時には、https://clojuredocs.org にあるドキュメントで調べられますが、更にSourceに飛んで実装を見ると、中身から理解できて良いと思いました。
案外、関数の中身は簡潔に書かれているものも多いです。例えば->マクロのソースと->>マクロのソースなどを見ると、初心者でも頑張れば読める量だと思いますし、比較してみると違いがはっきりすると思います。
- 知らない関数があった時には、https://clojuredocs.org にあるドキュメントで調べられますが、更にSourceに飛んで実装を見ると、中身から理解できて良いと思いました。
終わりに
自分がClojureを学んでいて、日本語コンテンツが少ないとか、入門者がとっつきやすい教材が少ないなど感じたので、その辺りについては、今後少しでも貢献できたらいいなと思います。
まだまだ1個学ぶと5個分からないことが出てくるような状態ですが、挫折せず来年以降も頑張りたいですね。