4Clojure has a lovely series of exercises to help you practice Clojure. I don’t know much Clojure yet. I’ve basically been taking what I know of Emacs Lisp and trying to cram it into Clojure syntax. (compose is pretty cool!) I should probably read through a Clojure tutorial and some kind of syntax reference. (Hyperpolyglot is neat!) But hey, I’ve gotten through 21 problems so far.
Tom Marble and I were chatting about Clojure, Emacs, and Org Babel. As it turns out, there are lots of ways to interact with 4clojure problems from within Emacs. Tom told me about the 4clojure package by Joshua Hoff, which is probably slightly improved with the following code:
(require 'clojure-mode) (defun my/4clojure-check-and-proceed () "Check the answer and show the next question if it worked." (interactive) (let ((result (4clojure-check-answers))) (unless (string-match "failed." result) (4clojure-next-question)))) (define-key clojure-mode-map (kbd "C-c C-c") 'my/4clojure-check-and-proceed)
That one doesn’t track your progress on the website, though, so you’ll still want to copy and paste the solution yourself.
I like working within Org Mode so that I can easily take notes along the way. Here are the notes I took while figuring out how to get Clojure and Org to work together. http://www.braveclojure.com/basic-emacs/ is nice. http://bzg.fr/emacs-org-babel-overtone-intro.html has a good introduction. Here’s what I used from those:
Install Java (at least version 6), Clojure and Leiningen.
Install the clojure-mode and cider Emacs packages
Evaluate this by moving the point to the
#+begin_src line and running
(add-to-list 'package-archives '("melpa" . "http://melpa.milkbox.net/packages/") t) (package-refresh-contents) (package-install 'clojure-mode) (package-install 'cider)
And then evaluate this afterwards:
(add-to-list 'org-babel-load-languages '(emacs-lisp . t)) (add-to-list 'org-babel-load-languages '(clojure . t)) (org-babel-do-load-languages 'org-babel-load-languages org-babel-load-languages) (setq nrepl-hide-special-buffers t cider-repl-pop-to-buffer-on-connect nil cider-popup-stacktraces nil cider-repl-popup-stacktraces t) (cider-jack-in)
That should let you evaluate this:
(list? '(1 2 3 4))
And that let me do stuff like this for #27: Palindrome Detector:
(defn __ [x] (= (seq x) (reverse x))) (list (false? (__ '(1 2 3 4 5))) (true? (__ "racecar")) (true? (__ [:foo :bar :foo])) (true? (__ '(1 1 3 3 1 1))) (false? (__ '(:a :b :c))))
If all the results are true, then I’ve passed. Yay! In the web interface, __ is where your answers go. Fortunately, it’s also a valid Lisp name, so I can defn a function to replace it when testing locally. The proper answer would probably be something like
(fn [x] (= (seq x) (reverse x))) when submitted through the web interface, which is close enough.
it would be great to have something like 4clojure for Emacs Lisp – a site where you can practise solving small, well-defined problems. =) Has someone already written one?