[Date Prev] [Date Next] [Thread Prev] [Thread Next] Date Index Thread Index Search archive:
Date:Mon Aug 15 13:47:45 1993 
Subject:Re: deleting the nth item of a list 
From:Steve Knight 
Volume-ID:930815.02 

A.Sloman (A.Sloman@uk.ac.bham.cs) wrote:
> This is a question about programming style in Pop-11.
> One of my students fell over the most obvious way to define a
> procedure to remove the N'th element of a list.

Surely the most obvious way is to walk the list, counting as you
go, and skip the Nth element.  This is how I would write it.

define delete_nth( n, list ); lvars n, list;
    [% 
        lvars i, k;
        for i with_index k in list do
            unless i ==# k do
                i 
            endunless
        endfor
    %]
enddefine;

To be rather more accurate, I WOULD write it that way IF the -for- loop
syntax wasn't broken :-)


> I wonder what the most elegant solution is? (He doesn't want the
> original list changed.)

Here are three ``elegant'' solutions. 

;;; nb. -onlyfirst- comes from the PLUG source code archive.  I think
;;; that Aaron's suggestion of ``allfirst'' is a better name, though.
;;; The main defect with this solution is that it cheerfully accepts
;;; 0 for -n-.  And worse, it really is elegant.
define delete_nth( n, L ); lvars n, L;
    onlyfirst( n-1, L ) <> allbutfirst( n, L )
enddefine;

;;; This has a unique "Pop" flavour, I think you'll admit.
define delete_nth( n, L ); lvars n, L;
    popstackmark;
    lvars k = destlist( L );
    popstackmark -> subscr_stack( fi_check( k - n + 1, 0, k ) );   ;;; yes!
    sysconslist();
    sysconslist_onto();
enddefine;

;;; But this just *has* to be my favourite .... a superb abuse of
;;; list syntax.  (nb. -swap- comes from the PLUG source code archive
;;; too.  It just exchanges the top two elements of the stack.)
define delete_nth( n, L ); lvars n, L;
    [^^( erase( swap( applynum( L, dest, n ) ) ) )]
enddefine;

Steve