A place to cache linked articles (think custom and personal wayback machine)
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

4 роки тому
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. title: Clojure from the ground up: welcome
  2. url: https://aphyr.com/posts/301-clojure-from-the-ground-up-welcome
  3. hash_url: 3e0624e344552c5fe90c30d8c32418dd
  4. <p>This guide aims to introduce newcomers and experienced programmers alike to the
  5. beauty of functional programming, starting with the simplest building blocks of
  6. software. You’ll need a computer, basic proficiency in the command line, a text editor, and an internet connection. By the end of this series, you’ll have a thorough command of the Clojure programming language.</p>
  7. <h2>Who is this guide for?</h2>
  8. <p>Science, technology, engineering, and mathematics are deeply rewarding fields, yet few women enter STEM as a career path. Still more are discouraged by a culture which repeatedly asserts that women lack the analytic aptitude for writing software, that they are not driven enough to be successful scientists, that it’s not cool to pursue a passion for structural engineering. Those few with the talent, encouragement, and persistence to break in to science and tech are discouraged by persistent sexism in practice: the old boy’s club of tenure, being passed over for promotions, isolation from peers, and flat-out assault. This landscape sucks. I want to help change it.</p>
  9. <p><a href="https://twitter.com/WomenWhoCode">Women Who Code</a>, <a href="http://www.pyladies.com/">PyLadies</a>, <a href="http://www.blackgirlscode.com/">Black Girls Code</a>, <a href="http://railsbridge.org/">RailsBridge</a>, <a href="http://www.girlswhocode.com/about-us/">Girls Who Code</a>, <a href="http://www.girldevelopit.com/">Girl Develop It</a>, and <a href="http://www.lambdaladies.com/">Lambda Ladies</a> are just a few of the fantastic groups helping women enter and thrive in software. I wholeheartedly support these efforts.</p>
  10. <p>In addition, I want to help in my little corner of the technical community–functional programming and distributed systems–by making high-quality educational resources available for free. The <a href="/tags/jepsen">Jepsen</a> series has been, in part, an effort to share my enthusiasm for distributed systems with beginners of all stripes–but especially for <a href="http://aphyr.com/posts/275-meritocracy-is-short-sighted">women, LGBT folks, and people of color</a>.</p>
  11. <p>As technical authors, we often assume that our readers are white, that our readers are straight, that our readers are traditionally male. This is the invisible default in US culture, and it’s especially true in tech. People continue to assume on the basis of my software and writing that I’m straight, because well hey, it’s a statistically reasonable assumption.</p>
  12. <p>But I’m <em>not</em> straight. I get called faggot, cocksucker, and sinner. People say they’ll pray for me. When I walk hand-in-hand with my boyfriend, people roll down their car windows and stare. They threaten to beat me up or kill me. Every day I’m aware that I’m the only gay person some people know, and that I can show that not all gay people are effeminate, or hypermasculine, or ditzy, or obsessed with image. That you can be a manicurist or a mathematician or both. Being different, being a stranger in your culture, <a href="http://aphyr.com/posts/274-identity-and-state">comes with all kinds of challenges</a>. I can’t speak to everyone’s experience, but I can take a pretty good guess.</p>
  13. <p>At the same time, in the technical community I’ve found overwhelming warmth and support, from people of <em>all</em> stripes. My peers stand up for me every day, and I’m so thankful–especially you straight dudes–for understanding a bit of what it’s like to be different. I want to extend that same understanding, that same empathy, to people unlike myself. Moreover, I want to reassure everyone that though they may feel different, they <em>do</em> have a place in this community.</p>
  14. <p>So before we begin, I want to reinforce that you <em>can</em> program, that you <em>can</em> do math, that you <em>can</em> design car suspensions and fire suppression systems and spacecraft control software and distributed databases, regardless of what your classmates and media and even fellow engineers think. You don’t have to be white, you don’t have to be straight, you don’t have to be a man. You can grow up never having touched a computer and still become a skilled programmer. Yeah, it’s harder–and yeah, people will give you shit, but that’s not your fault and has nothing to do with your <em>ability</em> or your <em>right</em> to do what you love. All it takes to be a good engineer, scientist, or mathematician is your curiosity, your passion, the right teaching material, and putting in the hours.</p>
  15. <p>There’s nothing in this guide that’s just for lesbian grandmas or just for mixed-race kids; bros, you’re welcome here too. There’s nothing dumbed down. We’re gonna go as deep into the ideas of programming as I know how to go, and we’re gonna do it with everyone on board.</p>
  16. <p>No matter who you are or who people <em>think</em> you are, this guide is for you.</p>
  17. <h2>Why Clojure?</h2>
  18. <p>This book is about how to program. We’ll be learning in Clojure, which is a modern dialect of a very old family of computer languages, called Lisp. You’ll find that many of this book’s ideas will translate readily to other languages; though they may be <a href="http://aphyr.com/posts/266-core-language-concepts">expressed in different ways</a>.</p>
  19. <p>We’re going to explore the nature of syntax, metalanguages, values, references, mutation, control flow, and concurrency. Many languages leave these ideas implicit in the language construction, or don’t have a concept of metalanguages or concurrency at all. Clojure makes these ideas explicit, first-class language constructs.</p>
  20. <p>At the same time, we’re going to defer or omit any serious discussion of static type analysis, hardware, and performance. This is not to say that these ideas aren’t <em>important</em>; just that they don’t fit well within this particular narrative arc. For a deep exploration of type theory I recommend a study in Haskell, and for a better understanding of underlying hardware, learning C and an assembly language will undoubtedly help.</p>
  21. <p>In more general terms, Clojure is a well-rounded language. It offers broad library support and runs on multiple operating systems. Clojure performance is not terrific, but is orders of magnitude faster than Ruby, Python, or Javascript. Unlike some faster languages, Clojure emphasizes <em>safety</em> in its type system and approach to parallelism, making it easier to write correct multithreaded programs. Clojure is <em>concise</em>, requiring very little code to express complex operations. It offers a REPL and dynamic type system: ideal for beginners to experiment with, and well-suited for manipulating complex data structures. A consistently designed standard library and full-featured set of core datatypes rounds out the Clojure toolbox.</p>
  22. <p>Finally, there are some drawbacks. As a compiled language, Clojure is much slower to start than a scripting language; this makes it unsuitable for writing small scripts for interactive use. Clojure is also <em>not</em> well-suited for high-performance numeric operations. Though it is possible, you have to jump through hoops to achieve performance comparable with Java. I’ll do my best to call out these constraints and shortcomings as we proceed through the text.</p>
  23. <p>With that context out of the way, let’s get started by installing Clojure!</p>
  24. <h2>Getting set up</h2>
  25. <p>First, you’ll need a Java Virtual Machine, or JVM, and its associated
  26. development tools, called the JDK. This is the software which <em>runs</em> a Clojure
  27. program. If you’re on Windows, install <a href="http://www.oracle.com/technetwork/java/javase/downloads/index.html">Oracle
  28. JDK 1.7</a>. If you’re on OS X or Linux, you may already have a JDK installed.
  29. In a terminal, try:</p>
  30. <code class="block">which javac
  31. </code>
  32. <p>If you see something like</p>
  33. <code class="block">/usr/bin/javac
  34. </code>
  35. <p>Then you’re good to go. If you don’t see any output from that command, install the appropriate
  36. <a href="http://www.oracle.com/technetwork/java/javase/downloads/index.html">Oracle
  37. JDK 1.7</a> for your operating system, or whatever JDK your package manager has available.</p>
  38. <p>When you have a JDK, you’ll need <a href="http://leiningen.org">Leiningen</a>,
  39. the Clojure build tool. If you’re on a Linux or OS X computer, the instructions below
  40. should get you going right away. If you’re on Windows, see the Leiningen page
  41. for an installer. If you get stuck, you might want to start with a
  42. <a href="http://blog.teamtreehouse.com/command-line-basics">primer on command line basics</a>.</p>
  43. <code class="block">mkdir -p ~/bin
  44. <span class="nb">cd</span> ~/bin
  45. curl -O https://raw.githubusercontent.com/technomancy/leiningen/stable/bin/lein
  46. chmod a+x lein
  47. </code>
  48. <p>Leiningen automatically handles installing Clojure, finding libraries from the
  49. internet, and building and running your programs. We’ll create a new Leiningen
  50. project to play around in:</p>
  51. <code class="block"><span class="nb">cd</span>
  52. lein new scratch
  53. </code>
  54. <p>This creates a new directory in your homedir, called <code>scratch</code>. If you see <code>command not found</code> instead, it means the directory <code>~/bin</code> isn’t registered with your terminal as a place to search for programs. To fix this, add the line</p>
  55. <code class="block"><span class="nb">export </span><span class="nv">PATH</span><span class="o">=</span><span class="s2">"$PATH"</span>:~/bin
  56. </code>
  57. <p>to the file <code>.bash_profile</code> in your home directory, then run <code>source ~/.bash_profile</code>. Re-running <code>lein new scratch</code> should work.</p>
  58. <p>Let’s enter that directory, and start using Clojure itself:</p>
  59. <code class="block"><span class="nb">cd </span>scratch
  60. lein repl
  61. </code>
  62. <h2>The structure of programs</h2>
  63. <p>When you type <code>lein repl</code> at the terminal, you’ll see something like this:</p>
  64. <code class="block">aphyr@waterhouse:~/scratch$ lein repl
  65. nREPL server started on port 45413
  66. REPL-y 0.2.0
  67. Clojure 1.5.1
  68. Docs: (doc function-name-here)
  69. (find-doc "part-of-name-here")
  70. Source: (source function-name-here)
  71. Javadoc: (javadoc java-object-or-class-here)
  72. Exit: Control+D or (exit) or (quit)
  73. user=&gt;</code>
  74. <p>This is an interactive Clojure environment called a REPL, for “Read, Evaluate,
  75. Print Loop”. It’s going to <em>read</em> a program we enter, run that program, and
  76. print the results. REPLs give you quick feedback, so they’re a great way to
  77. explore a program interactively, run tests, and prototype new ideas.</p>
  78. <p>Let’s write a simple program. The simplest, in fact. Type “nil”, and hit enter.</p>
  79. <code class="block"><span class="nv">user=&gt;</span> <span class="nv">nil</span>
  80. <span class="nv">nil</span>
  81. </code>
  82. <p><code>nil</code> is the most basic value in Clojure. It represents emptiness,
  83. nothing-doing, not-a-thing. The absence of information.</p>
  84. <code class="block"><span class="nv">user=&gt;</span> <span class="nv">true</span>
  85. <span class="nv">true</span>
  86. <span class="nv">user=&gt;</span> <span class="nv">false</span>
  87. <span class="nv">false</span>
  88. </code>
  89. <p><code>true</code> and <code>false</code> are a pair of special values called <em>Booleans</em>. They mean
  90. exactly what you think: whether a statement is true or false. <code>true</code>, <code>false</code>, and <code>nil</code> form the three poles of the Lisp logical system.</p>
  91. <code class="block"><span class="nv">user=&gt;</span> <span class="mi">0</span>
  92. <span class="mi">0</span>
  93. </code>
  94. <p>This is the number zero. Its numeric friends are <code>1</code>, <code>-47</code>, <code>1.2e-4</code>, <code>1/3</code>,
  95. and so on. We might also talk about <em>strings</em>, which are chunks of text surrounded by double quotes:</p>
  96. <code class="block"><span class="nv">user=&gt;</span> <span class="s">"hi there!"</span>
  97. <span class="s">"hi there!"</span>
  98. </code>
  99. <p><code>nil</code>, <code>true</code>, <code>0</code>, and <code>"hi there!"</code> are all different types of <em>values</em>; the
  100. nouns of programming. Just as one could say “House.” in English, we can write a
  101. program like <code>"hello, world"</code> and it evaluates to itself: the string <code>"hello
  102. world"</code>. But most sentences aren’t just about stating the existence of a thing; they involve <em>action</em>. We need <em>verbs</em>.</p>
  103. <code class="block"><span class="nv">user=&gt;</span> <span class="nv">inc</span>
  104. <span class="o">#</span><span class="nv">&lt;core$inc</span> <span class="nv">clojure.core$inc</span><span class="o">@</span><span class="mi">6</span><span class="nv">f7ef41c&gt;</span>
  105. </code>
  106. <p>This is a verb called <code>inc</code>–short for “increment”. Specifically, <code>inc</code> is a
  107. <em>symbol</em> which <em>points</em> to a verb: <code>#&lt;core$inc clojure.core$inc@6f7ef41c&gt;</code>–
  108. just like the word “run” is a <em>name</em> for the <em>concept</em> of running.</p>
  109. <p>There’s a key distinction here–that a signifier, a reference, a label, is not
  110. the same as the signified, the referent, the concept itself. If you write the
  111. word “run” on paper, the ink means nothing by itself. It’s just a symbol. But
  112. in the mind of a reader, that symbol takes on <em>meaning</em>; the idea of running.</p>
  113. <p>Unlike the number 0, or the string “hi”, symbols are references to other
  114. values. when Clojure evaluates a symbol, it looks up that symbol’s meaning.
  115. Look up <code>inc</code>, and you get <code>#&lt;core$inc clojure.core$inc@6f7ef41c&gt;</code>.</p>
  116. <p>Can we refer to the symbol itself, <em>without</em> looking up its meaning?</p>
  117. <code class="block"><span class="nv">user=&gt;</span> <span class="ss">'inc</span>
  118. <span class="nv">inc</span>
  119. </code>
  120. <p>Yes. The single quote <code>'</code> <em>escapes</em> a sentence. In programming languages, we call sentences <code>expressions</code> or <code>statements</code>. A quote says “Rather than <em>evaluating</em> this expression’s text, simply return the text itself, unchanged.” Quote a symbol, get a symbol. Quote a number, get a number. Quote anything, and get it back exactly as it came in.</p>
  121. <code class="block"><span class="nv">user=&gt;</span> <span class="ss">'123</span>
  122. <span class="mi">123</span>
  123. <span class="nv">user=&gt;</span> <span class="o">'</span><span class="s">"foo"</span>
  124. <span class="s">"foo"</span>
  125. <span class="nv">user=&gt;</span> <span class="o">'</span><span class="p">(</span><span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span><span class="p">)</span>
  126. <span class="p">(</span><span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span><span class="p">)</span>
  127. </code>
  128. <p>A new kind of value, surrounded by parentheses: the <em>list</em>. LISP originally stood for LISt Processing, and lists are still at the core of the language. In fact, they form the most basic way to compose expressions, or sentences. A list is a single expression which has <em>multiple parts</em>. For instance, this list contains three elements: the numbers 1, 2, and 3. Lists can contain anything: numbers, strings, even other lists:</p>
  129. <code class="block"><span class="nv">user=&gt;</span> <span class="o">'</span><span class="p">(</span><span class="nf">nil</span> <span class="s">"hi"</span><span class="p">)</span>
  130. <span class="p">(</span><span class="nf">nil</span> <span class="s">"hi"</span><span class="p">)</span>
  131. </code>
  132. <p>A list containing two elements: the number 1, and a second list. That list
  133. contains two elements: the number 2, and another list. <em>That</em> list contains two
  134. elements: 3, and an empty list.</p>
  135. <code class="block">user=&gt; '(1 (2 (3 ())))
  136. (1 (2 (3 ())))</code>
  137. <p>You could think of this structure as a tree–which is a provocative idea,
  138. because <em>languages</em> are like trees too: sentences are comprised of clauses, which can be nested, and each clause may have subjects modified by adjectives, and verbs modified by adverbs, and so on. “Lindsay, my best friend, took the dog which we found together at the pound on fourth street, for a walk with her mother Michelle.”</p>
  139. <code class="block">Took
  140. Lindsay
  141. my best friend
  142. the dog
  143. which we found together
  144. at the pound
  145. on fourth street
  146. for a walk
  147. with her mother
  148. Michelle</code>
  149. <p>But let’s try something simpler. Something we know how to talk about.
  150. “Increment the number zero.” As a tree:</p>
  151. <code class="block">Increment
  152. the number zero</code>
  153. <p>We have a symbol for incrementing, and we know how to write the number zero.
  154. Let’s combine them in a list:</p>
  155. <code class="block"><span class="nv">clj=&gt;</span> <span class="o">'</span><span class="p">(</span><span class="nb">inc </span><span class="mi">0</span><span class="p">)</span>
  156. <span class="p">(</span><span class="nb">inc </span><span class="mi">0</span><span class="p">)</span>
  157. </code>
  158. <p>A basic sentence. Remember, since it’s quoted, we’re talking about the tree,
  159. the text, the expression, by itself. Absent interpretation. If we remove the
  160. single-quote, Clojure will <em>interpret</em> the expression:</p>
  161. <code class="block"><span class="nv">user=&gt;</span> <span class="p">(</span><span class="nb">inc </span><span class="mi">0</span><span class="p">)</span>
  162. <span class="mi">1</span>
  163. </code>
  164. <p>Incrementing zero yields one. And if we wanted to increment <em>that</em> value?</p>
  165. <code class="block">Increment
  166. increment
  167. the number zero</code><code class="block"><span class="nv">user=&gt;</span> <span class="p">(</span><span class="nb">inc </span><span class="p">(</span><span class="nb">inc </span><span class="mi">0</span><span class="p">))</span>
  168. <span class="mi">2</span>
  169. </code>
  170. <p>A sentence in Lisp is a list. It starts with a verb, and is followed by zero or
  171. more objects for that verb to act on. Each part of the list can <em>itself</em> be
  172. another list, in which case that nested list is evaluated first, just like a
  173. nested clause in a sentence. When we type</p>
  174. <code class="block"><span class="p">(</span><span class="nb">inc </span><span class="p">(</span><span class="nb">inc </span><span class="mi">0</span><span class="p">))</span>
  175. </code>
  176. <p>Clojure first looks up the meanings for the symbols in the code:</p>
  177. <code class="block"><span class="p">(</span><span class="o">#</span><span class="nv">&lt;core$inc</span> <span class="nv">clojure.core$inc</span><span class="o">@</span><span class="mi">6</span><span class="nv">f7ef41c&gt;</span>
  178. <span class="p">(</span><span class="o">#</span><span class="nv">&lt;core$inc</span> <span class="nv">clojure.core$inc</span><span class="o">@</span><span class="mi">6</span><span class="nv">f7ef41c&gt;</span>
  179. <span class="mi">0</span><span class="p">))</span>
  180. </code>
  181. <p>Then evaluates the innermost list <code>(inc 0)</code>, which becomes the number 1:</p>
  182. <code class="block"><span class="p">(</span><span class="o">#</span><span class="nv">&lt;core$inc</span> <span class="nv">clojure.core$inc</span><span class="o">@</span><span class="mi">6</span><span class="nv">f7ef41c&gt;</span>
  183. <span class="mi">1</span><span class="p">)</span>
  184. </code>
  185. <p>Finally, it evaluates the outer list, incrementing the number 1:</p>
  186. <code class="block"><span class="mi">2</span>
  187. </code>
  188. <p>Every list starts with a verb. Parts of a list are evaluated from left to
  189. right. Innermost lists are evaluated before outer lists.</p>
  190. <code class="block"><span class="p">(</span><span class="nb">+ </span><span class="mi">1</span> <span class="p">(</span><span class="nb">- </span><span class="mi">5</span> <span class="mi">2</span><span class="p">)</span> <span class="p">(</span><span class="nb">+ </span><span class="mi">3</span> <span class="mi">4</span><span class="p">))</span>
  191. <span class="p">(</span><span class="nb">+ </span><span class="mi">1</span> <span class="mi">3</span> <span class="p">(</span><span class="nb">+ </span><span class="mi">3</span> <span class="mi">4</span><span class="p">))</span>
  192. <span class="p">(</span><span class="nb">+ </span><span class="mi">1</span> <span class="mi">3</span> <span class="mi">7</span><span class="p">)</span>
  193. <span class="mi">11</span>
  194. </code>
  195. <p>That’s it.</p>
  196. <p>The entire grammar of Lisp: the structure for every expression in the language.
  197. We transform expressions by <em>substituting</em> meanings for symbols, and obtain
  198. some result. This is the core of the <a href="http://en.wikipedia.org/wiki/Lambda_calculus">Lambda Calculus</a>, and it is the theoretical basis for almost all computer languages.
  199. Ruby, Javascript, C, Haskell; all languages express the text of their programs in different ways, but internally all construct a <em>tree</em> of expressions. Lisp simply makes it explicit.</p>
  200. <h2>Review</h2>
  201. <p>We started by learning a few basic nouns: numbers like <code>5</code>, strings like
  202. <code>"cat"</code>, and symbols like <code>inc</code> and <code>+</code>. We saw how quoting makes the
  203. difference between an <em>expression</em> itself and the thing it <em>evaluates</em> to. We
  204. discovered symbols as <em>names</em> for other values, just like how words represent
  205. concepts in any other language. Finally, we combined lists to make trees, and
  206. used those trees to represent a program.</p>
  207. <p>With these basic elements of syntax in place, it’s time to expand our
  208. vocabulary with new verbs and nouns; learning to <a href="http://aphyr.com/posts/302-clojure-from-the-ground-up-basic-types">represent more complex values and transform them in different ways</a>.</p>