From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Mark H Weaver Newsgroups: gmane.lisp.guile.devel Subject: Re: truth of %nil Date: Tue, 7 Jul 2009 07:14:09 -0400 Message-ID: <20090707111406.GA1388@fibril.netris.org> References: <87k52uvhnt.fsf@arudy.ossau.uklinux.net> <20090702142823.GA1401@fibril.netris.org> <877hyqk8bx.fsf@arudy.ossau.uklinux.net> <20090703153218.GA1382@fibril.netris.org> <20090705024135.GA2363@fibril.netris.org> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: ger.gmane.org 1246965534 1089 80.91.229.12 (7 Jul 2009 11:18:54 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Tue, 7 Jul 2009 11:18:54 +0000 (UTC) Cc: guile-devel , Neil Jerram To: Andy Wingo Original-X-From: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Tue Jul 07 13:18:46 2009 Return-path: Envelope-to: guile-devel@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.50) id 1MO8hB-0001zF-Ld for guile-devel@m.gmane.org; Tue, 07 Jul 2009 13:18:46 +0200 Original-Received: from localhost ([127.0.0.1]:58908 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MO8hA-0007qW-Dc for guile-devel@m.gmane.org; Tue, 07 Jul 2009 07:18:44 -0400 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1MO8dD-0005s4-5M for guile-devel@gnu.org; Tue, 07 Jul 2009 07:14:39 -0400 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1MO8d8-0005nd-Dp for guile-devel@gnu.org; Tue, 07 Jul 2009 07:14:38 -0400 Original-Received: from [199.232.76.173] (port=34266 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MO8d8-0005nO-1z for guile-devel@gnu.org; Tue, 07 Jul 2009 07:14:34 -0400 Original-Received: from world.peace.net ([204.107.200.8]:38595) by monty-python.gnu.org with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1MO8d7-0007D5-Ph for guile-devel@gnu.org; Tue, 07 Jul 2009 07:14:33 -0400 Original-Received: from localhost ([127.0.0.1] helo=fibril.netris.org ident=hope8) by world.peace.net with esmtp (Exim 4.69) (envelope-from ) id 1MO8cp-00005T-Oj; Tue, 07 Jul 2009 07:14:17 -0400 Content-Disposition: inline In-Reply-To: X-detected-operating-system: by monty-python.gnu.org: GNU/Linux 2.6 (newer, 3) X-BeenThere: guile-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Developers list for Guile, the GNU extensibility library" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Errors-To: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.lisp.guile.devel:8847 Archived-At: Having thought more about optimizing %nil handling, it occurs to me that we will also want boolean tests from within lisp to be optimized. >From lisp, three values are considered to be false: #f, '(), and %nil. We can use the same bit-masking trick to do these tests quickly if we make sure that these three values differ in only two bit positions. Therefore, I suggest that the first four SCM_MAKIFLAG values should be #f, %nil, '(), and another never-to-be-used value which would also be considered false by lisp code as a side effect of the masking trick. In my previous proposal, I made sure to keep SCM_BOOL_F and SCM_BOOL_T in IFLAG numbers 0 and 1. If this is important, it could still be arranged by making the aforementioned two bit positions something other than the lowest two bits of the IFLAG number, but that would mean our three lisp-false values would be spread out (e.g. 0/2/4/6). Therefore, unless someone tells me otherwise, I'm going to assume it's okay to put SCM_BOOL_F and SCM_BOOL_T in IFLAG numbers 0 and 4. These still have the property that SCM_BOOL_F and SCM_BOOL_T differ by only one bit, and that SCM_BOOL_F is IFLAG number 0, both of which seem potentially useful. So, in my new proposal, the first five IFLAGS are as follows: #define SCM_BOOL_F SCM_MAKIFLAG (0) #define SCM_ELISP_NIL SCM_MAKIFLAG (1) /* SCM_MAKIFLAG (2) would also be considered "false" by lisp code * and therefore should remain unassigned */ #define SCM_EOL SCM_MAKIFLAG (3) #define SCM_BOOL_T SCM_MAKIFLAG (4) This numbering has the nice properties that 0 is #f, the first two are considered false by scheme, and the first four are considered false by lisp. [An alternative numbering for which the following macros would also work is: ((#f 0) (#t 1) (%nil 2) (unused 4) (() 6)), if it's important to keep #f and #t together] The testing macros would be as follows (these can of course be renamed if my other pending proposal is rejected): #define scm_is_false(x) \ (((x) & ~(SCM_ELISP_NIL ^ SCM_BOOL_F)) == (SCM_ELISP_NIL & SCM_BOOL_F)) #define scm_is_true(x) \ (((x) & ~(SCM_ELISP_NIL ^ SCM_BOOL_F)) != (SCM_ELISP_NIL & SCM_BOOL_F)) #define scm_is_null(x) \ (((x) & ~(SCM_ELISP_NIL ^ SCM_EOL)) == (SCM_ELISP_NIL & SCM_EOL)) #define scm_is_false_xxx_assume_not_lisp_nil(x) ((x) == SCM_BOOL_F) #define scm_is_true_xxx_assume_not_lisp_nil(x) ((x) != SCM_BOOL_F) #define scm_is_null_xxx_assume_not_lisp_nil(x) ((x) == SCM_EOL) And the lisp boolean tests would be something like this: /* * Since we know SCM_ELISP_NIL and SCM_BOOL_F differ by exactly one * bit, and that SCM_ELISP_NIL and SCM_EOL differ by exactly one bit, * and that they of course can't be the same bit (or else SCM_BOOL_F * and SCM_EOL be would equal), it follows that SCM_BOOL_F and SCM_EOL * differ by exactly two bits, and those are the ones we need to * mask out to collapse all three values together. */ #define scm_is_lisp_false(x) \ (((x) & ~(SCM_BOOL_F ^ SCM_EOL)) == (SCM_BOOL_F & SCM_EOL)) #define scm_is_lisp_true(x) \ (((x) & ~(SCM_BOOL_F ^ SCM_EOL)) != (SCM_BOOL_F & SCM_EOL)) What do you think? Also, you may have noticed that I've been using the term "lisp" instead of "elisp". This is because guile may support other lisps in the future, and they will also need the same %nil handling. (For that matter, we could even use %nil to implement an "old scheme" language which treats '() as false.) With this in mind, should SCM_ELISP_NIL be renamed to SCM_LISP_NIL? Andy: thanks for the warm reception, and I'll answer your questions in a later email. Best regards, Mark