Hacker News new | comments | show | ask | jobs | submit login
A Clojure Crash Course (braveclojure.com)
252 points by nonrecursive 1376 days ago | hide | past | web | 57 comments | favorite

Concludes with:

By this point I highly recommend actually writing some code to solidify your Clojure knowledge if you haven't started already.

While I will be among the quickest to acknowledge that there is great value to be gained by typing in example code, without structured exercises, the article might be providing a fine tutorial or feature list or cookbook, but it is not a course.

Courses look more like "Learn Python the Hard Way" than blog entries. They're hard to make and one for Clojure is sorely needed. The easy parts of Clojure are the syntax and the common idioms. That's why Lisps have a long history as introductory programming languages. The hard part is learning to apply them to the sort of hard problems that one applies other programming languages to.

All that to say, that there's nothing wrong with the article as an article. In fact I think it represents an admirable amount of work for a positive purpose. My only criticism is that it is not what it says it is, and the only reason that is a criticism is that it claims to do heavy lifting which it does not.

Apologies if the title submitted to HN was confusing. The actual chapter title is "Do Things: a Clojure Language Crash Course" but I felt that was too verbose here. The text is explicit about what will be covered: "In this chapter, you're going to explore the elements which comprise this Lisp core: syntax, functions, and data."

Clojure language crash course is meant to distinguish these aspects from the other aspects of Clojure: the environment, the artifact ecosystem, and the mindset. I mention this distinction in the introduction: http://www.braveclojure.com/

Other chapters begin to cover the mindset, or how to do things the Clojure way. "The Joy of Clojure" also covers this, from what I understand. Rich Hickey's talks are also great, of course.

I agree. Rich Hickey's talks are an excellent resource, and he refers to them as talks not as courses, even though he expects and hopes some people will learn something from them.

There's nothing to apologize for. It's just that it isn't a crash course, or a course of any kind for any meaningful meaning of "course".

And I meant what I said about the amount of effort and thought that the article represents being worthy of praise...and what I said about there being a need for actual courses in Clojure.

>It's just that it isn't a crash course, or a course of any kind for any meaningful meaning of "course".

It absolutely is a crash course, for the most common colloquial definition of the term "crash course," although in a very nitpicky fashion the blog entry is not a "true course of study." The reality is when people say "crash course" in common English they almost never mean a formal course of study. Usually it's used in the context of someone needing to learn something quickly in order to do something else. A professor might spend 10 minutes at the beginning of a class doing a "crash course" on binary arithmetic, because it's needed for something else that's on the lesson plan for the day. Such a crash course might have no exercises and no materials whatsoever, but nobody reasonable is going to object to the term.

The blog entry is focused, brisk, and thorough, the key elements of a course intended to be completed rapidly for a specific purpose. Does it fail to fill a learning gap that clojure needs filled? Probably. But that doesn't make it wrong to call it a crash course.

Typically a crash course is equal in content and student expectations to a normal course. What makes it a crash course is that it has a compressed time schedule. Courses with an emphasis on lightening the weight of the content typically are prefixed by "A Survey of", "An Introduction to", etc.

The professor covering binary arithmetic does not hear objections for several reasons. While the social context of the classroom and the explicit expert-novice relationship are among them, the analogy is undermined because teaching Clojure is not a precursor to teaching something else. In the article it is the end, itself.

Under the usage you are suggesting, "A crash course in the JVM" in the context of teaching Clojure would fit the analogy better.

Honestly, no, you're incorrect, at least in Australian English. A crash course is a turn of phrase, to denote being taught an overview of a topic in a short time, usually informally, with a focus on what is important to the students future endeavours in that area.

But I do apologize! It seems to me like this misunderstanding has made you a bit grumpy. I apologize if that's the case. If it's not, then I apologize for being wrong!

Whatever it is, it is the beginning of something really great and thanks to flyingmachine for creating it and sharing his knowledge. If it is a course, article, or tutorial, either way it is something that get more people familiar with Clojure.

Thank you :-)

There really needs to be a JVM crash-course for clojure... I can understand the syntax well-enough, but I want to know what java libs i need/how i use them/etc. ie. when I have to "leave clojure".


Clojure has been around long enough that people have wrappers around most of the interesting common use java libs. If you're looking for something domain specific then it's usually better to find which java libs cover the domain and work from there.

On top of that, direct java interop is not bad at all.

Here is a talk on it: http://www.infoq.com/presentations/Clojure-Java-Interop

I confess I haven't watched that talk yet and only remembered hearing about it as I wrote this. But I imagine it is a good Launchpad.

The point is, direct Java interop is useless, potentially worse, if you don't know anything about Java.

I plan on adding that to the book. In the mean time, I have a series on Java for Clojurists: http://www.flyingmachinestudios.com/programming/how-clojure-...

What do you mean? If you know Clojures syntax for Java interop, reading Java API's shouldn't be much of a problem. Searching for java howtos on how to use sockets and such should also give you a fair amount of results...

Yes... but reading api documentation isnt a tutorial. I was asking for a tutorial for common java api stuff. If a tutorial goes through some common apis then you can get a feel for how to read the documentation through a clojure lens.

I've been productive with Clojure and Java-interop for over a year now despite never using Java before.

Navigating the Java terrain is comical. Often, performing what I would consider a library's basic use-case involves the collaboration of multiple objects I never could've reverse-engineered from the API docs. Yet the library doesn't throw me a bone with any sort of `## Usage` overview.

Fortunately, it seems nobody else knows how to do trivial things with Java (or libraries like Bouncy Castle) either, so I've found it reliable to lean on google queries to find the 1,000 questions that have already been asked and answered.

I hope this provides a good introduction to the Clojure language, apart from concerns about building and running Clojure programs. I'd love any feedback :)

I can't speak to the Clojure introduction, because I was already semi-familiar with the language. However, I found your site via Google a few weeks ago when I was looking for an introduction to Emacs + Clojure. Having gone down this road several times in the past, I have to say that this is the best tutorial I've ever found on that topic.

The repl and window examples were just what I needed as a complete Emacs newbie. The Emacs chapter was similarly good. It seemed to be aimed at someone who wanted to start writing code quickly. This is the first time in years that I've worked through an Emacs tutorial without firing up vim to edit a config file (at which point I usually realize that I won't be switching to Emacs that day).

Thank you for taking the time to write all of this.

Thank you for the feedback! Encouraging comments like this really help keep me motivated. I'm glad that the emacs tutorial was useful for you :)

Great introduction - really well written, enjoyable to read. I read an article about clojurescript / om / react [0] the other day which piqued my interest - this is the first tutorial I've gone through on Clojure.

The api actually feels pretty similar to Python (eg rest-param ~= args) so it mapped over nicely for me. I studied functional programming some years ago and have tinkered with the like of erlang in the past so none of the concepts you presented felt too foreign.

I might be going insane but it looks like you have a typo in there - 'whether the ;; the part's name'*.

Kudos, again.

[0] http://swannodette.github.io/2013/12/17/the-future-of-javasc...

I came across your website googling for how to set up emacs w/ clojure... for someone with prior emacs experience, your step 2: "Delete ~/.emacs or ~/.emacs.d if they exist" seemed... extreme. If you have a time, maybe listing the key packages and what they do (and what they replace) would be really helpful.

I have been really enjoying this tutorial. If you wanted to be super timely you could add instructions for doing it in Light Table.

Basic instructions. I use cmd for the shortcuts below, substitute ctrl on non-mac platforms.

1. Install Leiningen http://leiningen.org/ you do not need to install clojure, lein will grab clojure for you.

2. `lein new playground` from the command line to create a 'playground' project

3. Open Light Table

4. ctrl-space `woto` for "Toggle Workspace tree"

5. Add the playground project folder you just created

6. cmd-o `core.clj` to open the main clojure file for the project

7. On an empty line type `(+ 1 1)` and hit cmd-enter

Things will grind away for a while as all the dependencies are downloaded and the JVM starts up. Get a cup of coffee or something. Eventually you'll see a green `2` show up.

You can then type anything in the tutorial and hit cmd-enter to evaluate it or cmd-shift-enter to evaluate the entire file. Think of the file as a shell with an editable history instead of something you'd want to commit to source control.

Documentation is searchable via ctrl-shift-d or moving your cursor on top of a function name and hitting ctrl-d. Autocomplete is available on tab, you can jump to definition with cmd-. and back with cmd-,

Very useful!

Additional question: I noticed how on the clojurescreencasts site the author of the videos uses InstaREPL in split screen mode. I couldn't figure out how to do that with my own installation of LT. Do you know?

The split is 'Tabset: Add a tabset' and you can just drag the instarepl tab over.

I was wondering the same thing. While I don't think Emacs users will ever say that LightTable is better, they should consider:

1. LightTable might be better for new Clojure users who aren't yet attached to Emacs

2. You can use (some) Emacs key bindings in LightTable

/not to start an editor war/

At the risk of starting a war - I'm used to Vim. Is there a benefit to looking into LightTable or Emacs if I want to get into Clojure?

Lisps work better from an editor that can provide tight REPL integration. I've used vim for 15 years and use it for everything else but it does not do this well. Clojure support via vim-fireplace is better than nothing and I've used it (and it's predecessors) for couple hundred line projects spaced out over the last few years but it's never felt good to me. Fireplace and the nREPL, unlike the older integration schemes, almost always work but my current complaint is that I don't like how the output is presented.

Light Table does the integration right. You load up a clojure file, hit eval, and it works without having to mess with it. Additionally, it works well with Clojurescript, which I never really got working with Vim fireplace. The doc system is integrated, autocomplete works. The Light Table vim plugin provides decent but not great vim emulation (e.g. the b text object is missing, which is important for a lisp) and while it's not as nice for editing as my heavily customized home vim setup, I'm happier doing Clojure in LT than in Vim.

In a word - Yes. I've been using vim exclusively for the past year, after a brief stint with emacs, but this post prompted me to go back and try emacs again. Over the year of vim use I've never really been satisfied with editing clojure in vim, it just doesn't work as well as emacs for that purpose.

This weekend I decided to try out emacs with evil-mode and now I've switched permanently to that set up, it's the best of all worlds, you get to have all the emacs/clojure integration goodness while still having super-powerful vi keybindings and editing capabilities.

I'd recommend you give it a shot at least :)

LightTable and Emacs's SLIME (through swank, for clojure) likely provide much better lisp integration than what vim has available. I've got no idea what's available in vim so I may be wrong, but here's SLIME: http://www.cliki.net/SLIME%20Features

Slime has been completely replaced by cider.


also nrepl

I was used to Vim as well, but I decided to jump into Emacs and Clojure at the same time.

Once I installed Evil-mode (Vim bindings), an Emacs buffer felt so similar to Vim that I was immediately productive.

From there, I could just focus on the other things like how to open a file (C-x f) and how to launch nREPL and begin evaluating code within Clojure source files.

I tried this route for a long time but didn't find it to be worth it at all. All the plugins you use will still have horrible chording style shortcuts.

I'm much happier now that I'm just using vim-fireplace.

There may be, I'm not that familiar with either, but do try vim-fireplace, it's pretty darn good.

Grayrest explained why something like LightTable is so nice, but it's probably worth mentioning that LightTable has a built-in Vim keybindings mode as well, so it will hopefully not be too unfamiliar.

I recently started using light table. You shouldn't need to install leiningen, just open up light table, hit ctrl/cmd - space, and type instarepl. select the option to open a new instarepl, and it should start writing without any additional setup.

I would presume that the author is very proficient with Emacs and not deeply familiar with Light Table. If this is true, the tutorial would probably not teach you the most idiomatic way of using Light Table.

Thanks for the feedback! I should add a link to Light Table, but I don't think I'll end up writing instructions for it as it seems like the existing docs are pretty good.

I love the pacing of this tutorial. It has a wonderful no-nonsense delivery, and the pacing is fast enough to feel excitingly informative, but not so fast as to be intimidating.

This is really great writing. As an Emacs user who hasn't yet gotten very far into a lisp, I look forward to having time to sit down and really dig into this tutorial.

Thanks for creating this!

i found the Clojure koans useful. (http://clojurekoans.com/) they're aimed at beginners so they would be a good companion/followup to this

hey great tutorial! really easy to go through, super helpful.

My only suggestion : it would be great to have a small reference/cheatsheet/table to convert equivalent data structures and other syntactic details from closure to other languages. I found myself scrolling back up a lot to remember what "def" meant (coming from python this was confusing), whether "vector" was a dict or a list, etc. It interrupted the reading for a few seconds every time until "ah ha!" I found it.

I remember spending about 50% of my time learning Mongo syntax just checking out their mysql <-> mongo syntax table - I assume most people checking out your tutorial will have experience with some previous form of programming (like me).

I think most FP's will wince at the notion of a 1:1 comparison with any imperative language.

He's not really asking for a 1:1 comparison though, just a mapping of common constructs (and a note when a construct makes no sense) in order to get his bearings.

A bit outdated though e.g. for the first one, since 0.0.2060 cljs has grown (enable-console-print!) which sets print-fn to a wrapper around console.log. As a result, one can use all the usual clojure printing functions[0] and the output will be sent to the browser console.

[0] http://clojure.org/other_functions#Other%20Useful%20Function...

(not= "Clojure" "ClojureScript")

Great suggestion. Thank you!

Technically this is the transliteration of that ruby code:

    (def severity :mild)
    (def error_message "OH GOD! IT'S A DISASTER! WE'RE ")
    (if (= severity :mild)
      (def error_message (str error_message "MILDLY INCONVENIENCED!"))
      (when (= severity :terrible)
        (def error_message (str error_message "DOOOOOOOMED!"))))
And if we consider that a good transliteration then I'm not sure why this wouldn't suffice for the second one:

    (def failed_protagonist_names [
       "Larry Potter"
       "Doreen the Explorer"
       "The Incredible Bulk"

    (def failed_protagonist_names
        (assoc failed_protagonist_names 0 "Gary Potter"))

     ;; => ["Gary Potter" "Doreen the Explorer" "The Incredible Bulk"]

This repl snippet should show that you're not actually changing a data structure in place. Rather, you're creating a new data structure and changing an existing binding:

  user=> (def a [1 2 3])
  user=> (def b a)
  user=> (def a ["a" "b" "c"])
  user=> a
  ["a" "b" "c"]
  user=> b
  [1 2 3]

As a Clojure fan, while I appreciate the author's effort, and admit I would do a much worse job, I'm bothered by oversimplifications like these:

- "Like all Lisps, it employs a uniform structure"

- "All Clojure code is written in a uniform structure"

- "Forms have a uniform structure."

- "In other languages, different operations might have different structures depending on the operator and the operands."

- "No matter what operator you're using or what kind of data you're operating on, the structure is the same."

It's pretty obvious that forms don't have a uniform structure (e.g. the structure of a number is pretty different from the structure of a vector), and that the structure depends on the operator (e.g. `def` special form vs. `or` macro).

Yes, Clojure syntax is relatively simple, no need to oversell it.

Still, that's a minor issue that doesn't detract from the overall quality and usefulness of the work.

One of the ideas I'm trying to convey is that the structure of the code is different from the syntax. With Clojure, special forms like def, if, etc, provide syntax in that each one has different rules for how their arguments get evaluated or, in the case of def, how the environment is changed. On top of that, you have macros which allow you to introduce arbitrary syntax.

However, all Clojure code does have the same uniform structure. It's all composed of s-expressions, which are either atoms or other s-expressions enclosed in parentheses (for lists), braces (for maps), or brackets (for vectors).

Thanks again for this feedback, having to explain this has given me some ideas for how to improve the chapter :)

Thanks for the feedback, I've been finding it tricky to get the explanation right here.

I don't have much time now and I'll try to reply with more later, but macros, special forms, and functions do indeed all have the same structure of opening parenthesis, operator, operands, closing parenthesis.

This is really helpful. As someone who's never worked with a JVM language (or Lisp, for that matter) or Emacs, braveclojure is really enjoyable. Thanks!

I've been having fun using clojure over the past week or two, and it's really nice to get a tutorial on all the vocabulary. Thanks.

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | DMCA | Apply to YC | Contact