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

Re: Issue: COERCE-INCOMPLETE (Version 2)



I'm willing to deal with this on a line-item basis if people want to point to
some line items they would strike, change, or add in order to fix things.
If people wanted to flush all of the made-up types, I wouldn't probably object.
But I hope they'd do it for a more purposeful reason than just because it
doesn't perpetuate the status quo. I'm hoping that we'll at least adopt CHAR-CODE
and CHAR-INT because I believe them to be the most useful.  What I wanted to
do, though, was to present a fully elaborated proposal because the last version
(COERCE-FROM-TYPE, v1) only alluded to what might be done and I was worried
that the idea wasn't clear in everyone's mind. Perhaps now it's all too clear. :-)

In the case of ACCESSIBLE-SYMBOL, I certainly agree with your reservations
to an extent, but let me tell you where I was coming from. Btw, I think
the SYMBOL coercion is far more suspect than the ACCESSIBLE-SYMBOL declaration
for reasons that I hope will become apparent.

Anyway, let me address a number of specific points in an attempt to keep
this complicated conversation focused...

 * Version 1 of COERCE-INCOMPLETE from Japan proposed that coercing an
   integer to a character should assume that INTERN should be called.
   I wanted to address that request specifically and not just leave it
   out as if I'd ignored their request.

   The reason I could not address their proposal by simply including it
   in mind is that it doesn't have the good `symmetry' property mentioned
   in the outline. If you do 
	(COERCE (COERCE *SOME-SYMBOL* 'STRING) 'SYMBOL)
   and INTERN is the coercion from symbol to string, then this is only an
   identity if *SOME-SYMBOL* is in the current package. The thing that an
   ACCESSIBLE-SYMBOL declaration would tell you is that 
	(EQ *SOME-SYMBOL* (INTERN (SYMBOL-NAME *SOME-SYMBOL*)))
   The KEYWORD declaration provides that same piece of information, of
   course, but it's not possible to make every symbol a keyword, while it
   is possible to make every symbol accessible (albeit not at the same time).

   As it happens, I don't feel a need to justify these as declarations. It's
   not like all declarations in CL are indispensable. Sometimes it's good to
   provide the capability just for completeness. There are plenty of other
   declarations that are equivalently useful/useless. Nevertheless, in a
   very real sense, they ought to be useful from both a discrimination and a
   declaration standpoint because as discriminators they can test whether
   COERCE is defined on them, and as declarations, they can say it is safe
   for COERCE to do a particular coercion which in the absence of that 
   declaration might be very questionable.

   These are not types in the sense that they could be classes, but that
   doesn't make them unimportant. They are view types which specifically
   address the issue that one real type (class) can be used to represent any
   of several abstract types. And COERCE is about coercing abstract types,
   not classes. If it were not, then it would be obvious what definition to
   give it in all cases purely on the basis of CLASS-OF and there would be
   no dispute.

 * The same problem came up with CHAR-CODE, by the way. The Japanese proposal
   specified that they wanted integers to be treated as char-codes for
   no apparent reason (other than, presumably, some particular pragmatic
   reason they were focused on at the time they wrote the proposal). I wanted
   to suit that need without compromising the useful property, so I concocted
   CHAR-CODE.

 * You seem down on TYPE-OF. There are two issues here really:

     - Is it necessary/appropriate for the `type' arguments to really be
       types. It is possible, of course, to do like DOCUMENTATION and just
       say there's a fixed list of words with no necessary relation to
       types, for example.

       In fact though, as I mentioned above, it's potentially useful, both
       for discrimination and declaration, for them to be actual types.
       So I saw no need to restrict that.

     - More importantly, I might want to say that COERCE should just take
       4 required arguments. In fact, I might want to invert arg3 and arg4
       so that "coerce X from fixnum to float" was written 
       (COERCE X 'FIXNUM 'FLOAT).

       The issues here, though, are ...

	 . Compatibility. Making the argument required means that we'd
           break existing code. My proposal avoids that problem. If we're
	   going to break existing code, I'd just as soon we can justify it.

	 . Convenience. Often, TYPE-OF (were it more well-defined), is
	   exactly what is needed, so I think it's reasonable to establish
	   it as a default. Further, the to-type is not something for which
	   there is likely to be reasonable default, so it wants to precede
	   the optinoal argument.

       So I hope you can see from this why I resisted both my inclination to
       make the `from' argument required, and to invert the argument order.

  * I am, by the way, disturbed by your use of the phrase "isn't very
    type-like". To me, the purpose of types is to identify the set of
    operations on an object, and to restrict the amount of discrimination
    which must be done for those operations which are generic. I think this
    satisfies that purpose of types to the letter. If you want to make the
    case that I'm doing something creative and interesting, then I'll buy
    into it. If you want to make the case that I'm doing something
    blasphemous, you'll have to advance a considerably more elaborate
    philosophy and convince me to buy into it. I'm not saying I won't listen.
    I'm just saying I don't see it.

  * On the subject of INTEGRAL-FLOAT, I confess to using sloppy wording.
    "no fraction" was obviously a poor choice. It took me all day to write this
    thing and I didn't expect it to be a final draft, so I won't be surprised
    if that's not the last such little typo.

    Ditto about the typo in CHAR-INT. Thanks for spotting it.

  * In answer to your question about why call COERCE (rather than FLOAT), I
    think the answers are two (somewhat related):

      - Some people just want to learn fewer operators. They needn't learn
	FLOAT if they know COERCE. I happen not to be one of those people,
	but I've heard it enough places to believe it to be true.

      - You may wonder why COERCE is powerful enough to not need FLOAT.
 	Note that currently, CL says you can convert any (non-complex)
	number to a FLOAT. But that's not invertible. If instead it said
	you could convert any rational to a float or any integer to an
	integral-float, both of those operations would be invertible.
  	Also, the union of these two capabilities (and of float<->float
 	conversion, if you insist) is as powerful as what's offered now.
	No functionality would be lost, and yet things would be described
	in a way that permitted the nice `symmetry' property we're talking
	about.

 * I'm confused about your remark that it is "treacherous to support 
   symmetric coercion for any pair of types where the coercion in either
   direction is information losing". I'm trying to work through the exercise
   to see if in fact any information is necessarily lost. Consider:
    (COERCE (COERCE " S:>kmp>foo.lisp " 'PATHNAME 'STRING) 'STRING 'PATHNAME)
   might return "S:>kmp>foo.lisp" rather than " S:>kmp>foo.lisp ".
   Perhaps that argues for saying the argument type should be NAMESTRING,
   rather than STRING, to emphasize that the exact contents of the string do
   not matter, and that all that matters is the fact that the string 
   represents a particular pathname. If that's all it represents, then no
   information has been lost in the coercion because spaces were not part of
   the information. Remember, information is not structure -- it is structure
   + an intent to interpret that structure according to a particular set of
   rules. If those rules do not distinguish two structurally different
   objects, then those objects are equal.

   Anyway, I don't even necessarily think we have to -say- that COERCE is
   symmetric by nature. It might just be nice if it turned out to be true
   by accident ("true", but not "necessarily true" in the terms of Krypke --
   is that how you spell his name?).

[I keep putting `symmetry' in quotes because something tells me that when
 mathematicians say `symmetric' they mean something different than what we
 mean here. I think we know what we mean, but until someone tells me the
 usage is correct (or that it is not, and supplied a better term), I'll keep
 quoting it.]

The bottom line is that people have complained a lot about COERCE and
I'm trying to figure out what we might do about this. I'm not trying to
force anything down anyone's throat. But if we are going to analyze the
problem, we should do it thoughtfully and expect that there may be some
intermediate expression swell of ideas before we arrive at a bottom line.
I appreciate your having taken the time to read through the proposal in
detail and to answer it constructively. I hope you'll have time to get to
this reply in as much detail.

In particular, I'm interested in whether you buy any of my arguments at
all, whether you think there's another solution to COERCE or if you
think it's fine as it is or if you think it's just hopelessly broken,
and whether there are particular changes that could be made to my
proposal to make it more palatable to you -- ie, is there anything of
value in what I've said or do you think it's just way off track?

If you have time to go back and read the Japanese proposal (as annotated
and mailed to X3J13 by Masinter just before the last X3J13 meeting), you
might find that helpful. If you've lost your copy, I'll be happy to forward
you a copy.

 -kmp