From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Andy Wingo Newsgroups: gmane.lisp.guile.devel Subject: Re: guile and elisp Date: Sun, 28 Mar 2010 14:13:37 +0200 Message-ID: References: <20100327130750.GA9026@fibril.netris.org> <20100327180158.GC9481@fibril.netris.org> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: dough.gmane.org 1269781310 17790 80.91.229.12 (28 Mar 2010 13:01:50 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Sun, 28 Mar 2010 13:01:50 +0000 (UTC) Cc: guile-devel To: Mark H Weaver Original-X-From: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Sun Mar 28 15:01:46 2010 Return-path: Envelope-to: guile-devel@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1Nvs7b-0003Le-Ns for guile-devel@m.gmane.org; Sun, 28 Mar 2010 15:01:44 +0200 Original-Received: from localhost ([127.0.0.1]:58053 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NvroP-0001or-BR for guile-devel@m.gmane.org; Sun, 28 Mar 2010 08:41:53 -0400 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1Nvrlp-0000JQ-BL for guile-devel@gnu.org; Sun, 28 Mar 2010 08:39:13 -0400 Original-Received: from [140.186.70.92] (port=42586 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Nvri0-0007kK-EQ for guile-devel@gnu.org; Sun, 28 Mar 2010 08:39:12 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1Nvrhn-0003n3-E4 for guile-devel@gnu.org; Sun, 28 Mar 2010 08:35:05 -0400 Original-Received: from a-pb-sasl-quonix.pobox.com ([208.72.237.25]:42101 helo=sasl.smtp.pobox.com) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1Nvrhn-0003mz-4c for guile-devel@gnu.org; Sun, 28 Mar 2010 08:35:03 -0400 Original-Received: from sasl.smtp.pobox.com (unknown [127.0.0.1]) by a-pb-sasl-quonix.pobox.com (Postfix) with ESMTP id F0B49A4F03; Sun, 28 Mar 2010 08:35:02 -0400 (EDT) DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=pobox.com; h=from:to:cc :subject:references:date:in-reply-to:message-id:mime-version :content-type; s=sasl; bh=5MbM30VzS2miXJBr9UrFmPXVwtI=; b=x6JQUu 7Be1qRwFli36VUAdamgUwqKo65MaFJy7RZjtwcsfCxXLGvae/O12x9L2FrblU0qH zHtsF9cCyHYzNe1yEgoZPrK4ru78qIyNEqk4ar/N08qS/8g0Vr5IuPXJdEHlrYJ5 OzXJDYXKchfUMKwMzqm+I9y6insvfHZIzPJW0= DomainKey-Signature: a=rsa-sha1; c=nofws; d=pobox.com; h=from:to:cc :subject:references:date:in-reply-to:message-id:mime-version :content-type; q=dns; s=sasl; b=B7f2QcgHcYZY3McZbgpDcauMHOh4K3m/ Wgwu0gM1haNI2uYS6Z5wIbbxViuJpXWKeBaFKKTqWCO2gtXLp4l6CNCaCO76Ryjy S02+QNZRdODLovgxKz/5Qr49ykFnOn9TvGfBz8sex46Xytb6GRwVjlIEKAF+5u1+ rAtizd+4Z3I= Original-Received: from a-pb-sasl-quonix. (unknown [127.0.0.1]) by a-pb-sasl-quonix.pobox.com (Postfix) with ESMTP id DE6EBA4F02; Sun, 28 Mar 2010 08:35:01 -0400 (EDT) Original-Received: from unquote (unknown [82.123.111.19]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by a-pb-sasl-quonix.pobox.com (Postfix) with ESMTPSA id 4A58CA4F01; Sun, 28 Mar 2010 08:35:00 -0400 (EDT) In-Reply-To: <20100327180158.GC9481@fibril.netris.org> (Mark H. Weaver's message of "Sat, 27 Mar 2010 14:01:59 -0400") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.0.92 (gnu/linux) X-Pobox-Relay-ID: 543E0622-3A66-11DF-ADAD-D033EE7EF46B-02397024!a-pb-sasl-quonix.pobox.com X-detected-operating-system: by eggs.gnu.org: Solaris 10 (beta) X-BeenThere: guile-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Developers list for Guile, the GNU extensibility library" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Errors-To: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.lisp.guile.devel:10098 Archived-At: Hey Mark, Thanks for the thoughts. On Sat 27 Mar 2010 19:01, Mark H Weaver 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/