unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
From: Andy Wingo <wingo@pobox.com>
To: Mark H Weaver <mhw@netris.org>
Cc: guile-devel <guile-devel@gnu.org>
Subject: Re: guile and elisp
Date: Sun, 28 Mar 2010 14:13:37 +0200	[thread overview]
Message-ID: <m31vf4k5ji.fsf@pobox.com> (raw)
In-Reply-To: <20100327180158.GC9481@fibril.netris.org> (Mark H. Weaver's message of "Sat, 27 Mar 2010 14:01:59 -0400")

Hey Mark,

Thanks for the thoughts.

On Sat 27 Mar 2010 19:01, Mark H Weaver <mhw@netris.org> writes:

> (BTW, I'm deliberately writing "lisp" instead of "elisp" because these
> discussions should be relevant to any lisp dialect that uses nil for
> both false and eol, and in the future guile might support other
> lisps).

Sure, good point. Scheme is still a lisp, so it helps me to write
"elisp", but I'll try to parse your statements appropriately :)

> On Sat, Mar 27, 2010 at 05:54:24PM +0100, Andy Wingo wrote:
>> I'm not sure (I keep saying "not sure", and I'm really not :) that
>> *value* or *identity* is the way to solve this problem. To me the
>> question is more of *property* -- is this value false, is it equal? to
>> another, is it a boolean, etc.
>
> Well, if we can assume that all non-lisp code in the guile system will
> robustly handle nil by using the appropriate predicates, then yes,
> that's a fine solution with clear semantics.  I just don't think
> we can safely assume that.

Note that we have the same problem on the Scheme side, for code that
assumes that (not x) implies that x is eq? to #f. I don't want to change
eq?, so this hole will exist. But, at least it's a documentable hole,
and we can fix up any code that needs it without e.g. introducing the
concept of #f-but-not-end-of-list into elisp itself, likewise avoiding
introducing the concept of #f-or-end-of-list into Guile.

Which reminds me: another breakage point would be the canonical:

  (cond
    ((null? x) ...)
    ((not x) ...)
    ...)

The result if x is nil depends on the ordering of the null? and not
clauses.

> Someday there may be significant libraries and other complex software
> developed elsewhere being used in guile-emacs.  Most code outside of
> the lisp world has never had to cope with an ambiguous "maybe boolean
      ^^^^ Scheme?

> false or maybe the empty list" value.  When that code meets the lisp
> world, I guarantee you'll start seeing obscure bugs crop up.  The
> system as a whole will not be as robust as it could be.

Of course you're right. I've just been thinking that all solutions will
have this characteristic to greater or lesser degrees.

> A lot of code outside of lisp uses equality to test boolean values.
> If nil is distinct from #f, then that code will fail.

Such code is in poor style IMO; changing it to use the predicates would
make it cleaner and more correct. Not sure how much code would fall
under this case.

> A lot of code assumes that if a value is boolean, then it cannot be a
> list, and vice versa.

Yes. But what can you do? Not all nil values are actually one or the
other.

> Some code looks up booleans and/or lists in hash tables or other
> structures.  That code won't deal gracefully with list structures
> containing nil.

Ah, but it will! There are three cases here, sets with eq?, eqv?, and
equal?. Eq? sets, and to an extent eqv? sets, are designed to return a
value if the key is the actual value that was passed in.

So the key is an opaque value, and it doesn't really matter what it is,
because e.g. (memq x set) won't inspect what x is. X must actually *be*
the object that was inserted into the set; it doesn't matter what type
it is.

A similar argument applies to equal? maps/sets. If you inserted X into a
set, and call (member x set), then the call succeeds, as with eq? sets.

This only leaves the case in which you put X in, then construct a new Y
that should be equal? to X, and call (memq y set). Here's the kicker: if
X was constructed in elisp and contains a nil, and Y was constructed in
Scheme out of Scheme data and thus does not contain a nil, *they aren't
the same*. Not to Scheme anyway!

Of course elisp's equal? sets might operate differently, as I mentioned.

> Some object-oriented languages may overload an operation depending on
> whether a parameter is a boolean or a list.  I don't see how such code
> can deal with nil gracefully without being significantly rewritten.

Well, specifying on lists involves an O(N) calculation at method
dispatch time, so it's not a good idea; but with '() versus #f, GOOPS
can specify one is more specific than the other, but also provide a
protocol to override that default.

> Using your proposed intransitive equality predicates would handle many
> of the common cases properly, but not all of them.

I probably was unclear, but I've decided that intranstive equality is a
worse idea than (equal? '() nil) => #f. (For elisp though, (equalp '()
#f) => t, so equalp can be permissive and transitive.) I would suggest
making equal? in Scheme behave as eq? for booleans.

I don't think that deprecating nil is really an option, because some
nils really are lists and booleans. But I could be wrong on this point,
as on many others!

(More thoughts? :)

Andy
-- 
http://wingolog.org/




  reply	other threads:[~2010-03-28 12:13 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-03-25 12:22 guile and elisp Andy Wingo
2010-03-27 13:07 ` Mark H Weaver
2010-03-27 16:54   ` Andy Wingo
2010-03-27 18:01     ` Mark H Weaver
2010-03-28 12:13       ` Andy Wingo [this message]
2010-03-29  8:42 ` Ludovic Courtès
2010-03-29 10:43   ` Andy Wingo
2010-03-29 12:01     ` Ludovic Courtès
2010-03-29 18:32       ` Grant Rettke

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/guile/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=m31vf4k5ji.fsf@pobox.com \
    --to=wingo@pobox.com \
    --cc=guile-devel@gnu.org \
    --cc=mhw@netris.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).