From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: pjb@informatimago.com (Pascal J. Bourguignon) Newsgroups: gmane.emacs.help Subject: Re: Chained Object Type Predicates Date: Mon, 08 Jun 2009 14:58:08 +0200 Organization: Anevia SAS Message-ID: <7cmy8inaqn.fsf@pbourguignon.anevia.com> References: <80c94ce8-8e0b-4ebe-a575-f1f25a6fd734@n8g2000vbb.googlegroups.com> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: 8bit X-Trace: ger.gmane.org 1244468547 8635 80.91.229.12 (8 Jun 2009 13:42:27 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Mon, 8 Jun 2009 13:42:27 +0000 (UTC) To: help-gnu-emacs@gnu.org Original-X-From: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Mon Jun 08 15:42:25 2009 Return-path: Envelope-to: geh-help-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.50) id 1MDf7I-00017R-LY for geh-help-gnu-emacs@m.gmane.org; Mon, 08 Jun 2009 15:42:25 +0200 Original-Received: from localhost ([127.0.0.1]:48351 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MDf7I-0004rp-50 for geh-help-gnu-emacs@m.gmane.org; Mon, 08 Jun 2009 09:42:24 -0400 Original-Path: news.stanford.edu!newsfeed.stanford.edu!postnews.google.com!news4.google.com!proxad.net!feeder1-2.proxad.net!cleanfeed3-b.proxad.net!nnrp18-1.free.fr!not-for-mail Original-Newsgroups: gnu.emacs.help Face: iVBORw0KGgoAAAANSUhEUgAAADAAAAAwAQMAAABtzGvEAAAABlBMVEUAAAD///+l2Z/dAAAA oElEQVR4nK3OsRHCMAwF0O8YQufUNIQRGIAja9CxSA55AxZgFO4coMgYrEDDQZWPIlNAjwq9 033pbOBPtbXuB6PKNBn5gZkhGa86Z4x2wE67O+06WxGD/HCOGR0deY3f9Ijwwt7rNGNf6Oac l/GuZTF1wFGKiYYHKSFAkjIo1b6sCYS1sVmFhhhahKQssRjRT90ITWUk6vvK3RsPGs+M1RuR mV+hO/VvFAAAAABJRU5ErkJggg== X-Accept-Language: fr, es, en X-Disabled: X-No-Archive: no User-Agent: Gnus/5.101 (Gnus v5.10.10) Emacs/22.2 (gnu/linux) Cancel-Lock: sha1:YTdkMzQyYjc1NDExNWNhOTUxOGE0MDM5MDM3ZWNlMzNlNzFiZDY5NQ== Original-Lines: 72 Original-NNTP-Posting-Date: 08 Jun 2009 14:58:08 MEST Original-NNTP-Posting-Host: 88.170.236.224 Original-X-Trace: 1244465888 news-3.free.fr 28954 88.170.236.224:45039 Original-X-Complaints-To: abuse@proxad.net Original-Xref: news.stanford.edu gnu.emacs.help:169810 X-BeenThere: help-gnu-emacs@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Users list for the GNU Emacs text editor List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Errors-To: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.help:65041 Archived-At: Nordlöw writes: > How should i implement chained type predicate functions, for example > > (defun list-of-numbers-p (object) (and (listp object) ...)) > > should return t if object is of type list (listp) and its elements in > turn all are of type string (stringp) otherwise nil. Then why don't you call it list-of-strings-p ? There are several ways to do so. One way is to notice that a list is either nil (meaning the empty list) or made of a first item followed by a rest sublist. So you could write: (defun list-of-numbers-p (object) (or (null object) (and (consp object) (numberp (first object)) (list-of-numbersp (rest object))))) Another would be to use reduce: (require 'cl) (defun list-of-numbers-p (object) (and (listp object) (reduce (lambda (&optional (r rp) e) (if rp (and r (numberp e)) t)) object))) Finally, you may notice that in a list of numbers, every element is a number: (require 'cl) (defun list-of-numbers-p (object) (and (listp object) (every (function numberp) object))) You may write a macro to build these functions automatically: (defun proper-list-p (object) (labels ((step (slow fast) (cond ((eq slow fast) nil) ; circular list ((null (cdr fast)) t) ((atom (cdr fast)) nil) ; dotted list ((null (cdr (cdr fast))) t) ((atom (cdr (cdr fast))) nil) ; dotted list (t (step (cdr slow) (cdr (cdr fast))))))) (cond ((null object) t) ; empty list ((atom object) nil) ; not a list ((null (cdr object)) t) ; one-element list (t (step object (cdr object)))))) (defmacro proper-list-of (predicate) `(lambda (object) (and (proper-list-p object) (every (function ,predicate) object)))) (funcall (proper-list-of integerp) '(1 2 3 4)) --> t (funcall (proper-list-of integerp) '(1 2 "3" 4)) --> nil (funcall (proper-list-of integerp) '(1 2 3 . 4)) --> nil (funcall (proper-list-of integerp) '(1 2 #1=(3 4 . #1#))) --> nil -- __Pascal Bourguignon__