From bcbfc9400d660b0bf05104b399c1ad177669b456 Mon Sep 17 00:00:00 2001 From: Andy Wingo Date: Fri, 16 Apr 2010 09:38:29 +0200 Subject: [PATCH] more nil docs * doc/ref/api-languages.texi (Nil): Be a bit more thorough, and positive. --- doc/ref/api-languages.texi | 71 ++++++++++++++++++++++++++++++-------- 1 file changed, 57 insertions(+), 14 deletions(-) diff --git a/doc/ref/api-languages.texi b/doc/ref/api-languages.texi index 8109fbde8..a9531a273 100644 --- a/doc/ref/api-languages.texi +++ b/doc/ref/api-languages.texi @@ -107,8 +107,8 @@ code to maintain their current semantics. @code{nil}, which in Elisp would just be written and read as @code{nil}, in Scheme has the external representation @code{#nil}. -This decision to have @code{nil} as a low-level distinct value does -complicate interoperability between the two languages. Guile has chosen +This decision to have @code{nil} as a low-level distinct value +facilitates interoperability between the two languages. Guile has chosen to have Scheme deal with @code{nil} as follows: @example @@ -117,17 +117,62 @@ to have Scheme deal with @code{nil} as follows: (null? #nil) @result{} #t @end example +And in C, one has: + +@example +scm_is_bool (SCM_ELISP_NIL) @result{} 1 +scm_is_false (SCM_ELISP_NIL) @result{} 1 +scm_is_null (SCM_ELISP_NIL) @result{} 1 +@end example + +In this way, a version of @code{fold} written in Scheme can correctly +fold a function written in Elisp (or in fact any other language) over a +nil-terminated list, as Elisp makes. The converse holds as well; a +version of @code{fold} written in Elisp can fold over a +@code{'()}-terminated list, as made by Scheme. + +On a low level, the bit representations for @code{#f}, @code{#t}, +@code{nil}, and @code{'()} are made in such a way that the differ by +only one bit, and so a test for, for example, @code{#f}-or-@code{nil} +may be made very efficiently. See @code{libguile/boolean.h}, for more +information. + +@subsubsection Equality + Since Scheme's @code{equal?} must be transitive, and @code{'()} is not @code{equal?} to @code{#f}, to Scheme @code{nil} is not @code{equal?} to @code{#f} or @code{'()}. +@example +(eq? #f '()) @result{} #f +(eq? #nil '()) @result{} #f +(eq? #nil #f) @result{} #f +(eqv? #f '()) @result{} #f +(eqv? #nil '()) @result{} #f +(eqv? #nil #f) @result{} #f +(equal? #f '()) @result{} #f +(equal? #nil '()) @result{} #f +(equal? #nil #f) @result{} #f +@end example + However, in Elisp, @code{'()}, @code{#f}, and @code{nil} are all -@code{eqv} (though not @code{eq}). +@code{equal} (though not @code{eq}). + +@example +(defvar f (make-scheme-false)) +(defvar eol (make-scheme-null)) +(eq f eol) @result{} nil +(eq nil eol) @result{} nil +(eq nil f) @result{} nil +(equal f eol) @result{} t +(equal nil eol) @result{} t +(equal nil f) @result{} t +@end example These choices facilitate interoperability between Elisp and Scheme code, -but they are not perfect. Some code that is historically correct -standard Scheme is not correct in the presence of a second false and -null value. For example: +but they are not perfect. Some code that is correct standard Scheme is +not correct in the presence of a second false and null value. For +example: @example (define (truthiness x) @@ -156,9 +201,12 @@ Here, @code{my-length} will raise an error if @var{l} is a Both of these examples are correct standard Scheme, but, depending on what they really want to do, they are not correct Guile Scheme. Correctly written, they would test the @emph{properties} of falsehood or -nullity, not the individual members of that set. That is to say, use -@code{not} or @code{null?} to test for falsehood or nullity, not -@code{eq?} or @code{memv} or the like. +nullity, not the individual members of that set. That is to say, they +should use @code{not} or @code{null?} to test for falsehood or nullity, +not @code{eq?} or @code{memv} or the like. + +Fortunately, using @code{not} and @code{null?} is in good style, so all +well-written standard Scheme programs are correct, in Guile Scheme. Here are correct versions of the above examples: @@ -189,11 +237,6 @@ This problem has a mirror-image case in Elisp: Guile can warn when compiling code that has equality comparisons with @code{#f}, @code{'()}, or @code{nil}. @xref{Compilation}, for details. -On a low level, the bit representations for @code{#f}, @code{#t}, -@code{nil}, and @code{'()} are made in such a way that the differ by -only one bit, and so a test for, for example, @code{#f}-or-@code{nil} -may be made very efficiently. - @node Dynamic Binding @subsubsection Dynamic Binding