In object oriented programming, wrapping methods can be a good thing. Wrapping allows for composition which, in turn, reduces excessive subclassing. Even the Gang of Four like it, “Favor object composition over class inheritance. ... Our experience is that designers overuse inheritance as a reuse technique, and designs are often made more reusable (and simpler) by depending more on object composition. You’ll see object composition applied again and again in the design patterns.”
Unfortunately, the syntax for composition is markedly more difficult in many Object Oriented languages—basically everything from SmallTalk to Java.
Consider the following.
You have the class Book. A given Book instance will have a Cover. Covers can have a Color. A Book, likewise, has a color. The Book’s color is just the color of its cover. That’s how we say it in English. Here’s how we say it in Java.
Wrapping in Java
import java.awt.Color;
class FrontCover extends Cover {
private String _color;
public Cover(String color) {
_color = color;
}
public String getColor() {
return color;
}
public void setColor(String color) {
_color = color;
}
}
class Book {
private Cover _cover;
public Book(Cover cover) {
_cover = cover;
}
public String getColor() {
return _cover.getColor();
}
public void setColor(String color) {
_cover.setColor(color);
}
}
This is okay if you want to wrap one method, but if you want wrap many you need a new line for each. Moreover, if the method has many arguments, things get messy.
// in class Book
public ReturnObj manyArgs(Arg1 arg1, Arg2 arg2, Arg3, arg3) {
return _cover.manyArgs(arg1, arg2, arg3);
}
Wrapping is a hassle. Wrapping being a hassle leads to less wrapping. Less wrapping leads to less composition. Less composition leads to more subclassing. More subclassing leads to suffering.
Subclassing in Java
class Book extends Cover {}
This code is much simpler. It has the same behavior. However, it says that books are covers. In a way this is true, a book
// In class Book
public Cover loseCover() {
Cover cover = _cover;
_cover = null;
return cover;
}
Using the subclass implementation, it is nearly impossible for books to lose their covers. The book
Other essays, might stop right there. The philosopher in me won’t.
Why are we forced to either use our powers for good or for awesome? There’s no cosmic reason why wrapping has to be a hassle. And in a better language it wouldn’t be.
Will’s way of Wrapping
a Cover(color) is a Thing
a Book(cover) is a Thing where
color = lambda cover.color
color= = lambda cover.color=
Could anything simpler? Yes actually. For example, the parenthesis above are optional. So is the mention of “a Thing”, and why the defining of a setter and getter when we just want to say, “A book has a color property that’s the same as the color property of its cover.” So I write it like this:
a Cover color
a Book cover
has-property cover.color
Is that good or awesome? Foul? Foul wasn’t an option. Why are you calling foul? Of course, I can extend the language like that. I just need a way for saying that ‘has-property’ is the same the two lines of non-sense I used before. This is called “defining syntax”. And my language has a syntax defining capability that will knock your socks off.
`has-property $exp` | exp =~ `$exp.$id` =
`$id = lambda $exp
$('$id=') = lambda $exp`
Let’s do a little comparison. The Java code is 426 characters. The description in English is 172 characters. My code is 145 characters. This figure includes the definition of ‘has-property’.
Good or awesome? You decide.
Commentary