MOO-cows Mailing List Archive

[Prev][Next][Index][Thread]

Re: Frobs and other useless junk



At 11:40 AM 8/5/96 PDT, Michael Brundage <anomaly@u.washington.edu> wrote:
>How can you do frobs in-db already?  Simple: Let's say you create an
>abstract object called $value defining a generic MOO-value interface
>(with verbs like add(), multiply(), and so on).  Subclass it into
>separate objects (one for each type you wish to implement), even
>subclassing these if you want.  

We've done this on E_MOO, with the full intent of converting them to true
frobs once server support exists for it.  We called them datatypes though.
And we've taken the indirect route, $type.hash_table, $type.stream,
$type.table, etc.

I'm hesitant to discuss the actual design and implementation though, it's
long, and could start religious wars. :)

>MOO is not all things object-oriented.  It seems to
>me that adding in-db support for frobs is just going to triple the
>overhead (especially if done in this way) for almost no gain, since they
>can already be done in-db.  Moreover, it'll totally obfuscate MOO-code;
>when I see thing:(vrb)(@args)  I expect 'thing' to be an honest-to-God
>object, not just any possible MOO  value.

(that looks like a typo... should it have been "It seems to me that adding
in-server support for frobs..."?)
MOO may not be all things OO, but I believe this is mostly because of the
lack of other true OO concepts that the server should support, such as
non-overridable methods.  The lack of non-overridable methods has made all
accesses for things go through third parties instead of directly in the most
widely used core database.

    $object_utils:has_verb(object, verbname);
instead of
    object:has_verb(verbname);

The problem with this is that in an OO language, ALL of the basic types
should have object equlivents, that way, when you do call thing:verb(@args),
if thing is not an object, it gets promoted to one, and then the call is made.

>try
>  my_vector1 = $value_factory:create("vector", {1, 2, 3, 4});
>  my_vector2 = $value_factory:create("vector", {5, 6, -1, 0});
>catch (e)
>  player:tell("Error creating vector: "+$value.string:print(e));
>endtry

It's going through a third party to create them.  Not that this is all bad,
since you have to call a method on the object to get an instance of it.
Assuming we had a vector type on E_MOO, we'd use $type.vector:new() to get a
vector instance.

Your code example is a little confusing also.  I can't figure out why you'd
have $value.string define a :print method that would handle any type.  I
think it would make more sense to define a frob/datatype to handle values of
the same type that e is, and do:

    player:tell("Error creating vector: " + e:tostr()

(which we thought would be wise and that we've done on E_MOO).  This is
where frob support comes in handy.  You can stop creating utility methods
that think they know how to handle every possible type, and pass the actual
operation off to the value itself and tell it to do something.  (you could
have named it :print above, it doesn't matter, I perfer :tostr, since then
you know what type it's going to return).  Of course, if not using an
instance, you could still define a $type:tostr, and then call
$type:tostr(e), which would then dispatch to e:tostr(), if you like the
procedural approach.

>return $value.vector:convert_to_list(my_vector1:add(my_vector2));

Mmh.. what does $value_factory:create return?  An object?  It would have to
in order for the above line to work.

>This scheme is at least as workable as "frobs," with a comparable amount
>of overhead and the bonus that you can do it *now*, without any server
>hacks.  

Comparable amount of overhead?  Assuming your example above actually would
work with no server mods, there would actually be a large amount of overhead
in the constant object creation, destruction, and garbage collection that
needs to go on.  If frobs were in server, then garbage collection is no more
overhead than for other MOO values.

>It's also totally clear what is going on, just by looking at the
>code.  If you don't like the extra level of indirection, you can always
>create synonyms on #0, such as $array == $value.array   Notice that you
>can also create new types to your heart's content, and create types to
>encapsulate all existing MOO types (and operations on them).

The degree of clearness completely depends on the code being used, not the
semantics of the language and it's type support.

  (a)  object = $string_utils:explode("bone->head", "->");

  (b)  stream = $type.stream:new(...);
       lines = stream:read(10);

  (c)  stream = $type.stream:new(...);
       lines = $type.stream:read(stream, 10);

(a) is totally misleading, no matter what kind of typing the language
enforces.  (b) is what true frob support would look like, as you can see, we
are asking the stream we just created to return the next 10 lines.  (c) is
how it currently looks on E_MOO, not that bad, but (b) is still better, I
think, from a code maintaining and abstraction standpoint.

Built in support for custom types, frobs, makes code easier to read and
maintain, and abstracts complicated backends even more (you should see the
stream datatype object, it's complicated, and it's only half done).  Yes,
things still need to go through 'third parties' (in as much as handler
objects for the datatypes are considered 'third parties'), but they are
behind the scenes, away from the programmer.

>Of course, you can't do my_vector1+my_vector2, but (1) MOO is not C++
>(thank God), and (2) you'd have a similar problem with frobs, since
>$call_verb(my_vector1, "+", my_vector2) is still going to have to check
>the types of my_vector1 and my_vector2.

Well, this depends on implementation, and anything that is actually doing an
operation needs to have types checked anyway.  All of the methods on E_MOO
that handle datatypes are required, per our design, to check the type of the
datatype they were passed before doing any kind of manlipulations with/on
it, raising an error if it's an incompatible type.  I personally do not want
operator overloading in MOO, the entire thing would get overly confusing.

    vector_sum = $type.vector:add(vector1, vector2)
    vector_sum = vector1:add(vector2)

Either is fine with me, both read fine.

Its debatable if C++ is a good example of OO.

Andy.



Follow-Ups:

Home | Subject Index | Thread Index