guile-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: guile and elisp


From: Andy Wingo
Subject: Re: guile and elisp
Date: Sun, 28 Mar 2010 14:13:37 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/23.0.92 (gnu/linux)

Hey Mark,

Thanks for the thoughts.

On Sat 27 Mar 2010 19:01, Mark H Weaver <address@hidden> 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 via email to

[Prev in Thread] Current Thread [Next in Thread]