Further into Chapter 4

So I haven’t posted for a while. Many things happened over the past few weeks, including a trip to Boston to attend PAX East and my parents visiting for the weekend. I’ve found myself yearning to get back to Clojure, which is as good a sign as any that I’m approaching coder obsession. So, onward!

First, a bit of advice: If you’re learning a new programming language, you absolutely have to keep at it every single day, even if you only do a little. It’s only by daily reinforcement that you can solidify the lessons and syntax you learn as you progress. Immediately upon reopening my files and starting up the autotests I found myself struggling to remember what types were appropriate for what I was trying to do. It took much longer than it should have for me to complete the next stage of the game’s development.

I started running into some difficulty given that CLISP doesn’t have all the types that Clojure does, and has much simpler quote/unquote splicing. In Clojure, unquotes automatically fully-qualify any symbols within the unquoted sequence, leading to:

(there is a (clojure.core/unquote (last edge)) going (clojure.core/unquote (second edge)) from here)

Yeah, and after much fiddling around with this I was given advice to try using strings, which Clojure has the ability to manipulate in the way that I wanted. So here’s what I came up with for describe-location and describe-path and describe-paths

(def ^:dynamic *edges*
  {:living-room ['[garden west door]
                '[attic upstairs ladder]]
   :garden ['[living-room east door]]
   :attic ['[living-room downstairs ladder]]})

(defn describe-location
  "Describe the location in the node map. Really it's just
  an alias for 'get'."
  [location nodes]
  (get location nodes))

(defn describe-path
  "Describes a path from the edges map."
  [edge]
  (str "there is a " (last edge) " going " (second edge) " from here."))


(defn describe-paths
  "Describe all paths from a location given an edges map"
  [location edges]
  (join " " (map describe-path (get *edges* :living-room))))

One thing I’m becoming very unhappy with is the use of earmuffs for global variables. When I do them without the def &:dynamic *var* style Clojure buzzes irritation at me, but in this case *edges* is not dynamic and doesn’t need to be, so I’m inclined to just remove the earmuffs and make it a regular def.

As you can see I chose to use a map for the edges, just like what I used for nodes. Vectors describe the non-executable set of symbols describing the edge, but I”m not 100% certain it’s the right type for that data. I pulled clojure.string/join in because I discovered that str concatenates without spaces. The join function was usable without apply, and gradually with some testing in the REPL the solution came together and I got some passing tests!

I’ll continue working on it tomorrow. With more frequent efforts comes more progress and confidence!

Chapter 4

Yes, I’m skipping over chapter three in this journal. Chapter 3 explains the syntax of lisp and some common datatypes. The primary takeaway from Chapter 3 is that Clojure doesn’t have the c*r family of list digging functions, though I came across an implementation on Clojure Log:

(map #(get {\a first \d next} %) (second (re-find #"^c([da]+)r" string-stuff)))

Not sure if it works, or if I’ll put it into a function in land-of-lisp.core. Another important thing to note is that in Clojure an empty list is truthy, which fouls up some assumptions if you’re using Clojure to work through Land of Lisp, which relies on CLISP assumptions. I’m keeping this in mind as I read Chapter 4 and learn about branching forms.

Yes, chapter 4 is about special branching forms such as if and cond. Happily, cond does exist in Clojure. Unhappily, I discovered that it doesn’t have implicit progn. A resource pointed to me by the folks in #clojure helped out here, HyperPolyglot - Lisp tells us that do is what I want to use. So…

(defn pudding-eater
  "Page 56 pudding-eater function in Clojure"
  [person]
  (cond (= person 'henry)
          (do (reset! *arch-enemy* 'stupid-lisp-alien)
          '(Curse you Lisp alien - you ate my pudding))
        (= person 'johnny)
          (do (reset! *arch-enemy* 'useless-old-johnny)
          '(I hope you choked on my pudding johnny))
        :else
          '(Why u eat my pudding stranger?)
        ))

And despite the lack of examples the case version was easy enough to puzzle out:

(defn pudding-eater-case
  "Page 57 pudding-eater function in Clojure using case"
  [person]
  (case person
    henry
     (do (reset! *arch-enemy* 'stupid-lisp-alien)
     '(Curse you Lisp alien - you ate my pudding))
    johnny
     (do (reset! *arch-enemy* 'useless-old-johnny)
     '(I hope you choked on my pudding johnny))
    '(Why u eat my pudding stranger?)
    ))

Later in the chapter further wrinkles present themselves, when much to-do is made about eq, equal and =. In Clojure there is only =, which serves as well as equal. There is a troubling bit in the case of comparing different datatypes. For example, 4 and 4.0 aren’t equivalent, and there is no easy case-insensitve string comparison. We must somehow make do without the help of equalp, which does compare floats to integers, or strings regardless of case.

Two more chapters down, but no more games! I’m sad, but Chapter 5: Building a Text Game Engine, promises to kick some serious butt.

Guess what I got working!

Let’s start with the code:

(ns ch2
  (:require [land-of-lisp.core :as lol]))

(def ^:dynamic *small* (atom 1))
(def ^:dynamic *big* (atom 100))

(defn guess-my-number
  []
  (lol/ash (+ @*small* @*big*) -1))

(defn bigger
  []
  (reset! *small* ((fn [] (+ (guess-my-number) 1))))
  (guess-my-number))

(defn smaller
  []
  (reset! *big* ((fn [] (- (guess-my-number) 1))))
  (guess-my-number))

The real breakthrough happened last time, when I began using atom and reset! to modify my global state, but It wasn’t until now that I started to get close. My first problem was this:

failure in (.clj:6) : land-of-lisp.test.ch2
       (expect 75 (bigger))
       expected: 75 
            was: #<ch2$bigger$fn__651 ch2$bigger$fn__651@5f8f127c>

My atom was being set to a function reference from the looks of it. How was I supposed to get the function to be evaluated, and then use the evaluated value to set the new global? An idea crept up in my mind, and proved my instinct to wrap the function in an additional set of parens to be correct.

With the function reference gone, I was left only with satisfying the expectations, which turned up some unexpected numbers. I looked back and forth at the few pages describing these functions in CLISP but it wasn’t until I had stared through the page that the answer popped out at me. (bigger) is supposed to update *small* and (smaller) is supposed to update *big*!

So with that completed, I’m ready to charge through the rest of Chapter 2! As always, you can monitor my progress on Github.

Finally, some fun reads:

A declaration

Last time I wrote I was having some issues maintaining global state in Clojure, which is natural since one isn’t supposed to do such a thing. I got a lot of headscratching and pushback from the kind, smart, and helpful folks in #clojure who suggested I set Land of Lisp aside and work with a beginning Clojure book, then come back and translate LoL into Clojure once I had more skill with the language.

Let me take an aside. Everybody approaches learning a new programming language differently and there are many, many tools and strategies for going about it. When I learned Ruby, the resource that had the greatest, most lasting impact on me was _why’s Poignant Guide to Ruby. It’s not complete or even particularly good as a resource, but it infuses the act of learning a programming language with mystery, magic, and adventure. I naturally moved on to stronger resources, like the Pickaxe book and Eloquent Ruby, which helped me learn good style, strong Ruby idioms, and cemented what I had learned from _why in reality.

When I heard of Land of Lisp I was excited about the possibility of learning Clojure by working through it. Clojure is a LISP too, right? Common Lisp is pretty standard, right? Lisps have many similarities, right? These are all assumptions I’ve made that you, noble reader, should know I found to be rather naieve. Yet that does not diminish the excitement I feel when I pick up LoL and flip to the next page.

My goal in fighting LoL with Clojure is the challenge and adventure of growing my tenuous grasp on Lisp and Clojure by holding that knowledge up to the light and squinting, reading language documentation, and searching for solutions that please me. It will be grueling, it will be hard. I know I could probably learn more Clojure in a fraction of the time by using a more suitable text. And yet when I’m done with that book, having absorbed all the lessons within it, will I really love Clojure deep in my heart?

Dynamic Variables - Land of Lisp, Chapter 2

The way I’m currently going about learning more Clojure is by working through Conrad Barski’s delightful and strange book Land of Lisp, wherein one learns lisp by making games.

One of the first hurdles I had to tackle and make a decision about was Land of Lisp’s language of choice, Common Lisp, or CLISP. I quickly found that almost nothing in Common Lisp is common to Clojure, and so I had a choice. Either translate CLISP functions to Clojure, or implement them using Clojure. So far I’ve been using a mix, translating defun to defn, and writing my own implementation of ash rather than using bit-shift-right even though bit-shift-right satisfies the needs of the first game, ‘guess-my-number.’

I was immediately rewarded in having the chance to find the bit-shift functions, set them in an if statement, and within a short time (minus debugging and syntax-learning frustrations noted in an earlier post) had a working implementation of ash that affirmed my growing skill and knowledge with the language. But that was just one step and I’m still one more function away from a working guess-my-number.

Apparently in CLISP you might set a global dynamic variable by calling: (setparameter big 100) And update the value of that parameter with: (setf big 50)

Well, in Clojure I haven’t yet figured out how to mimic this functionality. Thankfully it alerted me to the special macro for defining a dynamic… something. I know that Clojure is all about immutability and programming functionally, which makes me concerned that programming in a CLISP way could get very difficult very fast.

And it has. I spent some time trying to figure out how to replicate the global state that Conrad sets up, and even asked in #clojure, helped by autodidakto. The full CLISP code looks like this: (defparameter small 1) (defparameter big 100)

(defun guess-my-number ()
  (ash (+ *small* *big*) -1))

(defun smaller ()
  (setf *big (1- (guess-my-number)))
  (guess-my-number))

(defun bigger ()
  (setf *small* (1+ (guess-my-number)))
  (guess-my-number))

The biggest outstanding issues are around setting some global state in clojure and updating that state. I almost have it working with an atom, but my atom gets (reset! to a fn reference instead of the return of the function. :|

Recommended: live-cljs A clojure implementation of Bret Victor’s interactive game coding in Inventing on Principle

Github of the project’s current broken state: Github/carlthuringer

Frustration with Expectations

So having seen the excellent @logosity talk about Continuous Testing for Clojure, I set up Expectations in my project. After some serious trial and error I came up with this:

;project.clj
(defproject land-of-lisp "0.1.0"
  :description "A series of unfortunate closures"
  :dependencies [[org.clojure/clojure "1.3.0"]
                 [org.clojure/math.numeric-tower "0.0.1"]
                 [expectations "1.3.6"] ]
  :plugins [[lein-expectations "0.0.2"]
            [lein-autoexpect "0.1.1"]])

;src/land-of-lisp/core.clj
(ns land-of-lisp.core
  (:require [clojure.math.numeric-tower :as math]))

;"Clojure implementation of CLISP ash"
(defn ash
  [number shift]
  (if (< shift 0)
    (bit-shift-right number (math/abs shift))
    (bit-shift-left number shift)))

;test/land-of-lisp/test/core.clj
(ns land-of-lisp.test.core
  (:require [land-of-lisp.core :as lol])
  (:use [expectations]))

(expect nil? nil)
(expect 22 ('lol/ash 11 1))

I bet you wonder what the problem is? Well, that expectation actually gets 1 when the test is run. If I change it to (expect 22 (‘lol/ash 11 2)) then it gets 2 when the test is run. Am I missing something here?!

I tried pasting into repl and replicated the problem. However, if I paste only my core.clj then the ash function works fine. If i then paste the test/core.clj it goes back to returning the shift instead of the proper output.

Stumped.

Edit! Mere moments after posting I checked #clojure and a friendly user had said that (‘lol/ash 11 1) won’t work because you can’t quote the symbol. Removing the quote fixed everything.

Block scripting on Chrome

So, I was just listening to the Security Now! podcast, episode 339, and heard about ScriptNo for Chrome. And immediately installed it. I’m a big fan of NoScript for Firefox, but until now there hasn’t been a particularly good plugin for Chrome that gives the same functionality. But now there is, and you can block and permit scripts all over the web wherever you go.

Get it from Google’s Store

Why would you do that? In fact, if you install this plugin right now and browse to your favorite website you may be shocked. Nothing works! I assume your favorite website makes use of a large number of scripts, of course, but that’ll be your experience. Now click the new ScriptNo plugin button and look. If you hover over the domains listed you can see what scripts are being blocked, and I can nearly guarantee that some of those scripts are for tracking, advertisements, or some other random garbage. So if you’re on facebook, permit the facebook scripts to run. Then reload the page and voila, facebook works, even though there are still a few blocked scripts.

ScriptNo gives YOU the power to decide what the sites you visit can and cannot do.

Writing about something I'm interested in

Something amazing happened Saturday. I wrote some hundreds of word about Starcraft, a log of games that I played throughout the day while doing stuff around the house.

I’m going to add a section to the site now for starcraft and post that plus the replays. But more than that, I discovered how incredibly motivating writing can be. I’m easily frustrated by Starcraft. It’s an incredibly masochistic and challenging experience to play multiplayer online, but writing about it not only encouraged me to think about my experience, but to keep going and apply my meditations to following games.

This has to have an application for the original intent of this journal, to blog about programming, being a developer, and living in a new city.

So here goes. I’ll start working on drafts of topics that cross my mind, projects and experiments, and see if that doesn’t just get me to post a lot, but also to stretch myself and grow as a developer.

Treading Water

It has begun to seriously worry me that I have taken a bit too long to settle into my new life as a developer here and I am not challenging myself on a daily basis. 

I have some aspirations for what I want to accomplish with my project, Magic Hat, the first of which being the implementation of user timezones so that the deadline and repeat times on Tasks are localized, making them useable to people who don’t live in California.

But the longer I take away from the project, the more difficult re-entry feels. What I’m realizing is that if I don’t force myself to put in a little work each day, I won’t grow as a developer, and I don’t want that. I will implement that timezone feature, and then I’ll look at converting my activerecord models to data access objects. Next comes backbone.js… and hopefully with that the app will be ‘perfect.’