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
|