From xemacs-m  Wed Jul  2 17:44:17 1997
Received: from cnri.reston.va.us (cnri.CNRI.Reston.VA.US [132.151.1.1])
	by xemacs.org (8.8.5/8.8.5) with ESMTP id RAA10675
	for <xemacs-beta@xemacs.org>; Wed, 2 Jul 1997 17:44:16 -0500 (CDT)
Received: from newcnri.CNRI.Reston.Va.US (newcnri [132.151.1.84]) by cnri.reston.va.us (8.8.5/8.7.3) with SMTPid SAA26136 for <xemacs-beta@xemacs.org>; Wed, 2 Jul 1997 18:47:26 -0400 (EDT)
Received: from anthem.CNRI.Reston.Va.US by newcnri.CNRI.Reston.Va.US (SMI-8.6/SMI-SVR4)
	id SAA11292; Wed, 2 Jul 1997 18:48:31 -0400
Received: by anthem.CNRI.Reston.Va.US (SMI-8.6/SMI-SVR4)
	id SAA16133; Wed, 2 Jul 1997 18:47:30 -0400
Date: Wed, 2 Jul 1997 18:47:30 -0400
Message-Id: <199707022247.SAA16133@anthem.CNRI.Reston.Va.US>
From: "Barry A. Warsaw" <bwarsaw@CNRI.Reston.Va.US>
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
To: xemacs-beta@xemacs.org
Subject: More on Ebola
X-Mailer: VM 6.32 under 20.3 "Sofia" XEmacs  Lucid (beta9)
Reply-To: bwarsaw@python.org
X-Attribution: BAW
X-Oblique-Strategy: Infinitesimal gradations
X-Url: http://www.python.org/~bwarsaw


I have the following situation in parts of CC Mode: I have lots of
places where I compare a character to a return value from
following-char or preceding-char, e.g.:

    (= (following-char) ?a)

and lots of places where I compare the return value to a list of
characters, e.g.:

    (memq (following-char) '(?a ?b ?c))

Virologists in the audience will recognize the risk factors for Ebola
infection in that second statement.  Now to make things more fun, in
the really nasty bigass function c-guess-basic-syntax I grab and cache
two oft-consulted characters, the first non-whitespace before point
and the first non-whitespace after point.  Turns out I do a lot of
both types of comparisons, and this gets me in a bind w.r.t. Ebola
warnings.

The = comparisons are great because of the type coersion so even if
f-c returns int(0), no Ebola.  But memq is really convenient to test
if a character is in a set of expected characters.  Here, because eq
is used, no type conversion occurs and Ebola festers.  But switching
to char-after & char-before everywhere sucks because at the boundary
conditions these two functions return nil.  Just try to (= nil ?a)!

I really don't want to add a test for nil before every = so how do I
reconcile the nil/0 semantics I'm expecting.  My current solution is
to add this definition:

(defsubst mem= (elt list)
  "Return non-nil if ELT is an element of LIST.  Comparison done with `='.
The value is actually the tail of LIST whose car is ELT."
  ;; I really hate to have to do this, but...
  (while (and list (/= elt (car list)))
    (setq list (cdr list)))
  list)

and use mem= instead of memq in the places where I want to test a
character for membership in a set of characters.  Kind of sucks
because it's slower than memq, but it shouldn't be hard to write it in 
C if necessary (and convince RMS to do the same?  hmm...)

One thing that I'd like to propose is to change f-c and p-c semantics
such that they return ^@ (char \000) instead of int 0.  Then eq/memq
shouldn't complain.  But I wonder how much that would break.  I'm now
ducking under the desk. :-)  Still, at first glance this seems like
the best backwards compatible approach, especially given the
deprecated nature of f-c and p-c.

Hmm, maybe I'll try to redefine f-c and p-c in my .emacs file and See
Wha Hoppens!

Comments?

-Barry

