On June 28, I will have the pleasure of giving a one-day course on the topic of demo-driven research for the PhD students attending the summer school organized at the University of Zurich.
Here is the teaser abstract:
Research is less about discovering the fantastic, as it is about revealing the obvious. Thus, the most important research challenge is not the fight against nature, but against our own entrenched assumptions.One way of fighting against our own assumptions is to expose them and get feedback. I advocate the practice of demo-driven research, a way of doing research that puts emphasis on presenting the state of research with any given chance and to any audience willing to listen. Strike that: it’s not just presenting, it’s demoing. It’s demoing the story of your idea. I want to get our hands dirty and make our ideas palpable and exciting enough to spark interest and raise helpful feedback.
You might think it is difficult or even impossible to demo what you do. It’s not, but it does require practice. You might think your subject is dry and not exciting for outsiders. It’s not, but it does require you to adopt a less obvious point of view.
In this course, we will take the time to tackle these points. And along the way, we will discover some more interesting side-effects of this approach.
Whitespace is the most basic variable of graphic design. We embrace it as soon as we see it. In particular, modern web pages offer good examples of whitespace usage. Yet, when we turn to the desktop, and in particular to development tools, whitespace tends to disappear, as if it would be a wasted space. There certainly are exceptions to the rule, such as LightTable, but to a large extent, the world of development tools is dominated by thick borders. I believe we can do better.
As an experiment, I started to work on a new look for Pharo and Moose that tries to maximize whitespace (I even chose a white whitespace). I started from the existing Glamour theme and removed color and lines where I did not see a good reason for having them.
My experiment is a primitive one: first, I started from a filled space; second, I only touched the theme of existing widgets without affecting the widgets themselves. Still, I believe it shows potential. Take a look at the pictures below (please try to ignore the thick gray buttons from the Pharo code browser).


You can reproduce the pictures by executing the following code in a recent Moose 4.8 image:
MooseImageSetupCommandLineHandler new
installFonts;
installAthens;
installGLMWhitespaceTheme.
To exploit whitespace at its full potential we need to make our widgets less dependent on lines and delimiters. During this experiment, I realized that our interfaces get often cluttered because we rely on fine-grained widgets that are designed to work independently from each other. As a consequence, to ensure their independence they have to be distinct which often leads to explicit delimiters. A way out of this trap is to approach the design globally and construct interfaces out of higher level patterns based on widgets that work tightly together.
Whitespace is a resource. We should fill it only for a good reason. Carefully.
The transition to Athens, the new vectorial canvas in Pharo, requires also a transition from bitmap fonts to free type fonts. There are quite a number of free fonts available these days, but they are distributed as files and this is less convenient for a Pharo image.
To fix the problem, I created a little project:
Gofer new
smalltalkhubUser: 'girba' project: 'FreeFonts';
package: 'FontInstaller';
load.
The project contains the FontInstaller class (did I mention it was small?) that imports TTF fonts from the file system and installs them in dedicated classes in the image.
Let’s take a look at an example. To use the FontInstaller all you need are the font files. In our example, I downloaded the Source Code Pro font and unzip the contents in the Fonts folder next to the Pharo image:
| fontDirectory |
fontDirectory := FileSystem workingDirectory / 'Fonts' /
'SourceCodePro_FontsOnly-1.017'.
FontInstaller new
installFromDirectory: fontDirectory / 'TTF'
url: 'http://sourceforge.net/projects/sourcecodepro.adobe/'
license: ((fontDirectory / 'LICENSE.txt') readStreamDo: #contents).
Executing this code results in the creation of several packages, each of them containing exactly one class. For example, the regular font ends up in the SourceCodeProRegular class that is placed in a package with the same name. Fonts can add a significant size to the image, and users might want to load only a selected set from a font family. Having a one font per package mapping makes it easier to customize loading.
The font is stored as a byte array in the fontContents, and it also has an install convenience method that stores it in the font provider. The license and url are placed in the class comment, while the name of the original file (used for traceability purposes) is stored in another method.
Following this scheme, I created a repository (http://www.smalltalkhub.com/#!/~girba/FreeFonts) with fonts from five font families:
For example, suppose you want to install the Source Code Pro Regular as a code font in your Pharo image. In this case, you need to load only the SourceCodeProRegular package and install it. The code might look like this:
Gofer new
smalltalkhubUser: 'girba' project: 'FreeFonts';
package: 'SourceCodeProRegular';
load.
(Smalltalk at: #SourceCodeProRegular) new install.
FreeTypeSystemSettings loadFt2Library: true.
StandardFonts codeFont: (LogicalFont
familyName: 'Source Code Pro'
pointSize: 10).
All in all, we got one step closer to adopting Athens.
What is your big idea? You do not have one? I do not believe that.
When most people think of the term "big ideas", they think of ideas that made it big. These are the BIG ideas.
But, I am more interested in those ideas that appear with big letters in your head. They make your eyes blink. These are the big IDEAS.
While BIG ideas capture the headlines, it is big IDEAS that capture the imagination. Just because you might not see right from start how an IDEA can become BIG, it does not make it less interesting. At least for you. And that is what matters.
So, what is your big idea?
We have ported Moose to Pharo 2.0. One of the nice additions in Pharo is the command line infrastructure that brings the opportunity to have a smooth integration with a continuous integration server like Jenkins.
Here is what we did for Moose. First, let’s start with the requirements:
- We wanted to use the latest Pharo 2.0 image and VM so that we can provide instant feedback
- We wanted to load the code that comes with ConfigurationOfMoose
- We wanted to run all the tests that come with our configuration
- We wanted to setup the image with Moose-specific settings and tools
The first requirement is supported out of the box via the bash scripts supplied by Pharo:
wget --quiet -qO - http://pharo.gforge.inria.fr/ci/script/ciPharo20.sh | bash
wget --quiet -qO - http://pharo.gforge.inria.fr/ci/script/ciPharoVMLatest.sh | bash
These scripts will download the latest image and VM and will unzip them in the current folder. Easy.
The second requirement is also supported nicely by the Pharo image:
REPO=http://www.smalltalkhub.com/mc/Moose/Moose/main
./vm.sh $JOB_NAME.image config $REPO ConfigurationOfMoose --install=development
What the script does is to trigger the config command line handler that corresponds to executing the code from ConfigurationCommandLineHandler. The CommandLineHandler hierarchy is a new addition to Pharo, and it essentially lets you customize from within the image the handling of command line arguments. In this case, the scripts loads the #development version of the ConfigurationOfMoose from $REPO, and at the end it saves the image.
The third requirement was only partially supported. The image comes with a TestRunnerCommandLineHandler that lets you specify something like:
./vm.sh $JOB_NAME.image test --junit-xml-output "Moose-.*"
However, Moose is a large project formed by multiple sub-projects, and we wanted to run not only the tests that are in Moose core packages, but also the tests that come with the sub-projects. To solve this problem, I created the MooseTestRunnerCommandLineHandler subclass that specializes the default test runner with a list of packages derived from the configuration:
MooseTestRunnerCommandLineHandler>>packages
| packages |
packages := Set new.
self addTestPackagesFrom: self mooseDevelopmentVersion to: packages.
self mooseDevelopmentVersion projects do: [ :each |
self addTestPackagesFrom: each version to: packages ].
^ packages
The code makes use of the infrastructure provided by the superclass and just lists all packages that are in the ’Tests’ group in the current configuration and in all directly referred configurations. Once this new command is available in the image, we can invoke it via the command line:
./vm.sh $JOB_NAME.image moosetest --junit-xml-output
However, still the question was how to get it in the image. Nothing simpler: I just added it in a package loaded by the configuration (the package is called Moose-Development-Tools). Thus, once the configuration is loaded, we can simply run the tests.
This final requirement can not be supported out of the box by Pharo given that it is highly specific to Moose. To support it, I created another command line handler that can install the settings:
activate
self cleanupWorld.
self installLogo.
self installGLMTheme.
self installGTInspector.
Smalltalk snapshot: true andQuit: true
This being achieved, we can run:
./vm.sh $JOB_NAME.image mooseimagesetup
That is it. With minimal shell scripting dependency we have achieved a rather complex setup of an image. For reference, here is the whole script:
wget --quiet -qO - http://pharo.gforge.inria.fr/ci/script/ciPharo20.sh | bash
wget --quiet -qO - http://pharo.gforge.inria.fr/ci/script/ciPharoVMLatest.sh | bash
wget --quiet -qO - http://pharo.gforge.inria.fr/ci/image/PharoV20.sources
./vm.sh Pharo.image save $JOB_NAME
REPO=http://www.smalltalkhub.com/mc/Moose/Moose/main
./vm.sh $JOB_NAME.image config $REPO ConfigurationOfMoose --install=development
./vm.sh $JOB_NAME.image mooseimagesetup
./vm.sh $JOB_NAME.image moosetest --junit-xml-output
zip -r $JOB_NAME.zip $JOB_NAME.image $JOB_NAME.changes PharoV20.sources
The resulting image can be found at: https://ci.inria.fr/moose/job/moose-latest-dev-4.8/