From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: "Pascal J. Bourguignon" Newsgroups: gmane.emacs.help Subject: Re: Why is booleanp defined this way? Date: Fri, 17 Apr 2015 22:55:34 +0200 Organization: Informatimago Message-ID: <87wq1amq49.fsf@kuiper.lan.informatimago.com> References: NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Trace: ger.gmane.org 1429304723 20742 80.91.229.3 (17 Apr 2015 21:05:23 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Fri, 17 Apr 2015 21:05:23 +0000 (UTC) To: help-gnu-emacs@gnu.org Original-X-From: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Fri Apr 17 23:05:20 2015 Return-path: Envelope-to: geh-help-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1YjDRv-0000U3-At for geh-help-gnu-emacs@m.gmane.org; Fri, 17 Apr 2015 23:05:19 +0200 Original-Received: from localhost ([::1]:43515 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YjDRu-000382-N6 for geh-help-gnu-emacs@m.gmane.org; Fri, 17 Apr 2015 17:05:18 -0400 Original-Path: usenet.stanford.edu!fu-berlin.de!uni-berlin.de!individual.net!not-for-mail Original-Newsgroups: gnu.emacs.help Original-Lines: 97 Original-X-Trace: individual.net Ou6/XMgXFhfvqsI3WZF8ywmA0LG5wjy+XmrWytn9uHljQc7y/g Cancel-Lock: sha1:MGRlNDA5NTU4MGNmMDkwNTZkNjFkNDMwZDYxNGYwYmUwODlhM2ZlZA== sha1:qgOrQfma9uuQxvRY2u4S6+Hj604= Face: iVBORw0KGgoAAAANSUhEUgAAADAAAAAwAQMAAABtzGvEAAAABlBMVEUAAAD///+l2Z/dAAAA oElEQVR4nK3OsRHCMAwF0O8YQufUNIQRGIAja9CxSA55AxZgFO4coMgYrEDDQZWPIlNAjwq9 033pbOBPtbXuB6PKNBn5gZkhGa86Z4x2wE67O+06WxGD/HCOGR0deY3f9Ijwwt7rNGNf6Oac l/GuZTF1wFGKiYYHKSFAkjIo1b6sCYS1sVmFhhhahKQssRjRT90ITWUk6vvK3RsPGs+M1RuR mV+hO/VvFAAAAABJRU5ErkJggg== X-Accept-Language: fr, es, en User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux) Original-Xref: usenet.stanford.edu gnu.emacs.help:211500 X-BeenThere: help-gnu-emacs@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Users list for the GNU Emacs text editor List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Original-Sender: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.help:103782 Archived-At: Marcin Borkowski writes: > Hi all, > > this is what I found in subr.el: > > ,---- > | (defun booleanp (object) > | "Return t if OBJECT is one of the two canonical boolean values: t or nil. > | Otherwise, return nil." > | (and (memq object '(nil t)) t)) > `---- > > Seemingly, it doesn't make much sense: what is the purpose of saying > > (and (whatever) t) > > instead of just > > (whatever) > > for a predicate? Of course, this "normalizes" any "truthy" value to > "t", but is it really needed for anything (except perhaps being > elegant)? There's a difference between a boolean and a generalized boolean. Also notice how the docstrings give the SPECIFICATION of the function: (defun booleanp (object) "Return t if OBJECT is one of the two canonical boolean values: t or nil. Otherwise, return nil." (and (memq object '(nil t)) t)) (defun generalized-booleanp (object) "Return t if OBJECT is a generalized boolean, otherwise return nil" t) ; all the lisp objects are generalized booleans, by definition! (defun truep (generalized-boolean) "Return t if GENERALIZED-BOOLEAN is true, nil otherwise." (and generalized-boolean t)) (defun falsep (generalized-boolean) "Return t if GENERALIZED-BOOLEAN is false, nil otherwise." (null generalized-boolean)) Obviously, the last three functions are idiotic, given that almost all the boolean lisp operators actually take generalized boolean, and that there is already NULL and NOT doing the same job as the last. You don't write: (if (truep (member fruit '(apple banana))) 'fruit 'vegetable) you write: (if (member fruit '(apple banana)) 'fruit 'vegetable) Also a little trick to obtain a boolean from a generalized boolean, instead of (and … t), is to use the double negation: (not (not …)). Arguably, not being a function it could be slower, but a sufficiently smart compiler should be able to generate the same code, or in the case of emacs lisp virtual machine, produce actually shorter byte code, since not is a virtual machine instruction: (defun f (x) (and x t)) (disassemble (byte-compile 'f)) byte code: args: (x) 0 varref x 1 goto-if-nil-else-pop 1 4 constant t 5:1 return (defun g (x) (not (not x))) (disassemble (byte-compile 'g)) byte code: args: (x) 0 varref x 1 not 2 not 3 return But this is really nit-picking. -- __Pascal Bourguignon__ http://www.informatimago.com/ “The factory of the future will have only two employees, a man and a dog. The man will be there to feed the dog. The dog will be there to keep the man from touching the equipment.” -- Carl Bass CEO Autodesk