Twitter icon.
Random notes on software, programming and languages.
By Adrian Kuhn

Archive for October, 2008

How do I track time? II


Wednesday, October 22nd, 2008

Recently, I showed how to use the command line and a ruby script to keep track of time. Due to popular demand, here is the full script (including time cloud generation).

track_my_time.rb

The script is used as follows:

% I am back from lunch
0d 0:46'32"
% I read mail
0d 0:12'05"
% I fixed bug 20446 in Some.app for Acme
0d 1:38'12"
% …

On monday, you can use --cloud to show the time cloud of last week. A time cloud is a tag cloud with all terms that appear in last week’s entries, weighted by frequency and duration of the containing entries. No stemming so far, but you can provide a stopword list in a separate file.

For example, my time cloud of last week looks as follows:

Installation instructions and more usage see script file.

TermMap of OOPSLA


Tuesday, October 21st, 2008

While browsing the proceedings of this year’s OOPSLA, I thought, hey let’s create a themescape of the proceedings. So I fired up SoftwareCartographer and created a “code map” of all PDFs found in the CD. Normally I use SoftwareCartographer to analyse the vocabulary of software systems, but since it operates on vocabulary only, it can be applied on normal text files aswell.

But before we dive into software cartography, the word cloud of all proceeding documents:

Obviously, there are many Java programmers fighting with their type systems at OOPSLA. In the cloud above, the terms are weighted by number of occurrences in the proceeding documents. I guess on a cloud weighted by fun, Smalltalk Superpowers and Animal Verbing would show up the largest.

On the picture above, we see the “CodeMap” of OOPSLA together with the word cloud of selected papers (click for larger version). CodeMap is a visualization to show source code files (here PDF files) and how similar they are in terms of vocabulary [WCRE 2008]. Each file is rendered as a hill, file size is used as the hill’s height. Location of the files reflects topical similarity. Files that use the same vocabulary are close to each other, files that use different vocabulary are far apart of each other.

SoftwareCartographer is written in Smalltalk, if you have VW installed you can download the WCRE demo and apply it your own software systems or conference papers. Software-Cartographer uses Hapax and Pimon, but not Moose.

ZIP Code Map of Switzerland


Wednesday, October 15th, 2008

Inspired by Robert Kosara’s US ZIP Scribble Map as well as Stefan Zeiger’s ZIP Code Map of Germany, I’ve done a small script that renders Switzerland as a ZIP code map.

Edit: obviously, Robert Kosara has also done a ZIP scribble map of Switzerland, but it is broken. On the US original he explores the correlations of 1000-blocks of ZIP codes and state boundaries. On his Swiss map however, he directly groups the lines by cantons! Which is obviously not the same since we have 26 cantons but only nine blocks of 1000 ZIP codes.

In particular interesting is how the red and brown ZIP code blocks are dividing the canton Valais by its two languages: French and German! (For foreigners: the valais is the huge valley in the south-east which is covered half by red lines and half by brown lines.)

The script is written in Pimon, a small visualization framework for VW Smalltalk. Of course, Pimon has a DSL! The layout- and drawing DSL of Pimon offers a fluent interface that targets the end-users of common Desktop applications. Figures are grouped, aligned and positioned as you would do it in an Desktop application, rather than forcing the programmer to wrap his head around vector algebra with all its x’s and y’s.

The following bunch of Pimon code specifies a tree layout (the same in Java):

TreeLevel >> arrange
    | group |
    group := Group new
        addAll: self treeChildren;
        horizontalWithGap: 4;
        alignTop.
    Group new
        add: self treeParent;
        add: group;
        verticalWithGap: 16;
        alignCenter.
    self resizeToElements.

I started porting Pimon to Java last year, but only got 80% done and thus never released it to the public. However, it is sad to let code decay without being used and maybe the parts that are working turn out to be useful for your projects, thus I published it today:

Method Namespaces for Smalltalk?


Monday, October 6th, 2008

Packaging for Smalltalk is in the air. The topic emerged twice today, first at lunch when discussing Pharo with Adrian and Lukas, and later when Toon showed me CaesarJ. In both discussions, I argued that we need method namespaces for Smalltalk.

Class reopening is a well known, that is extending an existing classes with new methods. In Smalltalk classes are typically reopened using a package extension mechanism, whereas Python and Ruby use “monkey patching” (even though modules might be a better solution).

The problems that arise from these approaches are discussed en detail by Gilad Bracha on his blog, I will thus start media res using a simple example. Imagine that two libraries, A and B, both extend the String class with an #asURL method. Two implementations of the same method are provided. Thus the problem: which implementation is used? Or more precise, on what kind of context does the choice among these two implementations depend?

As it is now in Smalltalk, the latter implementation overrides the former, and thus (assumed that the load order is first A then B) the definition of #asURL in B wins and is always used. This is obviously broken, since all code in A and all clients that expect A’s implementation are likely to fail.

As it is suggested in Classboxes, the – take a deep breath – imports of the lexical scope in which the current thread was started decides which version is picked (based on IM conversation with Alex, this was not obvious to me from his thesis). I have never used this solution in practice, but it does not seem to address the problem at hand. First, usage of libraries is typically not separated by threads, that is, we typically want to use both A and B from the same thread. Second, the principle of least surprise is violated, as we can not tell which version is picked just by looking at the code (ie from lexical scope alone).

There is another approach, taken by C#’s extension methods. Each extension method is scoped within its namespace, that said, the #asULR method of A is picked for all calls from the lexical scope of A, and the #asURL method of B is picked for all calls from the lexical scope of B. Whenever some client code wants to call #asURL, it must explicitly import the method either from A or from B. This satisfies both the constraint that neither A nor B break each other or each other’s client code, and the principle of least surprise.

How can this by applied to Smalltalk?

  • The name of all compiled methods is prepended with the lexical scope, that is the name of the enclosing package. For example, #A_asURL if the method #asURL is defined by the package A, and vice versa for B.
  • The compiler prepends all message sends with the name of the lexical scope of the current method, that is the name of the enclosing package. For example, #A_asURL if #asURL is sent from package A, or #Foo_asURL if #asURL is sent from Client Foo.
  • When a client package, for example Foo, imports #asURL from a provider Package, lets say A, a hidden method #Foo_asURL is created that delegates to #A_asURL.

Of course, Browser, Debugger and Inspector should be updated to reflect and properly display this naming convention. For example, a code editor should show the names without prefix, whereas the debugger probably should display the extensions. The latter could also be controlled by a boolean setting. The generated code should run fine in any image.

How do I track time?


Thursday, October 2nd, 2008

I have a ruby script that appends a line with timestamp and all commandline arguments to a text file. Then I have an alias from “I” to this script, such that I can just type on the command line…

% I start working
0d 14:06'11"
% I have read mail
0d 00:27'45"
% I answered a question on stackoverflow.com
0d 00:11'32"
%

…and all that is recorded in a text file with timestamps.

Other scripts later use that text file to generate work reports, or just tag clouds of what I have done during the last weeks or months.

require 'date'
File.open('time.txt', 'a') do |f|
  f.puts "#{DateTime.now.strftime("%Y/%m/%d\t%H:%M:%S\t")}#{$*.join(' ')}"
end unless $*.empty?
back = DateTime.new
now = DateTime.new
File.open('time.txt') do |f|
  f.each do |line|
    unless line.strip.empty? then
      back = now
      now = DateTime.strptime(line,"%Y/%m/%d\t%H:%M:%S\t")
    end
  end
end
if $*.empty? then
  back = now
  now = DateTime.now.new_offset(of=0) + DateTime.now.offset # fix timezone!
end
diff = (now - back)
puts "#{diff.to_i}d #{(DateTime.new + (diff - diff.to_i)).strftime("%H:%M'%S\"")}"

API Conformance in Dynamic Languages


Wednesday, October 1st, 2008

As the provider of a library or framework, one of your major requirements it to guarantee a stable API from revision to revision. Your clients do not want an API that suddenly changes between two revisions of the same release.

Given a static language, as eg Java, this isn’t a big issue: define the entire API using interfaces, and as long as your classes compile, your API is complete. The same for your clients, as long as they declare all variables using the interface types, their code cannot accidentally invoke an internal method.

Different picture in dynamic languages, there are no means to guarantee API conformance with the compiler. There is no such thing as a dynamic typing system to prevent you from shooting in your clients feet.

End of the story?

Yes, if you are trapped in the taxonomy of typing system: weak, strong, static, lambda cube, duck duck go. Nope not at all, if you known that tests are to dynamic languages what types are to static languages. Just use the testing framework to reject a broken API, in the same way statically typed languages use a compiler!

In Fame (in the Smalltalk version), we check API conformance as follows:

testPublicInterface
  "Test method to check API conformance of Fame."
  self publicInterface do: [ :tuple |
    | class constructors methods |
    class := self class environment at: tuple first ifAbsent: nil.
    constructors := tuple second.
    methods := tuple third.
    self assert: class notNil.
    self assert: (class category startsWith: 'Fame').
    constructors do: [ :each | self assert: (class class canUnderstand: each) ].
    methods do: [ :each | self assert: (class canUnderstand: each) ]].

This method iterates over a list of tuples t = (class-name, constructor-names, method-names) and asserts that a Smalltalk class with the given name and methods exists. If part of the API is missing, the tests fail.

In addition, we have a pretty printer that uses the same list of tuples to generate human-readable API documentation. Furthermore we could make the IDE aware of this list and, for example, issue a warning when clients violate the API.

I am certainly not the first one to use the testing framework for API conformance. If you know of other projects doing so, please leave a comment.

For.example is Digg proof thanks to caching by WP Super Cache!