Planet Smalltalk

March 03, 2015

Clément Béra - Testing unsafe operations

For the runtime optimizer (Sista) I am working on, Eliot Miranda and I added new operations (we call them unsafe operations) in Cog’s interpreter and JIT compiler. Before testing them directly by running the optimizer and looking for crashes, I wrote tests to check that each unsafe operation works as expected. I’d like to discuss a bit the design of those tests in this post.

I’ll discuss a specific operation in the post, but all the unsafe operations are handled in a similar way. The operation I chose to described is called USmiLessOrEqual. This operation corresponds to <= but assumes the 2 operands are SmallIntegers, else the behavior of the instruction is undefined. The optimizer uses it only when it can ensure that the two operands are SmallIntegers.

What to test

To test USmiLessOrEqual, one could think I'm going to take an important range of integers and check that the result of each integer against each other integer within the range would give the correct answer. This approach looks nice, but it's clearly not what I want.

If one looks into the implementation of USmiLessOrEqual in the interpreter or in the JIT compiler, one would see that this operation forwards to the C operation <= for integers in the interpreter, and to the CPU instructions compare then jumpBelowOrEqual/jumpGreater in the JIT compiler. Hence, by testing a range of integers, one would actually test if the C operation <= for integers or the processor opcodes for comparison and branching actually works. I don't want to test the processor nor the C operations, I already trust them.

What I do want to test, however, is that the interpretation of the code and the machine code generated by the JIT compiler are correct for USmiLessOrEqual. For coverage, I don't want to test only a single case but I want all the branches to be taken. That means, for example, that I want to test all the possible branches used to generate machine code for USmiLessOrEqual in the code of the JIT compiler as well as all the branches that can be taken at runtime in the generated machine code.

Let's discuss how many possible branches there are when executing the code that performs the operation USmiLessOrEqual with the two operands a and b. I’ll discuss the different branches in the JIT compiler and machine code generated. I won’t discuss about the interpreter, but basically it has only a subset of the cases I describe.


a USmiLessOrEqual: b


pushTemp: 0
pushTemp: 1
callPrimitive: #USmiLessOrEqual

This operation expects the two operands to be integers. This is ensured by the runtime optimizer, and the behavior when a or b is not an integer is undefined, so we do not need to test the cases where a or b is not a SmallInteger. We’ll assume for the rest of the blog post that the two operands are SmallIntegers.

One could think there are actually two cases for this operation (we'll call them cases A):

Case A1: a <= b, so the operation should answer true.

Case A2: a > b, so the operation should answer false.

These two cases will definitely answer different results, they’ll definitely take two different paths in the virtual machine (one path pushing true on stack, the other pushing false) so they need both to be tested. But that’s more complex: if the operation USmiLessOrEqual is directly followed by a branchTrue or a branchFalse, the JIT compiler generates different machine code to quicken the branch execution.

The machine code for “a USmiLessOrEqual: b”, if not followed by a branch, looks like that:

cpu compare: a with: b
cpu jumpBelowOrEqual:
cpu push: false
cpu jump:
cpu push: true

There’s already a branch in the machine code, with one path pushing true and one path pushing false on the stack.

The machine code for “a branchFalse” or “a branchTrue” looks like that:

cpu compare: a with: false
cpu jumpEqual: (jump to false branch: )
cpu compare: a with: true
cpu jumpEqual: (jump to true branch: )
cpu callMustBeBooleanTrampoline
(code for false branch)
cpu jump: (jump over true branch)
(code for true branch)

There are three possible paths for a normal branch, depending on if a is true, false or a non boolean.

The JIT quickens the branch by directly using the branches of USmiLessOrEqual and not generating the push booleans as well as the comparison between booleans and true and false. USmiLessOrEqual answers true or false, so there’s no need to compile the mustBeBoolean fall back. The generated code for: “(a USmiLessOrEqual: b) branch” will then look like that:

cpu compare: a with: b
cpu jumpBelowOrEqual: (jump to true branch)
(code for false branch)
cpu jump: (jump over true branch)
(code for true branch)

We therefore needs to define three cases (we’ll call them cases B), depending on what follows USmiLessOrEqual:

Case B1 (no branch):
a USmiLessOrEqual: b

Case B2 (branchTrue):
(a USmiLessOrEqual: b) ifTrue: [ “some code” ]

Case B3 (branchFalse):
(a USmiLessOrEqual: b) ifFalse: [ “some code” ]

Cases A combined with cases B means that for the operation USmiLessOrEqual, we have 6 (2 * 3) different possibles cases to be tested.

In addition, the JIT compiler has to generate heavily optimized code (by carefully selecting the native instructions to generate) for unsafe operations as they’re present in optimized methods which are frequently used.

We’ll define two terms in the sense of Cog’s JIT compiler to explain briefly how instruction selection is performed.

A cpu constant means that the operand is conceptually a literal. I say conceptually because some literals (such as true, false, nil) are literals but are not present in the literal array of methods.

A cpu variable is a value that is in a register, spilled on stack or a cpu constant.

Let’s look again at the bytecode for “a USmiLessOrEqual: b”:

pushTemp: 0
pushTemp: 1
callPrimitive: #USmiLessOrEqual

The pushTemp: operations have generated in the JIT compiler code to put the operands in registers or to spill them on stack as they’re temporary variable. If the variable was a cpu constant, it would have just remembered the value and will generate the code for the cpu constant only when the constant will be used. For this operation, both operands are necessarily cpu variables.

Instruction selection depends on if one of the two operands is a constant or not. The generated code will first put values on stack in registers, then, if one operand is a constant, the JIT will generate a native instruction comparing a constant versus a register, else it will generate a native instruction comparing two registers.

The JIT compiler distinguishes 3 different operations at compilation time for USmiLessOrEqual:

Case C1: a is a cpu constant and b is a cpu variable

Case C2: a is a cpu variable and b is a cpu constant

Case C3: a is a cpu variable and b is a cpu variable

The JIT compiler backend assumes that if both operands are cpu constants, the operation would have been statically computed by the optimizer at compilation time. The operation would still work, it would just be optimized as if one of the operand was a cpu variable (putting one of the constant into a register first).

This means that in the machine code for USmiLessOrEqual, one has to test 18 cases (Cases A combined with cases B combined with cases C).

How to test all the cases

For convenience, I’m going to test this instruction image-side and not VM-side.

To test each case, I need to have a compiled method with the bytecode sequence I want to test. For example, I may want a sequence such as the two operands are cpu variables (not cpu constants) and the operation USmiLessOrEqual is followed by a branchTrue.

To do that, I created a method to instrument. Let’s look at its code:

"This method is instrumented in the tests. Do *not* edit it.

The instrumentation starts after the last temporary assignment.
Temporaries are result of message sends, so they're in registers
or spilled on stack, whereas literals are constants.

Code after the last temporary assignment is here to generate the
required literals and to let enough room in the bytecode zone of
the method for instrumentation."

| t50 t3 tArray tByteArray |
t50 := self get50.
t3 := self get3.
tArray := self getArray.
tByteArray := self getByteArray.
5 + 10 + #(1 2 3 4 5 6) first + #[1 2 3 4 5 6 7 8] first.
^ t3 + t50 + t3 + t50 + t3 + t50 + t3 + t50 + t3 + t50

In different tests, I will need 2 different integer constants, a byteArray and an Array in register or spilled on stack. This is why the method start by getting into temporary variables such values. The byteArray and the array are used in other tests than the one of USmiLessOrEqual. They’re used for tests on variable object access unsafe operations. I will not detail them here.

Let’s look quickly into the methods called:

^ 3

^ 50

^ #( 1 2 3 4 5 6 7 8 9 10 11)

^ #[ 1 2 3 4 5 6 7 8 9]

As explained in the method comments, the method will be instrumented after the last temporary assignment, in order to be able to use the values in temporary in the generated code.

Based on the original method’s code, I know that at the point where method instrumentation will start:

  • temporary variable number 0, t50, holds 50
  • temporary variable number 1, t3, holds 3
  • temporary variable number 2, tArray holds #( 1 2 3 4 5 6 7 8 9 10 11)
  • temporary variable number 3, tByteArray holds #[ 1 2 3 4 5 6 7 8 9]
  • literal number 0 holds 5
  • literal number 1 holds 10
  • literal number 2 holds #(1 2 3 4 5 6)
  • literal number 3 holds #[1 2 3 4 5 6 7 8]

The difference between values held by the literals and the ones held in temporary variables is that values held by the literals will be compiled into cpu constants, whereas values held by the temporary variables will be compiled either into an assignment to a register or spilled on stack.

Based on my knowledge on the current state of the method, I am going to use specific methods to generate the code I want. For example, if I want to generate the constant 5, I’m going to use:

genCst5: encoder
encoder genPushLiteral: 4

Now that I have everything at hand, let’s instrument the method. First I need to generate the bytecodes I want. I use a simple pattern (which may not be very well designed) where I hold in an array all the possible cases and the expected value. For USmiLessOrEqual, it’s cases description gives you:

1) Possible pairs of operands that answers true to USmiLessOrEqual (cases C, operands are cpu constants or not, I added a cases with 2 cpu constants as operands just in case):
{ self blockGenVar3 . self blockGenVar50 } .
{ self blockGenVar3 . self blockGenCst5 } .
{ self blockGenCst5 . self blockGenVar50 } .
{ self blockGenCst5 . self blockGenCst10 }

2) This is combined with the possible results answered (Cases A). Basically I’ll check that operand1 USmiLessOrEqual: operand2 answers true, and the opposite, operand2 USmiLessOrEqual: operand1 answers false:
{ self blockGenSuccessively: truePair . true } .
{ self blockGenSuccessively: (self invertedPair: truePair) . false }

3) Lastly I combined them with possibility of being followed by branches. For this purpose I used branches that push different integers on stack to check the result. For instance:

^ [ :encoder |
encoder genBranchPopFalse: 2.
self genCst5: encoder.
encoder genJump: 1.
self genCst10: encoder. ]

Here, if value on stack is true, there will be 5 on stack after the branch, else there will be 10. This bytecode sequence is equivalent to ifTrue: [ 5 ] ifFalse: [ 10] with the receiver of ifTrue:ifFalse: on stack.

Here are the different branch cases to combine (cases B), first arg is the block that generates or not the branch, the other is the expected result:
int := self jumpBlockResult: boolean.
{ self emptyBlock . boolean } .
{ self jumpFalse10Else5Block . int } .
{ self jumpTrue5Else10Block . int }

Ok. So for USmiLessOrEqual, we’re going to generate 24 (2 * 3 * 4) bytecode sequences to test. Let’s generate the first one:

  • The two operands are in registers or spilled on stack{ self blockGenVar3 . self blockGenVar50 }
  • The result of the operation will be true (3 <= 50)
  • The operation is not followed by a branch

I get the bytecode sequence:
65 pushTemp: 1 "holds 3"
64 pushTemp: 0 "holds 50"
248 243 7 callInlinedPrimitive: USmiLessOrEqual
92 ReturnTop

Note that we added a returnTop at the end to be sure that the method will return the result to test afterwards. We can’t let the original bytecode that remains in the compiled method be executed after our hand-written bytecodes.

Let’s now instrument the method:


On the figure, on the left is the original source code and bytecodes of the method. After the last temporary assignment, we override the bytecodes and write down our bytecode sequence. We use an instrumented method that is long enough so there’s enough room to correctly write down the test-generated bytecode.

Then, we need to void the method Cog VM state. The method may already be compiled to machine code with another bytecode sequence (from the previous tests for example, as they’re typically all run in a row). Voiding the Cog VM state asks the VM to flush its machine code state for the method to flush this kind of dependencies.

method voidCogVMState

Now we can run the method. I run it several times to have both the interpreter and the machine code results:

| res |
res := { nil . nil }.
res at: 1 put: self runMethodToInstrument. "interpreter result"
1 to: 5 do: [ :i | self runMethodToInstrument ]. "heat up the JIT"
res at: 2 put: self runMethodToInstrument. "jitted result"
^ res

Lastly, I can compare the two results I collected from the runtime to the expected result. The operation USmiLessOrEqual is fully tested !

Now, one needs to understand that such tests are not safe: if the test fails, sometimes one will just have an assertion failure, but in most cases one has a segmentation fault to debug in the VM simulator. I could run the test directly in the VM simulator to avoid such issues, but the VM simulator takes a while to start-up and to run any code. There is no perfect solution, but at least I have a way to test that the code I wrote in the JIT compiler is correct (though the real coder doesn’t test, only the ones who fear are testing ;-) )

March 02, 2015

Benoit St-Jean - PhlappyBird

Pharo vous propose maintenant un clone du jeu Flappy Bird, PhlappyBird.

Classé dans:Pharo, Smalltalk Tagged: Pharo, Smalltalk

Benoit St-Jean - Smalltalk en vrac (12)


Camp Smalltalk Ottawa en juin 2015.


Teapot 0.9 est arrivé!

TrashCan : une corbeille pour récupérer vos méthode supprimées!

MultiDictionary : un nouveau type de collection, une structure de données de plus à votre arsenal!

StNER : on peut dorénavant interagir avec le Standford Named Entity Recognizer.


Une démo de Roassal sur VisualWorks.

Classé dans:Pharo, Seaside, Smalltalk, VisualWorks Tagged: Camp Smalltalk, MultiDictionary, Ottawa, Pharo, Roassal, Standford Named Entity Recognizer, StNER, Teapot, TrashCan, VisualWorks

Benoit St-Jean - WebFileBrowser

WebFileBrowser, un interface web (Seaside) pour gérer vos fichiers.

Classé dans:Pharo, Seaside, Smalltalk Tagged: fichiers, Pharo, Seaside, Smalltalk, web

March 01, 2015

Torsten Bergmann - TrashCan of removed methods

Torsten Bergmann - Teapot 0.9 for Pharo

A new version of Teapot was released: Teapot 0.9!/~zeroflag/Teapot

It still less than 700 Lines of code and a nice micro web framework for Pharo. You need to load "ConfigurationOfTeapot-AttilaMagyar.6", if you are on Pharo 4 you can directly load it from the configuration browser.

 As this framework is very easy to use (it bases on the concept of URL routes): you can serve dynamic or static HTML pages, JSON and other web related stuff easily from Pharo. It is nice especially if frameworks like Seaside are too heavy for your web application needs.

Torsten Bergmann - AST Link Annotation Infrastructure

Pharo 4.0 also includes some more AST Link Annotation Infrastructure. Read more.

Torsten Bergmann - Language Detection using Pharo

Language Detection API is a service to query the language of a given input text. You can use it from Pharo. Read more.

Pharo Weekly - A simple AST-transformer plugin architecture for Opal…

A simple AST-transformer plugin architecture for Opal…

-> subclass OCCompilerASTPlugin
-> implement #transform e.g.

| rule |
rule := RBParseTreeRewriter replaceLiteral: 42 with: ‘meaning of life’.
rule executeTree: ast.

The plugin can be activated *per class hierarchy* by overriding #compiler

“the example plugin is active for this class”
^super compiler addPlugin: ASTPluginMeaningOfLife.

or of course for a single compilation:

(Smalltalk compiler addPlugin: ASTPluginMeaningOfLife) evaluate: ’42’

For review here:


Smalltalk Jobs - Smalltalk Jobs – 3/1/15

  • Leinster, Ireland (possibly Dublin) – Software Developer Advisor at Dell
    • Required Skills:
      • Unix/Linux
      • Excellent knowledge in GEMSTONE and Oracle databases. (Please do not forward any CVs with no experience in GEMSTONE and Smalltalk)
      • Smalltalk
      • Excellent SQL and/or PL/SQL knowledge
      • Good MQ series and SFTP knowledge
      • Java, HTML & JavaScript Knowledge
      • Good understanding of ITIL practices
      • Fluency in English language
    • Wanted Skills:
      • Familiar with various application architecture, from client-server to multi-tier web application architecture
      • Working with large scale transaction and reporting applications
  • Buenos Aires, ArgentinaKapital Financial Developer – Associate (Job ID 150021865) at J.P. Morgan
    • Required Skills:
      • Application development using Object Orientated technology (Smalltalk, Java, C#, Python etc), preferably on large scale systems.
      • Previous experience of Financial Services, preferably in Investment Banking.
      • Good communication and organizational skills, build good client relationships and takes ownership of issues.
      • Self motivated to learn and ask questions to produce the best technology solutions
Good luck with your job hunting,
James T. Savidge

View James T. Savidge's profile on LinkedIn

This blog’s RSS Feed

Filed under: Employment Tagged: jobs, Smalltalk, Smalltalk jobs

Benoit St-Jean - C’est une langue belle…

LanguageDetection : un outil Pharo pour détecter la langue !

Classé dans:Pharo, Smalltalk Tagged: détection, langue, Pharo, Smalltalk

Pharo Weekly - Language Detection API available in Pharo


Language Detection API is a service to query the language of a given input text. You will need to register an API key in the web site to use the service.

This client enables to use the service from Pharo Smalltalk. The output is an object containing the language code, a confidence score and a ‘is reliable’ boolean value.

Installation and usage details in the following post:



February 28, 2015

Hernán Morales Durand - LanguageDetection API Client in Smalltalk


Language Detection API is a service to query the language of a given input text. You will need to register an API key in the web site to use the service. This client enables to use the service from Pharo Smalltalk. The output is an object containing the language code, a confidence score and a 'is reliable' boolean value.


Inside Pharo, open the Configuration Browser and select LanguageDetection, then Install. Or evaluate the following expression:

Gofer it
smalltalkhubUser: 'hernan' project: 'LanguageDetection';
configurationOf: 'LanguageDetectionAPI';


| ldClient |
ldClient := LDApiClient new.
query: 'Des perles de pluie venues de pays où il ne pleut pas';
query: 'Een enkele taal is nooit genoeg ';
query: 'buenos dias señor';

February 27, 2015

Torsten Bergmann - Twins in Pharo

Torsten Bergmann - FOSDEM

If you were not able to participate in FOSDEM here is something to look at:

Torsten Bergmann - Videos and Slides from PharoDays

If you were not able to participate in PharoDays here is something you should look at:

ESUG news - Camp Smalltalk Ottawa June 2015

"Join us at Camp Smalltalk Ottawa 2015

If you enjoy programming Smalltalk or you're interested in promoting Smalltalk, come join us in Ottawa from June 12th to 14th for Camp Smalltalk Ottawa. Present your latest projects in lightning talks and chat with other Smaltalk developers.

The theme of this Smalltalk is "Send a Message". We'll be doing things to tell the world about Smalltalk and why we use it. All talks will be recorded and posted on YouTube. We'll interview Smalltalk developers for the Smalltalk Reflections podcast. We'll be developing frameworks for Smalltalk contests. More information will be available soon as we finalize the details.

On Friday June 12, we'll meet at the Ottawa Public Library to mingle and chat. Saturday and Sunday will be at the Shopify headquarters on Elgin Street."

Pharo Weekly - CompiledMethod got a Twin


In 40516 there is now a strange, but rather powerful mechanism for CompiledMethod: the Twin.

What does that do?

you can call on a method #createTwin

(ReflectivityExamples>>#exampleMethod) createTwin.

after this, the CompiledMethod has a high-level representation (the AST) attached that itself references the CompiledMethod
(they form a twin).

(ReflectivityExamples>>#exampleMethod) reflectiveMethod

The fun thing is now that one can install either in the class. Call #invalidate to make sure the reflective method is installed.

ReflectiveMethod implements #run:with:in: which calls a compilation hook (too re-create from the AST) and then installs that in the
method dict and then executes the method:

(ReflectivityExamples>>#exampleMethod) createTwin.
(ReflectivityExamples>>#exampleMethod) invalidate.
self assert: (ReflectivityExamples>>#exampleMethod) class = ReflectiveMethod.
self assert: ReflectivityExamples new exampleMethod = 5.
self assert: (ReflectivityExamples>>#exampleMethod) class = CompiledMethod.

Which means that this gives us an in-image, on-demand JIT compiler AST->Bytecode. In 50 lines of code.

e.g. try on Morph:

Morph methods do: #createTwin.
Morph methods do: #invalidate.

Counting which twin is installed shows us the working set of Morph:

(Morph methods select: [ :each | each class = CompiledMethod ]) size

some 330 method out of nearly 900….

So what can one do with this? In essence this turns the AST into a reflective representation for Methods
(if you care to set up twin creation + invalidation correctly).

What will this allow us to do? stay tuned…


Pharo News - Slides and Videos Pharo Days 2015

<p>The slides and videos for Pharo Days 2015 are now online:</p> <ul><li> <a href="">Slides on SlideShare</a></li></ul> <ul><li> <a href="">Slides (PDF)</a></li></ul> <ul><li> <a href="">Videos</a></li></ul>

Pharo News - Slides and Videos Pharo Days 2015

<p>The slides and videos for Pharo Days 2015 are now online:</p> <ul><li> <a href="">Slides on SlideShare</a></li></ul> <ul><li> <a href="">Slides (PDF)</a></li></ul> <ul><li> <a href="">Videos</a></li></ul>

Torsten Bergmann - Roassal visualization on VisualWorks

The Roassal visualization engine not only works on Pharo but also VisualWorks:

February 26, 2015

Pharo Weekly - The essential: many improvements daily

14990 MonitorDelay>>#signalLock:afterMSecs:inMonitor:queue: should return MonitorDelay object

14984 Improve protocol names in ComposableModel and subclasses

14996 LinkedList>>#select:thenCollect: is slow

14995 script: Pragma is also acceptable for non-unary methods

14991 ExampleSlotWithDefaultValue: allow default to be set in definition

14992 ScriptLoader: code path of Integrator needs to delete scripts, too

14982 Improved support for unknown bytecode

– Scriptloader test

14868 Unbound Globals (XBytecodeGenerator)

14989 Improve and simplify BlockClosure benchmarking

14901 Matrix>>extent is missing

14359 ScriptLoader linesOfCode ==> 108740

14981 Fixes for SistaV1 bytecode set (part 2)

14987 ShoreLine Reporter version 0.1.2

14983 MorphicEventDispatcher>>#dispatchEvent:with: needs to nil morph instance

14862 /is/this/possible? asFileReference size

13004 Key Mapping should have a GUI interface to show all definitions

14965 #class:instanceVariableNames: not needed in OldClassBuilderAdapter

14980 Method missing to decode bytecode set

14979 Fixes for SistaV1 bytecode set

14964 deprecated #anonymousSubclassOf:

14975 Generate initialize methods should be in initialization protocol

14967 MCFileTreeRepository does not implement #versionInfoFromVersionNamed: correctly

14954 load new configuration 2.9 (more morphic support)

14955 load new TxText configuration 2.8.3 (more morphic support)

14960 Extend Duration with a human readable print option and some related accessors

14963 addInstVarNamed: should use addSlot:

14970 TheManifestBuilder>>removeManifestOf:(manifest is shadowed)

14914 #initializeSlots: should not skip hidden slots

14942 Delay refactoring (part 2b) – clean out newCodeEnabled wrappers

14631 DNU GLMThemeIcons >> overlayModificationIconContents

14941 isObsolete returns true for anonymous classes

14728 NBFFICalloutAPI option WinUnicode is not prefixed with opt, as all the other options

14961 instantiation is misspelled in PharoSyntaxTutorial

14947 Missing allChildrenMatching:

14971 MorphicTransform: Better Argument Names

14949 String>>asPackage

14957 Number>>#percent

14958 DateModel>>#initializeWidgets error

14934 Load new Athens configuration 2.8

This fixes the following issues

case 14723 Make StrikeFonts working in Athens (font size related)
case 14710 AthensCairoCanvas setAA not implemented
case 14799 AthensCairoCanvas draws in empty rectangles

14935 Load new configuratoin of TxText 2.8.2

with the following fixes
case 14778 TxAthensLayoutView should not impose a x offset minimal value
case 14774 TxHighlightRenderer shapes badly computed when scrolling horizontally
case 14719 TxTextLayout startPosition and TxTexLayoutView scrolling management
case 14715 TxTextEditorMorph modifies dragged morph position
case 14687 TxTextPosition moveDown: can only move one line down

14940 timeToRunWithoutGC broken

14946 Replace senders of String>>#subStrings: in Tool-Finder

14937 better comments and test for Matrix

14060 MNU: receiver of “stepToCallee” is nil

14943 really deprecated #leap

14897 Date isLeapYear equally defined in Dates superclass

14483 Extract the PragmaCollector into its own package

14064 Improvements to checking termination of processes

2649 dont let an empty Rectangle #intersects:

14938 missing addModelItemsToWindowMenu: in WindowModel

14939 example for SearchableList does not work (MNU)

4795 Horizontal wheel events

14905 Missing test and clean code for SmalltalkImage>>#extractMinusParameters

14852 TTLCache should allow for custom TTLAssociation that can compute their own expiration

14869 Repeated methods in Trait Composition

14904 Slot: hand the correct class to slot in #buildNewClass

14899 add addSlot in testClassRespectsPolymorphismWithTrait

14874 WorldState>>#interCyclePause: failed

14895 Class Variable Refactoring -> Add produce error when pressing escape on dialog

14892 Slots: when class is created, #installingIn: is not called

14893 Slots: allSlots should filter hidden slots

14888 Matrix>>rows:columns arguments are unclear

14894 SimpleSwitchMorph lost onColor: aColor

14891 Slots: add #addSlot and #hasSlots

Pharo Weekly - How Far We’ve Come!

Sean De Nigris (an early pharo adopter) wrote the following:

It was so much fun watching the Pharo Days videos! Thanks for recording them
and I hope to be there next time :)

(note videos are here

Somewhere halfway through the playlist, it hit me how easily I was
downloading all the projects and images being talked about. I was
copy/pasting one-line Metacello scripts out of github READMEs, clicking in
the Configuration Browser, or downloading the latest code from CI – and it
all “just worked”!!!

Remember not too long ago when we were passing around custom scripts to load
multiple dependent packages, and explaining to outsiders that “we don’t need
github because Smalltalk invented SCM” (or whatever) while we created the
future invisibly, hidden away from the rest of the world?

After laying down so many building blocks (like FileSystem) that take the
system out of the way of creative expression, it is exciting to finally be
tackling some of the high-impact things… you know the ones we’ve been
avoiding… like Morphic, development tools, and the text editors.

And the steady streams of new talent and funding seem likely to keep the
successes coming.

So CONGRATULATIONS, Pharo Community!!!! We deserve it.

Now get back to work – we’ve got a future to create ;)

Pharo Weekly - GADM package for Pharo

I am pleased to announce the release of the GADM package for Pharo. GADM is a high-resolution spatial database of the location of the world’s administrative areas for use in Geographical Information Systems (GIS) and similar software.

The following post contains details about the release:

If anyone wish to extend it with the polygon data included in GADM, please feel free to request repository permission to upload changes.



Pharo Weekly - Pharo interface to the Stanford Named Entity Recognizer


I am announcing the release of StNER. StNER provides a Pharo interface to the Stanford Named Entity Recognizer (NER). (

Installation and usage details are described in the following post:



PS: Only tested in Windows 8.1

February 25, 2015

Hernán Morales Durand - StNER: Interface to the Stanford Named Entity Recognizer


StNER provides a Pharo Smalltalk interface to the Stanford Named Entity Recognizer (NER). The Stanford NER recognizer is an implementation of a Named Entity Recognizer, used for tagging raw text which is a central task in Information Retrieval and Natural Language Processing. The input is a sequence of words in a text, and the NER classifier - using already trained data - try to recognize typically three types of "Named Entities" (NEs) : NAME, LOCATION and ORGANIZATION (more classes exists). The output is the tagged text in some common tagging format for tagging tokens. This recognizer works better on input more similar to the already trained labeled data sets (muc6, muc7, conll2003), however there are reports to use it with tweets, and you can retrain to recognize entities for your particular needs.

To recognize text in other languages, for example, Chinese, German, or Spanish, a different classifier (in this context a .tgz file) can be used (see NLP Stanford Demo).


  • Java is required to run the server locally.
  • Download the Stanford NER packages.
  • Inside Pharo, open the Configuration Browser and select StNER, then Install. Or evaluate

    Gofer it
    smalltalkhubUser: 'hernan' project: 'StNER';
    configurationOf: 'StNER';

Launch the server

  • Start (from Smalltalk) the (Java) server using the StNER Smalltalk server interface. For example, to start the server with default parameters in Windows:

    StSocketNERServer new
    stanfordNERPath: 'c:\stanford-ner-2015-01-30\';
  • Query an input text using the StNER Smalltalk client interface.

Server Settings

Providing path location is mandatory. If no host or port is supplied, defaults to:
  • localhost (,
  • port 8080
  • JVM memory 1000m.
  • output format: inlineXML

You can configure the server with the following taggers:
  • 3 class NER tagger that can label: PERSON, ORGANIZATION, and LOCATION entities. (#setEnglish3ClassTagger)
  • 4 class NER tagger trained on the CoNLL 2003 Shared Task training data that labels for PERSON, ORGANIZATION, LOCATION, and MISC. (#setEnglish4ClassTagger)
  • 7 class NER tagger trained only on data from MUC (#setEnglish7ClassTagger): TIME, LOCATION, ORGANIZATION, PERSON, MONEY, PERCENT, DATE.

Client Usage

To tag text you can use the #tagText: method as follows:

StSocketNERClient new
tagText: 'University of California is located in California, United States'
and the output will be:

'University of California
is located in California,
United States' "
Another example including PERSON tagging:

StSocketNERClient new
tagText: 'Argentina President Kirchner has been asked to testify in court on the death of Alberto Nisman the crusading prosecutor who had accused her of conspiring to cover up involvement of Iran'
which results in:

'Argentina President Kirchner has been asked to testify in court on the death of Alberto Nisman the crusading prosecutor who had accused her of conspiring to cover up involvement of Iran'
Parse text to in-line XML

StSocketNERClient new
parseText: 'University of California is located in California, United States'
results in a Dictionary of Bag's with occurrences of tagged classes.

Francois Stephany - Android Google Study Jams Brussels

audience at the Study Jam

The Google Developer Study Jams Android Fundamentals is a worldwide study group organised by Google and Udacity. The principle is quite simple: people follows an online course on Udacity to become Android developers. Events are locally organized weekly so participants can share their problems, ideas and solutions.

The official website describes it perfectly:

Study Jams are an opportunity for students to receive free, in-person guidance and tutoring on the Udacity course in a fun classroom environment. Study Jam sessions are designed around the Udacity course structure, with a weekly session following each lesson (6 lessons), plus two additional weeks for completing and sharing course final projects. Students are expected to come to the Study Jam sessions having completed that week’s Udacity lesson online, so that the Study Jam time may be used to review key concepts, address questions, and work on individual projects. The live community atmosphere and tutoring is designed to help students achieve deeper learning around the concepts taught in the course.

The Google Developer Group of Brussels is organising the local event in Belgium in the beautiful working space Co.Station, next to the central station.

Friedger Müffke and I are the two tutors for the Brussels local group. We try to expand the content of the online course with some of our experiences. We also try to give the student a feeling of the Android ecosystem.

audience at the Study Jam

The Android fondamental course does not use any external libraries. Even for HTTP calls. Instead they ask the students to copy/paste a huge gist containing the code doing the call. I thought that it would have been nice to show the students how to include an external library.

We started to follow that path and we talked quite a lot about libraries that I find useful. Here are some of them:

  • OkHTTP, HTTP calls should be easy.
  • GSON, JSON manipulation.
  • Retrofit, Ideal if you want to interact with a REST+JSON webservice. Beware that it can feel a little bit magic, it's hard to know what's going on. It relies on OkHTTP and GSON to do its job.
  • EventBus, an EventBus for your application. It lets you send event throughout your application. *Otto, basically the same as EventBus. Try both and keep the one you prefer.
  • Timber, small librarie that makes it easier to deal with logs.

You can find all those library in the jcenter maven repository.

Many of those libraries are edited by Square. Check their open source listing for more goodness.

Another small tool that we covered (but that I haven't tested in real life yet) is Retrolambda. You integrate it into your build chain and it lets you write lambda expressions with java 7. Nobody knows when (or even if) Java 8 will be available on android, so this tool can come handy if you really want to use those lambdas.

We also mentioned Genymotion, a fast android emulator based on VirtualBox.

Someone has a question about Context last week. This article is quite good to grasp the differences between the different available contexts.

Last but not least, we talked about Android Weekly, a very nice newsletter that collects all the news from the Android ecosytem. It is a great way to discover new libraries and tools.

Thanks a lot to Anne Collet from Le Wagon Brussels to host us in Co.Station.

If you're interested and want to participate, join the Google Developer Group Brussels on Meetup!

Benoit St-Jean - GADM

GADM est une base de donnés spatiales de grande précision renfermant des informations spatiales, géographiques et de géolocalisation.  Au plus grand plaisir de tous, GADM est maintenant accessible à partir de Pharo!

Sur un tout autre sujet, savez-vous ce que représente le nombre 80738163270632 dans l’adresse du blogue de Hernan ( ?  La réponse dans quelques articles!

Classé dans:bases de données, Pharo, Smalltalk Tagged: base de données, GADM, géographie, géographique, géolocalisation, GIS, Pharo, Smalltalk, spatial, spatiales

Torsten Bergmann - GADM: Access to Global Administrative Areas in Pharo

Hernán Morales Durand announced the release of the GADM package for Pharo Smalltalk. GADM is a high-resolution spatial database of the location of the world's administrative areas for use in Geographical Information Systems (GIS) and similar software. Read more and try out here.

Hernán Morales Durand - GADM: Access to Global Administrative Areas in Smalltalk


GADM is a high-resolution spatial database of the location of the world's administrative areas for use in GIS and similar software. GADM is freely available for academic and other non-commercial use. The data contained in GADM was collected from spatial databases provided by NGO, National Governments, and/or maps and list of names available on the Internet (e.g. from Wikipedia).

Administrative areas include: countries, provinces, counties, departments, etc. up to five sublevels, which cover most boundaries in the world. For each level it provides some attributes, foremost being the name and in some cases variant names. GADM can also be used to extract polygon shapes for visualization, for example to build choropleth maps for regions. The GADM package includes the raw data in CSV format, which I parsed to build a browseable GADM world tree, allowing off-line access to the GADM database in a hierarchical fashion with objects, without need to perform on-line queries for basic requests. A hierarchical tree can be used to build a toponym browser for example.


From within Pharo 3, or Pharo 4 you can use the Configuration Browser, or evaluate the following expression:

Gofer it
smalltalkhubUser: 'hernan' project: 'GADM';
configurationOf: 'GADM';

Usage Examples

" To access to the whole World (as seen by GADM), evaluate "
GADMWorldTree root.

" Access country Lithuania "
GADMWorldTree @ 'Lithuania'.

" To acces the Part (Partido: spanish) where I am living:"
GADMWorldTree @ 'Argentina' @ 'Buenos Aires' @ 'La Plata'.

" You want to know which type of region is Los Angeles "
(GADMWorldTree @ 'United States' @ 'California' @ 'Los Angeles') typeName " 'County' "

" You wish to list all subregions in San Marino "
(GADMWorldTree @ 'San Marino') nodeNames
" a SortedCollection('Acquaviva'
'Borgo Maggiore'
'San Marino'
'Serravalle') "