Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Writing readable
✴ code
Clojure
Jiří Knesl
I am …
•

From functional programming I do
•
•

•

Clojure - Lispy, dynamic, server-side
LiveScript - Haskell-inspired, dy...
Left to right, up to bottom
•

Code which you read bottom-up right-to-left is
problematic (if you aren’t from culture whic...
With threading macros you
can do A LOT
•

some-> some->>

•

Swiss arrows (https://github.com/rplevy/swiss-arrows)
•

-<> ...
Get rid of useless code:
Compose for the great good!
•

The reason I started functional programming is
to get rid of usele...
Partial application and
composition
•

Instead of (defn a [x] (b (c x))) do:

•

(def a (comp b c))

•

Instead of (fn [x]...
Partial application and
composition
•

They combine together.

•

Instead of: (defn a [x] (b 11 (c 12 x)))

•

You can wri...
Partial application and
composition example
Macros
Macros
Rule #1 of Macros:
Don’t  use macros
•

HOFs are extremely powerful

•

There is a lot of existing macros

•

Partial Appl...
Rule #2 of Macros:
You can make language of your dreams

•

core.async is just group of macros

•

If you miss any feature...
•

But language design is hard (trust me,
I designed one)
•

You need special set of skills, it isn’t just add
operators, ...
Will you spot a mistake?
Will you spot a mistake?
There are two, three, four,
five … worlds!
•

While programming (especially in languages
with macros) you are not only lang...
So there are many DSLs
•

Application is collection of languages
•

Validation, time, money, GUI testing, security,
schema...
When designing language,
there are steps to follow:
1. Find and describe the terminology of your
domain
2. Use the termino...
Pure FP vs. Real World
•

In pure-FP everything is expression

•

In pure-FP you don’t need sequential calling of
function...
Side-effects
•

You need sequences of calls (do (first) (second) …)

•

You will use for (again)

•

You will have problems...
Side-effects
•

When designing your operators, think of it:
•

what if user needs more operations?

•

what about concurre...
Don’t Repeat

2
Yourself

•

See where you use similar code

•

Then decide if you want introduce new syntax
with macros
•...
Cheatsheet
•

¡Remember, it cannot be done without refactoring!

•

Is everything named properly
•

does it use users term...
Thanks!
•

Next step:

•

http://en.knesl.com

•

@jiriknesl (most of the tweets in Czech language
- sorry I will change i...
Writing readable Clojure code
Writing readable Clojure code
Writing readable Clojure code
Writing readable Clojure code
Writing readable Clojure code
Writing readable Clojure code
Writing readable Clojure code
Upcoming SlideShare
Loading in …5
×

Writing readable Clojure code

3,185 views

Published on

In my presentation I explain some techniques I do to make my Clojure code more readable.

Published in: Technology

Writing readable Clojure code

  1. 1. Writing readable ✴ code Clojure Jiří Knesl
  2. 2. I am … • From functional programming I do • • • Clojure - Lispy, dynamic, server-side LiveScript - Haskell-inspired, dynamic,clientside Big fan of productivity (Agile&Scrum, GTD) and quality (TDD, refactoring)
  3. 3. Left to right, up to bottom • Code which you read bottom-up right-to-left is problematic (if you aren’t from culture which reads bottom-up right-to-left) ! • #1 use -> or ->> • #2 use let
  4. 4. With threading macros you can do A LOT • some-> some->> • Swiss arrows (https://github.com/rplevy/swiss-arrows) • -<> … <> • -<>> … <> • some-<> some-<>> • (and others)
  5. 5. Get rid of useless code: Compose for the great good! • The reason I started functional programming is to get rid of useless code, what was your reason? • #1 Use partial application • #2 Use function composition
  6. 6. Partial application and composition • Instead of (defn a [x] (b (c x))) do: • (def a (comp b c)) • Instead of (fn [x] (+ 3 x)) or #(+ 3 %) do: • (partial + 3) ; shame it is not automatic as in Haskell, you would need only (+ 3)
  7. 7. Partial application and composition • They combine together. • Instead of: (defn a [x] (b 11 (c 12 x))) • You can write: • (def a (comp (partial b 11) (partial c 12))) • (which is longer and not readable for some of you now but it helps in real code especially after you get used to it - or if you are interested in Haskell) • In Haskell (and LiveScript): • a = (b 11) . (c 12)
  8. 8. Partial application and composition example
  9. 9. Macros
  10. 10. Macros
  11. 11. Rule #1 of Macros: Don’t  use macros • HOFs are extremely powerful • There is a lot of existing macros • Partial Application, Composition and HOFs take you long way without ever touching macros • Don’t tell anybody, I have 1 macro on hundreds of functions - and all my Clojure friends have similar codebases
  12. 12. Rule #2 of Macros: You can make language of your dreams • core.async is just group of macros • If you miss any feature, you can (and probably should) implement it
  13. 13. • But language design is hard (trust me, I designed one) • You need special set of skills, it isn’t just add operators, blocks here and there • Good syntax should improve code readability (or at least shouldn’t make it worse) • Good syntax compose with the rest
  14. 14. Will you spot a mistake?
  15. 15. Will you spot a mistake?
  16. 16. There are two, three, four, five … worlds! • While programming (especially in languages with macros) you are not only language user but language designer! • If you build business application, your language will be different from programmer building math application.
  17. 17. So there are many DSLs • Application is collection of languages • Validation, time, money, GUI testing, security, schema & types checking • Validateur http://clojurevalidations.info/articles/ getting_started.html • Kerodon https://github.com/xeqi/kerodon • Clj-time https://github.com/seancorfield/clj-time
  18. 18. When designing language, there are steps to follow: 1. Find and describe the terminology of your domain 2. Use the terminology in your application 3. Find another relations (to other parts, check how many times were ‘abstract’ constructs used) 4. Learn something (where did you do mistakes) 5. recurse (GOTO considered harmful)
  19. 19. Pure FP vs. Real World • In pure-FP everything is expression • In pure-FP you don’t need sequential calling of functions • In pure-FP there’s no time • Non-pure programming needs some constructs and your language design must follow it and should make it readable.
  20. 20. Side-effects • You need sequences of calls (do (first) (second) …) • You will use for (again) • You will have problems with Clojure lazy sequences (doall to solve all known problems) • • (take, map, filter and others return lazy sequence and do nothing automatically) But, try (for [x some-collection] (save-to-table1 x) (save-to-anothertable x) (and-show x)) • Hint: for expects only 1 expression (you must use (do…)) - which I see as a wrong design decision
  21. 21. Side-effects • When designing your operators, think of it: • what if user needs more operations? • what about concurrency? • how it will look with other operators? • where is application state? how it changes?
  22. 22. Don’t Repeat 2 Yourself • See where you use similar code • Then decide if you want introduce new syntax with macros • (But please, try to do it another way, for example HOFs, existing macros etc.)
  23. 23. Cheatsheet • ¡Remember, it cannot be done without refactoring! • Is everything named properly • does it use users terminology? • application is collection of DSLs • Can you read your code L-to-R up-to-bottom? • Aren’t there any unnecessary duplications?
  24. 24. Thanks! • Next step: • http://en.knesl.com • @jiriknesl (most of the tweets in Czech language - sorry I will change it soon :-))

×