b; yourself. Addition>>left: anExpression "Setter for left" left := anExpression. Addition>>right: anExpression "Setter for right" right := anExpression. Addition>>putOn: aStream "An Addition object knows how to print itself" aStream nextPut: $(. left putOn: aStream. aStream nextPut: $+. right putOn: aStream. aStream nextPut: $). Object subclass: #Program instanceVariableNames: '' classVariableNames: '' package: 'Wikipedia'. Program>>main | expression stream | expression := Addition left: (Addition left: (Literal with: 1) right: (Literal with: 2)) right: (Literal with: 3). stream := ExpressionPrinter on: (String new: 100). stream write: expression. Transcript show: stream contents. Transcript flush. Go Go does not support overloading, so the visit methods need different names. A typical visitor interface might be type Visitor interface { visitWheel(wheel Wheel) string visitEngine(engine Engine) string visitBody(body Body) string visitCar(car Car) string } Java example The following example is in the language Java, and shows how the contents of a tree of nodes (in this case describing the components of a car) can be printed. Instead of creating print methods for each node subclass (Wheel, Engine, Body, and Car), one visitor class (CarElementPrintVisitor) performs the required printing action. Because different node subclasses require slightly different actions to print properly, CarElementPrintVisitor dispatches actions based on the class of the argument passed to its visit method. CarElementDoVisitor, which is analogous to a save operation for a different file format, does likewise. Diagram Sources import java.util.List; interface CarElement { void accept(CarElementVisitor visitor); } interface CarElementVisitor { void visit(Body body); void visit(Car car); void visit(Engine engine); void visit(Wheel wheel); } class Wheel implements CarElement { private final String name; public Wheel(final String name) { this.name = name; } public String getName() { return name; } @Override public void accept(CarElementVisitor visitor) { /* * accept(CarElementVisitor) in Wheel implements * accept(CarElementVisitor) in CarElement, so the call * to accept is bound at run time. This can be considered * the *first* dispatch. However, the decision to call * visit(Wheel) (as opposed to visit(Engine) etc.) can be * made during compile time since 'this' is known at compile * time to be a Wheel. Moreover, each implementation of * CarElementVisitor implements the visit(Wheel), which is * another decision that is made at run time. This can be * considered the *second* dispatch. */ visitor.visit(this); } } class Body implements CarElement { @Override public void accept(CarElementVisitor visitor) { visitor.visit(this); } } class Engine implements CarElement { @Override public void accept(CarElementVisitor visitor) { visitor.visit(this); } }