1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-20 11:40:18 +02:00

more nil docs

* doc/ref/api-languages.texi (Nil): Be a bit more thorough, and
  positive.
This commit is contained in:
Andy Wingo 2010-04-16 09:38:29 +02:00
parent 3279b6b1f5
commit bcbfc9400d

View file

@ -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