Account Options

  1. Sign in
The old Google Groups will be going away soon, but your browser is incompatible with the new version.
Google Groups Home
« Groups Home
I never realized the funny difference between nil and () before.
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  19 messages - Collapse all  -  Translate all to Translated (View all originals)
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
jimka  
View profile  
 More options Nov 1 2011, 10:44 am
Newsgroups: comp.lang.lisp
From: jimka <ji...@rdrop.com>
Date: Tue, 1 Nov 2011 07:44:30 -0700 (PDT)
Local: Tues, Nov 1 2011 10:44 am
Subject: I never realized the funny difference between nil and () before.
I got this excerpt from Common Lisp the Language, 2nd Edition
http://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node9.html#SECTION00522...

An empty list may ... be written (); this normally denotes the same
object as nil.
(It is possible, by extremely perverse manipulation of the package
system, to cause the sequence of letters nil to be recognized not as
the symbol that represents the empty list but as another symbol with
the same name.)


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Madhu  
View profile  
 More options Nov 1 2011, 11:50 am
Newsgroups: comp.lang.lisp
From: Madhu <enom...@meer.net>
Date: Tue, 01 Nov 2011 21:20:58 +0530
Local: Tues, Nov 1 2011 11:50 am
Subject: Re: I never realized the funny difference between nil and () before.

There is only one, One, ONE!!, One, one symbol which is CL:NIL

* jimka <d6bccc83-d83e-4f44-aeb6-106fb1817...@s35g2000pra.googlegroups.com> :
Wrote on Tue, 1 Nov 2011 07:44:30 -0700 (PDT):

[cltl]

| An empty list may ... be written (); this normally denotes the same
| object as nil.  (It is possible, by extremely perverse manipulation of
| the package system, to cause the sequence of letters nil to be
| recognized not as the symbol that represents the empty list but as
| another symbol with the same name.)

There is no difference between CL:NIL and ().

This is probably GLS' idea of "extremely perverse manipulation of the
package system"

 (defpackage "FOO"
    (:use "CL")
    (:shadow "NIL")
    (:export "NIL"))

 (setq foo:nil t)
 (in-package "FOO")

 (eq nil ()) ;; => CL:NIL

But, There is no difference between CL:NIL and ().

There is only one, One, ONE!!, One, one symbol which is CL:NIL

--- Madhu


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Pascal Costanza  
View profile  
 More options Nov 1 2011, 12:04 pm
Newsgroups: comp.lang.lisp
From: Pascal Costanza <p...@p-cos.net>
Date: Tue, 01 Nov 2011 17:04:52 +0100
Local: Tues, Nov 1 2011 12:04 pm
Subject: Re: I never realized the funny difference between nil and () before.
On 01/11/2011 16:50, Madhu wrote:

That is not perverse. Here is something perverse:

CL-USER 1 > (rename-package :cl "COMMON-LISP-OLD")
#<The COMMON-LISP-OLD package, 3/4 internal, 978/1024 external>

CL-USER 2 > (defpackage "COMMON-LISP"
               (:use :common-lisp-old)
               (:shadow "NIL")
               (:export "NIL"))

Error: Defining system package COMMON-LISP.
   1 (continue) Define it anyway.
   2 (abort) Return to level 0.
   3 Return to top loop level 0.

Type :b for backtrace or :c <option number> to proceed.
Type :bug-form "<subject>" for a bug report template or :? for other
options.

CL-USER 3 : 1 > :c
#<The COMMON-LISP package, 0/16 internal, 1/16 external>

CL-USER 4 > (in-package :common-lisp)
#<The COMMON-LISP package, 0/16 internal, 1/16 external>

COMMON-LISP 5 > (defparameter nil 42)

Error: Defining variable NIL visible from package COMMON-LISP.
   1 (continue) Define it anyway.
   2 (abort) Return to level 0.
   3 Return to top loop level 0.

Type :b for backtrace or :c <option number> to proceed.
Type :bug-form "<subject>" for a bug report template or :? for other
options.

COMMON-LISP 6 : 1 > :c
NIL

COMMON-LISP 7 > nil
42

;-)

--
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
The views expressed are my own, and not those of my employer.


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Pascal J. Bourguignon  
View profile  
 More options Nov 1 2011, 12:46 pm
Newsgroups: comp.lang.lisp
From: "Pascal J. Bourguignon" <p...@informatimago.com>
Date: Tue, 01 Nov 2011 17:46:25 +0100
Local: Tues, Nov 1 2011 12:46 pm
Subject: Re: I never realized the funny difference between nil and () before.

That's not perverse.  Here is something perverse:

    ;; Add to your new common lisp package:

    (defun null (x) (or (eql x 'nil) (eql x nil)))

    (set-macro-character #\(
      (lambda (stream ch)
        (if (char= (peek-char t stream) #\))
           'nil
           (read-delimited-list #\)  stream t))))

so that (and (eql '() 'nil)
             (eql  ()  nil)
             (not (eql '()  nil))
             (not (eql  () 'nil))
             (null  ())
             (null '())
             (null  nil)
             (null 'nil))

--
__Pascal Bourguignon__                     http://www.informatimago.com/
A bad day in () is better than a good day in {}.


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Kaz Kylheku  
View profile  
 More options Nov 2 2011, 1:16 pm
Newsgroups: comp.lang.lisp
From: Kaz Kylheku <k...@kylheku.com>
Date: Wed, 2 Nov 2011 17:16:12 +0000 (UTC)
Local: Wed, Nov 2 2011 1:16 pm
Subject: Re: I never realized the funny difference between nil and () before.
On 2011-11-01, jimka <ji...@rdrop.com> wrote:

> I got this excerpt from Common Lisp the Language, 2nd Edition
> http://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node9.html#SECTION00522...

> An empty list may ... be written (); this normally denotes the same
> object as nil.
> (It is possible, by extremely perverse manipulation of the package
> system, to cause the sequence of letters nil to be recognized not as
> the symbol that represents the empty list but as another symbol with
> the same name.)

Forgetting to bring in symbols from the :cl package is hardly perverse,
let alone extremely perverse:

[1]> (defpackage :my-package (:use))
#<PACKAGE MY-PACKAGE>
[2]> (in-package :my-package)
#<PACKAGE MY-PACKAGE>
MY-PACKAGE[3]> nil

*** - SYSTEM::READ-EVAL-PRINT: variable NIL has no value
The following restarts are available:
USE-VALUE      :R1      Input a value to be used instead of NIL.
STORE-VALUE    :R2      Input a new value for NIL.
ABORT          :R3      Abort main loop


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
fortunatus  
View profile  
 More options Nov 2 2011, 8:00 pm
Newsgroups: comp.lang.lisp
From: fortunatus <daniel.elia...@excite.com>
Date: Wed, 2 Nov 2011 17:00:32 -0700 (PDT)
Local: Wed, Nov 2 2011 8:00 pm
Subject: Re: I never realized the funny difference between nil and () before.
I find the basic concept a little odd in itself:

CL-USER> (symbolp 'nil)
T                       <-- no sweat
CL-USER> (symbolp nil)
T                       <-- kind of freaky...
CL-USER> (symbolp '( ))
T                       <-- this freaks me out!!
CL-USER> (symbolp ( ))
T
CL-USER> (symbolp '( nil ))
NIL                     <-- finally back to normalcy - whew

A list is not a symbol but the empty list is a symbol?!!  The nothing-
value is a symbol?  That freaks me out!


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Ankur  
View profile  
 More options Nov 3 2011, 1:12 am
Newsgroups: comp.lang.lisp
From: Ankur <an...@lipidity.com>
Date: Thu, 03 Nov 2011 05:12:21 GMT
Local: Thurs, Nov 3 2011 1:12 am
Subject: Re: I never realized the funny difference between nil and () before.
* fortunatus <daniel.elia...@excite.com>

> I find the basic concept a little odd in itself:

> CL-USER> (symbolp 'nil)
> T                       <-- no sweat
> CL-USER> (symbolp nil)
> T                       <-- kind of freaky...

[1]> (symbolp ':hi)
T
[2]> (symbolp :hi)
T

> CL-USER> (symbolp '( ))
> T                       <-- this freaks me out!!
> CL-USER> (symbolp ( ))
> T

Why? () is the same as NIL, isn't it?

> CL-USER> (symbolp '( nil ))
> NIL                     <-- finally back to normalcy - whew

(listp '(nil)) => T

It's a list with one element.

> A list is not a symbol but the empty list is a symbol?!!  The nothing-
> value is a symbol?  That freaks me out!

It's defined that way, isn't it? What's freaky about it?

--
Ankur


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Kaz Kylheku  
View profile  
 More options Nov 3 2011, 1:46 am
Newsgroups: comp.lang.lisp
From: Kaz Kylheku <k...@kylheku.com>
Date: Thu, 3 Nov 2011 05:46:37 +0000 (UTC)
Local: Thurs, Nov 3 2011 1:46 am
Subject: Re: I never realized the funny difference between nil and () before.
On 2011-11-03, fortunatus <daniel.elia...@excite.com> wrote:

> I find the basic concept a little odd in itself:

> CL-USER> (symbolp 'nil)
> T                       <-- no sweat
> CL-USER> (symbolp nil)
> T                       <-- kind of freaky...

CL-USER> nil
NIL
CL-USER> 'nil
NIL

The object nil, when treated as program syntax to be evaluated,
evaluates to itself, nil. So nil and (quote nil) is the same.

(QUOTE X) and X is the same thing for any X which evaluates to itself!

Thus this is the case for most atoms, and some kinds of symbols. The symbol T,
and keyword symbols:

CL-USER> 5
5
CL-USER> '5
5

CL-USER> 'T
T
CL-USER> T
T

CL-USER> ':keyword-x
:KEYWORD-X
CL-USER> :keyword-x
:KEYWORD-X

> CL-USER> (symbolp '( ))
> T                       <-- this freaks me out!!

Note how the unquoted case freaks you out when you use nil,
and the quoted case freaks you out when you use (). Haha!

Since empty list is represented by the symbol NIL, symbolp has to return
T for an empty list.

> A list is not a symbol but the empty list is a symbol?!!  The nothing-

A list is not an encapsulated container of stuff like in some languages. It is
recursively defined as one of two things:

1. The symbol nil, denoting an empty list
2. A cons cell, with the first element of the list in CAR, and
   a list of the remaining elements in CDR.

(A cons cell which has something other than a list in CDR is called
an "improper list".)

So you cannot have an operation like

  (list-append list new_element)

unless list-append is an operator rather than a function. You cannot turn a
list stored in a location L from empty to non-empty without overwriting the
location L with a new object:

  (setf L (cons 1 L))  ;; prepend 1 to list L.

The above can be done using a standard macro:

  (push 1 L) ;; expands to something similar to (setf L (cons 1 L)).

The container's identity changes!

This is an important feature in Lisp because of this:

  (let* ((list1 '(1 2 3))
         (list2 (cons 0 list1))
         (list3 (cdr list1)))
   (values list1 list2 list3))

We can prepend to a list, or remove the first item from a list,
without modifying it in any way. (In fact the literal list '(1 2 3)
cannot be modified without invoking undefined behavior!)

The expressions which initialize list2 and list3 just perform some
pointer manipulations: allocate a cons cell, and stuff the existing
list into the CDR, thereby obtaining a longer list; or retrieve
the CDR of the original list to obtain a suffix of it shortened
by one item.

In Lisp, a lot of computation is done using lists, whereby old lists are turned
into parts of new lists, without a lot of unnecessary copying going on.

Recursion on list structures takes place without copying cells
thereby creating garbage.

> value is a symbol?

It's not a nothing value. It's an empty list value which also serves
as a boolean false.

To obtain a nothing value, call the function VALUES with no arguments:

 CL-USER> (values)

But, alas, even that is a symbol:

 CL-USER> (symbolp (values))
 T

:)

This is because if the expression (values) is used in a context
that requires a value, like a function argument, a default value
of NIL is supplied.  


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
fortunatus  
View profile  
 More options Nov 3 2011, 11:01 am
Newsgroups: comp.lang.lisp
From: fortunatus <daniel.elia...@excite.com>
Date: Thu, 3 Nov 2011 08:01:00 -0700 (PDT)
Subject: Re: I never realized the funny difference between nil and () before.
On Nov 3, 1:46 am, Kaz Kylheku <k...@kylheku.com> wrote:

> To obtain a nothing value, call the function VALUES with no arguments:

>  CL-USER> (values)

> But, alas, even that is a symbol:

>  CL-USER> (symbolp (values))
>  T

> :)

AAAAAAHHHHH!!!!

 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
fortunatus  
View profile  
 More options Nov 3 2011, 11:21 am
Newsgroups: comp.lang.lisp
From: fortunatus <daniel.elia...@excite.com>
Date: Thu, 3 Nov 2011 08:21:42 -0700 (PDT)
Local: Thurs, Nov 3 2011 11:21 am
Subject: Re: I never realized the funny difference between nil and () before.
On Nov 3, 1:46 am, Kaz Kylheku <k...@kylheku.com> wrote:

> A list is not an encapsulated container of stuff like in some languages. It is
> recursively defined as one of two things:

> 1. The symbol nil, denoting an empty list
> 2. A cons cell, with the first element of the list in CAR, and
>    a list of the remaining elements in CDR.

A very good point!

 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Barry Fishman  
View profile  
 More options Nov 3 2011, 11:40 am
Newsgroups: comp.lang.lisp
From: Barry Fishman <barry_fish...@acm.org>
Date: Thu, 03 Nov 2011 11:40:36 -0400
Local: Thurs, Nov 3 2011 11:40 am
Subject: Re: I never realized the funny difference between nil and () before.

On 2011-11-03 01:46:37 EDT, Kaz Kylheku wrote:

> (QUOTE X) and X is the same thing for any X which evaluates to itself!

I don't think so.  They evaluate to the same thing.  This is an
important distinction when writing macros:

 (non-eval-eq (a b)
   `(eq ',a ',b))

 (non-eval-eq (quote nil) nil)
 ==> nil
 (non-eval-eq () nil)
 ==> t

--
Barry Fishman


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Don Geddis  
View profile  
 More options Nov 3 2011, 11:29 am
Newsgroups: comp.lang.lisp
From: Don Geddis <d...@geddis.org>
Date: Thu, 03 Nov 2011 08:29:19 -0700
Local: Thurs, Nov 3 2011 11:29 am
Subject: Re: I never realized the funny difference between nil and () before.
Pascal Costanza <p...@p-cos.net> wrote on Tue, 01 Nov 2011:

Sure, but redefining symbols in the COMMON-LISP package already violates
the standard, right?  (Hence the continuable error you got.)  It's cute,
but CLTL hardly needed a parenthetical warning against people who
deliberately violate other parts of the standard.  Surely Steele had
some other example in mind...

        -- Don
___________________________________________________________________________ ____
Don Geddis                  http://don.geddis.org/               d...@geddis.org
There has been an alarming increase in the number of things you know nothing
about.


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Kaz Kylheku  
View profile  
 More options Nov 3 2011, 12:12 pm
Newsgroups: comp.lang.lisp
From: Kaz Kylheku <k...@kylheku.com>
Date: Thu, 3 Nov 2011 16:12:33 +0000 (UTC)
Local: Thurs, Nov 3 2011 12:12 pm
Subject: Re: I never realized the funny difference between nil and () before.
On 2011-11-03, Barry Fishman <barry_fish...@acm.org> wrote:

> On 2011-11-03 01:46:37 EDT, Kaz Kylheku wrote:
>> (QUOTE X) and X is the same thing for any X which evaluates to itself!

> I don't think so.

I see, this is what Tim Bradshaw was talking about a couple of days ago.

 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Tim Bradshaw  
View profile  
 More options Nov 3 2011, 3:58 pm
Newsgroups: comp.lang.lisp
From: Tim Bradshaw <t...@tfeb.org>
Date: Thu, 3 Nov 2011 19:58:27 +0000 (UTC)
Local: Thurs, Nov 3 2011 3:58 pm
Subject: Re: I never realized the funny difference between nil and () before.

Kaz Kylheku <k...@kylheku.com> wrote:

> A list is not an encapsulated container of stuff like in some languages. It is
> recursively defined as one of two things:

> 1. The symbol nil, denoting an empty list
> 2. A cons cell, with the first element of the list in CAR, and
>    a list of the remaining elements in CDR.

I think that NIL has been implementationally interesting sometimes though:
since (car nil) is nil &c, I think there have been (are?) implementations
which do some clever trick to make code not have to special-case NIL.
Someone who knows more about implementations than me might have a better
comment.

 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Kaz Kylheku  
View profile  
 More options Nov 3 2011, 4:22 pm
Newsgroups: comp.lang.lisp
From: Kaz Kylheku <k...@kylheku.com>
Date: Thu, 3 Nov 2011 20:22:02 +0000 (UTC)
Local: Thurs, Nov 3 2011 4:22 pm
Subject: Re: I never realized the funny difference between nil and () before.
On 2011-11-03, Tim Bradshaw <t...@tfeb.org> wrote:

> Kaz Kylheku <k...@kylheku.com> wrote:

>> A list is not an encapsulated container of stuff like in some languages. It is
>> recursively defined as one of two things:

>> 1. The symbol nil, denoting an empty list
>> 2. A cons cell, with the first element of the list in CAR, and
>>    a list of the remaining elements in CDR.

> I think that NIL has been implementationally interesting sometimes though:
> since (car nil) is nil &c, I think there have been (are?) implementations
> which do some clever trick to make code not have to special-case NIL.
> Someone who knows more about implementations than me might have a better
> comment.

By "not special case it" I think you mean that it actually looks like a symbol,
or cons cell, etc.

In unsafe compiled code you could get some boost if (car x) compiles to
something that doesn't check the type of x, if x is declared to be a list.  If
nil is actually a pointer to something that looks like a cons, you get smaller
code. One or two less words in the instruction cache, but a hit to the data
cache.

In a lot of code you do compare against nil. If this nil-cons could be located
a constant address in every image, then you can still do efficient tests for
the presence of nil.

It would just be annoying for someone debugging at the machine level, if nil
does not have a clear bit pattern, that's all. :)


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Tim Bradshaw  
View profile  
 More options Nov 3 2011, 5:10 pm
Newsgroups: comp.lang.lisp
From: Tim Bradshaw <t...@tfeb.org>
Date: Thu, 3 Nov 2011 21:10:44 +0000 (UTC)
Local: Thurs, Nov 3 2011 5:10 pm
Subject: Re: I never realized the funny difference between nil and () before.
Kaz Kylheku <k...@kylheku.com> wrote:

.

> By "not special case it" I think you mean that it actually looks like a symbol,
> or cons cell, etc.

Yes. The HOPL paper describes this, in fact, and it seems to be MACLISP
which I was remembering (a description of - I never used it). Interestingly
tha (car nil) = nil &c thing seems to have come from InterLisp, and wasn't
always true in other Lisps: I didn't know that.

 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Kaz Kylheku  
View profile  
 More options Nov 3 2011, 5:53 pm
Newsgroups: comp.lang.lisp
From: Kaz Kylheku <k...@kylheku.com>
Date: Thu, 3 Nov 2011 21:53:39 +0000 (UTC)
Local: Thurs, Nov 3 2011 5:53 pm
Subject: Re: I never realized the funny difference between nil and () before.
On 2011-11-03, Tim Bradshaw <t...@tfeb.org> wrote:

> Kaz Kylheku <k...@kylheku.com> wrote:
> .

>> By "not special case it" I think you mean that it actually looks like a symbol,
>> or cons cell, etc.

> Yes. The HOPL paper describes this, in fact, and it seems to be MACLISP
> which I was remembering (a description of - I never used it). Interestingly
> tha (car nil) = nil &c thing seems to have come from InterLisp, and wasn't
> always true in other Lisps: I didn't know that.

Really. Let's make a quick peek at the Lisp 1.5 manual.

Ah, here we go. Page 2:

  "car of an atomic symbol is undefined"

Not every good idea in Lisp was discovered early, like allowing (car nil) and
(cdr nil).

This has me googling for "A Short Ballad Dedicated to The Growth Of Programs"
by Ashwin Ram. :)


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Alex Mizrahi  
View profile  
 More options Nov 4 2011, 3:23 pm
Newsgroups: comp.lang.lisp
From: Alex Mizrahi <alex.mizr...@gmail.com>
Date: Fri, 04 Nov 2011 21:23:59 +0200
Local: Fri, Nov 4 2011 3:23 pm
Subject: Re: I never realized the funny difference between nil and () before.

> A list is not a symbol but the empty list is a symbol?!!  The nothing-
> value is a symbol?  That freaks me out!

It is in line with mathematical set theory notation where empty set is
represented with crossed O and other sets with a list of members, e.g.
0
{0}
{{0}}
{{0},0}

 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Rob Warnock  
View profile  
 More options Nov 5 2011, 12:04 am
Newsgroups: comp.lang.lisp
From: r...@rpw3.org (Rob Warnock)
Date: Fri, 04 Nov 2011 23:04:02 -0500
Local: Sat, Nov 5 2011 12:04 am
Subject: Re: I never realized the funny difference between nil and () before.
Tim Bradshaw  <t...@tfeb.org> wrote:
+---------------
| Kaz Kylheku <k...@kylheku.com> wrote:
| > By "not special case it" I think you mean that it actually looks like
| > a symbol, or cons cell, etc.
|
| Yes. The HOPL paper describes this, in fact, and it seems to be MACLISP
| which I was remembering (a description of - I never used it). Interestingly
| tha (car nil) = nil &c thing seems to have come from InterLisp, and wasn't
| always true in other Lisps: I didn't know that.
+---------------

CMUCL implements a variant of this overly-"clever" hack:

1. The value of NIL (0x28f0000b) is low-tagged with 0x3, which says LIST
   (well, CONS, really). CONS cells are two words only, and have no heap
   header word.

2. The process-wide single instance of the internal NIL *symbol structure*
   is located in a fixed place (0x28f00004), and is deliberately mis-aligned
   compared to "normal" symbols, which are aligned on 8-byte boundaries
   [as are all heap objects except NIL!].

3. The first two slots of the symbol NIL (Value & Hash) contain the
   value NIL (0x28f0000b) so that *WHEN TREATED AS A CONS POINTER*
   the value of NIL is of the correct format [including low-tag]
   to be a (CONS NIL NIL) cell pointer. So NIL == (CAR NIL) == (CDR NIL).

4. But *if* you can sneak the value of NIL past the usual low-tag checks
   in symbol-processing functions [the low-tag for a symbol is 0x7, the
   same as generic "other" heap objects], then the value of NIL when
   a *symbol's* low-tag (0x7) is subtracted from it -- I say again,
   *subtracted* from it, *not* masked off! -- is (0x28f0000b - 7) =
   0x28f00004, which is indeed the address of the *symbol* NIL's
   heap header.

Now somebody surely thought this was a performance advantage way back
when CMUCL was first designed, but these days with instruction execution
being *much* faster than memory references, there's a better way:

Simply allocate a small (8-bit) otherwise-unused "immediate" constant
to NIL [the value 0x2, "type_OtherImmediate0" is available & convenient],
and go ahead and put the special-case checks everywhere you need them
in the code. It's actually *faster* to test for an 8-bit immediate than
to compare against a full memory address. And there are really only a
few places that need to do the special-case test for NIL as a symbol.

I haven't yet made that change to CMUCL, but I did make it to my own
toy Lisp, QDL ("Quick & Dirty Lisp"), which uses the same low-tag scheme
as CMUCL... and originally used exactly the same NIL hack as well!!
Changing NIL from being a fixed-location oddly-aligned symbol to being
an "immediate" constant resulted in only a tiny speedup in my benchmarks,
but at least it *didn't* cause a slowdown!  ;-}

-Rob

-----
Rob Warnock             <r...@rpw3.org>
627 26th Avenue         <http://rpw3.org/>
San Mateo, CA 94403


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
End of messages
« Back to Discussions « Newer topic     Older topic »