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:
parent
3279b6b1f5
commit
bcbfc9400d
1 changed files with 57 additions and 14 deletions
|
@ -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
|
would just be written and read as @code{nil}, in Scheme has the external
|
||||||
representation @code{#nil}.
|
representation @code{#nil}.
|
||||||
|
|
||||||
This decision to have @code{nil} as a low-level distinct value does
|
This decision to have @code{nil} as a low-level distinct value
|
||||||
complicate interoperability between the two languages. Guile has chosen
|
facilitates interoperability between the two languages. Guile has chosen
|
||||||
to have Scheme deal with @code{nil} as follows:
|
to have Scheme deal with @code{nil} as follows:
|
||||||
|
|
||||||
@example
|
@example
|
||||||
|
@ -117,17 +117,62 @@ to have Scheme deal with @code{nil} as follows:
|
||||||
(null? #nil) @result{} #t
|
(null? #nil) @result{} #t
|
||||||
@end example
|
@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{'()}
|
Since Scheme's @code{equal?} must be transitive, and @code{'()}
|
||||||
is not @code{equal?} to @code{#f}, to Scheme @code{nil} is not
|
is not @code{equal?} to @code{#f}, to Scheme @code{nil} is not
|
||||||
@code{equal?} to @code{#f} or @code{'()}.
|
@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
|
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,
|
These choices facilitate interoperability between Elisp and Scheme code,
|
||||||
but they are not perfect. Some code that is historically correct
|
but they are not perfect. Some code that is correct standard Scheme is
|
||||||
standard Scheme is not correct in the presence of a second false and
|
not correct in the presence of a second false and null value. For
|
||||||
null value. For example:
|
example:
|
||||||
|
|
||||||
@example
|
@example
|
||||||
(define (truthiness x)
|
(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
|
Both of these examples are correct standard Scheme, but, depending on
|
||||||
what they really want to do, they are not correct Guile Scheme.
|
what they really want to do, they are not correct Guile Scheme.
|
||||||
Correctly written, they would test the @emph{properties} of falsehood or
|
Correctly written, they would test the @emph{properties} of falsehood or
|
||||||
nullity, not the individual members of that set. That is to say, use
|
nullity, not the individual members of that set. That is to say, they
|
||||||
@code{not} or @code{null?} to test for falsehood or nullity, not
|
should use @code{not} or @code{null?} to test for falsehood or nullity,
|
||||||
@code{eq?} or @code{memv} or the like.
|
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:
|
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
|
Guile can warn when compiling code that has equality comparisons with
|
||||||
@code{#f}, @code{'()}, or @code{nil}. @xref{Compilation}, for details.
|
@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
|
@node Dynamic Binding
|
||||||
@subsubsection Dynamic Binding
|
@subsubsection Dynamic Binding
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue