Upgrade to PRO for Only $50/Year—Limited-Time Offer! 🔥
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Clojure Linters
Search
Kent OHASHI
February 15, 2018
Programming
0
25
Clojure Linters
Utilise linters for clean Clojure code (*> ᴗ •*)ゞ
Kent OHASHI
February 15, 2018
Tweet
Share
More Decks by Kent OHASHI
See All by Kent OHASHI
🐬の推し本紹介2025: 『コーディングを支える技術 ――成り立ちから学ぶプログラミング作法』
lagenorhynque
0
61
KotlinでミニマルなResult実装による関数型エラーハンドリング
lagenorhynque
0
21
Functional Calisthenics in Kotlin: Kotlinで「関数型エクササイズ」を実践しよう
lagenorhynque
0
170
関数型言語テイスティング: Haskell, Scala, Clojure, Elixirを比べて味わう関数型プログラミングの旨さ
lagenorhynque
1
140
純LISPから考える関数型言語のプリミティブ: Clojure, Elixir, Haskell, Scala
lagenorhynque
1
160
From Scala/Clojure to Kotlin
lagenorhynque
0
70
TDD with RDD: Clojure/LispのREPLで変わる開発体験
lagenorhynque
0
99
🐬の推し本紹介2024: 『脱・日本語なまり 英語(+α)実践音声学』
lagenorhynque
1
130
do Notation Equivalents in JVM languages: Scala, Kotlin, Clojure
lagenorhynque
0
100
Other Decks in Programming
See All in Programming
Patterns of Patterns
denyspoltorak
0
160
認証・認可の基本を学ぼう後編
kouyuume
0
250
Findy AI+の開発、運用におけるMCP活用事例
starfish719
0
1.7k
Canon EOS R50 V と R5 Mark II 購入でみえてきた最近のデジイチ VR180 事情、そして VR180 静止画に活路を見出すまで
karad
0
130
Rubyで鍛える仕組み化プロヂュース力
muryoimpl
0
150
tsgolintはいかにしてtypescript-goの非公開APIを呼び出しているのか
syumai
7
2.3k
俺流レスポンシブコーディング 2025
tak_dcxi
14
9.4k
ゆくKotlin くるRust
exoego
1
140
Kotlin Multiplatform Meetup - Compose Multiplatform 외부 의존성 아키텍처 설계부터 운영까지
wisemuji
0
110
Claude Codeの「Compacting Conversation」を体感50%減! CLAUDE.md + 8 Skills で挑むコンテキスト管理術
kmurahama
1
610
AIコーディングエージェント(NotebookLM)
kondai24
0
220
令和最新版Android Studioで化石デバイス向けアプリを作る
arkw
0
430
Featured
See All Featured
職位にかかわらず全員がリーダーシップを発揮するチーム作り / Building a team where everyone can demonstrate leadership regardless of position
madoxten
47
33k
The B2B funnel & how to create a winning content strategy
katarinadahlin
PRO
0
180
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.4k
We Analyzed 250 Million AI Search Results: Here's What I Found
joshbly
0
240
GraphQLの誤解/rethinking-graphql
sonatard
73
11k
Build your cross-platform service in a week with App Engine
jlugia
234
18k
New Earth Scene 8
popppiees
0
1.2k
Pawsitive SEO: Lessons from My Dog (and Many Mistakes) on Thriving as a Consultant in the Age of AI
davidcarrasco
0
35
Exploring the relationship between traditional SERPs and Gen AI search
raygrieselhuber
PRO
2
3.4k
How to Ace a Technical Interview
jacobian
281
24k
Getting science done with accelerated Python computing platforms
jacobtomlinson
0
76
The Limits of Empathy - UXLibs8
cassininazir
1
190
Transcript
Clojure Linters
Self-introduction /laʒenɔʁɛ̃k/ カマイルカ lagénorhynque (defprofile lagénorhynque :name "Kent OHASHI" :languages
[Clojure Haskell Python Scala English français Deutsch русский] :interests [programming language-learning mathematics] :contributing [github.com/japan-clojurians/clojure-site-ja])
「Clojureをプロダクトに導⼊した話」
1. cljfmt: formatter 2. eastwood: linter 3. kibit: idiom checker
4. Example Usage 5. Other Tools
formatter cljfmt
What's the problem? (when something (something-else) )
$ lein cljfmt check (when something - (something-else) -) +
(something-else))
What's the problem? (when something something-else)
$ lein cljfmt check (when something - something-else) + something-else)
What's the problem? (filter even? (range 1 10))
$ lein cljfmt check (filter even? - (range 1 10))
+ (range 1 10))
What's the problem? (if something ala bala)
$ lein cljfmt check (if something - ala - bala)
+ ala + bala)
What's the problem? (or ala bala portokala)
$ lein cljfmt check (or - ala - bala -
portokala) + ala + bala + portokala)
linter eastwood
What's the problem? (ns linting-example.eastwood-target (:use [clojure.string]))
$ lein eastwood src/linting_example/eastwood_target.clj:2:10: unlimited-use: Unl imited use of ([clojure.string])
in linting-example.eastwood-tar get
What's the problem? (if-let [x []] (conj x 42) :falsy)
$ lein eastwood src/linting_example/eastwood_target.clj:4:1: constant-test: Test expression is always logical
true or always logical false: [] in form (if temp__5455__auto__ (clojure.core/let [x temp__5455__aut o__] (conj x 42)) :falsy)
What's the problem? (defn f [x] (def y (* x
x)) (+ y 2))
$ lein eastwood src/linting_example/eastwood_target.clj:9:8: def-in-def: There i s a def
of y nested inside def f
What's the problem? (defn g [x] "blah blah blah." (*
x x))
$ lein eastwood src/linting_example/eastwood_target.clj:12:7: misplaced-docstrin gs: Possibly misplaced docstring, g
src/linting_example/eastwood_target.clj:12:1: unused-ret-vals: C onstant value is discarded: "blah blah blah."
What's the problem? (defn h [str] (str "Hello, " str
"!"))
$ lein eastwood src/linting_example/eastwood_target.clj:17:3: local-shadows-var: local: str invoked as function
shadows var: #'clojure.core/str
idiom checker kibit
What's the problem? (defn add-one [x] (+ x 1))
$ lein kibit At src/linting_example/kibit_target.clj:4: Consider using: (inc x) instead
of: (+ x 1)
What's the problem? (defn check-if-zero? [x] (== x 0))
$ lein kibit At src/linting_example/kibit_target.clj:7: Consider using: (zero? x) instead
of: (== x 0)
What's the problem? (defn zip-with-* [xs ys] (map #(* %1
%2) xs ys))
$ lein kibit At src/linting_example/kibit_target.clj:null: Consider using: * instead of:
#(* %1 %2)
What's the problem? (defn coll->vec [coll] (into [] coll))
$ lein kibit At src/linting_example/kibit_target.clj:13: Consider using: (vec coll) instead
of: (into [] coll)
What's the problem? (defn flat-map [f coll] (apply concat (map
f coll)))
$ lein kibit At src/linting_example/kibit_target.clj:16: Consider using: (mapcat f coll)
instead of: (apply concat (map f coll))
Example Usage
e.g. ↓↓↓ lagenorhynque/situated-program- challenge/rest-server/project.clj :plugins [[jonase/eastwood "0.2.5"] [lein-cljfmt "0.5.7"] [lein-kibit
"0.1.6"]] :aliases {"lint" ^{:doc "Execute cljfmt check, eastwood and kibit."} ["do" ["cljfmt" "check"] ["eastwood" "{:source-paths [\"src\"]}"] ["kibit"]]} lein cljfmt check && lein eastwood <opts> && lein kibit = lein do cljfmt check, eastwood <opts>, kibit = lein lint # alias as `lint`
$ lein lint All source files formatted correctly == Eastwood
0.2.5 Clojure 1.9.0 JVM 9.0.1 Directories scanned for source files: src test == Linting rest-server.util == == Linting rest-server.boundary.db.core == == Linting rest-server.boundary.db.group == ... == Linting rest-server.handler.venue-test == == Linting rest-server.handler.meetup-test == == Linting rest-server.handler.member-test == == Warnings: 0 (not including reflection warnings) Exceptions thrown: 0
Other Tools
dependency lein deps :tree lein-ancient
namespace slamhound
dead code Yagni
vulnerability lein-nvd
test coverage cloverage
misc. lein-bikeshed
Utilise linters for clean Clojure code!
Further Reading Clojure Code Quality Tools My Clojure Toolchain: Leiningen
Automating Style In Clojure The state of code quality tools in Clojure clojure-style-guide