Hands-on with Clojure day 2

:: Clojure, Hacker School

As with yesterday’s post, important disclaimers:

  • I’ve used Racket heavily but not Clojure.

  • Opinions expressed herein are not those of my employer, were I to have one.

  • If indignation lasts more than four hours, please seek medical attention.

Day 2 with Clojure was much more fun! I didn’t hit speed bumps with tooling and workflow, so frequently. I was able to focus mostly on the code itself, which was wonderful.

For a slightly more realistic task, I decided to make a really simple function that, given a URL, would make a GET request and return the value of the Server response header (if any), and a list of URLs found on the page that are for other servers. The idea being, you could crawl from some starting point and accumulate some data about web server technology.

Hands-on with Clojure

:: Clojure, Hacker School

Until now, Clojure has been an “armchair” language for me. I’ve read a lot about it, and I’ve read a fair amount of code written in it. But aside from typing a few things into an online REPL like Try Clojure, I’ve not really used it hands-on.

A couple days ago I started my 12-week batch at Hacker School. First on my list is to get some real experience with Clojure.

And I’m going to blog about the experience.

Written in Racket

:: Racket

This is an overview of things I’ve created using Racket. Two motivations for writing this now:

  1. Over the last week I was at three conferences (whew!) where, when meeting or catching up with someone, I had to explain what I’ve been doing. I mentioned my current projects or projects I guessed they’d relate to. But that’s not necessarily representative of all that I’ve been able to do with Racket. I wish I’d been able to give a better overview. I have quite a few repos on GitHub, but that’s just a big list with no structure.

  2. In about a week I start my batch at Hacker School. I’ll likely spend less time with Racket, because the whole point is to learn new things. Now is a good time to take inventory. And I’ll be better prepared to talk about Racket there.

As a result, here’s an inventory, grouped into categories.

Destructuring lists with match

:: Racket

Let’s say you need to destructure a list with match, using a pattern that specifies a “rest” or “more” element. Be careful. You probably want to use list* not list.

Does your Racket project need a makefile?

:: Racket, racket-cookbook

NOTE: See my newer post.

Most of my Racket projects don’t use a makefile. Why would they? raco make or raco setup suffices.

But a makefile can consistently define some common project tasks. And it can really help when you want to generate HTML documentation from Scribble sources, and publish it to GitHub Pages using the automagical gh-pages branch.1

__FILE__ and __LINE__ in Racket

:: Racket, racket-cookbook

Many languages have a variable (or preprocessor macro) called __FILE__ or __file__ whose value is the pathname of the current source file. Likewise __LINE__ for the the source line number.

You probably need this less in Racket than you imagine. For example:

  • We wouldn’t test that __FILE__ ends in main.rkt; instead we’d use a main submodule (module+ main <your code here>).

  • To get a data file foo.dat located in the same directory as a source file we’d use (define-runtime-path foo.dat "foo.dat"). If we’re a package or executable this works regardless of where our files happen to get installed.

But if you really did need a __FILE__ in Racket, how would you do it?

Racket cookbook

:: Racket, racket-cookbook

Two parallel thoughts:

  1. I haven’t blogged in awhile. I’ve been heads-down on a few projects. Plus I haven’t had ideas I feel are “big” or unique enough to merit a post.

  2. It’s occurred to me that a “Racket Cookbook” might be a useful resource. Because examples. Because real-life, practical examples.1

Although I haven’t created a cookbook, my working assumption is that it would be better to write one recipe at a time. As they arise. As I think, “Ah right, this wasn’t obvious to me when I was learning Racket.”

So I plan to experiment with releasing the things one at a time, as short blog posts. Thereby terminating two avian organisms with one geologic projectile.

Not sure if I’ll keep it up. Definitely not sure if I’ll ever collect and polish them into a “book” of some form. They might only ever live as a racket-cookbook tag on this blog.

  1. Admittedly I rarely recall using any “cookbook” resource to find the answer to a problem I have. Taken literally, programming cookbooks are largely a failure, for me. On the other hand, flipping through one can give the “flavor” of a language. And as I’ve written, one valid learning strategy is to absorb things shallowly — you may not know the answer, but you know roughly where to find the answer. It rings a bell. Probably cookbooks fit that model — filling your head with, um, bells. 

Using syntax/loc and unit test macros

:: Racket, racket-cookbook, macros

In my previous post, I wrote about a nuance with syntax/loc, using the example of a macro that both defines and provides a function. But why don’t I back up, and look at a simpler example of why you’d want to use syntax/loc. The example is a simple macro you might often find yourself wanting, to reduce the tedium of writing unit test cases.

Using syntax/loc

:: Racket, macros

There’s a nuance to syntax/loc. The documentation says, emphasis mine:

Like syntax, except that the immediate resulting syntax object takes its source-location information from the result of stx-expr (which must produce a syntax object), unless the template is just a pattern variable, or both the source and position of stx-expr are #f.

What does “immediate” mean here?