Reading Clojure

Reading Clojure

If there's one thing that trips Clojure newcomers is how to read the damned thing.

Clojure's syntax is very simple, and yet newcomers to Clojure tend to project into the language the complexity of other languages they're used to. We'll go through a few Clojure examples and deconstruct them to show how there's even less syntax to it than you probably think.

Video: https://youtu.be/t_T5wtLyZos

3671c3425bbbc1de94d87374617646b7?s=128

Ricardo J. Méndez

September 13, 2017
Tweet

Transcript

  1. Reading Clojure Ricardo J. Méndez ricardo@numergent.com @ArgesRic
 https://mastodon.social/@ricardojmendez

  2. @ArgesRic This is about the thought process when evaluating things.

  3. @ArgesRic “What in the name of Cthulhu’s green tentacles did

    I commit to?”
  4. @ArgesRic Show of hands • Who here isn't programming in

    Clojure yet? • Who is kind of familiar with the language but still finding their footing? • Who considers themselves to be fully comfortable in it?
  5. @ArgesRic This one’s for the first two.

  6. @ArgesRic Learning stages • First we learn by reading; •

    Then we learn by imitating; • And finally, we learn by creating.
  7. @ArgesRic I bollocksed up the first two.

  8. @ArgesRic Clojure can be hard to read because of how

    simple it is.
  9. @ArgesRic Syntax is that part of the language that’s set

    in stone.
  10. @ArgesRic

  11. @ArgesRic Let’s describe how we see this.

  12. @ArgesRic

  13. @ArgesRic

  14. @ArgesRic Tokens are the wrong way of thinking about Clojure.

  15. @ArgesRic

  16. @ArgesRic So let’s dissect things a bit.

  17. @ArgesRic (1 2 3) 
 [1 2 3]
 (+ 1

    2 3)
 [+ 1 2 3]
  18. @ArgesRic Evaluation semantics

  19. @ArgesRic (+ 1 2 3) 
 (1 2 3)

  20. @ArgesRic Trick question!

  21. @ArgesRic (+ 1 2 3) 
 (1 2 3)

  22. @ArgesRic We can always quote a list.

  23. @ArgesRic If you’re joining us from Java… Or C#… 


    
 Or not-a-LISP...
  24. @ArgesRic “Yeah, yeah, homoiconicity, we get it”

  25. @ArgesRic *except all those special cases…

  26. @ArgesRic (if odd? (do-something [1 3 5 7]) (do-another-thing [0

    2 4 6]))
  27. @ArgesRic (if odd? (do-something [1 3 5 7]) (do-another-thing [0

    2 4 6]))
  28. @ArgesRic (if odd? (do-something [1 3 5 7]) (do-another-thing [0

    2 4 6]))
  29. @ArgesRic A special form aside…

  30. @ArgesRic “That’s the stuff that’s different!”

  31. @ArgesRic They aren’t special cases. They are primitives.

  32. @ArgesRic Primitives are so rare they are special.

  33. @ArgesRic Back to the if

  34. @ArgesRic (if odd? (do-something [1 3 5 7]) (do-another-thing [0

    2 4 6]))
  35. @ArgesRic (if odd? (do-something [1 3 5 7]) (do-another-thing [0

    2 4 6]))
  36. @ArgesRic (if odd? (do-something [1 3 5 7]) (do-another-thing [0

    2 4 6]))
  37. @ArgesRic (if odd? (do-something [1 3 5 7]) (do-another-thing [0

    2 4 6]))
  38. @ArgesRic “Branches, in parenthesis"

  39. @ArgesRic (if got-a-list? (convert-to-string [1 3 5 7]) "Got something

    else")
  40. @ArgesRic We are always evaluating. Stop thinking on terms of

    “execution”.
  41. @ArgesRic Back to defn

  42. @ArgesRic (defn plus-one [v w] (+ w v 1))

  43. @ArgesRic ( defn ; We are evaluating this plus-one [v

    w] (+ w v 1) )
  44. @ArgesRic ( defn plus-one ; All these [v w] ;

    are (+ w v 1) ; parameters. )
  45. @ArgesRic ( defn plus-one ; This is an identifier [v

    w] (+ w v 1) )
  46. @ArgesRic ( defn plus-one [v w] ; This is a

    vector w/param ids (+ w v 1) )
  47. @ArgesRic ( defn plus-one [v w] (+ w v 1)

    ; This is a list to evaluate )
  48. @ArgesRic ( defn ; We are invoking this plus-one ;

    This is an identifier [v w] ; This is a vector w/param ids (+ w v 1) ; This is a list to evaluate )
  49. @ArgesRic (defn get-from-string [conn long-url] (let [url (db/get-url conn long-url)

    parsed (db/parse url)] (clean-up parsed)))
  50. @ArgesRic ( defn get-from-string [conn long-url] ( let [url (db/get-url

    conn long-url) parsed (db/parse url)] (clean-up parsed) ) )
  51. @ArgesRic ( defn get-from-string [conn long-url] ( let [url (db/get-url

    conn long-url) parsed (db/parse url)] (clean-up parsed) ) )
  52. @ArgesRic ( defn get-from-string [conn long-url] ( let [url (db/get-url

    conn long-url) parsed (db/parse url)] (clean-up parsed) ) )
  53. @ArgesRic ( defn get-from-string [conn long-url] ( let [url (db/get-url

    conn long-url) parsed (db/parse url)] (clean-up parsed) ) )
  54. @ArgesRic Everything will follow this exact same pattern.

  55. @ArgesRic The Tao of Clojure: There is nothing but the

    list.
  56. @ArgesRic Let’s break some stuff!

  57. @ArgesRic (inc) (inc 1) (inc inc)

  58. @ArgesRic inc [inc] [inc 1] [inc 1 inc]

  59. @ArgesRic (defn a-function [v] [+ 1 2 3 4 5]

    (plus-one 2 3) plus-one [inc] [inc 1] v)
  60. @ArgesRic (defn a-function [v] [+ 1 2 3 4 5]

    (plus-one 2 3) plus-one [inc] [inc 1] v)
  61. @ArgesRic Abusing the syntax to disabuse you of misconceptions.

  62. @ArgesRic #1: "Everything needs to be wrapped in parenthesis." #2:

    "There’s all these special cases."
  63. @ArgesRic (apply + [1 2 3 4])
 (get {+ 1

    - 2 * 3} -)
  64. @ArgesRic … we’re about out of time

  65. @ArgesRic Thank you! Ricardo J. Méndez ricardo@numergent.com @ArgesRic https://mastodon.social/@ricardojmendez https://numergent.com/talks/