Elegance in Programming


In the latest Pharo release (Pharo 5.0) there’s an optional library/plugin called StateSpec.  This is the author’s description:

StateSpec is an object state specification framework. It describes particular object states by first class specifications. For example, there are SpecOfCollectionItem, SpecOfObjectClass and SpecOfObjectSuperclass. They can match and validate given objects. In case when an object doesn’t satisfy a defined specification you will get a failure with detailed information about the state problem.

                spec matches: anObject.

               spec validate: anObject. “it returns validation result which can be success or particular failure” 

To easily create specifications and validate objects by them StateSpec provides two kinds of DSL: ‘should’ expressions and ‘word’ classes.

The first allows you to write “assertions”:

                1 should be: 2

                1 should equal: 10

The second allows you to instantiate specs by natural readable words:

                Kind of: Number

                Instance of: String

                Equal to: ‘test’

Oddly, the way that the words DSL works is very reminiscent of how FORTH works, ‘WORDS’ are the main structure in FORTH, they act as both objects and messages (although, since ‘message’ is an object, in a certain sense a message is simply an arbitrary object without content – in FORTH, ‘WORDS’ may or may not have content).

In any case, I was looking at the source, to see how difficult it would be to implement in Eclipse with EMF (EMF to write the DSL’s, since it includes the two DSL’s).   A method called specComposer in an abstract class specObjectState applies the spec to the particular type of object the subclass deals with, which can be in Smalltalk, either of the DSL’s, or a mixture of any of the three.  As a result, the specComposer has to be pretty generic (the subclasses include specCollection, specCollectionItem, etc.).  The following is the code to handle NOT in any expression:

Not

^ self copy

invert;

yourself

The code for the invert and denial messages implementations look like this:

invert

denial := denial not.

self invertChildren

 

denial: aBoolean

denial == aBoolean

ifTrue: [ ^ self ].

self invert

invertChildren is an abstract method that needs to be implemented, since it will be different depending on the object type.  This is the implementation in the subclass SpecOfBlockState:

invertChildren

super invertChildren.

requiredFailure invert

That for me is what elegance in programming looks like.  Everything is as simple as possible (but not simpler), it’s properly composed (and decomposed).  NOT a 1200-line script dumped into whatever language structure is available.

Advertisements

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s