Bathroom Reading Material

Defining Life Based on Who You’re Stuck in a Room With

| Comments

I turned 18 in February of this year. I’ve long known that hitting that milestone would mean a lot major life changes in quick succession, and I have prepared to be overwhelmed. I’ve been told that being overwhelmed is the only logical human thing to experience when these sorts of things begin to happen. I’ve got to say, it’s one hell of a ride, but it’s one I’m very happy to be taking.

Work

I’ve been working with a wonderful company called Geni for the past year. Geni is a genealogy website dedicated to building a family tree of the whole world. You make an account and create your family tree.

Around two years ago, I was lucky enough to meet and become good friends with Justin Balthrop and Lance Bradley, both engineers at Geni. They had just created the cake build tool and I was one of the first users. The first experience I remember with these guys was me arguing with them over a feature cake had that I did not like, which was that it would start a swank server by default whenever you ran a command. I can’t remember the details of why this was a problem with me, but the end result was that they made the feature more configurable and off by default.

Days go by, we become friends. We met in person for the first time at the first Clojure Conj conference in late 2011. We spent the entire conference together. We had a lot of fun.

Eventually, Lance and Justin began talking about the possibility of me working at Geni as an intern. I think I was still 16 when I had my phone interview with the then-CTO, Amos. Several months passed while details were worked out. Amos left the company and Justin was promoted to CTO, which gave him more wiggle room for bringing me on as an intern quickly. I started in March of last year.

Oh my, what a wonderful year. 17 years old, working part time with Clojure from my own home all the way across the country. Even making money! Lance and Justin have taught me so much and given me so much experience. They’ve helped build my skill and my confidence in my skill, and I don’t think I’d be even remotely the man I am right now without their ongoing influence. I don’t think they’ll ever know what they’ve done and continue to do for me.

Turning 18

Turning 18 was always an important milestone for my Geni work. As long as I was a minor and still in high school, I could only work part time and the legality of things would be complicated.

Our plan was to fly me out to Los Angeles when I turned 18. I would work in the office for a week face to face with my coworkers and experience LA. A few weeks before I was meant to make this trip, I freaked out for a few days. Moving away from home is the expected end result of all of this. Unfortunately, there are circumstances preventing me from relocating my family at this point in time, and thus this is something that I would have to do alone.

Needless to say, this scared the hell out of me. So much so that I talked to Lance and Justin and pleaded for a way to continue working there and not have to uproot. Justin encouraged me to relax and just come out there for the trip and talk again after LA was no longer an imaginary place. His and Lance’s calm regarding this matter along with encouragement from my family to make this happen calmed me down significantly. I still wasn’t sure about moving, but the possibility stopped being ridiculous and began to make sense.

Los Angeles

The plan became a reality last week. I stepped on my flight on the morning of Friday the 13th. This was the first flight I had ever taken by myself, and it would lead me to a place farther away from home than I had ever been before.

I had a connection in Nashville where I got on a plane to Los Angeles. After this uneventful 4 hour flight, I found myself on an escalator down to a man waiting for me with my name on a card. This man drove me to the studio where I was to stay until the 21st. What makes this drive notable is that my best friend Alan (also an engineer at Geni) sent me a text message saying "Welcome to LA!". I smiled so hard that I’m surprised my teeth didn’t fall out. My entire experience was braced on this text message. Los Angeles stopped being this scary place where I would be alone. Much to the contrary, I was surrounded by friends; the greatest people I’ve ever had the privilege of knowing. And they all wanted me there. They were all waiting for me to arrive. If you’ve never experienced this, you’re missing out.

I was picked up shortly after arriving by Lance and carted to the Geni office on Sunset Boulevard for the first time. They had set me up a desk and an amazing Aeron chair. Lance gave me a tour of the office and then he, Justin, Alan, and I all headed across the street to BOA Steakhouse for a fantastic dinner.

This was the beginning of a whirlwind weekend where Lance showed me the most amazing things I’ve ever seen. He gave me the tour of a lifetime and conversation that I will never forget. Alan came along with us for a lot of the weekend activities. Notably, Lance showed me Hollywood, Santa Monica, and Venice. I had never seen the ocean before, so it was mind blowing. We all took our shoes off and stood in the cold waters of pacific tide at Venice beach. I’ve never had so much fun in my life. Not for one second did I think of home, leaving my family, uprooting, changing. All that mattered was how I felt, and I felt amazing.

We did so many things that weekend that I couldn’t bring them all to mind in order to list them even if I tried. Notably, we saw a wonderful movie called The Chronicle and Lance and Alan took me to my first 3D movie (Wrath of the Titans) which I thoroughly enjoyed.

Monday begins my first 40 hour week at Geni, working in the office face to face with my coworkers. I felt at home the moment I plugged my laptop into the monitor on my desk. The conversations between my coworkers are smart and well worth listening to, and we have plenty of fun in the office as well. Light Table was kickstarting at the time, so we had lots of conversation about that and we followed developments closely.

During the week, Lance and I would sometimes do stuff after work. Lance took me to the hills one night and showed me the most amazing view of the city from above. The lights go on forever and the cars appear to be infinite. It is like an ocean on land, and it surrounds you on every side. It is inspiring and overwhelming in its beauty and is one of my highlights from the week.

I got a lot of work done during the week. I had never bought into the whole you-gain-a-lot-by-working-face-to-face thing, but I have to say, I believe it now. It is a lot easier to get things done and to concentrate when you’re in an office setting. If you need something from somebody, you find them and talk to them. There are few distractions. I highly value an office setting now and I’m excited at the prospect of doing it every day.

By Thursday, two nights before the morning I was to leave, I found myself in a position that I never expected myself to be in: I did not want to go home at all. I was enjoying it so much that the fact that I had to go home at the end of the week had been entirely an afterthought. It was saddening when the time finally came.

On Thursday, Lance and I left work early and drove to Malibu. Lance has suggested that Venice beach was not a good first beach experience. I didn’t know what he meant until I saw the beaches of Malibu. They were so utterly majestic! The first thing I noticed was that I could, for the first time, noticeably smell the ocean air. We went below Point Dume and climbed over rocks to tide pools. The scenery took my breath away.

Earlier in the day, Justin told me he wanted to talk about my trip and my plans for the future. We went to a private room and talked. He was concerned about putting pressure on me. He asked me how I liked it there and if I had decided whether or not I wanted to come work at Geni full time and live in LA. I was telling him yes in the blink of an eye.

Things are set in motion now. I get my diploma on the 25th of this month (April), and Geni will be able to make me a full time offer. In the next couple of months, I’ll move to Los Angeles and begin a life on my own.

Stuck In A Room

There is an episode of House where House talks with a patient (who had been raped and was pregnant) who he is reluctant to treat. There is a part where the girl says something along the lines of "All life is is a series of rooms, and who you’re stuck in those rooms with adds up to what your life is.". This is what comes to mind when I think of this trip and my future.

Moving to LA, I will not be alone. In fact, I’ll be stuck in a series of rooms. The important thing is that there is nobody in this world who I would rather be stuck in those rooms with. I’ve got the best friends in the world, and I have the luxury of them also being my coworkers. I’ve never wanted to be stuck in a room so much in my life.

My friends have given me the best and most important week of my life. It was a life-changing trip that I will never forget. It has and will shape my life and future. A follower on twitter mentioned that it is amazing when things click, and I have to say that I agree.

I’m very excited about my future. My life is about to change radically, and I’m okay with it. I have choices and options I’ve never had before, and I see my path in front of me. It is going to be one hell of a ride, but it is a ride that I’m happy to take. Lance, Justin, Alan, thanks for making this a reality. Thanks for making things easy. Thanks for giving me an amazing new room to get stuck in.

Thanks for reading.

I Code With Things and Stuff

| Comments

A lot of radical changes in my development environment resulted in someone asking me if I’d write a blog post about it. I was already considering doing that, and the interest of at least one person is motivation enough to actually do it.

Background

I used Emacs for around two years. It started back in my Haskell days. You know how Lispers love Emacs because it has SLIME? Haskellers seem to love Emacs because it can handle Haskell’s complex indentation rules (rules that aren’t really rules but still shouldn’t be broken).

When I started using Clojure, I was lucky enough to already have some Emacs under my belt and so I continued using it.

Emacs

Oh how I love Emacs. When I used Emacs, I even used it as my IRC client via ERC. ido-mode was my lord and savior and a day without it was a day spent in the deepest bowels of hell.

When you use Emacs for a language like Clojure, you tend to get smug towards people who use other editors (particularly Vim) because you have SLIME, the Superior Lisp Interaction Mode Environment Blah Whatever. It is a fantastic development environment for Lisp languages (including Clojure) that provides debugging (I don’t think this actually applies to Clojure yet), completion, interactive development inside of Emacs, and all sorts of other stuff that makes birds sing and babies be born.

Though I used and loved Emacs, I almost never used SLIME. Don’t get me wrong, I respect and understand why it is so important to people, I just never really used it. If I did use it, it was because having a REPL inside of my Emacs window was more convenient than switching to a terminal window to enter some code. Plus, when you use SLIME (or inferior-lisp which is a completely different and simpler thing), you can send code from one buffer to another without copying and pasting. It makes things really quick and easy. That’s all I ever used SLIME for.

The greatest thing about Emacs is just how much you can do with it. The fact that SLIME is possible in the first place and that it can work out so well is spectacular. Emacs is built around a Lisp called elisp. As such, Emacs is probably the most extensible editor that ever has been or ever will be. You can make Vim do magic tricks, but Emacs really can pull a rabbit out of a hat.

And that’s what has always bothered me. When people talk about Vim vs Emacs they end up focusing on the least important things. You can’t even have a discussion about the merit of one or the other without a flurry of childish remarks. Sure, Emacs is an operating system. That’s the point. Emacs is an execution environment for a Lisp. It is designed for you to be able to do anything with it. That isn’t a flaw. It is insignificantly bigger than Vim and insignificantly more resource-intensive because it is supposed to be.

So, what about important things? Key chords versus colon commands? Sure, this one is relevant. A lot of people dismiss Emacs because of it being driven by keyboard shortcuts off of a number of modifier keys. In particular, a lot of people complain of "Emacs pinkie" because of the position of the control key and the number of times an Emacs user has to use it to get anything done. I can understand this complaint, though I’ve never experienced problems related to it. As a matter of fact, I’ve only had control mapped to caps lock for one year. My work sent me this laptop with it already remapped and I decided to leave it like that. I got used to it so it wasn’t in my interest to switch it back. I’m still not sure I’ve gained anything by having it moved there.

But yes, key chords vs colon commands does matter to some people and I can understand why.

Experimentation

I like trying new things in my development environment. New editors, new IRC clients, new color schemes, new terminal emulators, etc. I get bored. I recently started playing around with text editors with no real intention of moving away from Emacs.

First of all, a friend and I have been working on RefHeap, a pastebin with an API. The first thing I did was write an Emacs plugin (library?) for it. A lot of people wont even consider a pastebin unless it has support for their editor, so I figured hey, I should just use as many popular editors as possible and write a plugin for all of them. Next stop: Sublime Text 2.

Sublime Text 2

At first glance, this editor is beautiful. It has the prettiest indent guides I’ve ever seen and lovely syntax highlighting. It has an excellent set of themes including the full set of tomorrow night themes which I used the most at the time. It is also a highly extensible editor. Plugins are written in Python and aren’t very difficult to write if you can read an existing plugin or manage to find up-to-date information about them.

Unfortunately, it just doesn’t seem to have a very good editor. Trying to edit Lisp code in it is so painful that it is nearly impossible. It doesn’t know how to auto-indent even remotely properly and the Clojure syntax file that comes with ST2 breaks on regexes with escaped double quotes. I fixed that with a guy’s recommendation from twitter, but it was a bandaid on an infected wound.

The thing that bothers me the most about Sublime Text 2 is the way you open files with it. In Emacs and Vim, you can execute a command and type a path to a file anywhere on the harddrive with completion and interactive features (see ido-mode for Emacs and wildmenu for Vim). In ST2, you have two options for opening files:

  • You use the operating system’s Open File dialog.
  • You use the goto anything feature which lets you type a path and gives you fantastic fuzzy completion, but only works relative to your current directory, meaning you can’t be in /Users/anthony/foo and open a file in /Users/anthony/ like this.

Also, ST2’s Open File dialog is completely separate from its Open Folder function. If you want to open a folder instead of a file, you have to use that dialog. Oh, and there is no keyboard shortcut for this.

All in all, the operating system’s open file dialog is a really weak way for a programmer to navigate the file system to open the file he needs. There is nothing in ST2 stopping this from being implemented AFAIK, but I guess I’m the only one who thinks what is done now is completely insane. Separating opening files and opening folders and forcing it to be done via a OS dialog is just not something I’m prepared to live with.

I actually used Sublime Text 2 for about a day and a half until I really had to edit some Clojure code. There was just nothing to be done. I like Sublime Text 2, but it is pretty worthless for Clojure. Since RefHeap’s primary market is Clojure programmers and Sublime Text 2 users in the community are a very, very small minority, I just decided to call it quits on that. I will absolutely revisit this (it is really easy to write a RefHeap plugin in Python) if ST2 ever becomes better for Clojure and I can tolerate it long enough to test such a plugin.

I’d like to add that my opinion of ST2 is entirely based around its support for Clojure. From what I saw, it is an excellent editor for other languages such as Python and Ruby. This makes perfect sense because the author and majority of contributors (to the parts that you can contribute to) use these languages and don’t use Clojure. I expect that the Clojure portion of things will get more love as it gets more popular in the Clojure community.

Vim

My next stop was Vim. This is where things get interesting. VimL is the most horrid extension language for an editor that I have had the misfortune of working with. The thing is, Vim is a fantastic editor. I don’t know what the author was thinking when he designed this language, but I can only assume it was done during a binge drinking contest.

The only salvation is that there are Vim interfaces for a number of languages, including Scheme, Ruby, and Python. Unfortunately, you still have to write some VimL to glue it all together, but very little. The most important stuff can be written in one of those decent languages and you can generally keep your sanity. Seriously, go look at gist.vim, a plugin for Vim for the Gist API. It is pure VimL and a little over one thousand lines. No thanks.

I used Vim for a day and then I wrote that damned plugin. I dove in head first. The most information I could find for the Vim interface to any given language was for Python, and I was equally oblivious to all of these languages so I went with it. The actual Python part of things was dead simple. I spent maybe 3 hours on it (having not written a line of Python before). Then I spent another day and a half on the VimL glue part of things and I had a very nice and usable plugin. It was great!

At this point, I stopped caring about editors and was more concerned with how much fun I had with Python! I don’t very often just write shit in random languages just because I can, so it was nice to do new things. So I began having crazy thoughts to justify a rewrite in Ruby. Everybody loves Ruby! Nobody likes Python1! Let’s do it in Ruby!

So I did it in Ruby. This time, I wrote a whole API library first because I knew I’d be using it for more than refheap.vim. That was 6 different kinds of fun. As a bonus, I wrote a command-line tool for RefHeap as well. The actual Vim part of things was easy because the VimL glue was already written from the Python implementation.

I had lots of fun doing this, and it took me several days to do it. I used Vim for all of it, and that’s where things got interesting. I really liked Vim. I used Vim for about a week and a half probably 6 months before but gave up on it for Clojure development for one simple reason: it is not as smart as Emacs about indentation.

In Emacs, when you press tab, it indents exactly how much it is supposed to be indented. You can press tab for a month and it’ll only indent to what is correct for that language. Now, this varies for languages like Haskell because there is more than one correct indentation, but this kind of variation does not exist in Lisp and thus Clojure. Where this really begins to show is in an example like this:

1
2
3
4
(defn foo []
  (let [x]
    (y x)
    (z x)))

What happens if we want to take the let out of this code?

1
2
3
4
(defn foo []

    (y x)
    (z x))

Uh oh. Now what? We need to somehow reindent this whole thing so that that the two forms are lined up against the defn now that the let is gone. In Emacs, I would have walked through this hitting tab which would reindent each line in turn for me. But Vim isn’t smart about indentation it knows what to do when I hit return and insert a newline, but if I hit tab some more, it’ll indent some more. I didn’t think Vim had an answer to this until Chris Granger, a Clojurian vimerman, told me the secret to life, the universe, everything.

Vim has a concept of ‘text objects’. Basically, this is a way to intelligently select an area of text based on what it is surrounded by. This is fantastic for Clojure and Lisp in general because everything is surrounded by parentheses. So, to reindent this code, we can do =i(.

1
2
3
4
(defn foo []

 (y x)
 (z x))

Bang! And for the line that is left, we only have to hop down a line and hit dd, which deletes the line. This one single command changed my entire opinion of Vim.

Oh yeah, and I was really attached to paredit in Emacs. Bang!. Yes, this works really really well. It has all of the most important commands (for me, anyways) and it keeps things balanced. It isn’t quite as polished as the Emacs version, but it does work.

So, somewhere along the way, I became a Vim user. I haven’t used Emacs in at least two weeks, probably 3, and I am wildly productive in Vim. I never really used editor commands in Emacs (because I never remembered them long enough to use them for anything significant, which is probably because they took longer to enter than just doing the stuff manually).

Will I continue to be a Vim user forever? I thought I’d always use Emacs, but that turned out to not be the case. I do not want to go back to Emacs and do not see myself doing so in the near or distant future. I might find a reason to do so tomorrow and I might never find a reason to do so. We’ll see.

I’ve got one thing to add to this: I have nothing against Emacs. Seriously guys, you don’t have to hate one in order to prefer the other. If I had a good reason to use Emacs now, I would. I just started using Vim and realized I liked it and that I’m very productive in it. Emacs did its job just fine and I have no animosity towards it.

So, my development setup

This was supposed to be a post about my development environment but it turned into a really long post about how I got here. I think that is important. I need people to understand why I use the things I do because that is wildly more important than what I actually use. So, without further ado, here is what I’m using for development today and how I’ve got it set up.

Software

First of all, Vim. The first thing I did when I started using Vim was install janus. It gave me a bunch of useful keybindings out of the box and a whole lot of useful plugins that I probably wouldn’t have found otherwise. The most useful ones I’ve found so far are CtrlP, NERDCommenter, NERDTree, and Fugitive (oh em gee this is awesome). The most useful thing I’ve found not included with Janus is tabular.vim.

Also useful from Janus is that it bundles some plugins for highlighting markdown, mustache, haml, sass, scss, better Javascript, and git commits. Janus really is a good way to get started. You get basically everything you need and you don’t have to go hunting for how to do it.

I know what you’re interested in is my Clojure setup, and I’m probably going to disappoint you with it. I use VimClojure, and the first thing I did was delete anything even remotely related to nailgun. Remember I said I never really used SLIME in Emacs? I haven’t even bothered trying to do anything similar in Vim. I believe the author is rewriting the stuff for nREPL, and I’ll probably give it a go once that is done, but I’ll probably never use it much. I actually like lein repl and I use it. I do tons of interactive development, I just don’t do it in my editor. Am I missing out? Probably. Do I care as long as I still get things done and am productive? God no.

Besides paredit.vim, that’s it for my Clojure setup. Just VimClojure’s syntax highlighting and indentation stuff and Leiningen. Clojure is simple. Don’t need much more than that.

Oh, I also use OS X. The Vim I use is MacVim and my terminal emulator is iTerm2, simply because it is less quirky than Terminal.app.

My color scheme is solarized dark unless I’m in the sun, in which case I go with solarized light. I’m not entirely satisfied with solarized, but there aren’t a lot of good color schemes with both light and dark backgrounds. The color scheme I like the most and used before solarized was Tomorrow Night. I really liked it, but there are some problems with the Vim highlighting that I’m not entirely satisfied with, and Chris Kempson, the author, doesn’t seem to care about it anymore and never responds to pull requests (of which there are many) and issues. I still use a tomorrow-nightish theme on RefHeap because I can control it, but I don’t use it for my system anymore. If I had more time, I’d just fork it and work on it myself, but it’s quite a task. I sure wish somebody would though.

Also, iTunes. I consider music a part of my development environment. Yes, I know about the disdain for iTunes, the reason I use it over other media players is outside the scope of this blog post.

Hardware

I use a 2,2 macbook pro from ‘06 or ‘07. I did not pay a penny for this. The company I work for, Geni, gave me this laptop. It is old, but it still works really well and the hardware isn’t really ancient. It has 3GB RAM and a 2.33GHz intel core 2 duo. The only issues I have with it is that it is rather unsightly, has a DVI port, doesn’t have the newer and better multitouch trackpad, and is big and bulky.

My ideal hardware would be a new 13-15 inch macbook pro, but I think I’d be fine with a macbook air. In a pinch, I’d appreciate a middle class thinkpad loaded with arch linux. Unfortunately, I am not a man of means right now.

Conclusion

I am currently a Vim user recently converted from Emacs. If you’re new to Clojure and you like Vim more than Emacs or are already familiar with Vim, please ignore everybody who tells you that you need to use Emacs. You will be just fine with Vim. I chose Vim after two years of using Emacs, and I’ve yet to be dissatisfied. If you want to check out Emacs, by all means, do so. Having it under your belt and having more options is always good, but understand that it is absolutely not a necessity for Clojure.

If you’ve stumbled upon this blog post trying to find the best way to get started with Clojure, then you have found your answer. The answer is "whatever you are comfortable with". Go install Leiningen and use it instead of trying to ‘install’ Clojure, and then use whatever editor you are familiar with. If you already like Emacs, use Emacs; if you like Vim, use Vim; even if you’d be more comfortable starting with an IDE, you are fine. Go get Counterclockwise for Eclipse or La Clojure for IDEA. If it begins to not be enough for you, check out the editors. There is no wrong answer here and no silver bullet. My friend Phil Hagelberg says it best: whatever you do, do not let your editor get in the way of you learning Clojure.

Thanks for reading.

1 This is a joke. Please take it as such. I don’t dislike Python. Python is our friend. Take a deep breath.

Thanks a lot to Andrew Brehaut for proof-reading and advising me a bit. He made me do this, so if anything I say here offends you, please direct all furious comments and bashing at his email address. Thank you.

Waving Our Tentacles

| Comments

Everybody knows that Github is fantastic. It is a wonderful service that not only hosts your Git repositories but also gives you a great platform for managing your projects and handling large-scale collaboration. It has arguably the best code review mechanism around (the pull request) as well as project wikis, issues, organizations, and even private repositories (on paid accounts) for the non-FOSS and business folk. It is an essential tool for the open source developer.

But we’re not really here to talk about Github as a service. We’re here to talk about Github’s new v3 API and my Clojure library, tentacles, that provides a Clojure interface to it.

While writing the library, I obviously had to test things as I went along. In doing this, I realized how elegant and powerful it is to work with APIs from Clojure if you have a simple and concise library for doing so. The Github API has some really neat things in it that are really fun to play with, even if we aren’t doing anything with them. This post is going to serve several purposes:

  1. We’re going to learn how to use Tentacles.
  2. We’re going to learn how to use some important parts of the Github API.
  3. We’re going to use the Clojure REPL as a prompt for interacting with the Github API – a very powerful concept.
  4. We’re going to get to see what Tentacles can do.

Note that I’ll be using two accounts in my examples: Raynes, my own account and amalloy, Alan Malloy’s account. It is about time he and I compete for world domination. Furthermore, I’m going to pretty-print some results with clojure.pprint.

Playing along

If you want to play along, go ahead and create a new project.

lein new tentacles-fun

Next, edit your project.clj file and add [tentacles "0.1.2"] to your :dependencies. After that, just run lein repl and have a blast.

Users

Tentacles supports the entire Github API, but we’re going to start with Github’s user api. It has some very interesting data that we can look at.

We can, of course, get information about a user.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
user> (require '[clojure.pprint :as pp])
nil
user> (require '[tentacles.users :as users])
nil
user> (pp/pprint (users/user "amalloy"))
{:followers 30,
 :following 9,
 :gravatar_id "1c6d7ce3810fd23f0823bf1df5103cd3",
 :name "Alan Malloy",
 :avatar_url
 "https://secure.gravatar.com/avatar/1c6d7ce3810fd23f0823bf1df5103cd3?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-140.png",
 :bio nil,
 :location "Los Angeles, CA",
 :html_url "https://github.com/amalloy",
 :public_repos 56,
 :created_at "2010-08-18T16:37:15Z",
 :login "amalloy",
 :url "https://api.github.com/users/amalloy",
 :email nil,
 :type "User",
 :public_gists 160,
 :hireable false,
 :blog "http://hubpages.com/profile/amalloy",
 :id 368685,
 :company "Geni"}

You might note that Alan’s bio is nil. That’s because he has no life. Robot and all that.

Next, let’s learn a thing or two about ourselves. First, we’re going to need our authentication information quite a bit, so lets go ahead and def it so we don’t have to type our password 10 thousand times.

1
2
user> (def auth "Raynes:REDACTED")
#'user/auth

Truthfully, I just wanted to only have to do that once because I have a habit of forgetting to remove my password during demonstrations like this.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
user> (pp/pprint (users/me {:auth auth}))
{:disk_usage 46932,
 :collaborators 0,
 :plan
 {:private_repos 0, :collaborators 0, :space 307200, :name "free"},
 :followers 85,
 :following 36,
 :gravatar_id "54222b6321f0504e0a312c24e97adfc1",
 :name "Anthony Grimes",
 :avatar_url
 "https://secure.gravatar.com/avatar/54222b6321f0504e0a312c24e97adfc1?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-140.png",
 :bio
 "My name is Anthony Grimes. I live in a small town called Eldridge in Alabama. I am a programmer and a very avid supporter of functional programming and Clojure. I am currently writing a book on Clojure called [Meet Clojure](http://meetclj.raynes.me). I'm the author (or co-author) of a number of Clojure projects including [Try Clojure](http://tryclj.com) and [clojail](https://github.com/flatland/clojail), having spoken about the latter at Clojure Conj 2011. I am currently employed by [Geni](http://geni.com) as a paid intern working with Clojure on the backend.",
 :location "USA, AL",
 :html_url "https://github.com/Raynes",
 :owned_private_repos 0,
 :public_repos 58,
 :created_at "2009-02-14T03:25:23Z",
 :private_gists 137,
 :login "Raynes",
 :url "https://api.github.com/users/Raynes",
 :email "i@raynes.me",
 :type "User",
 :public_gists 457,
 :total_private_repos 0,
 :hireable false,
 :blog "http://blog.raynes.me",
 :id 54435,
 :company "Geni"}
nil

As you can see, I definitely have a life.

So, what’s up with how we gave tentacles our authentication info? We passed it a map containing an :auth key. This is an idiom in tentacles. The Github API has a lot of API calls that can have required as well as optional arguments. Most of the POST api calls take a JSON hash of data (but not all of them). Tentacles represents this in a very simplistic way. Any API call that takes optional arguments or does something special when given auth info translates to a function whose last argument is an optional map. Any API call that requires authentication, regardless of whether or not it has optional arguments, must take an options map (even if it will only ever contain the auth info). Furthermore, any required arguments that an API call takes are required positional arguments to the equivalent tentacles function.

Okay, so I have this theory. I am pretty certain that I am much more popular than Alan. I’m nicer, arguably smarter, definitely better looking, and I certainly wear better clothes. Can the Github API tell me if I’m correct? You bet it can! The obvious and canonical measure of epeen size is follower count! Let’s tally ‘em up!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
user> (pp/pprint (users/followers "amalloy"))
[{:login "MayDaniel",
  :avatar_url
  "https://secure.gravatar.com/avatar/e917432c8e85f043647b2c57b443c56f?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-140.png",
  :url "https://api.github.com/users/MayDaniel",
  :gravatar_id "e917432c8e85f043647b2c57b443c56f",
  :id 188450}
 {:login "Raynes",
  :avatar_url
  "https://secure.gravatar.com/avatar/54222b6321f0504e0a312c24e97adfc1?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-140.png",
  :url "https://api.github.com/users/Raynes",
  :gravatar_id "54222b6321f0504e0a312c24e97adfc1",
  :id 54435}
 {:login "tonyl",
  :avatar_url
  "https://secure.gravatar.com/avatar/43b2ca65e7a2cadf849adf103e6c066d?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-140.png",
  :url "https://api.github.com/users/tonyl",
  :gravatar_id "43b2ca65e7a2cadf849adf103e6c066d",
  :id 31147}
  ...]

Okay, so that isn’t very helpful. Github gives us very verbose information about followers and it gives us a lot of info. Let’s trim that down a bit.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
user> (pp/pprint (map :login (users/followers "amalloy")))
("MayDaniel"
 "Raynes"
 "tonyl"
 "jColeChanged"
 "hoggarth"
 "ossareh"
 "stonegao"
 "ohpauleez"
 "raek"
 "segfaulthunter"
 "invaliduser"
 "gigasquid"
 "Clinteger"
 "odekopoon"
 "devn"
 "dbyrne"
 "imissmyjuno"
 "k4rtk"
 "xmlblog"
 "jeremyheiler"
 "amcnamara"
 "sconover"
 "srid"
 "mbacarella"
 "carlwarnick"
 "spoon16"
 "octopusgrabbus"
 "daviddavis"
 "andreisavu"
 "RafalBabinicz")
nil

That’s better. Now count them.

1
2
user> (count (users/followers "amalloy"))
30

Huh? That’s no good! He definitely has more followers than that. What’s going on here is that Github paginates results. By default, there are 30 items per page of results and the maximum number of results per page is 100. Let’s go ahead and set it to 100.

1
2
user> (count (users/followers "amalloy" {:per-page 100}))
30

Oh… He really does only have 30 followers. Well then. Moving on.

1
2
user> (count (users/followers "Raynes" {:per-page 100}))
85

I think I’ve won this one. It’s the hair that does it, I think. There is also a specialized call to get the currently authenticated user’s followers, so we could have used it instead:

1
2
user> (count (users/my-followers {:auth auth :per-page 100}))
85

Any way you skin it, I’m better looking than Alan. But who is the better person? Who is the most… outgoing? Let’s find out!

1
2
user> (count (users/following "amalloy" {:per-page 100}))
9

9… What about me?

1
2
user> (count (users/following "Raynes" {:per-page 100}))
36

This just isn’t looking good for ol’ Alan. That’s enough of that, before I hurt his feelings.

This isn’t all you can do with the user API. Check out the docs if you want to see the rest.

Repos

So far, we’ve found out that I am better looking than Alan, more popular, and that I am a better person. But that isn’t all that matters! Who is the most hardcore coder? Tentacles tentacles on the octocat, who of us two does not code trash?

Our first measure will be a repository count. If I have more repositories than he does, then obviously I love coding more than him. Github has a dedicated API call for getting the authenticated user’s repositories, but we don’t want to use that, since it would also list private repos. While I don’t actually have any of those, I don’t want to be accused of skewing these numbers. This is srs bsns! Nonetheless, tentacles has a function for that called repos, just in case you need it (for cheating).

1
2
3
4
user> (require '[tentacles.repos :as repos])
nil
user> (count (repos/user-repos "Raynes" {:per-page 100}))
58

Wow! I have 58 repositories! Let’s see how many of those are forks.

1
2
user> (count (filter :fork (repos/user-repos "Raynes" {:per-page 100})))
27

Wow! 27. I’m a forkaholic. Now for Alan.

1
2
user> (count (repos/user-repos "amalloy" {:per-page 100}))
56

Ooooooh, it’s close. It all comes down to the forks now.

1
2
user> (count (filter :fork (repos/user-repos "amalloy" {:per-page 100})))
38

HAH! Now, I’m not good at math, but I’m pretty sure that means I have more original repositories than he does. Cause that’s how I roll. Obviously, given these numbers, I love this craft waaaaaaay more than Alan does.

But who has the most popular code? I say we compare the number of watchers on our most popular projects.

1
2
user> (count (repos/watchers "4clojure" "4clojure" {:per-page 100}))
100

I highly doubt that that is an even 100. It probably just cut off at 100 because that’s our max. Let’s check the next page.

1
2
user> (count (repos/watchers "4clojure" "4clojure" {:per-page 100 :page 2}))
27

127 watchers! What about my biggest project?

1
2
user> (count (repos/watchers "flatland" "lazybot" {:per-page 100}))
53

Oh noes! Maybe that isn’t my biggest one.

1
2
user> (count (repos/watchers "Raynes" "tryclojure" {:per-page 100}))
57

._. I concede. He wins this one. Alan obviously has the most popular projects. You can’t win ‘em all.

Just for fun, let’s look at language stats:

1
2
3
4
5
6
user> (pp/pprint (repos/languages "Raynes" "tryclojure"))
{:Clojure 7419, :JavaScript 4471}
nil
user> (pp/pprint (repos/languages "4clojure" "4clojure"))
{:Shell 527, :Clojure 159307, :JavaScript 106110}
nil

We’ve both employed some tricks to make it so Github doesn’t think our projects are Javascript projects. I don’t store my JS dependencies in the repo and Alan puts them in a directory that Github doesn’t care about. We’re both clever, in any case.

This doesn’t even touch what the repo API is capable of. With Github’s v3 API, even download uploads are supported! Check out the full API in the marginalia docs

Issues

I wonder who has the worst code? I bet that if we check the number of issues on our top projects, we’ll be able to find this out.

1
2
user> (count (issues/issues "Raynes" "tryclojure" {:per-page 100}))
0

Bang! No open issues. ‘Cause that’s how I roll. Let’s check the closed ones as well.

1
2
user> (count (issues/issues "Raynes" "tryclojure" {:per-page 100 :state "closed"}))
20

So a total of 20 issues. What about 4Clojure?

1
2
user> (count (issues/issues "4clojure" "4clojure" {:per-page 100}))
29

Ahahaha! They’ve got more issues open than I have open and closed combined.

1
2
user> (count (issues/issues "4clojure" "4clojure" {:per-page 100 :state "closed"}))
100

Doesn’t even fit on one page!

1
2
user> (count (issues/issues "4clojure" "4clojure" {:per-page 100 :state "closed" :page 2}))
59

159 closed issues! Wow! That must be some terrible code. I feel sad for the little fellow.

As with the rest of our examples, this is only the tip of the iceberg. Check out the Marginalia docs for more.

Gists

Finally. One final competition. Gists. The way I see it, if I have more gists than Alan does, then I’m… uh… I’m just a damned better person. I don’t need a reason.

1
2
3
4
5
6
user> (require '[tentacles.gists :as gists])
nil
user> (count (gists/user-gists "amalloy" {:per-page 100}))
100
user> (count (gists/user-gists "amalloy" {:per-page 100 :page 2}))
60

160 gists. Not bad. I bet I can do better.

1
2
3
4
5
6
7
8
9
10
user> (count (gists/user-gists "Raynes" {:per-page 100}))
100
user> (count (gists/user-gists "Raynes" {:per-page 100 :page 2}))
100
user> (count (gists/user-gists "Raynes" {:per-page 100 :page 3}))
100
user> (count (gists/user-gists "Raynes" {:per-page 100 :page 4}))
100
user> (count (gists/user-gists "Raynes" {:per-page 100 :page 5}))
57

457 public gists! PUBLIC ONES! I am obviously, for reasons I am not certain of, the better person.

The Gist API is extensive and complete. It even includes a way to create gists now! Check out the rest in the Marginalia docs.

Conclusion

I’m better than Alan.

Real Conclusion

The Github API is awesome. Clojure is an awesome language for working with APIs. Working with APIs interactively is fun. Tentacles is fun. I like Tentacles. Tentacles is cool.

Thus concludes our demonstration. This post only just touches the capabilities of the Github v3 API. Tentacles supports all of it. Check out the Marginalia docs and the Github API docs for more awesome.

Finally, these numbers/stats are obviously meaningless, so don’t look into them too much. It’s all in good fun.

The Clojure Community and Me

| Comments

Origins

When I was around 13 years old, I played a game called Diablo II. You’ve probably heard of it or played it. It was a fun little RPG that had a huge community of hackers surrounding it. I would often visit the blizzhacker’s IRC channel and chat with the community of programmers, or just listen in awe as they talked about amazing things that made no sense to me and left me baffled at how anyone could understand it. One person in particular was a Haskell programmer. He was a very smart fellow that I looked up to and whose opinion I valued. Some of these people were C#, C, and even D programmers. This was my first introduction to programming.

I decided that this was something I was interested in and would like to do, so I spent the next couple of months beating my head against Python, C#, Boo, and a number of other languages that I probably played with and simply don’t remember. Nothing really made much sense during that time. Python was the closest I got to things clicking. I had a lot of time to do these things because I’ve always been home-schooled.

I always say that Haskell was my first language. That is not entirely true. I played with many languages in the beginning. Haskell was, however, my first real introduction to programming. It was the first language that made sense. It was through Haskell that I was able to make sense of programming as a whole, including Object Oriented programming.

A lot of people wonder if learning Haskell, a purely functional language, as a first language would make OOP languages be as difficult to learn and understand as functional languages are to OOP developers. My answer, given my experiences, is no. Learning a functional language first gave me the programming foundations that I needed to understand OOP and how it compared to other paradigms. Basically, Haskell told me "Hey, this is programming. This is what it means and this is what you do." and then Object Orientation was just another layer on top of that. Another way of doing things. Programming is simple, but OOP clouds that and makes it look unnecessarily complex. If I had to teach someone to program, I think I’d start with a functional language given my experiences.

Enter Clojure

So what comes after Haskell? After I had used Haskell for a couple of months and had got a few projects under my belt, it was time for a new step. I felt that my next logical step was a Lisp. Clojure was new and getting a lot of attention. It was very practical, had an amazing set of minds behind it, and a very welcoming tight-knit community.

I didn’t do a whole lot with Clojure at first. I spent a lot of time just learning the language and not actually doing anything. My first serious Clojure project was lazybot (originally known as sexpbot), an extensible IRC bot. It was a great project that I still use and actively maintain.

Originally, lazybot was a Pircbot. While Pircbot is an excellent Java library and is easy enough to use from Clojure, I really wanted to have a Clojure IRC library to use for it. That was my next project, Irclj. Irclj is an asynchronous (a word that I didn’t understand at the time of writing it) IRC protocol library that I am currently in the process of rewriting. Nonetheless, it was my first introduction to lower-level network programming and the first time I’d ever done anything with any internet protocol. You can find lazybot in its current incarnation in the #clojure IRC channel where he provides services such as Clojure and Haskell code evaluation.

That project was my gateway into the world of serious programming. I spent a lot of the next year working on lazybot and writing plugins for it. I had some other projects here and there, but lazybot was the one that mattered the most to me.

Things People Enjoy

If I’m known for anything at this point, then I’m known for Try Clojure. It is a website that, like TryRuby, is designed to introduce people to the Clojure language very quickly by providing an interactive tutorial and an in-browser REPL that evaluates code on the server side. This was accomplished originally using Heinz N. Gies’s clj-sandbox Clojure sandboxing library and eventually one that my best friend Alan Malloy and I wrote later, called Clojail.

How To Get Famous

Clojure Conj 2010 brought a lot of firsts for me. It was my first trip outside of the state of Alabama where I was born, raised, and still live; my first time flying in an airplane; my first conference; and the first time that I felt that I was a real member of a community. It was, in general, a huge leap in my life. The last two years have seen me grow the courage to consider myself a ‘real’ programmer, and begin programming professionally.

But it wasn’t really just the conference that did these things for me. It was the months leading up to the conference.

I wasn’t going. I was 16 and I didn’t have a job. My family is not particularly poor, but with the bulk of our income coming from disability checks, conferences were just not really something that could ever possibly happen. But I was okay. I mean, I was sad that I’d miss such a huge event, but I never expected to be able to go in the first place so the realization that it wasn’t happening was easy to take.

I’m not sure exactly how it happened, but I think somebody in the #clojure IRC channel asked me if I was going to the conference. Either that or I mentioned it for some reason. Chas Emerick happened to be watching. He immediately messaged me privately and asked me why I wasn’t going to be able to make it. I told him that I simply did not have the funds to travel to North Carolina, pay for lodging, and register at the conference. Furthermore, it wouldn’t be just me – my mother would need to travel with me (for obvious reasons). He said, in so many words, "well, let’s see what we can do".

Not much time passed before Chas told me Relevance had happily agreed to cover my stay at the hotel and waive the conference registration fee. I was floored. Chas decided that the best way to get the rest of the funds for air travel and miscellaneous travel expenses would be to hold a fund-raiser. He wrote a blog post, set the goal for $1000, and threw up a paypal donate button. And so it began.

Oh how the twitterverse rooted for Anthony Grimes on that day. Hacker News, Reddit, IRC. Even people outside of the Clojure community itself were donating for my cause. A whopping 72 minutes later, our goal had been reached (and slightly exceeded). 72 minutes is what it took for the Clojure community and others to raise $1000 for a 16 year old kid to be able to attend his first conference. Chas bought my mother and I our plane tickets and I was on my way.

This would spark what is now becoming a tradition. For this last conference, Chas Emerick once again took it upon himself to help somebody get to the conference. Ambrose Bonnaire-Sergeant had to travel much farther than me and thus his expenses were much greater. The Clojure community once again rose to the task and met the goal.

Clojure Conj 2010

Oh wow. What a whirlwind. I honestly only remember the very best parts of the whole trip. It’s all just a big bright and colorful blur.

I arrived at the hotel and walked into the lobby. How appropriate was it that the first person I met and talked to was Chas Emerick, sitting right there in the lobby with his laptop as if he were waiting on me. I resisted the urge to hug and kiss him and instead opted to shake his hand.

When I checked in to get my room key, the woman at the counter said, and I quote, "It’s about time! Everybody has been asking if you had arrived.". That certainly blew my mind.

The next two people I met, also appropriately, were Lance Bradley and Justin Balthrop, two of my very best friends and people who would eventually be my co-workers. I didn’t even get to sit down once I got to the room, they already had me walking with them to a restaurant. We had fun that night.

The next day was even crazier than the last. Everyone who saw me wanted to shake my hand and talk to me. People would ask me about my experiences and praise me for my projects. I felt so much like a celebrity. Even Rich Hickey himself would speak to me and shake my hand later on.

The conference was wonderful. The talks were great, but the social aspect of it is what truly made it the most important experience of my life. Meeting everybody for the first time. The energy that emanated from everyone pulsed so hard that it could almost make your teeth rattle.

2011

The next year was a blast for me. A few months after the conference, I was hired as an intern at Geni, working remotely under Justin Balthrop and Lance Bradley, two close friends, on the site’s backend with Clojure. With Clojure! My first job is developing Clojure! Winning! I quickly learned that making money is wonderful and that Macbook Pros are the best things since sliced bread.

At about the same time I got my job, I also landed a book deal with No Starch Press. I’m currently writing a book called Meet Clojure for them.

Clojure Conj 2011

The moment Clojure Conj 2011 was announced, I was plotting my way there. Clojure conferences are wildly addictive. Worse than heroin. But hey, I was making some money now. But hey, this conference is going to cost even more than the last. But hey, maybe Geni will pay for some of it? But hey, I’m 17, so liability is a big complicated legal bitch. Mostly, I knew I would get there some how, but I hadn’t quite worked out exactly how. If I had to, I would just save my paychecks for a month or so and not spend very much at all. This would have worked out, since I still live at home and have the privilege of being fed by a lovely woman with excellent shopping and frying pan foo. But hey, it didn’t have to work out.

Speaking

I vowed that I would not submit a talk for Clojure Conj 2011. I was utterly certain that I would not be able to perform a 40 minute long presentation in front of the entire Clojure community and be able to keep them interested while doing it.

But damn them all to hell, Justin, Lance, and Alan decided that they would submit talks. Every single Clojure person at Geni was submitting a talk except for me. I conceded, assuming that there would be no earthly chance of my talk getting chosen, and submitted a talk about JVM sandboxing and Clojail.

So, my talk got accepted. As soon as I cleaned out my undergarments and finished receiving congratulations from my friends, I went and cleaned them out once more. This was great though. It meant that Relevance would pay for my room (which also meant my mother’s room), waive the conference registration fee, and even give me a travel stipend (once I arrived) that would cover my own plane ticket. That dropped the total costs of the conference (disregarding miscellaneous expenses) to around $250. Winning!

Actually Doing It

But shit, now I have to compose and perform a talk. For 40 minutes. In front of Rich Hickey and everyone else that I am intimidated by and who is exceedingly smarter than I am.

So, I did what any person this terrified would do. I forgot it happened and waited until about two months before the conference before I even thought about writing the talk. I ended up doing the majority of it over about two weeks because Justin had given me the ultimatum that I would either practice it live with my co-workers over Skype or not get paid. ;)

It went surprisingly well over Skype. They gave me insanely awesome feedback and a lot of encouragement. The Clojail talk was the product of not only my blood sweat and tears, but those guys as well. That they convinced and (half-serious) forced me to practice the talk was the best thing that could happen to me. It showed me how nervous I would be at the Conj and taught me how to control it.

The Conference

I was once again greeted with a healthy round of handshakes after my arrival at the venue. Early registration was great. I met Carin Meier, a person whom I had worked with on 4Clojure. A handshake would not do for her, no, she wanted a hug. That was when I really felt that things would be okay and that, regardless of what happened with my talk, everything would work out in the end.

And it did. After meeting my best friend in person for the first time, Alan Malloy; after Carin Meier’s big ol’ bear hug; after letting the atmosphere of Clojure Conj 2011 and the Clojure community once again sink in and take hold of me, I felt so good that I didn’t bother practicing my talk again before I performed it. I was okay.

My talk went great. It was well received and people praised me for it for the remainder of the conference. Either immediately after or during my talk, Rich Hickey tweeted (a rare occurrence) the following: "@IORayne is awesome, killer job on library and talk! #clojure_conj". And if that wasn’t enough to make me piss myself in glee, he approached me right after my talk, shook my hand, and said the equivalent in person. This man, the public speaker of the decade, praised me on my speaking abilities. Holy. Shit.

After that, I did a brief interview with Chas for his podcast Mostly Lazy, and a slightly longer interview with Runtime Expectations of Codebass radio. Both should be made public soon.

Oh man, Clojure Conj 2011. I’ve never attended a non-Clojure Conj conference before, but surely this is as good as it gets, right? I can not think of a single thing that I did not like about the whole experience. Relevance knows how to put on a conference.

Conclusion

I’m not really sure why I wrote this. I suppose I did it for two reasons:

  1. At least 10 thousand people asked me about my origins at the Conj. Wondering how I got into programming and such.
  2. I can not say enough good things about the Clojure community. Sometimes I just need to tell people about it, and I can’t think of a better way to do that than by pointing out that my entire life has been built around it.

So, that’s me. Where I came from, what I’ve done, and more importantly, what the Clojure community has done for me. I owe so much to all of you that I can’t really express my thanks in words. Instead, I hope that my contributions to the world will be enough. My motivation is to make you proud.

Future

It’s nice to have one of these.

I don’t really know what the future will hold. At the very least, more projects will always be forthcoming. I want to make nice things. Furthermore, I do currently have a job, albeit an internship (a paid one), with Geni. I’d like to work with them full time at some point after I turn 18 and graduate high school. This would obviously involve extended stays in California and most likely a move, even if not immediately. That’s all some pretty serious stuff that I nor my co-workers are taking lightly. They are very supportive of me to the point that they allow me to work remotely, even though I am the only one who does so on a regular basis. This means that they have to actively put effort forth to keep me in the loop about things, since I’m not there to hear their conversations. I’ve never once saw them complain about it.

So, I think my future is bright. I’m happy that I’m busy and I have a lot of great things ahead of me. I look forward to the future and whatever it may bring.

Thanks for reading.

-Anthony

P.S. Many thanks to Dominik Picheta and Ricky Elrod for reading this for me and making sure I’m not insane.

Moving Try Clojure to Heroku

| Comments

tl;dr: At first I was like "uhh…" but then I was like "AH!".

I started playing with Heroku a bit recently. I had heard all sorts of wonderful things about it and figured it was worth giving a go. I never expected to get anything done because I wasn’t willing to put a lot of effort into it, since I was planning on just playing around with things.

So, my plan was to see if I could get Try Clojure running on Heroku. I took a seat and began reading documentation. Well, if a two minute blog post is documentation. The funny thing is, it wasn’t until I actually decided to move it to Heroku permenantly that I actually had to read official Heroku documentation, and that was only to find out how to get my domain pointed at the Heroku instance and to find out more info about how much the site would be able to handle on the free plan.

It took me all of 10 minutes to get Try Clojure running on Heroku. The only reason it took that long was because I didn’t know that I had to start my server on a port that Heroku sets the environment variable PORT to. So, about 8 of those 10 minutes were me committing a fix for that. It was less a less than 5 line change.

I had to modify its project.clj file to add a :jvm-opts line to set the Java policy file for the application, but that was only because cake reads jvm options from .cake/config and Leiningen takes a key in project.clj for them. At this point in time, Heroku only supports Leiningen on the Clojure stack. I’ve been told that cake is not out of the question in the future. It doesn’t really matter because it was a good idea to add :jvm-opts to my project.clj so that I could maintain complete Leiningen compatibility in Try Clojure. I have absolutely nothing against Heroku for not supporting cake – it simply isn’t a big deal, since Leiningen and cake have mostly compatible project descriptions and Try Clojure’s project file is very simple.

Finally, I had to create a Procfile containing the following:

web: lein run

and this tells Heroku how to run my code.

After my code was set up, all I had to do was sudo gem install heroku and then heroku create --stack cedar and bang, my project was a Heroku project. To deploy, I simply ran git push heroku master, which pushed my code to the heroku remote that heroku set up when I ran the create task. The code was pushed, it ran my code with lein run, shot me a link to the app, and tada – Try Clojure runs on Heroku.

I was completely floored by how easy all of this was. And that’s how easy it always is. When I want to deploy, I just push my code to the heroku remote with git and Heroku handles the restarting and everything with absolutely no work on my part at all. This workflow won me over immediately.

So great, I have Try Clojure running on Heroku. Just an experiment and it worked really well. At this point, I had no intention of moving to Heroku permenantly. I didn’t know much about Heroku and how much the free account would give me.

I mentioned that it was running on Heroku on Twitter (and probably in the #clojure IRC channel as well, but I don’t quite remember). The next day, technomancy (Phil Hagelburg) asked me in the IRC channel if the main Try Clojure instance was running on Heroku, and I told him the equivalent of "Hell no, I don’t know anything about Heroku and I only have a free account. I don’t trust Heroku enough to move it over.". It struck me as odd when he replied with "Heh" followed by a cute joke, but it didn’t dawn on me why he did it.

The next day, I remembered that technomancy had just recently started working at Heroku himself! One of our very own popular Clojurians! I ended up talking with him (he kindly approached me, offering to help) later that day. I read a lot of documentation around the same time and asked him a few questions.

What confused me the most was the concept of a ‘dyno’. This is a process of any type running on Heroku. Processes for stuff like Mongrel or Resque and, of course, your app and its own processes. In my case, I have one web process, which is what I defined in my Procfile.

Heroku takes a time-based approach to its services and billing. The idea is that you pay for how many hours each dyno that you use has run in a given month, and every free account has 750 free dyno hours. If I only run one dyno all month, I don’t have to pay anything at all. And even if an app that I use was to get slashdotted or something similar that would generate massive amounts of traffic, all I’d have to do is run a command or two to scale things up. I could add a dyno or two and only run them for as long as the traffic was too hard for a single dyno to handle the traffic, then I could scale it back down and I’d hardly have to pay anything at all unless I used those dynos for quite a while. You only pay for what you use, and you aren’t obligated to use anything more than what you need/want!

This all made me feel much better about the whole thing. Try Clojure is a fairly simple site that doesn’t get tons of traffic, so I decided I’d go ahead and move the main instance to Heroku. I even bought a new domain, tryclj.com to celebrate the move.

Try Clojure is now running entirely on Heroku, and I’m really enjoying it. I haven’t had to scale things up at all at this point, even though it got pounded with traffic when Heroku tweeted about the move. I kept an eye on it during that time and it never even slowed down.

Really, what won me over is the workflow. It is soooo easy. I mean, deployments by pushing to a git remote? That’s just beautiful. I can make changes and deploy them faster than a Github employee! Finally, the fact that Phil was so eager to help me really says something about Heroku in my book. If they hire people like him, I bet the rest of their team is equally as lovely.

I look forward to a long and fruitful future with Heroku, and I thank them for their fantastic service and giving me a reason to not have to host and maintain that site on my own VPS.

Try Clojure’s source code is on Github. Check it out if you’re interested in seeing a simple website that runs on Clojure, the excellent Noir web framework, and Heroku.

Problems With Clojure + Homebrew?

| Comments

There is a fix-all solution to any problems you’re having with Clojure + Homebrew.

1
$ brew uninstall clojure
Followed by
1
$ brew install cake
Or
1
$ brew install leiningen

In all seriousness, if you’ve installed Clojure via any package manager and you’re having problems, that’s because it doesn’t make any sense whatsoever to install Clojure through a package manager. The JVM ecosystem just doesn’t work that way. Clojure is essentially a library – it’s stored in a jar.

Instead, you want to install a build tool. Cake or Leiningen are Clojure build tools. They are your ‘interface’ to Clojure. They handle all the project management, classpath management, REPL management, compilation, and everything else that you shouldn’t need to or try to do on your own.

Do not try to ‘install’ Clojure. Install a build tool instead. It’ll prevent 98% of all beginner issues related to classpaths and make it easier for people in the Clojure mailing list and IRC channel to help you with real problems. Furthermore, they make it really easy to manage everything from small scripts to large projects, and can even give you properly classpathed repls as easy as cake repl and lein repl.

Meet Clojure Update

| Comments

This just in: progress, son.

Today was a great day for this budding author. I finished my next chapter, chapter 7 (tentative), and sent it to my editor. I’m not having any trouble at all keeping up with my deadlines.

Even better is that, about 20 minutes ago, I decided who I wanted my technical reviewer to be: Chris Granger, an insanely smart fellow and active member of the Clojure community. He is very interested in doing it, but nothing is official yet (I swear to God, all happened 20 minutes ago). I’ll be sure to tweet about it when it is official.

LibreOffice is much easier to face when you don’t have to do shit with it other than actually write the book and send each chapter individually. Of course, I’d still rather write my book in a plain text format, but beggars can’t be choosers and it works.

I’ve mostly been renovating mostly-complete chapters so far before sending them in. The real test will be writing new chapters from scratch, something that I’m going to have to face soon. I’m pretty sure I’ll make it though. I’m highly motivated because I have a fantastic technical reviewer, more communication with my publisher, and amazing friends encouraging me to get this sucker done.

Everything I’ve said before about the book still applies. There will be a free copy released when the book is finished that I am hoping will become an important entry-point for new Clojurians. I hope to do something similar to Learn You A Haskell and have a pretty HTML version of the book.

In summary, 2 chapters have been submitted to my publisher for review. Still targeting every 3 weeks for new chapters. Technical reviewer acquired but not entirely official yet. Morale is high.

Stay tuned.

Meet Clojure Update

| Comments

I haven’t written a status update for Meet Clojure in quite a while, so here it is.

Keith, my editor, emailed me a few weeks ago wanting to work out a new schedule for the book. Several months had passed with little communication between us and I didn’t get very much work done on the book, so this was a welcome surprise. We worked out a schedule: first chapter in 2 weeks and then a new chapter every 3. I finished the first chapter nearly a week before my September 22nd deadline.

This is good news. Chapter 4 is done and is currently undergoing review. It is one of the largest and most important chapters of the book, so it’s actually a pretty large chunk of progress.

We are very excited to have a real solid schedule for the book and I am anxious to get more of the book finished. Schedules are fantastic motivation. That said, our new schedule will certainly not allow for a 2011 release. There is isn’t even speculation as to when it’ll all be ready to ship at this point, so I can’t really provide any information on that. The important thing is that I am actively working on this and that I have real deadlines that it would not be good for me to miss.

As far as my relationship with Libre/OpenOffice goes, it’s still a little strained. I’ve found that most of my hatred for it came while I was converting the existing book from my Pandoc markdown workflow to the No Starch OpenOffice workflow. It was extreme tedium and required a lot of things that OpenOffice isn’t designed for.

It is much, much easier to actually write new content with OpenOffice. No Starch’s template switches styles intuatively and when appropriate all by itself, so I rarely have to do a whole lot of mouse stuff. I do miss Emacs and markup, and I definitely wish OpenOffice didn’t suck at keybindings on OS X, but I’ll survive.

In summary: Work being done. Progress being made. Unicorns being milked for their magic.

Stay tuned.

Moved to Octopress

| Comments

I spontaneously decided today that, while sick, I would spend the day setting up Octopress and trying it out. I did. I liked. I replaced wordpress with it. Unfortunately, this comes with a few consequences.

  • I used exitwp to import my Wordpress posts into Octopress. While it did its job importing the posts, it managed to clobber paragraph breaks and all of my code along the way. I’m going to try to fix this as best I can in my most important posts, but I’m not going to do it for all of them.
  • All of the old links are broken. I never used readable links with Wordpress and Octopress (rightfully) uses them by default. Luckily, my blog isn’t very popular so the link breakage will be less significant. I do apologize to anyone linking to my blog though and hope that this doesn’t inconvenience them too much.
  • All of the comments are gone. Comments didn’t move with the Wordpress post, and since the links have changed and I’m using Disqus now, there isn’t a simple way to retrieve them.

I firmly believe that the benefits of switching to Octopress will outweigh the issues, even if the benefits only apply to me. I’m very excited to write my posts in Emacs and markdown and to be getting rid of a useless MySQL instance and several instances of php-cgi.

All Media Centers Suck

| Comments

Recently, I’ve had a little down time thanks to appendicitis and a good round of surgery, so I’ve been working on getting a media center set up on my laptop. Unfortunately, none of them do everything that I require. The big choices right now are XBMC, Plex, and Boxee. They’re all excellent in some areas and pathetic in others.

My Requirements

I’m pretty picky about what I need from a media center. My needs are not the same as everyone else. First of all, I have a poor internet connection. It’s fast enough to stream from Netflix, but it’s a verizon mifi card, and they don’t like it when you rape their bandwidth. Therefore, I have to keep my streaming to a minimum. Because of that, I have these things called DVDs. They’re these neat little discs that hold movies. I get them from Netflix and Redbox and I put them into my little disc drive and movies play on my screen. It works pretty well. I need for my media center to handle, at a minimum, Pandora radio, Netflix streaming, DVD playback, music playback, and the ability to control it all from my android phone with a wifi remote. Sounds easy, doesn’t it? Guess what. None of them do it.

Boxee

Boxee is great. It’s a little do-it-all media center that can run on your computer or a dedicated "Boxee Box" that you can buy. Ever since the Boxee box came out, development has been focused on it. Recently, everybody started whining so they promised to pick development back up and have a release out by… this fall. In any case, Boxee in its current incarnation is very nice. It can play Pandora better than Plex, and it can stream Netflix just fine. It can do a whole lot of other stuff as well. Unfortunately, the latest version for the mac, 0.9.23.15885, cannot play DRM’d DVDS. They’ve disabled DVD support and an issue in their issue tracking about it was closed as ‘won’t fix’ with no explanation. Goodbye Boxee. I hope that, in that next release, it’ll be enabled. If the DVD support worked, Boxee would be absolutely perfect.

XBMC

XBMC is the biggest one of them all. It’s the media center that the other media centers we’re talking about were based on. It’s a fantastic media center within itself. However, it doesn’t even come close to doing what I need. Out of all the things I require, the only thing it does is handle DVD playback and music playback. They haven’t even taken a shot at adding Netflix and such. No clue why, seeing as how the media centers like Boxee and Plex that are based on it do implement them. There are third party add-ons for Netflix and Pandora though. Haven’t tried the Pandora add-on, but the Netflix plugin, XBMC flicks, at this point in time, doesn’t work. It hasn’t worked for the better part of this year. Whether or not it’ll actually be fixed is up in the air. XBMC isn’t really much of an option for me.

Plex

Plex is awesome. It is like Boxee in that it gets all of the streaming and local media stuff right. Its Pandora support is a little wonky but appears to work. The Netflix support is perfectly fine. The problem is that it doesn’t support DVD playback in a meaningful way. It has *some* support for it. You can turn it on and hit ‘dvd’ in the menu. It goes straight to the DVD menu. I couldn’t find any settings for anything, and turning on subtitles is tedious and unintuitive. You can’t even eject the disc when you’re done. Plex is great, but the DVD support is basically worthless. The biggest thing that irks me is how little the developers seem to care about DVD support. I’m beginning to wonder if I’m the only person who sees the importance of it. For the past 2 years or so, they’ve been saying things like "It’s on our radar." and "We need to improve that." but haven’t done anything. Maybe in the next 10 years or so when DVDs are obsolete they’ll finish up the DVD support. ;) Now, there is a workaround. You can set up applications to launch from within Plex. For example, you can make the mac’s default DVD player launch, and when it’s closed, Plex will reopen. Nice! The problem is that, while I *can* control Plex using the Plex remote from my Android phone, I cannot control DVD player. Alas, the dream is dead. Until Plex has decent DVD playback, I’m out of options. I’m extremely disappointed with my findings. At this point in time, all media centers suck (in certain ways).

Updates: July 19, 2011

Eventually I decided on Plex. I ripped my entire DVD collection so the poor DVD support is less of an issue for me now. Furthermore, the Pandora plugin crappiness is not their fault. It turns out, Pandora is run by assholes who favor Boxee. I still think Boxee is nice. Plex is nicer. The media server and manager is fantastic and I can think of tons of uses for it in the future. Boxee plans to release a new version this fall (after the majority of their userbase had given up on them, assuming they had abandoned the downloadable version for the Boxee Box version), so it remains to be seen if it can win my heart. I doubt it. All it has that Plex doesn’t have that I want is a decent Pandora app, and it isn’t even Plex’s fault that it doesn’t have a good one. Boxee could be the best all around if it just had a few more developers to spare towards the downloadable version. But, it’s forgivable. They aren’t a huge company and they have to prioritize. I just wish the Boxee Box wasn’t the priority. They had a dream and they’re living that dream. Good for them!