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