In case you’re interested in programming languages and you’re working from Peter Sestoft’s book Programming Language Concepts, I’ve just posted some supplementary materials to my ITU page. It consists of a tutorial for converting from regular expressions to discrete finite automata via NFAs and a tutorial on constructing typing derivations in the particular miniature ML-like language used in the book.
You can find them on my tutorials page.
I recently needed to use Scalacheck with a milestone release of the compiler, and it took me a little while to wrap my head around the infrastructure. To preserve the steps for prosperity, I’m documenting them here, as I couldn’t find it described anywhere.
The first step is to understand the relationship between the various parts:
- SBT is responsible for compiling your project, running tests, and generally performing the same role as make or ant. It also uses Ivy for retrieving library dependencies.
- Apache Ivy provides an infrastructure for dependency management. Libraries exist in repositories, similar to Debian package repositories, and they are available in multiple versions.
When you add library dependencies in your project’s SBT configuration, it will find the code by first looking in your local Ivy repository, then in any remote repositories that are configured. In other words, even if you don’t have access to the remote repositories, you can still put libraries in your local repository to be found by SBT.
Libraries such as Scalacheck that are intended to be used with multiple versions of Scala will typically use the
crossScalaVersions setting to build against multiple compiler versions. The workflow to get a library working is, then:
- Get ahold of the source code to the library
- In build.sbt, find the
crossScalaVersionssetting. Add the desired version of Scala.
- Run sbt. At the command line, type
+ test. This will compile the project for each configured version of Scala and run the tests.
- Assuming the project passes, run
+ publish-localto push the compiled version
Now, the library will be available in your other projects.
If you try to use Ensime with newer versions of SBT, you’ll find that SBT grows to fill available memory and then crashes. This is because the latest released version of Ensime assumes the project format of an old version of SBT. To fix this, just add the following to your .emacs after you require Ensime:
"Does a build.sbt or a project/build.properties exists in the given path."
(or (file-exists-p (concat path "/build.sbt"))
(file-exists-p (concat path "/project/build.properties"))))
The problem occurs because Ensime looks for your project directory by recursively going to parent directories until it sees something that looks like an SBT project. Eventually, it ends up in root, and SBT crashes while trying to recursively enumerate all the files in the current directory. Redefining this function to also look for newer project formats fixes the issue.
I typically manage my references with CiteULike. My typical workflow is to add the articles that I’m interested in, and then while writing, keep a complete copy of the exported BibTeX next to the LaTeX files. This gets tedious to maintain by hand, so I wrote this little chunk of elisp to download the file and name it the way I do.
To use, simply place it in a file called “citeulike.el” on your load-path and add “(require ‘citeulike)” to your .emacs. Make sure to look at the customization options. Then, run “M-x citeulike-download-bibtex” in your LaTeX buffer.
;;; Copyright (C) 2011 David Christiansen
;;; Author: David Christiansen <david @davidchristiansen.dk>
;; This program is free software: you can redistribute it and/or
;; modify it under the terms of the GNU General Public License as
;; published by the Free Software Foundation; either version 3 of the
;; License, or (at your option) any later version.
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
;; General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING. If not, write to the
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
;; To make downloading an updated copy of references from CiteULike easier.
(defgroup citeulike nil
"Options for CiteULike support"
(defcustom citeulike-username ""
"CiteULike username, used for downloading BibTeX exports."
(defcustom citeulike-export-username-prefix nil
"Whether to add a username prefix to keys"
:type '(choice (const :tag "Yes" t)
(const :tag "No" nil))
(defcustom citeulike-export-key-type 0
"What kind of keys to put in the exported BibTeX"
:type '(choice (const :tag "Prefer personal key; otherwise use numeric key" 0)
(const :tag "Prefer personal key; otherwise use AuthorYearTitle key" 4)
(const :tag "Prefer numeric keys" 1)
(const :tag "Only export articles with a personal key" 2)
(const :tag "Export both keys" 3))
(defcustom citeulike-export-include-amazon-link nil
"Include Amazon links for books in exported BibTeX"
:type '(choice (const :tag "Yes" t)
(const :tag "No" nil))
(defcustom citeulike-export-clean-urls t
"Escape URLs for BibTeX?"
:type '(choice (const :tag "Escaped URLs" t)
(const :tag "Don't escape URLs" nil))
(defcustom citeulike-export-smart-wrap 0
"Work around BibTeX capitalization"
:type '(choice (const :tag "Don't wrap" 0)
(const :tag "Smart wrap whole field" 1)
(const :tag "Smart wrap individual words" 2))
(defun citeulike-export-url ()
"do_username_prefix=" (if citeulike-export-username-prefix "1" "0") "&"
"key_type=" (number-to-string citeulike-export-key-type) "&"
"incl_amazon=" (if citeulike-export-include-amazon-link "1" "0") "&"
"clean-urls=" (if citeulike-export-clean-urls "1" "0") "&"
"smart_wrap=" (number-to-string citeulike-export-smart-wrap)))
(defun citeulike-download-bibtex ()
(let* ((extension (file-name-extension buffer-file-name))
(rest (file-name-sans-extension buffer-file-name))
(target (if (equal extension "tex")
(concat rest ".bib")
(read-file-name "Filename to save: "))))
(if (or (equal citeulike-username "") (not (stringp citeulike-username)))
(error "No valid CiteULike username is configured")
(let* ((command (concat "wget \"" (citeulike-export-url) "\""
" -O " target))
(final-command (read-string "Command: " command)))
My primary editor for use with F# is Emacs. One feature that I missed in F# mode was the ability to load the file corresponding to the current buffer. Here’s some elisp to do it. Put this in your .emacs file, and then when you are editing an F# module you can load it at the toplevel by pressing C-c C-f.
"Load the filename corresponding to the present buffer in F# with #load"
(let* ((name buffer-file-name)
(command (concat "#load \"" name "\"")))
(when (y-or-n-p (concat "Do you want to save \"" name "\" before loading it? "))
(save-excursion (fsharp-simple-send inferior-fsharp-buffer-name command))))
(define-key fsharp-mode-map "\C-c\C-f" 'fsharp-load-buffer-file)))
Well, it’s just about time we get another beer post in here.
My girlfriend’s sister’s family has a hop plant in their back yard (Brewer’s Gold). Last year, which was its first year, it yielded about 20 grams of dried cones. This year, it looks as though it will be a bit more. Hops are such an amazing plant – everything in this picture is from just one plant!
I don’t know exactly how much their will be when it’s done drying, but the plant definitely outdid itself from last year. I look forward to getting some good beer out of this!
I regeringen og Dansk Folkepartis nye udlændingeaftale er der kommet
et pointsystem, hvor udlændinge, som ønsker en tidsubegrænset
opholdstilladelse, skal opnå 100 point ved at demonstrere deres
integration i det danske samfund på forskellige måder. Før i tiden
behøvede man at opholde sig i Danmark i 7 år, eller 5 år hvis man
havde fuldtidsjob, og bestå nogle prøver. Nu kan man få
tidsubegrænset opholdstilladelse allerede efter 4 år.
Umiddelbart lyder forslaget meget godt – indvandrere er belønnet for
at integrere sig, og der er mulighed for hurtigere at blive
selvstændig. Desværre viser en nærlæsning af aftalen, at regeringen
og Dansk Folkeparti stadig lider af akut betontænkning i forhold til
indvandring og integration.
Den største grund til at bruge point er, at man vil kunne være
fleksibel og tage højde for forskellige menneskers livssituationer.
Hvis man er i stand til at integrere sig hurtigt på nogle måder og
ikke på andre, så behøver man ikke blive hængt op på én ting, som man
ikke kan. Desværre er pointsystemet i den nye aftale skruet sådan
sammen, at det har karakter af den gamle ufleksible tænkning.
70 ud af de 100 nødvendige point kommer nemlig i én samlet pakke.
Uden disse 70 point, er der ikke mulighed for at nå 100. Denne pakke
er ret omfattende. Bl.a. skal man bestå en danskprøve og en skriftlig
prøve om dansk historie og samfund. Desuden skal man skal have haft
fuldtidsarbejde i 3½ ud af de seneste 4 år og fortsat have
fuldtidsarbejde på ansøgningstidspunktet. De resterende 30 point
kommer i blokke på 15 point, og inkluderer fine ting som frivilligt
arbejde for almennyttige foreninger og højere sprogprøver.
Reelt er der tale om et system, hvor man er stillet en lang række
ufravigelige krav plus en liste over fire krav, hvorfra man skal vælge
to. Her er der ikke nytænkning – det er blot en gammel vare i ny
In my last post, I described my first-ever experience with homebrewing. Adam and I were excited and hooked, and even before DC Birthday Beer was done fermenting, we brewed our second batch. Our goal was to make something as far as possible from an English pale ale, while staying within the bounds of the equipment and space that we have in my kitchen. That meant a few things:
- No lagering, as there’s no way I can fit an extra fridge in my apartment
- Extract only, because we didn’t have a lauter tun (and we were intimidated by all-grain brewing)
We were initially interested in creating an oatmeal stout, but we did some research and found out that at least a partial mash is necessary to make use of the oats. We decided to brew a very dark brown ale instead, using more American flavors.
The recipe is not based off of any particular recipe. We just browsed around various homebrew sites and read various recipes for strong brown ales. After doing this, we looked through Maltbazarens site until we found ingredients that we thought would work. Our initial desire to brew a stout was reflected in our choice of extra-dark malt extract in addition to more ordinary lighter malts. Our desire for a more American flavor can be seen in our choice of Amarillo hops for flavoring and a California ale yeast strain (which we also selected in order to be able to make a somewhat stronger beer).
For this beer, we used 1 kg extra dark dry malt extract and 3 kg amber liquid malt extract. Our bittering hops consisted of 19g Northern Brewer at 10.53% AA boiled for an hour, and we used 14 g Amarillo hops (9.5% AA) boiled for 10 minutes for flavoring. The original gravity was 1.056, and our initial calculations predicted 1.015 final gravity with 6.5% alcohol by volume. At the start of fermentation, we had 19 liters. We pitched White Labs California Ale yeast (WLP001).
This beer took a few days longer to ferment than our first beer, which I suppose may have been due to the higher concentration of sugars in the wort. It could have also been due to different temperatures in our kitchen, which I unfortunately don’t have a cost- and space-effective way to control.
Our second bottling day went much more smoothly than our first, primarily thanks to a new and better bottle brush. The new brush has a head with a number of steel bristles that can be drawn up into a narrow sheath that is small enough to fit in the neck of the bottle. Once it is inserted, the brush can be pushed out of the sleeve and into the bottle, which causes it to spin. This new brush knocked a great deal of time, effort and frustration off of the bottle-washing process.
We used 144g organic unrefined cane sugar dissolved and boiled in 5 dl water for priming the bottles. The final gravity was 1.014, which means that our initial calculations were almost right on target.
Some Like it Brown took much longer than DC Birthday Beer to carbonate. Two weeks after bottling, it had only the slightest hint of fizz and absolutely no head. We were afraid that we had somehow killed our yeast, and that the beer wouldn’t carbonate. It tasted nice, but flat beer isn’t exactly my favorite.
Luckily, with time, the beer developed bubbles. The flavor ended up being very nice, with nice but not overpowering malty sweetness and a slight almost burnt edge from the extra-dark malt. The combination tasted almost a bit like raw licorice root. There was a noticable hop flavor, with some subdued citrus notes in the background that nicely complemented the extra dark malt. The color of the beer was very dark, nearly black, which was a bit of a surprise. It actually looks completely black unless it is held up to the light, where a rich reddish brown color reveals itself. We had actually been expecting a slightly lighter shade of brown, but this is nice too. All in all, I think it’s a pretty fine beer, especially for our second try, and I look forward to tasting how the flavor develops.
Together with my friend Adam, I’ve recently started brewing beer at home. We’ve made two beers so far, a pale ale and a dark brown ale.
I’ve been interested in homebrewing for some years now, but I haven’t been in a good place where I could do it. Either I had no money for equipment or the place I lived was unsuited to having a fermenter sitting around. Finally, however, I have an apartment of my own with a spare corner in the kitchen and a girlfriend who will tolerate a bucket full of strange microorganisms bubbling away.
Our first beer (called “DC Birthday Beer” because the basic brewing equipment was a birthday present to me from aforementioned tolerant girlfriend and her mother) ended up being very bitter, without the large amount of hop aromas that I’d been expecting. It was light-bodied with light amber color.
Our recipe was based off of John Palmer’s “Cincinnati Pale Ale” in his book How to Brew, but I made a mistake buying malt. We ended up having to mess around with the recipe quite a bit, scaling it down from 19 to 16 liters. We also changed the mix of hops to attempt a more English than American flavor.
We started by boiling 6.5 liters of water, after which we added 1.5 kg light malt extract syrup and 0.5 kg medium dry malt extract. After this was returned to the boil, we added 16g Northern Brewer pellet hops (10.53% alpha acids) and boiled for 50 minutes. After this, we added 24g East Kent Goldings hops (6.8% AA) and boiled for 10 more minutes. We then cooled the wort and added to colder water in the fermenter giving a total of 16 liters. Finally, we pitched White Labs English Ale yeast (WLP002) and put the lid and airlock on the fermenter.
When measuring the temperature of the wort immediately priort to pitching the yeast, I managed to drop the thermometer into the fermenter. What followed was about 10 minutes of fishing around for it with a soup ladle and barbecue tongs, trying hard not to breath to much into the wort or touch it with our fingers in order to avoid contamination. We were actually quite concerned, but it seems to have turned out fine anyway. The initial gravity of the wort was 1.044.
All in all, we were both surprised by how quick and easy brew day was. We had expected a long, grueling process, but with the exception of the dropped thermometer, it was easier than making a big pot of soup. It was really fun watching the airlock begin to bubble – it’s a similar feeling to the one I get from my sourdough, but even more dramatic!
A couple of weeks later, when the airlock stopped bubbling, it was time to bottle the beer. We had saved up a number of bottles from parties and such, and we quickly learned the importance of rinsing bottles out properly. It was an awful lot of work to scrub them all out and get them to the immacualte cleanliness demanded. It took all day, and it was not fun at all. Immediately after, I purchased a much better brush for the next batch.
The beer was bottle-conditioned. This means that active yeast remains in the beer after bottling. This yeast continues to transform various waste products from the fermentation process for some time. It is also responsible for carbonating the beer. Unfortunately, we didn’t write down how much priming sugar we used for the carbonation, but it was based on a formula from Palmer’s book.
The final gravity of the beer was 1.010, giving a modest 4.4% alcohol by volume.
After the bottles were cleaned and sanitized, we attached the bottle filler to the bucket and went at it. It was amazing to see just how much yeast was at the bottom of the bucket – far more than we had had in the tiny vial from the homebrew shop. Yeast is so cool! After capping the bottles, I stashed them away in a far corner of the apartment wrapped in a plastic garbage sack in case any bottles exploded.
Being interested in the process, we drank the hydrometer sample. There were a lot of intense yeasty flavors evident, combined with a lot of hop bitterness. Adam actually thought that the beer had been contaminated and gone sour! Nevertheless, we let the beer age and do its thing.
We’ve drunk most of the bottles by now, and the beer has definitely improved over the last month or so. When it was just finished carbonating, it had a lot of very fruity flavors evident. It even smelled somewhat like bananas! The flavor was reminiscent of a hefeweizen. These fruity yeasty flavors were not what we had expected or aimed for at all, but it didn’t taste bad. Over time, they diminished significantly, and today it tastes like a somewhat too bitter pale ale.
Next time I make a beer in this style, I want to use a bit less bittering hops and a bit more flavoring and aroma hops. In addition, it would be nice if I could figure out how to make the final beer a tad bit sweeter to counterbalance the bitterness of the hops a bit better.
All in all, I think it’s a good first start. It really got me hooked on homebrewing, and we’ve made another beer since then. I’ll write it up in another post.