[Chapter 9] What exactly more powerful in Lisp compare to OOP in making object hierarchy?

65 views
Skip to first unread message

Rickert

unread,
Mar 13, 2012, 2:58:15 PM3/13/12
to Land of Lisp
(defstruct monster (health (randval 10)))
(defstruct (orc (:include monster)) (club-level (randval 8)))
(push #'make-orc *monster-builders*)

From the note, it claims that:
<b>
Notice how powerful this approach is. We can create as many new
monster types as we
want, yet we’ll never need to change our basic Orc Battle code. This
is possible only in
languages like Lisp, which are dynamically typed and support functions
as first-class
values. In statically typed programming languages, the main Orc Battle
code would
need some hardwired way of calling the constructor for each new type
of monster. With
first-class functions, we don’t need to worry about this.</b>

How exactly this is different from statically typed languages? Suppose
I got:

class Monster {
private:
int health_;
public:
Monster(int health):health_(health) { }
virtual ~Monster () {}
int get_health() const { return health;}
};

class Orc {
private:
int club_level_;
public:
Orc(int health, int club_level):Monster(health),
club_level_(club_level) {}
virtual ~Orc() {}
};

enum MonsterType {
Orc,
.....
};

class MonsterFactory {
public:
Monster* create_monster(MonsterType t){
if (t == Orc) return new Orc( /* supplied arguments
*/);
}
};

I know I have to write more code, and I can't use functions in /*
supplied arguments */ to have less code and more convenient. Still,
how can Lisp perform this:

"the main Orc Battle code would need some hardwired way of calling the
constructor for each new type of monster. With first-class functions,
we don’t need to worry about this."

*monster-builder* is analogous to my MonsterFactory, (push #'make-orc
*monster-builders*) is the same as adding new code for constructing
new monster type: if (t == ....) return new MonsterType (/* supplied
arguments */.

In both C++ version and Lisp version, I have to do the same thing,
except in Lisp I do it shorter and easier to read. But the idea is the
same. I still have to "hardwired way of calling the constructor for
each new type of monster" in both C++ and Lisp, as I have stated above
for adding new types. Or am I missing something?

And what is "yet we’ll never need to change our basic Orc Battle
code"? How is adding new type related to "our basic Orc Battle code"?
If I add new type in C++, I simply add new type, such as adding
another class called Hydra, and what does this Hydra class have to
with my existing Orc class to make me change Orc code?

Conrad

unread,
Mar 13, 2012, 3:06:43 PM3/13/12
to Land of Lisp
In C++, there's no way to create a map between Monster types and
functions that create monsters. In C++, the only way to create a new
Foo object is to write out the words "new Foo(...)". This is why you
need a MonsterFactory that has a big if-then statement where you check
for every possible monster type and than manually write the test "new
Orc(...)", "new Hydra(...)", etc. It would be nice in C++ if you could
just create a map of monster types to creator functions, but there is
no dynamic way to create a monster (Other languages such as Java and
C# have ways of doing this, but in a roundabout, complicated way)

This is what I was trying to convey in that text. In short, Lisp
doesn't need a MonsterFactory with a long if-then statement in it.

Rickert

unread,
Mar 14, 2012, 12:47:29 AM3/14/12
to Land of Lisp
After reading this article: Dynamic Object Model -
http://dirkriehle.com/computer-science/research/2005/plopd-5.pdf , I
think I understand the dynamic aspect you mentioned (I would really
appreciate if my understanding is verifeid by someone). Basically, in
order to dynamically create new data type of a specific domain (such
as banking accounts according to the examples of the paper) in
runtime, we need to model the metadata of that datatype (in this case,
AccountType is the metadata of Account), and model the metadata of its
properties (PropertyType with TypeChecking is the metadata of
Property). The Account object is just value holder for the common and
unchanged properties. The variants of Account (Such as SavingAccount,
CheckingAccount..) is kept by the AcccountType, and AccountType and
the properties of AccountType is supplied at runtime by the user
through user input. In this example, this pattern is useful if we have
500 different types of accounts, each is a bit different by each other
(such as SavingAccount has no overdraw limit but CheckingAccount
does). To model a class hierarchy in such dynamic environment by
predefining at compile time is impossible.

Is this what you refere to, Mr.Conrad?

So, I can see that with Lisp, I can define a structure of an object
very easy. However, the example code at the note is not really clear
how it strongly supports dynamic objection creation. i.e. if I want to
create variants of Orc, such as FarmerOrc, BattleOrc, FemaleOrc.... in
the same manner as Account creation above (which means I may add/
modify the existing structure of the Orc and its variants at runtime),
how can I do that dynamically at runtime, by user suppliedi nput?

Btw, I had another question about syntax expression:
http://stackoverflow.com/questions/9555387/what-is-syntax-expression .
Feel free to look at it if you have free time.

Rickert

unread,
Mar 14, 2012, 2:57:13 PM3/14/12
to Land of Lisp
Finally, I got it. Sorry for my carelessness, about the Orc Battle
code mentioned in the book. Because Orc is model in the game, somehow
I mistook the main game code, which is name Orc Battle for the code of
the Orc model. Upon rereading the code, Orc Battle code is the main
game code at the highest level. And to add more types into the game,
we can dynamically add without changing the main function, using the
(funcall) function. Meanwhile, in other languages, we have to
statically compile and modify the object creation code.

On Mar 14, 12:47 am, Rickert <tuhdo1...@gmail.com> wrote:
> After reading this article: Dynamic Object Model -http://dirkriehle.com/computer-science/research/2005/plopd-5.pdf, I
Reply all
Reply to author
Forward
0 new messages