Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Clojure Linters
Search
Kent OHASHI
February 15, 2018
Programming
0
23
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
関数型言語テイスティング: Haskell, Scala, Clojure, Elixirを比べて味わう関数型プログラミングの旨さ
lagenorhynque
1
92
純LISPから考える関数型言語のプリミティブ: Clojure, Elixir, Haskell, Scala
lagenorhynque
1
96
From Scala/Clojure to Kotlin
lagenorhynque
0
43
TDD with RDD: Changed Developer Experience through Clojure/Lisp REPLs
lagenorhynque
0
76
My Favourite Book in 2024: Get Rid of Your Japanese Accent
lagenorhynque
1
110
do Notation Equivalents in JVM languages: Scala, Kotlin, Clojure
lagenorhynque
0
79
map関数の内部実装から探るJVM言語のコレクション: Scala, Kotlin, Clojureコレクションの基本的な設計を理解しよう
lagenorhynque
0
73
Kotlin Meets Data-Oriented Programming
lagenorhynque
0
67
Introduction to Tree Representations in RDB 2024
lagenorhynque
0
98
Other Decks in Programming
See All in Programming
アセットのコンパイルについて
ojun9
0
130
AIと私たちの学習の変化を考える - Claude Codeの学習モードを例に
azukiazusa1
10
4.3k
Compose Multiplatform × AI で作る、次世代アプリ開発支援ツールの設計と実装
thagikura
0
170
基礎から学ぶ大画面対応(Learning Large-Screen Support from the Ground Up)
tomoya0x00
0
3.2k
1から理解するWeb Push
dora1998
7
1.9k
Updates on MLS on Ruby (and maybe more)
sylph01
1
180
ユーザーも開発者も悩ませない TV アプリ開発 ~Compose の内部実装から学ぶフォーカス制御~
taked137
0
190
Testing Trophyは叫ばない
toms74209200
0
890
The Past, Present, and Future of Enterprise Java
ivargrimstad
0
400
そのAPI、誰のため? Androidライブラリ設計における利用者目線の実践テクニック
mkeeda
2
1.8k
ぬるぬる動かせ! Riveでアニメーション実装🐾
kno3a87
1
230
CloudflareのChat Agent Starter Kitで簡単!AIチャットボット構築
syumai
2
510
Featured
See All Featured
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
4k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
52
5.6k
YesSQL, Process and Tooling at Scale
rocio
173
14k
Code Review Best Practice
trishagee
71
19k
Documentation Writing (for coders)
carmenintech
74
5k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
48
9.7k
Six Lessons from altMBA
skipperchong
28
4k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
49
3k
The Illustrated Children's Guide to Kubernetes
chrisshort
48
50k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
9
810
Site-Speed That Sticks
csswizardry
10
820
Code Reviewing Like a Champion
maltzj
525
40k
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