[DGD]Fwd: Foreach and anonymous functions in DGD

Felix A. Croes felix at dworkin.nl
Mon Jan 29 16:58:32 CET 2001


Lee Salzman <lee.salzman at lvdi.net> wrote:

> (The DGD mailing list seems to be not accepting
>  my post so I'm sending this directly to you. :])

The DGD mailing list is particular about what is in the Sender:
field.  In the email you sent me, it was just `lee'.  If you can
manage to make it `lee.salzmam at lvdi.net', your postings should be
accepted.


>    I've been looking around for other drivers than MudOS
> lately (due to its bloat and lack of maintenance) and
> somewhat decided to settle with DGD. However, certain
> features MudOS provides are definitely convenient and
> I, rmm, hacked one or two of them into DGD(some parts
> more hackish than others), namely foreach() has been
> implemented for both arrays and mappings as well as
> anonymous functions (not hellish-looking lambda
> closures or awkward functionals, but prettier
> looking anonymous functions).
>
>    These modifications, in diff and tarball form,
> can be found at:
>    http://www.lvdi.net/~lee.salzman/dgd-mod.diff.gz
>    http://www.lvdi.net/~lee.salzman/dgd-mod.tar.gz

Some comments on the state of that code:

 - You left some debugging code in mud/kernel/sys/userd.c.
 - Fairly pointless changes to mud.dgd, src/Makefile and src/alloc.c.  A
   number of whitespace-only changes in code elsewhere; you'll want to
   remove these since they will only make tracking the vanilla driver
   source more difficult.
 - src/comp/pool.c and src/comp/pool.h are not in the diffs.
 - evaluate() doesn't seem to be checking if the object in which the
   anonymous function is defined still exists.
 - Should function_name() and function_owner() really exist?  The latter
   even assumes that the owner is a string, rather than an object.


>    Whether or not these changes are too controversial
> to be accepted into the main body of code I leave
> to Dworkin. :) 

If the code is cleaned up a bit, these changes could make for some
pretty neat add-on packages.  I suggest making this into two separate
packages, though.

I am still of the opinion that LPC does not need anonymous functions.
Foreach has theoretical problems with mutable expressions such as
mappings; also I have doubts about the addition of variable
declarations in a statement, and non-mutable loop variables, to LPC.


>    At a glance, foreach() is just a rather simple
> construct that maps down to for(;;) with some
> hidden temporary variables thrown in to handle
> iteration over an array or mapping as appropriate
> (this is only about 50 lines of code or so). Many
> problems ensued over the tokenizer's reserved keyword
> hashing technique, so I just tacked on a simple
> decision tree in the changes in the m ean time
> (how the heck did you generate the hash table? >:]).

Do a web search on "minimal perfect hashing". :-)


> ex:
> foreach (string key, int value in ([ "foo" : 3 ]))
>    bar (key, value);

I didn't see a nil check on the array or mapping.  Since you generate
LPC code with calls to kernel functions, you should add such a check,
or people will get errors like "bad argument 1 for sizeof" instead.


>    As for anonymous functions, the implementation
> is vaguely based on lambda lifting. The bulk of
> the work was making the compiler support compilation
> of nested functions (of whatever sort). However, I
> wasn't quite sure how to get a persistent reference
> to a specific function definition in a control block
> so I put in a temporary hack that just generates
> a "pseudo-unique" name for each closure. (which
> of course should also be fixed if it is seen fit
> to incorporate anonymous functions).

You can stick to unique function names, as long as they are
unique within the object, and not callable with call_other().
But it's better to make them private and call them with i_funcall()
rather than i_call().  You can keep the current naming scheme if
you like, those names just wouldn't be used in calls anymore.


> ex: 
> sum = evaluate (\int(int x, int y) { return x + y; }, 2, 3);
> => sum == 5
>
>    '\' is the lambda operator. If return type is 
> omitted, mixed is assumed.

In DGD's typechecking modes 1 and 2, no return type normally means
`void'.


> As they are only anonymous
> functions, you can only refer to global variables or 
> local variables in the anonymous function, as opposed 
> to also in the enclosing function. A corresponding 
> 'function' type was added as well.

Have you thought about anonymous functions defined in destructed
objects?  Your code doesn't handle this; it would be easy to check
if the object is destructed and cause an error or do nothing in that
case, but is that actually what <should> happen?

Regards,
Dworkin

List config page:  http://list.imaginary.com/mailman/listinfo/dgd



More information about the DGD mailing list