Path: utzoo!utgpu!water!watmath!clyde!rutgers!sri-spam!sri-unix!quintus!sun!pitstop!sundc!seismo!uunet!mcvax!ukc!its63b!aiva!jeff From: jeff@aiva.ed.ac.uk (Jeff Dalton) Newsgroups: comp.lang.lisp Subject: Re: Filtering Vectors in CL Question Message-ID: <242@aiva.ed.ac.uk> Date: 28 Jan 88 13:11:03 GMT References: <1350001@otter.HP.COM> <1350003@otter.HP.COM> Reply-To: jeff@uk.ac.ed.aiva (Jeff Dalton) Organization: Dept. of AI, Univ. of Edinburgh, UK Lines: 82 In article <1350003@otter.HP.COM> kers@otter.HP.COM (Christopher Dollin) writes: >One note and one direct mail reply (to which I don't have access, being >on a different machine ...) suggested using REMOVE-IF-NOT. I tried to send mail, but I think it failed (I got a failure message). Now I'll try news... >Alas! I have asked the wrong question. The existance of a primitive to >perform the operation gives few clues as to idiomatic style ... Well, it *is* the idiomatic style. What do you do in Pop? When you asked the question, you gave this solution: define filter( v, p ); lvars v, procedure p; {% appdata ( v, procedure ( x ); lvars x; if p( x ) then x endif endprocedure ) %} enddefine; > which makes a vector out of all the elements in v that satisfy p, > generates no garbage, and runs acceptably fast. What would you do without appdata, which looks to be at about the same level as REMOVE-IF-NOT? >So suppose someone says "please implement 'remove-if-not'. I would like >your solution to generate no garbage if possible and to be reasonably >efficient". >Or suppose they say "write a function to copy a list, eliminating items >that do not satisfy a predicate and duplicating elements which do". Well, if it's a *list*, you can do: (defun filter (p l) (mapcan #'(lambda (x) (if (funcall p x) (list x))) l)) or various other things... But it seemed that the point of your original question was that doing it for a *vector* was messy in Lisp but (happened to be) easy in Pop. That's just because Pop has different primitives. So I think REMOVE-IF-NOT was a fair answer. As for your other questions... In Christopher Dollin writes: > If p and q are functions with arbitrary in-arity and out-arity, what is the > idiomatic efficient way of writing a function > > (compose p q) Your Lisp solution is pretty much how it must be done, but in some implementations it would not require any consing because the &rest list would be on the stack. In Pop, you can use chain or something, can't you? In CL, I suspect people just write the appropriate lambda-expression in-place rather than use a general composition operation. > Similarly if p is a function, what is an idiomatic or efficient way to > define > > (partapply p a1 ... an) > > which produces a function which, when applied to arguments b1 ... bn, > applies p to a1 ... an b1 ... bn. If you want to do exactly this, Pop wins because it's built-in, but in most cases lexical closures are more appropriate. For example, you can easily make dynamic lists in CL or implement a general DELAY w/o having to know the variables that must be "frozen". Pop does have some primitives that make some things easier. Lisp has different primitives that make other things easier. In some cases, Pop is nicer; in others, it isn't. Jeff Dalton, JANET: J.Dalton@uk.ac.ed AI Applications Institute, ARPA: J.Dalton%uk.ac.ed@nss.cs.ucl.ac.uk Edinburgh University. UUCP: ...!ukc!ed.ac.uk!J.Dalton