Subject: Implementation of Lists?

From: [email-masked] (Jack Eifrig)
Date: Thu, 29 Jul 1993 07:30:30 -0700

How are lists implemented in the LambdaMOO server?  Coming from the
functional language community, I just assumed they would be implemented
as garbage-collected cons cells, but now I'm thinking that they're
actually fixed-length arrays of pointers, judging from the kinds of
built-in functions available on them.

The thing that got me thinking about his was the code for "$root:tell_lines()"
in the LambdaCore database.  This function takes either a single line of
text or a list of such lines, and spews them to the player's connection.
It's implemented as:

                    lines = args[1];
                    if (typeof(lines) != LIST)
                       lines = {lines};
                    endif
                    for line in (lines)
                       this:tell(line);
                    endfor

rather than the more obvious, and seemingly more efficient:

                    lines = args[1];
                    if (typeof(lines) != LIST)
                       this:tell(line);
                    else
                       for line in (lines)
                          this:tell(line);
                       endfor
                    endif

In the actual implementation, why isn't the formation of the list (which is
then immediately destructed) a serious performance penalty?

---

From: [email-masked] (Erik Ostrom)
Date: Thu, 29 Jul 1993 07:53:31 -0700

It probably is.  (Well, "serious performance penalty" in the context of
LambdaCore kind of makes me look at you funny, but yeah.)

I've changed the LambdaMOO implementation:

      lines = args[1];
      if (typeof(lines) == LIST)
	for line in (lines)
	  this:tell(line);
	endfor
      else
	this:tell(lines);
      endif

Probably the right change to the implementation, speeding it up even further,
would be

      for line in (args[1])
        this:tell(line);
      endfor

and if people try to :tell_lines(something that isn't a list), they deserve
what they get.  :tell_lines is probably not the right place for this
particular flexibility.  Before making this change, though, I'd want to grep
around some to see what will be broken.

---

From: Judy Anderson <[email-masked]>
Date: Thu, 29 Jul 1993 12:36:53 -0700

Since the contract of :description (in the lambdacore) is to return
either a string or a list of strings, and nearly every :look_self
method uses a variant of player:tell_lines(this:description()), I'd
say it's a little late to change the contract of :tell_lines.  Heck,
some people have been passing non-list things to :tell_lines,
expecting the tostr() to be done by :tell_lines, which it is, in
$player:tell_lines.  I've only recently gone through our data
collection of who is doing this improper calling of :tell_lines and
warned said verb owners that they'll start getting tracebacks pretty
soon after we flush the map_builtin("tostr",line) from
$player:tell_lines.

Yeah, code efficiency in lambdacore does make one wanna laugh, sigh.

---

From: Pavel Curtis <[email-masked]>
Date: Mon, 2 Aug 1993 19:39:42 -0700

> Date:	Thu, 29 Jul 1993 07:30:30 -0700
> From:	[email-masked] (Jack Eifrig)
> 

They're implemented as fixed-length arrays of MOO values.

> The thing that got me thinking about his was the code for
> "$root:tell_lines()" in the LambdaCore database.  This function takes either
> a single line of text or a list of such lines, and spews them to the player's
> connection.  It's implemented as:
> 
>                     lines = args[1];

It's not a serious performance penalty because, in a interpreter for a language
like MOO, this little tiny allocation (which isn't all that expensive in the
first place) is entirely dwarfed by the general interpreter overhead.

	Pavel