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
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,
(funcall) function. Meanwhile, in other languages, we have to
> 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.
> On Mar 14, 2:06 am, Conrad <drc...@gmail.com> wrote:
> > 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.
> > On Mar 13, 2:58 pm, Rickert <tuhdo1...@gmail.com> wrote:
> > > (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?