This post is part of an ongoing series about Affordances and Programming Languages.

Every object-oriented language provides a way to construct new instances of a class, perhaps by passing in some parameters. In many languages, there is a single, canonical way to do this.

In C++, we define one or more unnamed constructor methods:

C++ Constructors
class Point
{
public:
Point(double x, double y) :
x(x),
y(y)
{
}
Point(const Point& other) :
x(other.x),
y(other.y)
{
}
// ...
private:
double x;
double y;
};
Point p1(4.5, 42.1);
Point p2(p1);

We don’t actually need to define the second (copy) constructor here, because the C++ compiler will generate it for us, but I include it to show that there can be more than one constructor, as long as they all have unique signatures.

Ruby is similar, in that we define an :initialize method:

Ruby Constructor
class Point
def initialize(x, y)
@x = x
@y = y
end
# ...
end
p1 = Point.new(4.5, 42.1)

What if we also wanted to be able to create points using polar coordinates? In both Ruby and C++, we can no longer use the standard constructor mechanism, because we have no way to tell if we’re being passed rectangular or polar coordinates. In C++, both constructors would have the same signature, and in Ruby, we can only have one :initialize method.

In both of these languages, it is possible to use the Named Constructor Idiom:

C++ Named Constructors
class Point
{
public:
static Point rectangular(double x, double y)
{
return Point(x, y);
}
static Point polar(double r, double theta)
{
return Point(r * std::cos(theta), r * std::sin(theta));
}
// ....
private:
Point(double x, double y) :
x(x),
y(y)
{
}
double x;
double y;
};
Point p1 = Point::rectangular(4.5, 42.1);
Point p2 = Point::polar(4.5, 42.1);
Ruby Named Constructors
class Point
private_class_method :new
def self.rectangular(x, y)
new(x, y)
end
def self.polar(r, theta)
new(r * Math.cos(theta), r * Math.sin(theta))
end
def initialize(x, y)
@x = x
@y = y
end
# ...
end
p1 = Point.rectangular(4.5, 42.1)
p2 = Point.polar(4.5, 42.1)

In C++ and Ruby, the named constructor idiom is not obvious to new programmers. It’s not a hard idiom to learn, but it isn’t the “happy path” way to do things, so it isn’t as common in those languages.

In Smalltalk, however, all constructor methods are named constructors. For constructors that take no arguments, using #new is the convention, but it’s really just another method.

Our Point example would look like this in Smalltalk:

Smalltalk Constructors
Point class>>x: x y: y
^self basicNew initializeX: x y: y
Point class>>r: radius theta: angleInRadians
^self x: radius * angleInRadians cos y: radius * angleInRadians sin
Point initializeX: anX y: aY
x := anX.
y := aY
"..."
p1 := Point x: 4.5 y: 42.1.
p2 := Point r: 4.5 theta: 42.1

So, Smalltalk affords the use of named constructors, which makes them relatively more common in that language than in other object-oriented languages.