MOO-cows Mailing List Archive
[Prev][Next][Index][Thread]
The History Of Frobs, Part Zero (was Re: Use for $call_verb)
> But as number of people expressed it, custom datatypes is on the big wish
> list... and if I remember well some of the tales of Uncle Jay, Erik
> implemented frobs in-server ages ago...
Actually, I've been meaning to repost The History Of Frobs, since it
will no doubt clear some things up. In retrospect, I'm no longer
rabid about being able to call verbs on integers, but aside from that
I think most of the appended message is nice to understand.
> Yours in darkness,
>
> Dark Janus
DARK JANUSES ARE LOGGING EVERYTHING
OK, message follows.
Message-Id: <199503060437.XAA17747@fuji.ccs.neu.edu>
Date: Sun, 5 Mar 1995 20:37:02 -0800
From: Jay Carlson <nop@ccs.neu.edu>
To: Alex Stewart <riche@crl.com>
cc: quinn@access.mountain.net (Quinn), moo-cows@parc.xerox.com,
nop@fuji.ccs.neu.edu
Subject: Re: non-overridable verbs/frobs
> > While I'm on the topic of "things in Cold that seem reasonable to add
> > to MOO", how about frobs? They're a data-type which is basically
> > an inexpensive object.
I'd love to see dictionaries too, but I don't want to give Rob yet
another opening to point out that LPMOO already has them....
> In my opinion, frobs are really an ugly botch that look a lot more useful than
> they actually are (no offense to Greg, he did a lot of really nice things in
> ColdMUD, but frobs just aren't one of them).
Frobs are something that orginally came out of DistortionMOO, and
originally were written in-db. DistortionMOO was built from
Minimal.db, so we had to write everything from scratch, and that made
us think about The Right Way To Do Things a lot. What originally
triggered frobs was this: how should I print the result of an eval?
In LambdaCore, there was a big switch statement in
$string_utils:print:
if (typeof(value) == LIST)
elseif (typeof(value) == STR)
elseif (typeof(value) == ERR)
elseif ((typeof(value) == OBJ)
This struck me as being terribly un-OO. So I made an object called
$type with two verbs on it:
@program $type:class
value = args[1];
type = typeof(value);
return {$integer, $object, $string, $error, $list}[type -1];
This returned an object that was the `class' of a value.
@program $type:*
"I know what you're thinking: AUUUGH A STAR VERB GET IT OFF ME.";
value = args[1];
class = this:class(value);
return class:(verb)(@args);
This verb forwarded verb calls to the appropriate class of a value.
So you could do:
$type:to_string(4)
and it would turn into $integer:to_string(4) and
$type:to_string({1, 2})
and it would turn into $list:to_string({1, 2}). $integer, $object,
$string et al would have an appropriate :to_string verb on them.
Because lists are the only aggregate value in MOO, you use them for a
lot of data structures. For instance, a good way to represent verbs
is {object, verbname}. It would be nice if you could give THAT list
a class, and have cool :to_string and :owner and :controlled_by verbs
for it. So I modified $type:class to special-case a certain kind of
list:
{E_TYPE, class_object, value, value, value, ...}
So now you can represent references to verbs as {E_TYPE, $verb,
object, verbname}. $type:class() would return $verb, and you could
do $type:controlled_by(verb_or_prop_ref, player). Essentially,
you've associated a method suite with a list.
This is a very useful idea. My in-db implementation was ugly. Erik
was in fact so disgusted by $type that he reimplemented it in the
server. There were now six holy data types, as far as the server was
concerned: numbers, objnums, strings, errors, lists and
lists-with-a-class, aka frobs. (We actually had long discussions
about what to name these things....) Use of typeof() was deprecated
in favor of the new primitive, class(), which returned $integer etc.
The verb call operator, `:', was overloaded to work on any data type.
It replaced $type:*; where you previously wrote `$type:to_string(5)',
in the new system you simply wrote `5:to_string()'. New syntax for
frob constructors was added: `$verb->(obj, name)' constructed the
obvious frob in the same way that `{object, name}' constructed a list.
We wandered around delightedly building real types for all the
typical things we did in MOO programming. It felt really good to
escape from $foo_utils hell.
> What I'd much rather see (and
> what I suspect we won't see in MOO unless someone rewrites it significantly,
> but oh well.. maybe this could be a suggestion for Fable?) is user-definable
> datatypes (what frobs should be, but aren't).
Frobs are useful for most of the things you'd use lists for. You
just have to remember what they are: lists with a method suite.
Although we gave up on patching the server to support frobs directly,
they live on in the JHcore pronoun_sub, jtext and jaddress
systems---see <http://jhm.ccs.neu.edu:7043/help/subject!tagged-lists>
and <http://jhm.ccs.neu.edu:7043/help/subject!dispatchers>. Most new
projects I design are framed in similar terms.
Frobs give you much of what you want from user-defined value types,
within the constraints of existing MOO value semantics.
> With user-definable datatypes, you could take a DB object (say, $mydata_type),
> and associate a new MOO datatype to that object, such that values of that type
> would call verbs on $mydata_type for all the standard operations (+, -,
> tostr(), etc), optionally including calling verbs on the value as if it were an
> object
Rog suggested this for Distortion---the only issue here is that + has
to bottom out SOMEWHERE; $integer:+ would be handled by the server.
> (which, unlike frobs, I would very much like to see call a prefixed verb
> on the base object, instead of a verb of the same name (i.e. mydata:fooey()
> should call $mydata_type:verbcall_fooey(mydata) or some such, NOT
> $mydata_type:fooey(mydata))
Ah, yes, this is one of the classic problems with frobs. Let's make
the problem a little more clear. Suppose I have an object I want to
print. So I write:
text = object:to_string();
But what if `object' is $integer?
$integer:to_string()
...which promptly blows up because it's expecting to be called like
$integer:to_string(5). Oops. So it turns out that frob methods have
to live in a separate namespace from normal object methods. Rog
proposed that instead of the rewrite
5:to_string() => $integer:to_string(5)
we could use instead
5:to_string() => $integer:(":to_string")(5)
thus prefixing all frob methods with `:'. This would work, although
someone expressed interest in totally separating the two kinds of
methods.
> and these verbs would be able to actually modify
> the value in question if appropriate (like you can do with objects, but you
> can't do with frobs)..
Which brings us back to one of the big reasons values like lists are
immutable in MOO. I have a list of people allowed into a room in
`this.cool_people'. I have a verb to let people read it:
@program here:cool_people
return this.cool_people;
So if you're annoyed because I don't think you're cool, if lists were
mutable you could write:
people = jay.location:cool_people();
people[1] = player;
...thus changing the first element in the list to be you---and
because you're actually operating on my room's .cool_people property
(instead of a copy), now you're cool!
> I'm not sure how to do that last bit without pointers
> (which I don't think are a good idea, no), but I do feel that it's very
> necessary to make anything along these lines actually useful as "inexpensive
> objects" instead of just "interesting toy concepts"..
I think frobs are useful, but they're not a solution to everything.
> I fear I'm not making a lot of sense to anybody besides myself, but oh well..
Nah, perfect sense. I'm just using your letter to moo-cows to get
some history out of my system; you probably understand most of the
issues I blathered about up there.
Incidentally, if you have a design for inexpensive objects in the MOO
framework, I'd be glad to hear it.
Jay Carlson
nop@io.com nop@ccs.neu.edu
Flat text is just *never* what you want. ---stephen p spackman
Follow-Ups:
References:
Home |
Subject Index |
Thread Index