<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><atom:link rel="hub" href="http://tumblr.superfeedr.com/" xmlns:atom="http://www.w3.org/2005/Atom"/><description>Drool and dribble from Karl Trygve Kalleberg regarding work and hobbies.


Software projects I presently work on: KolibriFX - algorithmic trading startupStratego/XT - DSL for program transformationSpoofax - IDE metatooling toolFrida IRE - collaborative reverse engineering

I also used to hang out in the ERs of various hospitals working as a medical doctor, but that’s on hold.</description><title>Software, Finance, Medicine</title><generator>Tumblr (3.0; @karltk)</generator><link>http://blog.kalleberg.org/</link><item><title>Hackathon in Delft: Gone!</title><description>&lt;p&gt;I’ve been at it again. In the previous autumn/winter season, I spent &lt;a href="http://blog.kalleberg.org/post/1463611782/hackathon-in-delft-go"&gt;a month in Delft&lt;/a&gt;, hacking on the &lt;a href="http://strategoxt.org"&gt;Stratego&lt;/a&gt;/&lt;a href="http://spoofax.org"&gt;Spoofax&lt;/a&gt; program transformation infrastructure.&lt;/p&gt;

&lt;p&gt;Now that another winter is here, I’ve had the good fortune to repeat what is slowly becoming a tradition. This year I even found time to reserve two months for a more extended hackathon.&lt;/p&gt;

&lt;p&gt;Many really good things came of out of the stay. A few of the immediate results are:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;A &lt;a href="http://blog.kalleberg.org/post/15456843436/a-command-line-interpreter-for-spoofax"&gt;command line interpreter for Spoofax&lt;/a&gt; that works on Linux/Unix/Windows. &lt;/li&gt;
&lt;li&gt;An &lt;a href="http://blog.kalleberg.org/post/16354946489/an-eclipse-console-for-spoofax"&gt;interactive Spoofax console&lt;/a&gt; for Eclipse.&lt;/li&gt;
&lt;li&gt;A major revamp of the &lt;a href="http://hydra.nixos.org/jobset/spoofax/spoofax-release"&gt;Spoofax&lt;/a&gt; build system that makes both development and bootstrapping a lot easier. &lt;/li&gt;
&lt;li&gt;A highly &lt;a href="http://hydra.nixos.org/jobset/spoofax/plasticode"&gt;experimental plugin for scripting source code analysis and manipulation&lt;/a&gt; inside of Eclipse. &lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;I am also involved in several on-going projects for bringing the necessary parts of the Spoofax infrastructure to the web. Interesting results should start popping up over the new few months.&lt;/p&gt;

&lt;p&gt;As is the case for most startups, finding the time to contribute back to the upstream projects we use is always difficult. Whenever this happens, though, the payoff is often substantial.&lt;/p&gt;</description><link>http://blog.kalleberg.org/post/16823174245</link><guid>http://blog.kalleberg.org/post/16823174245</guid><pubDate>Tue, 31 Jan 2012 18:00:05 +0100</pubDate><category>delft</category><category>strategoxt</category><category>compilers</category><category>dsl</category><category>spoofax</category><category>plasticode</category></item><item><title>An Eclipse Console for Spoofax</title><description>&lt;p&gt;More good news, everyone! I have found time to integrate the &lt;a href="http://blog.kalleberg.org/post/15456843436/a-command-line-interpreter-for-spoofax"&gt;command line shell for Spoofax&lt;/a&gt; into Eclipse. You can now have all sorts of tricky conversations with the Spoofax interpreter inside a perfectly innocent-looking Eclipse console:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://media.tumblr.com/tumblr_ly9hbyvyg01qa7x28.png" alt="A conversiation with Spoofax"/&gt;&lt;/p&gt;

&lt;p&gt;As you can see, there are still rough edges to be ironed out. One of them is clearly the color palette. Another is the lack of inline rules, which are not supported yet. Neither are dynamic rules (and it is doubtful they ever will be — we are currently exploring other opportunities for dealing with context-sensitive rewrite rules).&lt;/p&gt;

&lt;p&gt;You can bring up the actual console by using the console page selector in the top right-hand corner of your console, like you do for the other types of consoles:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://media.tumblr.com/tumblr_ly9hvgQnft1qa7x28.png" alt="Console page selector"/&gt;&lt;/p&gt;

&lt;p&gt;Remember that you can always report the issues you come across in &lt;a href="http://yellowgrass.org/project/Spoofax"&gt;YellowGrass&lt;/a&gt; and tag me (&lt;code&gt;@karltk&lt;/code&gt;).&lt;/p&gt;</description><link>http://blog.kalleberg.org/post/16354946489</link><guid>http://blog.kalleberg.org/post/16354946489</guid><pubDate>Mon, 23 Jan 2012 18:34:58 +0100</pubDate><category>spoofax</category><category>compilers</category><category>dsl</category><category>programming languages</category><category>strategoxt</category></item><item><title>A Command Line Interpreter for Spoofax</title><description>&lt;p&gt;&lt;strong&gt;Updated&lt;/strong&gt; with screenshot! Also take a look at the Eclipse Shell.&lt;/p&gt;

&lt;p&gt;Good news, boys and girls! If you happen to be a &lt;a href="http://strategoxt.org"&gt;Stratego&lt;/a&gt; and/or &lt;a href="http://spoofax.org"&gt;Spoofax&lt;/a&gt; user, you might appreciate that I finally took some time to piece together an interactive command line interpreter—-a REPL—-for Spoofax.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://media.tumblr.com/tumblr_ly9h5q5apP1qa7x28.png" alt="A small chat session with the Spoofax interpreter"/&gt;&lt;/p&gt;

&lt;p&gt;There are numerous other things you can do in the shell. The help “page” gives a short summary.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;1/ok&gt; :help
 :help                       -- print this page
 :forget var1 var2 ... varN  -- forget specific global variables
 :forget strat/(n,m)         -- forget strategy with arity (n, m), e.g :forget zip/(1,0)
 :forget _                   -- forget all global variables
 :arity strategy             -- show available arities for a strategy
 :strategies                 -- show all global strategies
 :vars                       -- show all global variables
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now that I’m a full time Spoofax-user, low hanging productivity fruits suddenly seem a lot more ripe for the picking. I’ve personally been using &lt;a href="http://strategoxt.org/Stratego/StrategoShell"&gt;Stratego Shell&lt;/a&gt; for a long time for my interactive needs, but it was getting increasingly out of date. Enter the Spoofax Interpreter, which runs on the JVM.&lt;/p&gt;

&lt;p&gt;With a good portion of help from &lt;a href="http://i361.photobucket.com/albums/oo51/fswphoto/sir-not-appearing-in-this-film.jpg"&gt;Rob&lt;/a&gt; and &lt;a href="http://www.st.ewi.tudelft.nl/~dolstra/"&gt;Eelco&lt;/a&gt;, I set up a build job for this thing in the hydra build farm, so that the &lt;a href="http://hydra.nixos.org/jobset/spoofax/spoofax-interpreter/latest"&gt;latest builds&lt;/a&gt; will always be available.&lt;/p&gt;

&lt;p&gt;There are bound to be a bunch of stuff that doesn’t work. When you find issues, please report them in &lt;a href="http://yellowgrass.org/project/Spoofax"&gt;YellowGrass&lt;/a&gt; and tag me (&lt;code&gt;@karltk&lt;/code&gt;). I’m especially interested in how well this works on the more obscure developer platforms, such as Windows and OSX.&lt;/p&gt;

&lt;p&gt;A sample contribution could be a &lt;code&gt;cmd&lt;/code&gt; script that makes this thing easily start on Windows. Hint, hint.&lt;/p&gt;</description><link>http://blog.kalleberg.org/post/15456843436</link><guid>http://blog.kalleberg.org/post/15456843436</guid><pubDate>Mon, 23 Jan 2012 18:15:54 +0100</pubDate></item><item><title>"One downside to the Kindle is that you can no longer throw a bad book across the room in disgust."</title><description>“One downside to the Kindle is that you can no longer throw a bad book across the room in disgust.”&lt;br/&gt;&lt;br/&gt; - &lt;em&gt;Lisa L&lt;/em&gt;</description><link>http://blog.kalleberg.org/post/15740604013</link><guid>http://blog.kalleberg.org/post/15740604013</guid><pubDate>Thu, 12 Jan 2012 23:24:49 +0100</pubDate></item><item><title>A Year of Kindle</title><description>&lt;p&gt;I’ve had my Kindle for exactly a year now. My experience so far: it’s really great! After a multi-year long lull where I didn’t do any reading (except for school and work), I’m now back into a rather steady reading pace.&lt;/p&gt;

&lt;p&gt;A few highlights from 2011:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;em&gt;Slaughterhouse Five&lt;/em&gt;, Kurt Vonnegut&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Too Big to Fail&lt;/em&gt;, Andrew Ross Sorkin&lt;/li&gt;
&lt;li&gt;&lt;em&gt;The Big Short&lt;/em&gt;, Michael Lewis&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Liar’s Poker&lt;/em&gt;, Michael Lewis&lt;/li&gt;
&lt;li&gt;&lt;em&gt;The Prince&lt;/em&gt;, Niccolò Machiavelli (&lt;a href="http://www.gutenberg.org/"&gt;Project Gutenberg&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;em&gt;At the Mountains of Madness&lt;/em&gt;, Howard Phillips Lovecraft (Gutenberg)&lt;/li&gt;
&lt;li&gt;&lt;em&gt;The Call of Cthulhu&lt;/em&gt;, Howard Phillips Lovecraft (Gutenberg)&lt;/li&gt;
&lt;li&gt;&lt;em&gt;The Art of Money-Getting&lt;/em&gt;, Phineas Taylor Barnum (Gutenberg)&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Anthem&lt;/em&gt;, Ayn Rand (Gutenberg)&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;It’s the 6” Kindle that I use the most, though I also have a 9.7”. The 6” is so small that I always take it in my backpack when I travel anywhere (which I find myself doing a lot). Compared with all other battery-powered devices I have, the battery life is phenomenal. Easily lasts a month, even with a decent amount of reading.&lt;/p&gt;

&lt;p&gt;Of course, the Amazon store is great. Being able to get a new book practically anywhere you go, at a moment’s notice is sweet. For example, I got really bored on the bus in England this summer, so I got a new book straight off of Amazon then and there — no extra charge though I downloaded it over 3G internet in a foreign country.&lt;/p&gt;

&lt;p&gt;But for all the greatness of the Amazon store, I must perhaps say that I appreciate the freely available books even more, especially those you get through Project Gutenberg. I’m slowly working my way through old classics like &lt;em&gt;The Age of Reason&lt;/em&gt; and &lt;em&gt;The Republic&lt;/em&gt;. I never managed to do that with paper books, simply because I didn’t bring the books along all the time. Now, when I have the inclination for some moral philosophy, I actually spend ten minutes or an hour reading further in, say, &lt;em&gt;The Theory of Moral Sentiments&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;I concede that there are many reasons why I wouldn’t want to buy a Kindle, but the fact that I read a lot more—and even enjoy the reading itself more—outweighs all those reasons for me.&lt;/p&gt;</description><link>http://blog.kalleberg.org/post/15259672964</link><guid>http://blog.kalleberg.org/post/15259672964</guid><pubDate>Tue, 03 Jan 2012 23:30:08 +0100</pubDate></item><item><title>"Hold snudlene på dåkkår!"</title><description>“Hold snudlene på dåkkår!”&lt;br/&gt;&lt;br/&gt; - &lt;em&gt;Håvard Sørbø&lt;/em&gt;</description><link>http://blog.kalleberg.org/post/14262759807</link><guid>http://blog.kalleberg.org/post/14262759807</guid><pubDate>Thu, 15 Dec 2011 16:00:06 +0100</pubDate></item><item><title>Hambrosgade, København</title><description>&lt;img src="http://25.media.tumblr.com/tumblr_lvp36oE46n1qapkemo1_r2_500.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;Hambrosgade, København&lt;/p&gt;</description><link>http://blog.kalleberg.org/post/13740667589</link><guid>http://blog.kalleberg.org/post/13740667589</guid><pubDate>Sun, 04 Dec 2011 20:55:26 +0100</pubDate></item><item><title>"Men etter noen måneder måtte vi se inn i realitetens blodskutte øyne."</title><description>“Men etter noen måneder måtte vi se inn i realitetens blodskutte øyne.”&lt;br/&gt;&lt;br/&gt; - &lt;em&gt;John Ivan Wiik&lt;/em&gt;</description><link>http://blog.kalleberg.org/post/7340209759</link><guid>http://blog.kalleberg.org/post/7340209759</guid><pubDate>Thu, 07 Jul 2011 14:48:32 +0200</pubDate></item><item><title>"… long before any human race as we know had shambled out of apedom."</title><description>“… long before any human race as we know had shambled out of apedom.”&lt;br/&gt;&lt;br/&gt; - &lt;em&gt;Howard Phillips “H. P.” Lovecraft&lt;/em&gt;</description><link>http://blog.kalleberg.org/post/4280535221</link><guid>http://blog.kalleberg.org/post/4280535221</guid><pubDate>Sat, 02 Apr 2011 12:40:57 +0200</pubDate></item><item><title>"Gjør som meg: spis deg tjukk, så fryser du ikke."</title><description>“Gjør som meg: spis deg tjukk, så fryser du ikke.”&lt;br/&gt;&lt;br/&gt; - &lt;em&gt;Uno Wackelin&lt;/em&gt;</description><link>http://blog.kalleberg.org/post/3530610544</link><guid>http://blog.kalleberg.org/post/3530610544</guid><pubDate>Sat, 26 Feb 2011 22:52:13 +0100</pubDate></item><item><title>"How can NASA send a spacecraft billions of miles through the solar system and somehow end up flying..."</title><description>“How can NASA send a spacecraft billions of miles through the solar system and somehow end up flying so close to a comet only a few kilometers in diameter? It’s done with math.”&lt;br/&gt;&lt;br/&gt; - &lt;em&gt;Ed Weiler, NASA Science Mission Directorate&lt;/em&gt;</description><link>http://blog.kalleberg.org/post/3526133766</link><guid>http://blog.kalleberg.org/post/3526133766</guid><pubDate>Sat, 26 Feb 2011 18:42:12 +0100</pubDate></item><item><title>"It’s not the end, but really the journey that matters, in the end."</title><description>“It’s not the end, but really the journey that matters, in the end.”&lt;br/&gt;&lt;br/&gt; - &lt;em&gt;Lennart Kats paraphrasing Ursula K. Le Guin&lt;/em&gt;</description><link>http://blog.kalleberg.org/post/2701047595</link><guid>http://blog.kalleberg.org/post/2701047595</guid><pubDate>Tue, 11 Jan 2011 20:38:00 +0100</pubDate></item><item><title>Merging a Mercurial repository back into Subversion</title><description>&lt;p&gt;In a recent project, I forked an upstream SVN repository into a new Mercurial repo, to do some exploratory programming. The exploration proved very fruitful, so I decided to merge the code back into the upstream SVN repo.&lt;/p&gt;

&lt;p&gt;Should be simple, right? Wrong. For posterity, here’s a high-level walkthrough that might also be of interest to others.&lt;/p&gt;

&lt;h3&gt;The Premise&lt;/h3&gt;

&lt;p&gt;Your case might differ from mine, so YMMV. Here’s my case:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;I copied a specific SVN revision (no history) into a freshly created Mercurial repo.&lt;/li&gt;
&lt;li&gt;All subsequent development happened on the Mercurial repository (multiple developers, resulting in multiple tips and several merges along the way).&lt;/li&gt;
&lt;li&gt;At the end, we wanted to “replay” the revision history from the Mercurial repository back into a new subdir in the upstream SVN repo, under &lt;code&gt;branches/&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;I wanted to retain as much of the Mercurial revision history as possible, and make it look like all the development had happened in SVN all the time. &lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;I almost got what I wanted. The only caveat was that I ended up having to collapse parts of the Mercurial revision history: The stretches in the revision history with multiple concurrent branches were collapsed into one revision. We only had a few cases of this, so it wasn’t really a biggie.&lt;/p&gt;

&lt;h3&gt;Tooling&lt;/h3&gt;

&lt;p&gt;After some investigation and a few stranded attempts, I ended up with the following Mercurial extensions for the job:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;a href="http://mercurial.selenic.com/wiki/HgSubversion"&gt;hgsubversion&lt;/a&gt; — checked out source, then ran &lt;code&gt;./setup.py install --user&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://mercurial.selenic.com/wiki/RebaseProject"&gt;rebase&lt;/a&gt; — part of the default Mercurial distro, but must be enabled (see below).&lt;/li&gt;
&lt;li&gt;&lt;a href="http://mercurial.selenic.com/wiki/GraphlogExtension"&gt;graphlog&lt;/a&gt; — same story as for rebase.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://mercurial.selenic.com/wiki/CollapseExtension"&gt;collapse&lt;/a&gt; — just checked out source, and  pointed Mercurial to it.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;For reference, this is the relevant section of my &lt;code&gt;$HOME/.hgrc&lt;/code&gt; file:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;[extensions]
rebase =
hgsubversion = /home/karltk/.local/lib/python2.6/site-packages/hgsubversion
hgext.graphlog =
collapse = /home/karltk/apps/hgcollapse/hgext/collapse.py
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Setting up for merging&lt;/h3&gt;

&lt;p&gt;I ended up using two local working directories for the job, plus copies of several intermediate stages to get me back in track whenever I made mistakes.&lt;/p&gt;

&lt;p&gt;We started with prepping a new branch in SVN, containing the exact revision that the Mercurial repo had been created from. This branch lives in &lt;code&gt;https://path-to-your-svn-repo/branches/new-branch&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Then, the local working copies were simply created with:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;code&gt;hg-repo&lt;/code&gt;, initialized with &lt;code&gt;hg clone https://path-to-remove-hg-repo hg-repo&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;svn-repo&lt;/code&gt;, initialized with &lt;code&gt;hg clone https://path-to-remove-svn-repo/branches/new-branch svn-repo&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Thanks to the &lt;code&gt;hgsubversion&lt;/code&gt; extension, Mercurial can pull from and push to SVN repos. The remote end remains a SVN repo, but locally you work on a Mercurial repository. However, you immediately run into a big feature mismatch between SVN and Mercurial: you cannot push to a remote SVN repository, unless the local Mecurial revision history is completely linear — i.e., no branches nor merges in the local history.&lt;/p&gt;

&lt;h3&gt;Linearizing the Mercurial revision history&lt;/h3&gt;

&lt;p&gt;Since SVN only accepts a linear revision history, any non-linearities (shown as parallell lines when you do &lt;code&gt;hg glog&lt;/code&gt;) found in the &lt;code&gt;hg-repo&lt;/code&gt; must be ironed out. This is where &lt;code&gt;hg collapse&lt;/code&gt; comes in. By looking at the branch and merge revisions in the &lt;code&gt;glog&lt;/code&gt;, I collapsed parallell areas of the revision history manually. E.g. &lt;code&gt;hg collapse -r 82 -r 89 -f&lt;/code&gt;, drops you into the commit editor and allows you to manually merge the commit messages for the collapsed revisions.&lt;/p&gt;

&lt;p&gt;Once &lt;code&gt;hg glog&lt;/code&gt; showed a linear history, I was ready to merge.&lt;/p&gt;

&lt;h3&gt;Doing the merging (rebasing!)&lt;/h3&gt;

&lt;p&gt;Now that we have a linear revision history again, we can go ahead and merge the Mercurial repository into SVN. Except, we cannot &lt;em&gt;merge&lt;/em&gt;. We must &lt;em&gt;rebase&lt;/em&gt;. A merge would introduce a non-linearity in the revision history, stopping us dead in our tracks.&lt;/p&gt;

&lt;p&gt;The procedure I found went somewhat like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# cd hg-repo
# hg push -f ../svn-repo
# cd ../svn-repo
# hg glog
# hg rebase -b &lt;latest revision in log&gt; -d &lt;first revision in log&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;When looking for &lt;code&gt;&lt;latest revision in log&gt;&lt;/code&gt; you are looking for the latest revision from the Mercurial repo changes. The &lt;code&gt;&lt;first revision in log&gt;&lt;/code&gt; is really the latest revision of the SVN repo changes. What we want to do, is to tuck all the Mercurial repo changes onto the last SVN change. And this is exactly why we are using &lt;code&gt;rebase&lt;/code&gt; and not &lt;code&gt;merge&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In my case, the &lt;code&gt;&lt;first revision in log&gt;&lt;/code&gt; was 0 and the &lt;code&gt;&lt;latest revision in log&gt;&lt;/code&gt; was 83.&lt;/p&gt;

&lt;p&gt;When I ran &lt;code&gt;hg rebase -b 83 -d 0&lt;/code&gt;, there were numerous merge conflicts — because &lt;code&gt;rebase&lt;/code&gt; uses &lt;code&gt;merge&lt;/code&gt; behind the scenes. I just resolved these normally using &lt;code&gt;hg resolve&lt;/code&gt;, and then continued the rebasing using &lt;code&gt;hg rebase -c&lt;/code&gt;. After a few more conflicts and resolutions, the processes ended.&lt;/p&gt;

&lt;p&gt;During the rebasing process, frequent copies of the entire &lt;code&gt;svn-repo&lt;/code&gt; directory tree is advised. In essence, you’re doing destructive updates to your local copy of the &lt;code&gt;svn-repo&lt;/code&gt;, and you can only check in your result after all the rebasing is finished. Having a safety net proved quite useful, at least for me:)&lt;/p&gt;

&lt;p&gt;After the rebasing was complete, &lt;code&gt;hg glog&lt;/code&gt; told me that everything was linear and good. At this point I did&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# hg outgoing
# hg push
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If you see “Sorry, can’t find svn parent of a merge revision.” when trying &lt;code&gt;hg outgoing&lt;/code&gt; or &lt;code&gt;hg push&lt;/code&gt;, it probably means that your revision history (as told to you by &lt;code&gt;hg glog&lt;/code&gt;) is non-linear. These parts should be &lt;code&gt;hg collapse&lt;/code&gt;-ed away.&lt;/p&gt;</description><link>http://blog.kalleberg.org/post/2337246985</link><guid>http://blog.kalleberg.org/post/2337246985</guid><pubDate>Thu, 16 Dec 2010 17:03:00 +0100</pubDate></item><item><title>Hackathon in Delft: Go!</title><description>&lt;p&gt;It’s that time of the year again. The glorious month of intensive parser implementation, compiler engineering and &lt;a href="http://martinfowler.com/articles/languageWorkbench.html"&gt;language workbenches&lt;/a&gt; — the essentials of any IDE — has arrived. I’ve retreated to the &lt;a href="http://www.tudelft.nl/"&gt;TU Delft&lt;/a&gt; campus for the month of November to hack on interactive language infrastructure for &lt;a href="http://kolibrifx.com"&gt;our startup&lt;/a&gt;, and to think big thoughts about IDEs and DSLs in general.&lt;/p&gt;

&lt;p&gt;Our startup is a user of both &lt;a href="http://strategoxt.org"&gt;Stratego&lt;/a&gt; and &lt;a href="http://spoofax.org"&gt;Spoofax&lt;/a&gt;, so it was only natural to join forces with &lt;a href="http://swerl.tudelft.nl/bin/view/EelcoVisser"&gt;Eelco Visser&lt;/a&gt; and some of his henchmen here in Delft, who are the maintainers of said projects.&lt;/p&gt;

&lt;p&gt;For somewhat practical and somewhat nostalgic reasons, I decided to stay at the TU Delft campus. Campus life here already brings back memories of my year living at &lt;a href="http://nl.wikipedia.org/wiki/Studentencomplex_Cambridgelaan"&gt;Cambridgelaan&lt;/a&gt;: the access to lightning fast broadband in your dorm room, the four minute walk to the lab, the 24-hour party people (aka &lt;a href="http://en.wikipedia.org/wiki/Erasmus_Programme"&gt;Erasmus&lt;/a&gt; students), and the freedom to follow your biological clock.&lt;/p&gt;

&lt;p&gt;Time for some commits:)&lt;/p&gt;</description><link>http://blog.kalleberg.org/post/1463611782</link><guid>http://blog.kalleberg.org/post/1463611782</guid><pubDate>Tue, 02 Nov 2010 20:33:00 +0100</pubDate><category>compiler</category><category>delft</category><category>dsl</category><category>kolibrifx</category><category>spoofax</category><category>startup</category><category>strategoxt</category></item><item><title>DIY: Fixing the MSN connector for Empathy</title><description>&lt;p&gt;I just got bitten by bug &lt;a href="https://bugs.launchpad.net/ubuntu/+source/telepathy-butterfly/+bug/663670"&gt;663670&lt;/a&gt;: &lt;em&gt;empathy doesn’t connect to msn - blocked connection&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;It turns out that Microsoft made changes on the server side two days ago that crashes &lt;code&gt;telepathy-butterfly&lt;/code&gt;, the MSN connector used by Empathy.&lt;/p&gt;

&lt;p&gt;Fortunately, the fix is simple.&lt;/p&gt;

&lt;p&gt;# sudo nano /usr/lib/pymodules/python2.6/papyon/service/description/SingleSignOn/RequestMultipleSecurityTokens.py&lt;/p&gt;

&lt;p&gt;Then goto line 24 and replace&lt;/p&gt;

&lt;p&gt;CONTACTS = (“contacts.msn.com”, “?s=1&amp;id=24000&amp;kv=7&amp;rn=93S9SWWw&amp;tw=0&amp;ver=2.1.6000.1”)&lt;/p&gt;

&lt;p&gt;with&lt;/p&gt;

&lt;p&gt;CONTACTS = (“contacts.msn.com”, “MBI”)&lt;/p&gt;

&lt;p&gt;After that, hit the “reconnect” button in Empathy and it should now connect to MSN. You don’t have to restart Empathy, even. These are the times I love scripting languages.&lt;/p&gt;</description><link>http://blog.kalleberg.org/post/1361639129</link><guid>http://blog.kalleberg.org/post/1361639129</guid><pubDate>Thu, 21 Oct 2010 00:36:13 +0200</pubDate><category>ubuntu</category><category>empathy</category><category>python</category><category>msn</category></item><item><title>"Det er fakta. Men det er ikke rett."</title><description>“Det er fakta. Men det er ikke rett.”&lt;br/&gt;&lt;br/&gt; - &lt;em&gt;meg selv&lt;/em&gt;</description><link>http://blog.kalleberg.org/post/1323612311</link><guid>http://blog.kalleberg.org/post/1323612311</guid><pubDate>Sat, 16 Oct 2010 02:17:32 +0200</pubDate></item><item><title>"Ingenting i livet er gratis. Ikkje ein gong det besta."</title><description>“Ingenting i livet er gratis. Ikkje ein gong det besta.”&lt;br/&gt;&lt;br/&gt; - &lt;em&gt;Håvard Sørbø&lt;/em&gt;</description><link>http://blog.kalleberg.org/post/1321609728</link><guid>http://blog.kalleberg.org/post/1321609728</guid><pubDate>Fri, 15 Oct 2010 20:37:29 +0200</pubDate></item><item><title>Prototype of a Scannerless, Generalized Left-to-right Rightmost (SGLR) derivation parser for JavaScript</title><description>&lt;p&gt;Need a Scannerless, Generalized Left-to-right Rightmost (&lt;a href="http://strategoxt.org/Sdf/SGLR"&gt;SGLR&lt;/a&gt;) derivation parser for JavaScript? Then my &lt;a href="http://bitbucket.org/karltk/jsglr-gwt"&gt;JSGLR-GWT proof-of-concept&lt;/a&gt; might interest you. (If you don’t know what a scannerless GLR parser is, then you are probably not interested in writing modular grammars for your programming language implementation anyway — or you might want to read a few sections down).&lt;/p&gt;

&lt;p&gt;A word of warning: I’m not claiming it is written &lt;em&gt;in&lt;/em&gt; JavaScript, merely &lt;em&gt;for&lt;/em&gt; JavaScript. I simply took our &lt;a href="http://strategoxt.org/Stratego/JSGLR"&gt;old Java-based SGLR implementation&lt;/a&gt; and massaged it quite heavily until GWT could spit out a working version for the JavaScript interpreters.&lt;/p&gt;

&lt;h3&gt;Performance&lt;/h3&gt;

&lt;p&gt;The performance is, quite frankly, beyond my wildest expectations. I’ve not made a single attempt at performance tweaking for the JavaScript engines yet, and still I manage to parse through 830 lines of Stratego code in ~3 seconds (Chromium 7.0.519.0). For smaller fragments, even Firefox 3.5 manages to keep up: it manages ~20 lines in ~1s (Chromium does that test in 74ms).&lt;/p&gt;

&lt;p&gt;To most people, this probably doesn’t sound very fast at all, but I was much worse off when I initially wrote JSGLR back in 2006 — and that used a term(tree) library that wasn’t hacked together over night. All in all, I think there are plenty of performance tweaking opportunities, and the JavaScript engines are getting faster almost by the minute.&lt;/p&gt;

&lt;p&gt;Now, another reason for my optimism, is my use case. I’m interested only interested in JavaScript port of SGLR for interactive use. Think web IDE. My aim is to attain interactive speeds when editing text. A few optimization ideas off the top of my head:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;Tweak the parser to only reparse the lines that have changed. This alone might be enough to survive with the current level of performance.&lt;/li&gt;
&lt;li&gt;Reduce the extreme amount of garbage created currently by using object pools.&lt;/li&gt;
&lt;li&gt;Do the initial parse on the server-side, at least for larger files. &lt;/li&gt;
&lt;/ul&gt;&lt;h3&gt;What is a Scannerless GLR parser anyway?&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;(optional reading)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;SGLR does &lt;em&gt;not&lt;/em&gt; separate your parser into the usual two steps: (1) lexer/tokenizer/scanner followed by (2) LL- or LR-style parsing of the token stream. Instead, SGLR runs the parser on every character. This is why it’s &lt;em&gt;scannerless&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The next point, GLR, is tricker to explain briefly. Remember that a parser takes a string of text and creates a (parse) tree for it. There might, at some stage during the parsing, be multiple possible trees that might fit the text seen so far. This is called an &lt;em&gt;ambiguity&lt;/em&gt;. We don’t yet know what is meant by the text. Only by continue reading, will it (hopefully) become apparent. However, this is where the &lt;em&gt;k&lt;/em&gt; comes in. LL(&lt;em&gt;k&lt;/em&gt;)/LALR(&lt;em&gt;k&lt;/em&gt;) lets you look only &lt;em&gt;k&lt;/em&gt; tokens into the future. GLR allows you to look &lt;em&gt;all&lt;/em&gt; tokens into the future (for SGLR, I should probably say all &lt;em&gt;characters&lt;/em&gt; into the future.).&lt;/p&gt;

&lt;p&gt;Typically, LL and LALR-parsers, such as the archaic Yacc and Bison parsers, force you to contort your grammar a lot to meet the &lt;em&gt;k&lt;/em&gt;-token lookahead. If you have ever run into the dreaded “shift/reduce” conflict, you know what I’m talking about.&lt;/p&gt;

&lt;p&gt;The combination of scannerless and GLR gives us something wonderful: &lt;em&gt;grammars are closed under composition&lt;/em&gt;. So, if you write grammars for languages &lt;em&gt;L1&lt;/em&gt; and &lt;em&gt;L2&lt;/em&gt;, you can just make a new module &lt;em&gt;L3&lt;/em&gt;, include &lt;em&gt;L1&lt;/em&gt; and &lt;em&gt;L2&lt;/em&gt;, et voila — you have &lt;em&gt;L3 = L1 ∪ L2&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Trying such a stunt with LALR will almost invariably push you into the “shift/reduce”-conflict corner. Admittedly, there is a significant trade-off or gotcha with the (S)GLR approach. And it is very similar to the trade-offs/gotchas with early vs late binding, or static vs dynamic typing.&lt;/p&gt;

&lt;p&gt;If, after processing the entire text, there &lt;em&gt;still&lt;/em&gt; are multiple possible parse trees, GLR will give you all of them. So, you catch the ambiguity at runtime. But you can use GLR to say more: the set of grammars you can express with GLR is larger than that of LL(k) and LALR(k).&lt;/p&gt;

&lt;p&gt;The trade-off is simple: with LL(&lt;em&gt;k&lt;/em&gt;)/LALR(&lt;em&gt;k&lt;/em&gt;), you are guaranteed to only have one, &lt;em&gt;unambiguous&lt;/em&gt;, tree at the end — but the you might not be able to express the language you want to design. With SGLR, you are free to express the full class of context-free grammars, but the parsing result might be a forest of trees. It’s up to you to prune the forest afterwards, finding the tree you want.&lt;/p&gt;

&lt;p&gt;I’m not claiming that SGLR is the best solution for all kinds for parsing needs. With great power comes great responsibility. You might not always need great power, and great responsibilty is usually just a liability, anyway;)&lt;/p&gt;

&lt;h3&gt;Implementation Details&lt;/h3&gt;

&lt;p&gt;To interested parties, this is what I did:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;I ripped out the dependence on the &lt;a href="http://www.cwi.nl"&gt;CWI&lt;/a&gt; &lt;a href="http://buildfarm.st.ewi.tudelft.nl/releases/meta-environment/channels-v3/aterm-unstable/"&gt;ATerm&lt;/a&gt; library and (yet again) wrote my own. Mostly hacked together based from scratch, but with the &lt;a href="http://strategoxt.org/Tools/ATermFormat"&gt;Textual ATerm Format (TAF)&lt;/a&gt; parser stolen from the &lt;a href="https://svn.strategoxt.org/repos/StrategoXT/spoofax/trunk/spoofax/org.spoofax.interpreter.core/src/java/org/spoofax/interpreter/terms/"&gt;BasicStrategoTerm&lt;/a&gt; implementation. &lt;/li&gt;
&lt;li&gt;Ripped out all references to &lt;code&gt;java.io&lt;/code&gt; and replaced with my own stuff, based on strings. &lt;/li&gt;
&lt;li&gt;Wrote a tiny &lt;a href="http://google-web-toolkit.googlecode.com/svn/javadoc/1.5/com/google/gwt/user/server/rpc/RemoteServiceServlet.html"&gt;RemoteServiceServlet&lt;/a&gt; to allow the client side to access the parse tables from server side.&lt;/li&gt;
&lt;li&gt;Added a tiny hack to also fetch parse tables as TAFs and load these on the client side. &lt;/li&gt;
&lt;li&gt;Various other minor fixes all over the place.&lt;/li&gt;
&lt;/ul&gt;</description><link>http://blog.kalleberg.org/post/1256702765</link><guid>http://blog.kalleberg.org/post/1256702765</guid><pubDate>Wed, 06 Oct 2010 19:57:00 +0200</pubDate><category>stratego</category><category>parsing</category><category>spoofax</category><category>jsglr</category><category>sglr</category><category>glr</category><category>compilers</category><category>programming languages</category><category>javascript</category><category>gwt</category><category>strategoxt</category></item><item><title>"Ahhh! Thermite; the stuff that dreams are made of!"</title><description>“Ahhh! Thermite; the stuff that dreams are made of!”&lt;br/&gt;&lt;br/&gt; - &lt;em&gt;Kurt Kristian Lyngholm&lt;/em&gt;</description><link>http://blog.kalleberg.org/post/1206170473</link><guid>http://blog.kalleberg.org/post/1206170473</guid><pubDate>Tue, 28 Sep 2010 23:35:26 +0200</pubDate></item><item><title>Great things in the Eclipse JDT</title><description>&lt;p&gt;Since we started with the &lt;a href="https://kolibrifx.com"&gt;KolibriFX&lt;/a&gt; project six months ago, I have programmed a lot of Scala and Java, plus some  &lt;a href="http://strategoxt.org"&gt;Stratego&lt;/a&gt; and JavaScript. I love programming in Scala and Stratego because my implementations are shorter and usually a lot easier to reason about. I often get this warm, fuzzy feeling of having captured something tricky in an elegant fashion.&lt;/p&gt;

&lt;p&gt;However, in day-to-day programming, Java has one killer feature that makes up for a lot of cruft in the language: the Eclipse JDT. I recently spent a few days rewriting some of our Scala code to Java, and that really brought the point home. I find that, at least for our code-base, the JDT offers productivity benefits that far outweigh the linguistic disadvantage Java suffers compared to Scala.&lt;/p&gt;

&lt;p&gt;The points that follow will be an old hat to programmers familiar with the JDT, though they might serve as a reminder that for all its flaws, the JDT is a rather great tool, after all.&lt;/p&gt;

&lt;h3&gt;Realtime Compilation&lt;/h3&gt;

&lt;p&gt;This is probably the biggest tool-provided productivity booster I know of. I’ve always been a huge fan of realtime compilation, because it encourages flow. It brings me into “the zone”, “the flow” or whatever you prefer to call it. Whenever I have to wait for the compiler for more than a few seconds, I lose my flow and switch to another desktop “to remain productive”. This invariably forces an expensive mental context switch, and ultimately reduces my productivity, &lt;em&gt;but without reducing my perception of productivity&lt;/em&gt; — I’m still doing stuff, so I feel I’m moving forward, except I’m not.&lt;/p&gt;

&lt;p&gt;Realtime compiler error messages and warnings, allow me to mindlessly work through the live updated list until it’s empty. At that point, I run my unit tests and continue flowing until they’re all green. I get to decide how quickly I work. The computer (nearly) always follows my pace, so &lt;em&gt;I’m&lt;/em&gt; the performance bottleneck. It makes me feel in control. I easily enter the flow, and I stay there. One thing I use as a flow marker is how often I watch the time. With Scala, 5 minutes rarely go by before I check it, since I’m waiting for the compiler to churn through. With the JDT, an hour may pass, easily.&lt;/p&gt;

&lt;p&gt;This is not a bash on Scala. Stratego has the same problem, but we’re working on an incremental compiler to improve the problem there. I predict that both Scala and Stratego will eventually have compilers working at interactive speeds, and the same degree of flow will be attained as with the JDT compiler.&lt;/p&gt;

&lt;h3&gt;Quick Fixes&lt;/h3&gt;

&lt;p&gt;Beyond realtime compilation, the JDT offers additional inspiration for up-and-coming languages: its refactorings and quick fixes make life with Java easy and nearly enjoyable. Based on my usage the last week, these are my favourite quick fixes (admittedly, this list changes from week to week, based on the nature of the programming tasks):&lt;/p&gt;

&lt;h2&gt;Assign to Field&lt;/h2&gt;

&lt;pre&gt;&lt;code&gt;class X {
   X(int y|) {
   }
 }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;With the cursor placed after &lt;code&gt;y&lt;/code&gt;, quick fix suggests the creation of a new field, &lt;code&gt;private final int y&lt;/code&gt;, and also adds the line &lt;code&gt;this.y = y&lt;/code&gt; to the constructor body.&lt;/p&gt;

&lt;h2&gt;Extract to Separate File&lt;/h2&gt;

&lt;p&gt;File &lt;code&gt;X.java&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class X { ... }
class Y| { ... }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;With the cursor after &lt;code&gt;Y&lt;/code&gt;, quick fix suggests that the class &lt;code&gt;Y&lt;/code&gt; be moved to a separate file, &lt;code&gt;Y.java&lt;/code&gt;, and it deals with all the imports at the top of both &lt;code&gt;X.java&lt;/code&gt; and &lt;code&gt;Y.java&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;Generate Getters and Setters&lt;/h2&gt;

&lt;pre&gt;&lt;code&gt;class X {
   private int x;
   private int y;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Creates &lt;code&gt;getX&lt;/code&gt;/&lt;code&gt;setX&lt;/code&gt; and &lt;code&gt;getY&lt;/code&gt;/&lt;code&gt;setY&lt;/code&gt;. You can control if you want both &lt;code&gt;get&lt;/code&gt; and &lt;code&gt;set&lt;/code&gt; on a per-variable basis.&lt;/p&gt;

&lt;h2&gt;Change Visibility to ‘x’.&lt;/h2&gt;

&lt;p&gt;File &lt;code&gt;foo/X.java&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;package foo;
class X {
   Horoscope computeHoroscope();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;File &lt;code&gt;bar/Y.java&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;package bar;
class Y {
   ...
   x.computeHoroscope()|;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If you are in another package and invoke, &lt;code&gt;x.computeHoroscope()&lt;/code&gt;, quick fix tells you that friendly access is not possible, and suggests adding &lt;code&gt;public&lt;/code&gt; to the &lt;code&gt;computeHoroscope()&lt;/code&gt; method declaration.&lt;/p&gt;

&lt;h2&gt;Add/remove Argument to Match.&lt;/h2&gt;

&lt;p&gt;File &lt;code&gt;IntPair.java&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class IntPair {
   Pair(int x) {
   }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;File &lt;code&gt;Main.java&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;IntPair x = new IntPair(10, 100)|;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The usage doesn’t match any of the known constructors of &lt;code&gt;IntPair&lt;/code&gt;. Quick fix is going to suggest that another argument is added to &lt;code&gt;IntPair#IntPair(int)&lt;/code&gt;, so that it becomes IntPair#IntPair(int,int).&lt;/p&gt;

&lt;h2&gt;Change type of ‘x’ to match expression.&lt;/h2&gt;

&lt;pre&gt;&lt;code&gt;String currentTime = new Set&lt;HashMap&lt;String, Integer&gt;&gt;();
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The type mismatch prompts quick fix to suggest replacing &lt;code&gt;String&lt;/code&gt; with &lt;code&gt;Set&lt;HashMap&lt;String, Integer&gt;&gt;&lt;/code&gt; for the variable &lt;code&gt;currentTime&lt;/code&gt;. You may also sometimes get away with&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;currentTime| = new Set&lt;HashMap&lt;String, Integer&gt;&gt;();
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and ask quick fix to &lt;code&gt;create new local variable&lt;/code&gt; with the cursor placed near &lt;code&gt;currentTime&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;Infer generic arguments&lt;/h2&gt;

&lt;pre&gt;&lt;code&gt;Map map = new HashMap&lt;String, String&gt;()|;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Here, quick fix can compute the correct generic arguments for Map (&lt;code&gt;&lt;String, String&gt;&lt;/code&gt;).&lt;/p&gt;

&lt;h2&gt;Import Type ‘x’.&lt;/h2&gt;

&lt;pre&gt;&lt;code&gt;new HashMap&lt;String, String();
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Quick fix may be used to quickly import java.util.HashMap. It allows you to stop fussing about the endless imports lists, and it actually works flawlessly 99% of the time (sometimes, it may insert the import in a funny place if your code is not parseable at the time you ask for an import).&lt;/p&gt;

&lt;h3&gt;Wrapping Up&lt;/h3&gt;

&lt;p&gt;Most of the above features are great when writing fresh code. However, they’re even better when you need to change code — especially the realtime compilation feature. Refactorings that may take hours in Stratego or Scala are usually done in minutes in Java, thanks to the IDE support. Imagine where we may go with that kind of IDE support for the newer languages…&lt;/p&gt;</description><link>http://blog.kalleberg.org/post/1111675028</link><guid>http://blog.kalleberg.org/post/1111675028</guid><pubDate>Sun, 12 Sep 2010 23:50:50 +0200</pubDate><category>scala</category><category>java</category><category>stratego</category><category>programming</category><category>eclipse</category><category>jdt</category><category>realtime compilation</category><category>strategoxt</category></item></channel></rss>

