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