Welcome, young lisper. I see you have heard the summons from the mystical forces. Prepare yourself for a journey like no other. Your view of programming shall change, and change for the better. You must shed your past beliefs and practices. This is a new path, one that bears little resemblance to the paths you have trodden before. And that is a good thing.

Initiation rites

You have two options - either use an online one-click setup or bite the bullet and install clojure and other tools on your local machine. I recommend the latter option, since you will have to do it at some point. But I am not without sympathy. Setup can be a pain and can be discouraging.
Follow the instructions on calva online for a zero-install approach to getting started with clojure.

If you have chosen the traditional route, you will need three things to get started.

  1. Java
  2. Clojure
  3. A text editor with clojure extensions.

1. Java

You need java to run clojure. So download that if you don’t have java on your system download java.

Check that java is installed with this command.

java --version

you need java 11 or higher So please upgrade if your java version is lower than 11.

2. Clojure

Most clojurists use leiningen to manage their clojure projects. Let’s follow their tradition. You can either head to the leiningen page and follow their instructions. download leiningen or use a package manager.

Ubuntu

sudo apt-get install leiningen

Mac

brew install leiningen

Windows

With chocolatey

choco install lein

With scoop

scoop install leiningen

Test your install

lein version

if you get something like this then you’re good to go

Leiningen 2.9.6 on Java 16.0.1 OpenJDK 64-Bit Server VM

3. Text editor setup (optional)

Follow the intructions of each extension on how to get up and running. It’s nice to do the setup now, but for this blog post we won’t need the specific extensions, so you can skip this for now.

VSCode

I personally use vscode a lot, and sometimes intellij. I recommend this if you don’t know emacs or vim

Calva is a beautiful extension that you can install in vscode. It’s all you need.

Intellij

Cursive is an extension you can use. It does have a free license for non-commercial use

Emacs

Cider is a highly recommended package to use.

If you use some other text editor, you can google around. I obviously can’t cover every editor.

First steps

Despite what you may have heard, lisp is not hard. In fact, it is a very simple language, with simple rules. Clojure is a lisp dialect(programming languages have dialects? don’t worry about that right now), so don’t get confused, because I use those terms interchangeably.
Clojure is easy, you’ll learn about 80% of the syntax in the next two minutes.

The repl

open up a terminal/bash shell, and type lein repl.

$ lein repl

you should see something like this.

user=> 

This is the REPL (read-eval-print-loop). We will type our code in the repl. The repl reads the input, evaluates it, and prints out the answer.

user=> 1
1
user=> 2
2

Alright, let’s get started!

Calling functions

Let’s say we have a function named add in python that adds two numbers. This is what the function call looks like.

>>> add(1,2)
3

all you have to do to make this valid clojure code is, move ( to the left of add, like this

(add 1 2)

That’s valid clojure code. All you did was move a parenthesis and remove the comma. In fact, you can keep the comma and it will still be valid (but don’t, it’s not recommended)

If you tried typing that in the repl you probably got an error like this.

user=> (add 1 2)
Syntax error compiling at (REPL:1:1).
Unable to resolve symbol: add in this context

That’s cause add is not the name of a function. replace add with + and try.

user=> (+ 1 2)
3

YEEET! But that probably looks odd to you. You’re used to 1+2 not + 1 2. But tell me, doesn’t add(1,2) or (add 1 2) look proper? why should you discriminate between add and + ? Both are functions. In fact, other languages discriminate between add and +, but not lisp.

Here’s one benefit to writing (+ 1 2) . If you had to add 10 numbers in another lanuage you would have to write something like

>>> 1+2+3+4+5+6+7+8+9+10
55 

the same thing in lisp would be

user=> (+ 1 2 3 4 5 6 7 8 9 10)
55

Now, isn’t that rad?!

Defining functions

let’s fix this error.

user=> (add 1 2)
Syntax error compiling at (REPL:1:1).
Unable to resolve symbol: add in this context

When Clojure says it’s unable to resolve the symbol, it means you haven’t defined that thing (or imported it). Let’s define add to fix this error.

(defn add [a b]
    (+ a b))

okay, there are a couple of things going on here. For one, there is a second pair of parentheses!
let’s start with stuff we know.
(+ a b) is syntax to add a and b where a and b are two variables that will hold two numbers.
The [a b] in (defn add [a b] are the arguments that the function expects.
In this case it is two. defn is what you use to define functions, this is very similar to python or ruby’s def. This function definition is not that different from a python definition.

; in Clojure     ; # in python
(defn add [a b]  ; def add(a,b): 
    (+ a b))     ;     return a+b

Also, comments in clojure start with ;. I’m trying to really drive home the fact that lisp syntax is not that different (at least in the initial stages).

paste the add definition in your repl, and try calling it a few times.

user=> (defn add [a b]
  #_=>     (+ a b))

user=> (add 1 2)
3
user=> (add 7 8)
15

Why clojure does not have return.

As you saw in python’s definition of add, you had to explicitly tell python to return a value. A lot of languages have this, java, C, C++, ruby, why doesn’t clojure? In clojure (or lisp) if you place something in parenthesis, it’s like saying “yo lisp, do me a fava', find the solution to the thing inside the parenthesis and give me the answer”.
In programming jargon, everything inside a parenthesis is an expression, and lisp evaluates the expression and returns the value. If you don’t know what an expression is, a simple way to think of it is any line of code that returns a value. 1+1 is an expression and so is add(1,2). Lisp only has expressions (no statements), so in lisp every ( ) returns a value. Even println in clojure returns a value, it is nil.

user=> (println "hello")
hello
nil

And that’s why you didn’t have to explicitly tell add to return the result.

(defn add [a b]
    (+ a b))

The anatomy of a named function

add is a named function because it has a name “add”, simple, right? There are unnamed functions too, but we won’t get to that just yet. A named function consists of three parts, a name, arguments, and a function body.

;     name   arguments
;     ---    ----    
(defn add    [a,b] 
;   body
;   ------- 
    (+ a b))

Everything that comes after the arguments is the function body. The body can be as long as you want.

What if a function has multiple expression in its body?

Let’s look at a function that has multiple expressions in it’s function body.

(defn do-math [a b]
    (+ a b)
    (- a b)
    (* a b))

This function has three expressions

  1. (+ a b)
  2. (- a b)
  3. (* a b)

Which one will be returned? If you guessed (* a b) then you’d be right, this is because lisp always returns the value of the last expression in the function body.

Go ahead try it out in the repl.

user=> (do-math 4 5)
20

In do-math (* a b) was the last expression. Try switching around the expressions in do-math’s body and see how the output changes.

Function names can have special characters too

Did you notice that there was a - in do-math? This would be illegal in other languages. you can’t define a python function named do-math, instead it would be do_math. In fact, ?, >, !, etc are perfectly valid to use in clojure function names. Just a few examples of clojure functions that use these.
every?, conj!.
Don’t worry if you don’t understand what these do, just know that these are valid clojure names.

Recap

  1. You learnt the function call syntax (function-name arg1 arg2 arg3).
  2. You learnt how to define new functions with defn.
  3. You learnt that function names can have special characters like ? and -.

Exercises

I’m giving you some simple exercises, please please do them. If you want me to look at your solutions or help you out, or YOU HAVE FEEDBACK, tweet at me https://twitter.com/the_lazy_folder (especially if you have feedback).

Problems

  1. create a function subtract that subtracts two numbers.

    user=> (- 4 2)
    2
    
  2. create a function add-three-nums that adds three numbers.

    user=> (add-three-nums 1 2 3)
    6
    
  3. BONUS create a function I-want-the-one that takes no arguments and returns 1 always.

    user=> (I-want-the-one)
    1
    user=> (I-want-the-one)
    1
    user=> (I-want-the-one)
    1
    

why can’t I do this ("hello") ?

if you tried to get the repl to print “hello” you probably got this error.

user=> ("hello")
Execution error (ClassCastException) at user/eval2017 (REPL:1).
class java.lang.String cannot be cast to class clojure.lang.IFn (java.lang.String is in module java.base of loader 'bootstrap'; clojure.lang.IFn is in unnamed module of loader 'app')

this is because… *screeching brakes* I think that’s enough for today. I’ll explain this in part 2 of the series.

For now, use this.

user=> "hello"
"hello"