smalltalk

Posted by Jorge Silva

Nowadays, more applications are RIA oriented solutions. RIA (Rich Internet Applications) is a new kind of application with more advantages than traditional applications. It emerges as a combination of features offered by web applications and desktop applications. Even multimedia capabilities are covered because these environments have internal players.

RIA is a new concept that is growing with the advent of Adobe’s product Flex, Flash, OpenLaszlo and the Ajax platform.

The goal of this presentation is to show by example the way to integrate a pure Smalltalk back-end with a flexible front-end made it with Flex, using web services. In this way we:

  • Obtain Smalltalk capabilities to model my business domain

  • Give my application a rich and appealing interface in short time, with many problems already solved.

With this integration we look for best domain modeling techniques with Smalltalk, as reflective capabilities, dynamic typing and, in the other hand, to get the best communicative interface as RIA.

Finally, integrating in this manner is a perfect complement when developing applications not only web but desktop too, because you give the final product a unique dynamism thank to Smalltalk and a rich, friendly and interactive interface as Flex (o more generally RIA).

This presentation was presented at ESUG 2009. You can see the handouts here:

View more presentations from 10Pines.

Mutation testing

18 Sep 2009
Posted by Hernan Wilkinson

During the 70s, mutation testing emerged as a technique to assess the fault-finding effectiveness of a test suite. It works mutating objects behavior and looking for tests to “kill” those mutants. The surviving mutants are the starting point to write better tests. Thus, this technique is an interesting alternative to code coverage regarding test quality.

However, so far it is a “brute force” technique that takes too long to provide useful results. This characteristic has forbidden its widespread and practical use regardless new techniques, such as schema-based mutation and selective mutation. Additionally, there are no mutation testing tools (to our knowledge) that work on a meta-circular and dynamic environments, such as Smalltalk, so the compile and link time are the current technique's bottleneck.

This presentation will introduce the notion of mutation testing, analyzing its advantages and disadvantages with a Smalltalk-based tool. The tool uses the Smalltalk's dynamic and meta-programming facilities to notably reduce the time to get valuable output and help to understand and implement new tests due to its integration with the rest of the environment.

This presentation was presented at ESUG 2009. You can see the handouts here:

View more presentations from 10Pines.
Posted by Hernan Wilkinson

When talking about Smalltalk, there is definitively an over use on the possibility to add messages to Object class. It is so easy to do it, that people usually do it just to get something working fast, even if the coding is poor. There are a lot of messages (mainly #isXXX messages) that do not belong to Object and represent a bad design decision. Most of them are implemented there because they are "handy" and easily "reused". For example #-> or #assert: implemented in Squeak. Definitively not all objects should respond to them. Many of these messages are only used from "inside" the object, like the #assert: message.I would never write something like this: 1 assert: xxxx. Instead I would write: self assert: xxx witch clearly shows that #assert: is not a message that should be respond by every object, but only for those that represent assertions.

From my point of view, this issue is not an inheritance's problem per se, it is a miss-used of inheritance. If I try to use a hammer as a screwdriver, it is not the hammer's fault, but mine.
How is inheritance related with reuse? Well, that is an important question. Inheritance from the "pure theory" point of view, should not be use as a means of reuse. Reuse comes from good models, not from inheritance. Inheritance should be used as a tool to organize the knowledge that as a programmer, you are acquiring from the business domain. Classes should be use to represent the concepts and ideas you see in the business domain and inheritance should be used to organize how this concepts are related in an ontological way. So for example, an abstract class should represent an abstract concept wich defines the essential behavior that all the objects instances of its concrete subclasses should respond. Due to this relationship reuse comes aside, but reuse is not the means of inheritance. Subclassing just to reuse the implementation of a superclass is not a good design decision; it will bring problems sooner or later.

There has been an attempt to minimize the methods implemented in the Object class. For example on the Squeak distribution the class ProtoObject has been created. ProtoObject has only 35 methods whereas Object has 436! (on the basic image of Squeak version 3.10.x). Although ProtoObject has fewer methods, I do not agree with some of them. For example #ifNil: (and the like) and #tryNamedPrimitive: (and the like). Clearly these two messages (and their mutations) are implemented in ProtoObject as a means of reuse and not because every object should understand them. For example, why an account should respond #tryNamedPrimitive:? What does it mean to an account? A better design should have an object that represents the VM (for example) to which I can send the message #tryNamedPrimitive:. Of course the problem with this is how to access to this object and that is why that message is implemented in ProtoObject, because every object will inherit that method! And it will be so easy to use it as to write self tryNamedPrimitive: xxx. But thinking a little bit we can see that it is very easy to solve this problem. For example declaring this VM object in a global scope, so any object could send the message #tryNamedPrimitive: (and therefore reuse it), but not understand it. This brings me to the "rule" that says composition is a better tool to reuse.
The problem of using inheritance to reuse is that inheritance generates a strong coupling between the classes, its subclasses and its instances, where composition does not.

Inheritance generates an implementation and structural coupling between the classes and its subclasses (affecting directly their instances) where composition only couples an object with the composed one through the messages the former sends to the later. No implementation coupling, no structural coupling, just coupled by the message names one object send to the other, therefore a better design (the lower the coupling the better). This is the reason why good frameworks, black-box frameworks use composition over inheritance, where white-box frameworks being more immature, use inheritance to configure them.
This brings me to the idea of how hard should we stick to this, should we never "break" this rule? Well, I would not called it a rule but an heuristic, therefore it should be follow as much as possible, but we should also be pragmatic too. Sometimes subclassing to reuse while we are still learning about the problem is ok, is like making a white-box framework at the beginning. But we should never forget that our goal is a "black-box framework".
Other languages like Java do not suffer this problem and good designs can be implemented with it (although not so easily :-)). Java does not have this problem because Object class cannot be modified. This clearly shows that having too many methods in Object is not a problem of inheritance, but on how use it.

To summarize:

  • Inheritance should not be used to reuse, therefore having a lot of methods in Object class just because it is "handy" is a clear example of inheritance being used incorrectly. It generates unnecessary coupling which will make the system harder to change or refactor later.
  • Inheritance is just a tool; you can use it right or wrong.
  • There are other tools like composition and design techniques which solve the same problems and generate less coupling.
  • Reuse comes from good models, not from inheritance.