Moldable Object

Context

You are ready to start the process of creating an explainable system, either from scratch, or based on some existing software or data.

Problem

Where do you start coding an explainable system?

Forces

As a programmer, you want to quickly get feedback about the code you are writing.

Programmers are used to first writing code in a code editor, then compiling and running (or testing) it.

Code editors provide you feedback about the source code, not the live instances.

Solution

Start coding by inspecting moldable object , that is, a live instance of the class you are coding, not in a code editor.

Then you can incrementally add behavior to the object, and create custom views as you code to make the new behavior visible.

Moldable development is about making systems explainable with the help of custom tools, which means that you need to start the process by asking questions that you want to answer.In most cases you can't immediately start building the custom tools, but rather you need to explore the domain objects to understand how to answer the question. Once you know how to get the answer, you can turn the exploration steps into a custom tool.

Starting with a live object means that you can immediately start the exploration process. Turning the exploration of an object into a custom tool is the process of molding it, hence we call it a “moldable object.”

How do you obtain a moldable object?

You already have a class: create a Project Diary notebook page containing a code snippet to create an instance of the class, and start from there.

You don't have a class: start instead with a code snippet that instantiates an empty class, and then prototype the behavior.

You have a test case: turn the test case into an Example Object and start from there.

You have some data: wrap the data as a Moldable Data Wrapper

Steps

You can inspect a moldable object in many ways.

You can inspect the result of evaluating a Smalltalk expression in a Playground. This can be a code snippet in a Lepiter page, or a Playground associated with another tool, such as an Inspector or Coder.

GtLudoGame new 
  

If you inspect the code above, you will see at the bottom of the inspect a handle to lift and expose yet another playground. (You can also see the handle at the bottom of the next example below.)

You can also click on an Inspect Object button in many tools, for example at the top right of the Inspector of the Ludo Game.

Another way to get an instance is to inspect a runnable method. This can be a unary class-side method, such as FileLocator>>#imageDirectory imageDirectory ^ self origin: #imageDirectory

Another kind of runnable method is an Example method, such as GtMemoryGameExamples>>#chooseMatchingPair chooseMatchingPair <gtExample> | game | game := self fixedGame. game chooseCard: (game availableCards at: 6) . game chooseCard: (game availableCards at: 11) . self assert: game visibleCards size equals: 14. self assert: game isOver not. ^ game

You can also get to a live instance by navigating to it from another Inspector instance. Click, for example, on one of the cards of the previous example.

If the class you want to work with does not yet exist, you can still inspect a moldable object with the help of a fixit . From the code snippet below, we can inspect an instance of a class MyStackMachine, after clickibg on the wrench icon and selecting the Create class fixit.

sm := MyStackMachine new.
  

Once you have a moldable object, you can incrementally add behavior and custom views, and immediately see the effect on the live instance.

Now you can use the Playground at the bottom of the Inspector to prototype the new behavior. They key point is that the Playground is bound to the environment of the moldable object, so you have access to self and all the slots of the objects. Once you have working code, you can apply an Extract method refactoring, or you can copy-paste the code to a new method.

You can either directly add a new method in the Meta view in the Inspector (see the GtMemoryGame example above), or click on the Browse class button to open an Coder view.

Consequences

Instead of writing code in a text editor in the context of the source code of a class, you are always working in the context of a live object, whose behavior can be immediately explored. Instead of writing hypothetical code that you must afterward test, you start by prototyping code, and then extracting new behavior. Instead of trying to program custom tools in a vacuum, you first explore and prototype answers to questions, and then extract the code you need to create a custom tool.

Related patterns

If you are modeling external data, you can create a moldable object from a Moldable Data Wrapper.

Once you have a moldable object, you can mold it from a Contextual Playground.

Known uses

In Smalltalk, it is a common practice to modify code in the debugger, and continue execution. From the debugger one can explore the state and behavior of live objects on the stack, evaluate code snippets to test hypotheses, modify the compiled methods on the stack, and continue running the program.