From: axs@cs.bham.ac.uk (Aaron Sloman)
Newsgroups: comp.lang.pop
Subject: Re: Clarity VS Efficiency in POP11
Keywords: efficiency vs elegance
Date: 22 Nov 92 23:27:52 GMT
Organization: School of Computer Science, University of Birmingham, UK

ianr@syma.sussex.ac.uk (Ian Rogers) writes:

> Date: 22 Nov 92 13:14:43 GMT
> Organization: University of Sussex at Brighton
>
> tmr@cs.bham.ac.uk (Tim Read) writes:
> > It is my feeling as a competent beginner in POP11, that putting too many
> > efficiency hacks into your code tends to lose the inherent clarity that
> > POP11 provides.
>
> Efficiency *hacks* are bad, sure (Pop11 buys you clarity, a Good
> Thing IMHO)
(Tim)
> > An example of what I mean is using a temporary closure within a
> > loop, which looks nice and neat, but will cause extra garbage collections,
> > as opposed to using an lblock (As Aaron pointed out).
(Ian)
> So make a new data type (even notionally) and optimise the code,
> *after* you've finished development, by free-listing instances.
> ....
> In your case you can free-list the closures, either in a simple list
> if you're only making closures of a single procedure, or in a
> property that matches against the pdpart.
> ... example of how to make a freelist of closures....

Two points

a. Pop should support freelists for various kinds of datastructures,
for knowledgeable users without it being necessary for individuals
to create these mechanisms.  Poplog Pop-11 already does this for
lists (actually that was originally put in by John Gibson for system
use and I arranged for it to be exported for general use (in 1986,
for Poplog V13.6)). Steve Knight has been arguing for ages that the
mechanism should be generalised, and he is right. On the other hand
you are right that users *can* do it themselves to reduce garbage
collections, if they know enough. (Sometimes I think that if they
need to be told how to do it then they don't know enough to do it
safely!!!)

b. However, the sort of case brought up by Tim was one where I don't
think a free list is the answer. It involved replacing applist with
a for loop, inside an already nested pair of loops. Something like
this:

  for x_iter from X1 to X2 do
      for y_iter from Y1 to Y2 do
          applist
            (
              world(x_iter, y_iter),
                extract_detail(% x_iter - grid_x, y_iter - grid_y %)
            );
      endfor;
    endfor;

(I've slightly simplified the original example.) Here the second
argument to applist is a closure, and a new one is created on every
call of applist, then discarded. I don't believe it's worth creating
a free list of closures to prevent garbage collection in *this* sort
of context because I think replacing applist with an explicit "for"
look is actually not a *hack* in this case.

It is not quite as elegant as applist, but I think it is perfectly
acceptable, and for some people will be even clearer than the call
of applist. I.e.

  lblock; lvars item;

  for x_iter from X1 to X2 do
      for y_iter from Y1 to Y2 do
          for item in world(x_iter, y_iter) do
              extract_detail( item, x_iter - grid_x, y_iter - grid_y )
          endfor
      endfor;
  endfor;

  endlblock;

Anyone who doesn't like three nested for loops could, instead define
an additional procedure:

    define extract_location_details(list, xloc, yloc, grid_x, grid_y);
        lvars item, list, xloc, yloc, grid_x, grid_y;
        for item in list do
           extract_detail(item, (xloc - grid_x), (yloc - grid_y))
        endfor
    enddefine;

then the original would be replaced by

  for x_iter from X1 to X2 do
      for y_iter from Y1 to Y2 do
        extract_location_details
            (world(x_iter, y_iter), x_iter, y_iter, grid_x, grid_y)
      endfor
  endfor;

which I think is at least as clear and elegant as the call of
applist, and considerably more efficient, especially if "define
procedure" is used instead of just "define" to make sure that
there's no procedure type check on every iteration.

It's also more modular, as the introduction of the extra procedure
allows it to be reused, and to be redefined, e.g. during testing,
without tampering with the middle of a couple of nested loops.

Aaron
---
-- 
Aaron Sloman, School of Computer Science,
The University of Birmingham, B15 2TT, England
EMAIL   A.Sloman@cs.bham.ac.uk  OR A.Sloman@bham.ac.uk
Phone: +44-(0)21-414-3711       Fax:   +44-(0)21-414-4281