Removing from lists by description of values

The Standard Rules supports

To remove (existing entry - K) from (L - list of values of kind K), if present

and

To remove (N - list of Ks) from (L - list of values of kind K), if present

but today I needed something else so I made a little utility phrase for

To remove (D - description of values of kind K) from (L - list of K), if present:
tested only with 6M62
Include (-

! based on 6M62 LIST_OF_TY_RemoveValue
[ LIST_OF_TY_RemoveValuesByDesc list desc forgive      i j no_items odsize f delendum mf ;
	if ((list==0) || (BlkValueWeakKind(list) ~= LIST_OF_TY)) rfalse;
	if ((desc==0) || (~~desc ofclass Routine)) rfalse;
	no_items = BlkValueRead(list, LIST_LENGTH_F); odsize = no_items; mf = false;
	BlkValueWrite(list, LIST_LENGTH_F, no_items); ! Forces the list to be mutable
	for (i=0: i<no_items: i++) {
		delendum = BlkValueRead(list, i+LIST_ITEM_BASE);
		f = desc(delendum);
		if (f) {
			mf = true;
			if (KOVIsBlockValue(BlkValueRead(list, LIST_ITEM_KOV_F)))
				BlkValueFree(delendum);
			for (j=i+1: j<no_items: j++)
				BlkValueWrite(list, j-1+LIST_ITEM_BASE,
					BlkValueRead(list, j+LIST_ITEM_BASE));
			no_items--; i--;
			BlkValueWrite(list, LIST_LENGTH_F, no_items);
		}
	}
	if (odsize ~= no_items) rfalse;
	if (forgive) rfalse;
	if (~~mf) {
		print "*** Couldn't remove values because none matching description were present in the list ";
		LIST_OF_TY_Say(list, true);
		print " ***^";
		RunTimeProblem(RTP_LISTRANGEERROR);
	}
];
-).

To remove (D - description of values of kind K) from (L - list of K), if present:
	(- LIST_OF_TY_RemoveValuesByDesc({-lvalue-by-reference:L}, {D}, {phrase options}); -).
2 Likes

It occurs to me that maybe only other mad scientists would understand what that means, so I’ll explain…

The phrase lets you remove things from a list based on a description of values, which is the technical term for a qualified set. (You use them all the time, even if you haven’t heard that name for them.)

Suppose you have a list of numbers called L. Out of the box, you can say:

remove 5 from L;

or

remove {1,2,3} from L;

but you can’t say

remove odd numbers from L;

With this phrase, though, you can.

3 Likes

Nice!

But one could do

now L is the filter to odd numbers of L
1 Like

True, but that makes a copy rather than modifying it in place.

Good point! I don’t think I’ve paid any attention to the filter to... phrase since I first read about it (and promptly forgot it) years ago.

Though in that case you’re specifying what you want to keep instead of what you want to get rid of, and as the removal criteria get more complicated, it’s less easy to deploy a logical inversion of them, e.g.

remove off-stage men from L;

would be trickier with filter to..., though I suppose you can always set up a definition of any complexity with its opposite term and then use that to get the inverse…