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
ClojureScript × Type Inference
Search
Roman Liutikov
December 07, 2019
Programming
47
0
Share
ClojureScript × Type Inference
Roman Liutikov
December 07, 2019
More Decks by Roman Liutikov
See All by Roman Liutikov
React Kyiv – Dec 19, 2017
roman01la
1
230
React & ClojureScript in production at Attendify
roman01la
0
200
Web Apps performance & JavaScript compilers
roman01la
3
140
Introduction to React.js
roman01la
0
92
React Native: Native Mobile Development in JavaScript @ LvivJS 2016
roman01la
0
160
React Native: Are we there yet? (Pokémon edition) @ VinnytsiaJS '16
roman01la
0
410
React Native: Native mobile development with JavaScript
roman01la
0
200
ClojureScript, что ты такое?
roman01la
1
220
ClojureScript: what are you?
roman01la
2
140
Other Decks in Programming
See All in Programming
決定論的オーケストレーションの設計と実装 / Design and Implementation of Deterministic Orchestration
nrslib
2
410
CSC307 Lecture 17
javiergs
PRO
0
310
TSKaigi 2026 TypeScriptバックエンドのオブザーバビリティ戦略 — Datadog × NestJSの実践
taiseiyamamotoan
1
220
「AIで開発し、AIを届ける」をEvalでつなぐ 〜AIネイティブに始めるプロダクト開発の実践〜 / Connecting "Develop with AI, deliver AI" with Eval
rkaga
3
1.4k
Moments When Things Go Wrong
aurimas
3
140
運用エージェントは "作る" から "育てる" へ - 記憶と自己進化の3層設計パターン / self-evolving-agents-three-layer-agent-design
gawa
12
3.4k
AI時代の仕事技芸論 — ソフトウェア開発で「遊ぶように働く」職人的熟達のすすめ
kuranuki
1
600
作って学ぶ、 JSX (TSX) ランタイムの基本
syumai
7
1.5k
DynamoDBには集計系のクエリがないけどなんとかしたい
musan
1
120
ADKを使って簡単にAIエージェントを作ってみよう
k1mu21
0
150
セキュリティの専門家じゃなくてもできる。「セキュリティ意識」をアップデートして サプライチェーン攻撃への耐性を高めよう。
tk3fftk
5
500
OSもどきOS
arkw
0
390
Featured
See All Featured
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
46
2.8k
YesSQL, Process and Tooling at Scale
rocio
174
15k
First, design no harm
axbom
PRO
2
1.2k
Designing for Performance
lara
611
70k
What the history of the web can teach us about the future of AI
inesmontani
PRO
1
600
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
16
2k
Agile Actions for Facilitating Distributed Teams - ADO2019
mkilby
0
200
State of Search Keynote: SEO is Dead Long Live SEO
ryanjones
0
200
Facilitating Awesome Meetings
lara
57
6.9k
Optimising Largest Contentful Paint
csswizardry
37
3.7k
Lightning Talk: Beautiful Slides for Beginners
inesmontani
PRO
2
570
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
128
55k
Transcript
ClojureScript Type Inference
None
Type Inference a conclusion reached on the basis of evidence
and reasoning
Type Inference a conclusion reached on the basis of evidence
and reasoning 2019 is it a number? "2019" is it a number? can I add them?
Why in ClojureScript? Generate optimal JavaScript Catch stupid bugs at
compile time Improve externs inference
(if (yes) (no)) if (cljs.core.truth_( )) { yes(); } else
{ no(); }
(if ^boolean (yes) (no)) if ( ) { yes(); }
else { no(); } “type hint”
Types 'string 'number 'boolean 'seq 'array 'object 'any 'clj-nil nil
Types (defn f [x] (if x 1 "2")) #{number string}
Compiler phases Read Analyze Emit
Compiler phases Read Analyze Emit "(let [x 1] ...)"
Compiler phases Read Analyze Emit {:op :let :body ... :bindings
[{:name 'x :init {:op :const}} ...]}
Compiler phases Read Analyze Emit var x = 1;
Analyzer (defn weirdo [a b] (str a b)) (+ 1
(weirdo 2 3))
Analyzer 1 + weirdo(2, 3) WARNING: cljs.core/+, all arguments must
be numbers, got [number string] instead
Analyzer WARNING: cljs.core/+, all arguments must be numbers, got [number
string] instead (defn weirdo [a b] (str a b)) (+ 1 (weirdo 2 3))
Return Type Inference (defn ^string str [a b] ...) (defn
weirdo [a b] (str a b)) (+ 1 (weirdo 2 3))
String Coercion Elision (str a b) [str(a), str(b)].join("");
String Coercion Elision (str ^string a ^string b) [a, b].join("");
Predicate-Induced Inference (if (string? x) (str x "y") :else)
Specializations (def x "string") (def y #js [1 2 3])
(count x) (count y)
Specializations (def x "string") (def y #js [1 2 3])
x.length y.length
Externs Inference (defn http-get [url] (js/fetch url)) (-> (apply http-get
"example.com") (.then on-ok) (.catch on-error))
Externs Inference (defn http-get [url] (js/fetch url)) (-> ^js/Promise (apply
http-get "example.com") (.then on-ok) (.catch on-error))
Experiments
Dead Code Elimination (if x :then :else) 'clj-nil :else
Dead Code Elimination (if x :then :else) #{number string} :then
Specializations (def x "string") (def y #js [1 2 3])
(first x) (first y) x[0] y[0]
Specializations (def x "string") (def y #js [1 2 3])
(second x) (second y) x[1] y[1]
Specializations (def x "string") (def y #js [1 2 3])
(empty? x) (empty? y) x.length === 0 y.length === 0
Higher-order inference (identity 1) 'any (identity 1) 'number
Higher-order inference (apply str xs) 'any (apply str xs) 'string
Higher-order inference (defn f [] ([] 1) ([x] (str x
"y"))) (apply f xs) #{number string} (apply f "x" xs) 'string
Higher-order inference (map inc xs) ['seq 'number] (first xs) 'number
Type Inference + clojure.spec (defui component [x] [:h1 x]) attributes
map or child element?
Type Inference + clojure.spec (s/fdef component :args (s/cat :x map?
:y string?)) (defui component [x y] [:h1 x (str "Hello, " y)])
Summary Compiler gets smarter Your code gets faster without you
doing anything You don't have to know all of this But it might be useful to optimize hot path