[Prev][Next][Index][Thread]

A Proposal!!



Hi,

One of the gotchas that has bothered me about Dylan is add!().  In
particular I based my code on the Harlequin's Task List Manager example,
it compiled but it didn't work.  The problem turned out to be that I was
using the <list> class for my collection class instead of the
<stretchy-vector> class that the example used.  Thus since the result of
add!(<list>, <object>) is not necessarily == to the passed in <list>,
one must utilize the result.  The Task List Manager code uses an
optimization: since the result is guaranteed to be == the supplied
<stretchy-vector> it could skip assigning the result to a local
variable.

So I have come to believe that the versions of add!() that maintain
identity should be treated as a separate method from the versions that
don't maintain identity.  So I would like to propose a new convention.
First always utilize the result of a destructive operation that has a
'!' suffix.  Second, if a destructive operation maintains the identity
of its input, provide a second version of the method that returns no
result and has a '!!' suffix.  Thus one can choose between greater
portability, add!(), or greater optimization, add!!().  Hopefully the
following example will clarify my proposal:

The original add-task()

     define function add-task
         (task-list :: <task-list>, task :: <task>) => ()
       add!(task-list.task-list-tasks, task);
       task-list.task-list-modified? := #t
     end function add-task;

add-task() rewritten for portability:

     define function add-task!!
         (task-list :: <task-list>, task :: <task>) => ()
       task-list.task-list-tasks := add!(task-list.task-list-tasks,
                                         task);
       task-list.task-list-modified? := #t
     end function add-task;

add-task() rewritten for optimization using the proposed convention:

     define function add-task!!
         (task-list :: <task-list>, task :: <task>) => ()
       add!!(task-list.task-list-tasks, task);
       task-list.task-list-modified? := #t
     end function add-task;

    define inline-only add!!
        (stretchy-vector :: <stretchy-vector, new-element :: <object>)
        => ()
      add!(stretchy-vector, new-element);
    end function add!!;

One other important point is that if one changes one's collection class,
and you have typed your variables strongly, a compiler can flag calling
add!!() on a <list> as an error.  (For HD 1.2, this requires the
production settings.)  With the original code, such a change would cause
data corruption with no error.

So what do you think?  This convention could be applied to wide number
of methods add!!(), remove!!(), clear-memor


Sent via Deja.com http://www.deja.com/
Before you buy.



Follow-Ups: