Cleanup Issue COERCE-INCOMPLETE

Status
motion died for lack of second; withdrawn
Category
ADDITION/CHANGE
References
COERCE (p50)

Problem Description

COERCE is difficult to extend because ambiguities arise about the source type of the coercion.

For example, if the symbol STRING were permitted as a second argument to coerce, as in (COERCE NIL 'STRING), there would be two posssible return values: "" or "NIL". The choice would be arbitrary and would have to be specified by the documentation. No matter which was chosen, it would probably turn out to be a problem for some applications at some times.

Another example is (COERCE (CHAR-CODE #\A) 'STRING). This might return the same as (FORMAT NIL "~D" (CHAR-CODE #\A)) -- "65" in most ASCII-based implementations -- or it might return "A". Again, the choice would be arbitrary.

There is clear desire on the part of the user community to lift some of the existing restrictions on arguments to COERCE, but because of legitimate concerns about ambiguities, the Common Lisp designers have thus far refused to do so.

Unfortunately, the failure of COERCE to handle these cases means it is very difficult to learn to use COERCE. And the fact that COERCE is not easily learned contributes to difficulty in learning Common Lisp because instead of a single coercion operator with general purpose semantics, a number of very special purpose coercion operators must be learned instead.

Some middle ground needs to be found, which neither compromises the clear semantics and portable nature of COERCE nor complicates COERCE in a way that makes it unlearnable.

Also, some people have expressed a desire for COERCE to be more `symmetric.' Usually they seem to mean that they want it to be the case that if (COERCE x y) works, then (COERCE (COERCE x y) (TYPE-OF x)) should also work. Although this is not an essential desire, it would certainly be nice to achieve.

Proposal (LIMITED-ARBITRARY-EXTENSION)

Define COERCE to accept the following equivalences:

   1. (COERCE x 'STRING)    == (STRING x)
   2. (COERCE x 'PATHNAME)  == (PATHNAME x)
   3. (COERCE x 'RATIONAL)  == (RATIONAL x)

Clarify that

   4. (COERCE x 'FLOAT)     == (FLOAT x)

Rationale

Many users think of STRING, for example, as ``the way to coerce something to a string'' and are baffled why COERCE and STRING disagree on how to do this.

Such users think that if there's a moral battle to be waged over how to coerce an object to a STRING, the battle has already been lost by defining the STRING function -- that whatever decision is made for STRING must also apply to COERCE for the sake of simplicity.

Similar arguments can be made for PATHNAME, FLOAT, and RATIONAL.

Proposal (DEPRECATE)

Deprecate COERCE.

Rationale

COERCE is not functionally necessary -- no operation that it does cannot be done in some other way. As such, it is basically just a matter of syntactic convenience, and perhaps isn't worth having around if it will be the subject of endless debate. Deprecating it would allow us to declare this issue a `dead end' and focus our attention on matters of greater substance.

Current Practice

Presumably No one implements either of the proposals at this time, since none are compatible with CLtL.

Cost to Implementors

COERCE: Small to moderate.

DEPRECATE: None.

Cost to Users

  COERCE: This is an incompatible change. (COERCE 'NIL 'STRING) => ""
    but (STRING NIL) => "NIL".  How many applications are impacted by
    this change is not clear. It would be straightforward to shadow
    COERCE with an alternate definition that did the old thing in
    cases where people were worried. Once such cases have been 
    identified, rewriting 
     (COERCE X 'STRING)
    as
     (IF X (COERCE X 'STRING) "")
    will suffice in most cases.

DEPRECATE: No immediate work would be needed, although many maintained applications would get upgraded in order to use the primitives that are `in vogue.'

Cost of Non-Adoption

People will continue to see and debate the issues alluded to in the Problem Description.

Benefits

The cost of Non-Adoption will be avoided.

Aesthetics

COERCE: Many people will probably see the idea of making COERCE consistent with STRING, PATHNAME, FLOAT, and RATIONAL as a clear improvement -- possibly outweighing the costs of both an incompatible change and a decision to arbitrarily favor one treatment over the other.

DEPRECATE: Some may take the deprecation of COERCE as an aesthetic improvement because it eliminates the need to debate this issue further. Others may see the ``de-centralization'' of coercion as a step backward.

Discussion

Pitman supports COERCE-INCOMPLETE:LIMITED-ARBITRARY-EXTENSION. Hopefully Moon and Masinter support it, too, since it's basically patterned after a bunch of mail they were sending back and forth.

A proposal to extend COERCE to permit a ``view type'' argument was considered and rejected as too extreme to consider seriously in the timeframe available.

Pierson suggests that COERCE ought to be a candidate for generic function status.

Pitman thinks that making [two-argument] COERCE generic would be a -very- bad idea but believes that his earlier proposal involving a third `view type' argument might be able to accomodate such extension.

! Additional comments:

"... The thing about
COERCE-INCOMPLETE:LIMITED-ARBITRARY-EXTENSION that strikes fear
into my heart is that it wipes out CLtL's simple statement that
any sequence type may be converted to any other sequence type,
and starts people asking questions like does
(coerce nil '(vector character)) => "" or "NIL"?

... I'm inclined to vote no on both proposals and keep the (unsatisfactory) status quo."

"I believe that any change to the status quo is incomplete without providing a coercion mechanism whose "viewpoint" is that of a sequence. That is effectively what the current COERCE is, overloaded with those types which do not conflict with SEQUENCE.

Because of the problem of differing viewpoints, I'm inclined to think that COERCE should be shrunk down to only being a sequence coercion function, and all other coercions should be handled by the appropriate functions."

Edit History