Functions and corresponding methods with the same name in Shed
Thursday 4 October 2012 20:47
In Shed, we sometimes define functions that usually delegate to a method,
but also have some special cases or defaults if that method isn't implemented.
For instance, the function represent should produce a string
representation of an object. If the argument implements the method
represent, it calls that method. Otherwise, it uses the name
of the class of the object to generate the string. In code:
def represent fun(value: any) =>
if isInstance(value, Representable) then
value.represent()
else
defaultRepresent(value)
A problem arises when we want to call the function represent from
within an implementation of the represent method. For instance,
if we were implementing represent for the Some class:
def Some class(value: any) => {
// Skipping the rest of the implementation of Some for brevity
def represent fun() =>
"Some(" + represent(value) + ")"
}
This code won't compile since we're calling represent with a
single argument, value, but within the scope of the class,
represent refers to the zero-argument function that implements
represent specifically for Some.
There are several possible solutions to this problem, but the simplest one seems to be to use a different name for the method than for the corresponding function. For consistency, we can introduce the convention that the method name should be a simple variation on the function name. For instance, we might choose to use a leading underscore:
def represent fun(value: any) =>
if isInstance(value, Representable) then
value._represent()
else
defaultRepresent(value)
Although the leading underscore is perhaps a little ugly, that ugliness does
help to reinforce the idea that you shouldn't be calling
the method _represent directly. Instead, you should be using
the represent method. More generally, instead of calling a method
_foo, you should be calling foo (unless you're
actually implementing foo).
Topics: Functional programming, Language design, Shed