# ALPHA-TEST release of LambdaMOO version 1.8.0alpha6

Pavel Curtis (pavel@parc.xerox.com)
Tue, 16 Jan 1996 00:06:27 PST

- Messages sorted by:[ date ][ thread ][ subject ][ author ]

    I have made the next (and perhaps the last) *alpha-test* release of version
    1.8.0 of the LambdaMOO server in the usual place:

    	ftp://ftp.parc.xerox.com/pub/MOO/LambdaMOO-1.8.0alpha6.tar.Z

    This is still an ALPHA TEST release of the server and, although it's getting
    more and more stable as time goes on, there are almost certainly some more
    server-crashing, database-losing bugs remaining, so please DO NOT USE THIS
    RELEASE IN A PRODUCTION SETTING!

    Please continue to send your bug reports to the main MOO-Cows mailing list.
    I still expect to make at least one more test release before the final,
    production-approved one, but I'm now hoping that that will be a `beta' release
    (i.e., with no new major features to be added before final release).  We'll
    see, though.

    Here's the ChangeLog.txt entry for this release:
    -------------------------------------------------------------------------------
    Version 1.8.0alpha6, 16 January 1996
    -- Replaced panic with raising E_TYPE in the case where `x[$]' is applied to a
       non-string, non-list `x'.  (Thanks to Kipp the Kid for reporting this.)
    -- Fixed (yet another) bug in the stack-unwinding code; this one stuck the
       return information for each of a built-in's second and subsequent verb calls
       on successively higher stack frames, causing all manner of havoc, the least
       of which was somewhat surprising results from the (correct!) callers()
       built-in.  (Thanks once again to Brian Buchanan for reporting this bug; this
       marks the *third* bug in stack-unwinding that Brian has uncovered!)
    -- Changed the rules for binary strings slightly so that (a) TAB is no longer
       treated as a normal, printing character (i.e., it gets converted to `~011'
       on input in binary mode), and (b) `~' is treated just like all of the
       non-printing characters (i.e., it gets converted to `~176' on input in
       binary mode and the sequence `~~' is illegal in binary strings).  Change (a)
       removes one more source of TAB characters from the MOO (which can only be a
       good thing), and change (b) both simplifies the specification and makes it
       easier to compute the true length of a binary string (i.e., it's the length
       of the string itself minus three times the number of tildes).  (Thanks to
       James Deikun for these suggestions.)
    -- Fixed uninitialized-variable bug in the `program' command in emergency
       wizard mode.  (Thanks to Kipp the Kid for reporting it.)
    -- Fixed potential memory smash bug if #100 (or #200 or #400 or #800 or ...)
       was a recycled object in the DB file being loaded.  (Thanks to Dave Van
       Buren for sending me a DB file that tickled the bug and to Purify for
       pinpointing it.)
    -- Fixed bug that caused *all* settings of the .wizard property to be logged,
       instead of just those that set it to a true value.  (Thanks again to Dave
       Van Buren for reporting this.)
    -- Fixed bug accuracy of the top line number in tracebacks resulting from the
       setting of a wizard bit.  (Thanks one last time to DVB for sending me a
       traceback that contained such an error.)
    -- Added new built-in function `function_info([NAME])' which returns
       descriptions of built-in functions available on the server.  If NAME is
       provided, only the description of the function with that name is returned;
       if NAME is omitted, a list of descriptions is returned, one for each
       function available on the server.  Each description is a list of the
       following form:
    	{NAME, MIN_ARGS, MAX_ARGS, TYPES}
       NAME is the name of the built-in function, MIN_ARGS is the minimum number of
       arguments that must be provided to the function, MAX_ARGS is the maximum
       number of arguments that can be provided to the function or -1 if there is
       no maximum, and TYPES is a list of MAX_ARGS numbers (or MIN_ARGS if MAX_ARGS
       is -1), each of which represents the type of argument required in the
       corresponding position.  Each type number is as would be returned from the
       typeof() built-in function except that -1 indicates that any type of value
       is acceptable.  For example, here are several entries from the list:
    	{"listdelete", 2, 2, {4, 0}}
    	{"suspend", 0, 1, {0}}
    	{"server_log", 1, 2, {2, -1}}
    	{"tostr", 0, -1, {}}
       `listdelete()' takes exactly 2 arguments, of which the first must be a list
       (LIST == 4) and the second must be a number (NUM == 0).  `suspend()' has one
       optional argument that, if provided, must be a number.  `server_log()' has
       one required argument that must be a string (STR == 2) and one optional
       argument that, if provided, may be of any type.  `tostr()' takes any number
       of arguments and it can't be determined from this description which argument
       types would be acceptable in which positions.
          It should be noted that, in a feat of synchronicity, this new built-in
       brings the total number supported in the official server release to exactly
       100!  (Thanks to some-user-whose-message-I've-lost [feel free to mail me
       again so that I can patch this thank-you note] for suggesting such a
       built-in function.)
    -- Fixed the definitions of the built-in functions match(), rmatch(), index(),
       rindex(), and strsub() to accept any type of value for their final,
       `case-matters' flag argument.  Also fixed `verb_code()' to allow any type of
       value for either of its final two flag arguments.
    -- Added `scattering assignment' expression, allowing the elements of a list to
       be spread among multiple variables simultaneously; this could be used, for
       example, to get at the arguments to a verb in a more convenient form than
       the list `args'.
          A scattering assignment expression looks like this:
    	{ TARGETS } = EXPR
       where TARGETS is a comma-separated list of places to store elements of the
       list that results from evaluating EXPR.  A target has one of the following
       forms:
    	VARIABLE
    	    This is the simplest target, just a simple variable; the list
    	    element in the corresponding position is assigned to the variable.
    	    I call this a `required' target, since the assignment is required
    	    to put one of the list elements into the variable.
    	? VARIABLE
    	    I call this an `optional' target, since it doesn't always get
    	    assigned an element.  If there are any list elements left over
    	    after all of the required targets (and all of the other optionals
    	    to the left of this one) have been accounted for, then this
    	    variable is treated like a required one and the list element in the
    	    corresponding position is assigned to the variable.  If there
    	    aren't enough elements to assign one to this target, then no
    	    assignment is made to this variable, leaving it with whatever its
    	    previous value was.
    	? VARIABLE = EXPR
    	    This is also an optional target, but if there aren't enough list
    	    elements available to assign one to this target, the result of
    	    evaluating EXPR is assigned to it instead.  Thus, EXPR is a kind of
    	    `default value' for the variable.  The default value expressions
    	    are evaluated and assigned working from left to right *after* all
    	    of the other assignments have been performed.
    	@ VARIABLE
    	    Analogously to MOO argument lists, this variable is assigned a list
    	    of all of the `leftover' list elements in this part of the list
    	    after all of the other targets have been filled in.  It will be
    	    assigned the empty list, if there aren't any elements left over.  I
    	    call this a `rest' target, since it gets the rest of the elements.
    	    There may be at most one rest target in TARGETS.
       If there aren't enough list elements to fill all of the required targets, or
       if there are more than enough to fill all of the required and optional
       targets but there isn't a rest target to take the leftover ones, then E_ARGS
       is raised.
          Here are some examples of how this works.  Assume first that the verb
       `me:foo()' contains the following code:
    		b = c = e = 17;
    		{a, ?b, ?c = 8, @d, ?e = 9, f} = args;
    		return {a, b, c, d, e, f};
       Then the following calls return the given values:
    	    `me:foo(1) ! ANY'              => E_ARGS
    	    me:foo(1, 2)                   => {1, 17, 8, {}, 9, 2}
    	    me:foo(1, 2, 3)		   => {1, 2, 8, {}, 9, 3}
    	    me:foo(1, 2, 3, 4)		   => {1, 2, 3, {}, 9, 4}
    	    me:foo(1, 2, 3, 4, 5)	   => {1, 2, 3, {}, 4, 5}
    	    me:foo(1, 2, 3, 4, 5, 6)	   => {1, 2, 3, {4}, 5, 6}
    	    me:foo(1, 2, 3, 4, 5, 6, 7)	   => {1, 2, 3, {4, 5}, 6, 7}
    	    me:foo(1, 2, 3, 4, 5, 6, 7, 8) => {1, 2, 3, {4, 5, 6}, 7, 8}
       Finally MOO has a convenient mechanism for naming verb arguments, checking
       for there being exactly the right number of arguments, handling optional and
       `rest' arguments, etc.  I intend to start every new MOO verb of mine with a
       scattering assignment of `args', and I encourage other MOO programmers to do
       the same.
    -------------------------------------------------------------------------------