Join Arthur Ulfeldt for an in-depth discussion in this video The structure of the Clojure language, part of Up and Running with Clojure.
- [Narrator] Let's just reiterate that in Clojure code is lists. They generally take the form verb, object, object. So, the first thing in the list is the action, a function, a special form, for instance, if, or it might be a function like the plus operator. Then everything else after that is an argument to that action or function. These can be nested arbitrarily deeply and they're called s-expressions or just expressions, as we've mentioned.
So, we have function-name and a couple of arguments, classic s-expression. Here's an s-expression that starts with a special operator, has the same form. And the math operators, in Clojure, are just functions. There's no order of precedence for math operators in Clojure like many other languages have. You simply nest functions just like any other function call. This has the effect of putting the operator before the numbers that it works on, which takes a little getting used to.
So, let's talk about places where things can get names. Functions give their arguments names. As we see quite a few times here, I just want to call that out explicitly. The value x is the name for the argument that was passed to this function. So, this function takes that value, which is named x, and it's going to do some math and print out the results. Here we see that we're applying the multiplication function to the number two and whatever was passed as x. Here we're applying the multiplication function to the number two and what was multiplied with x taking the result of that and we're going to add one to it.
And down here, we do a little bit more. Same thing, but afterwards we're going to divide it by two. Let's let a computer do that work. All right. So we got the value out of the first print, eight, one more than that, nine, and half of nine is obviously nine over two. Here that we have an example of a ratio type enclosure. By default, math is safe in this language. It doesn't throw away precision without you explicitly requiring it to do so.
If you really want what you think of as division from almost every other language, that's the quote function. So the quotient function gives you the quotient of dividing five by two which is two. There's also the remainder function. And if you like to get back a fraction or a decimal, just wrap it in a call to double. There we get 2.5. Let expressions also give things names. Those names are referred to as locals. And they're only available within the let expression itself.
In our previous example, we had this expression times two x repeated every time all the way through. That gets a little tedious. Let's give it a name and reuse the name. So here, we're going to have an expression that begins with let, and it says we're going to let the name x two be a name for multiplying our argument by two. Then we're gonna say let x two plus one be a name for that previous result plus one.
So you can see, we're just building the same structure we had here with less repetition. And we're gonna let the name x two plus one over two be the same as that divided by two. Let's run it and see if it's actually the same. And there we get eight, nine, and nine halves. Comes out the same but with less repetition.
Arthur Ulfeldt covers the Leiningen build tool and setting up Clojure to work with the IntelliJ IDEA dev environment. He then reviews the basics of the syntax, including functions, expressions, values, macros, strings, and conditionals. He shows how to structure, compile, and deploy Clojure projects in Leiningen, and pull from Clojure's core library. In the final chapters, Arthur explores references and namespaces and points to resources to learn more about Clojure.
- Installing Leiningen
- Configuring IntelliJ IDEA
- Using REPLs to execute code
- Working with simple and composite values
- Mastering Clojure macros
- Exploring Clojure syntax
- Building a Clojure project with Leiningen
- Mapping, filtering, and reducing
- Binding and destructuring data
- Working with identities