Adaptation and typecasting (was Re: [Python-Dev] replacing
Phillip J. Eby
pje at telecommunity.com
Tue Oct 28 18:33:19 EST 2003
At 10:03 AM 10/29/03 +1100, Delaney, Timothy C (Timothy) wrote:
> > From: Phillip J. Eby [mailto:pje at telecommunity.com]
> > At 09:56 AM 10/28/03 +0100, Alex Martelli wrote:
> > >AND, adaptation is not typecasting:
> > >e.g y=adapt("23", int) should NOT succeed.
> > And, why do you consider adaptation *not* to be typecasting?
> > I always
> > think of it as "give me X, rendered as a Y", which certainly
> > sounds like a
> > description of typecasting to me.
>Because (IMO anyway) adaption is *not* "give me X, rendered as Y".
>Adaption is "here is an X, can it be used as a Y?".
>They are two distinct concepts, although obviously there are crossover
Yes, just like 2+2==4 and 2*2==4.
>A string cannot be used as an int, although an int can be created from the
>string representation of an int.
I'd often like to "use a string as an integer", or use some arbitrary
object as an integer. Of course, there's a perfectly valid way to express
this now (i.e. 'int()'), and I think that's fine and in my code I will
personally prefer to use int() to mean I want an int, because that's clearer.
But, if for some reason I have code that is referencing some protocol as a
*parameter*, say 'p', and I have no way to know in advance that p==int,
then the most sensible thing to do is 'adapt(x,p)', rather than
'p(x)'. (Assuming 'p' is expected to be a protocol, rather than a
Now, given that 'p' *might* be 'int' in some cases, it seems reasonable to
me that adapt("23",p) should return 23 in such a case. Since 23 satisfies
the desired contract (int) on behalf of "23", this seems to be a correct
adaptation. For a protocol p that has immutability as part of its
contract, adapt(x,p) is well within its rights to return an object that is
a "copy" of x in some sense. The immutability requirement means that the
"adapted" value can never change, so really it's a *requirement* that the
"adaptation" be a snapshot.
>Adaption should not involve any change to the underlying data - mutating
>operations on the adapted object should (attempt to) mutate the original
>object (assuming the adapted object and original object are not one and
I agree 100% -- for a protocol whose contract doesn't require immutability,
the way 'int' does.
I think now that I understand, however, why you and Alex think I'm saying
something different than I've been saying. To both of you, "typecasting"
means "convert to a different type" at an *implementation* level (as it is
in other languages), and I mean at a *logical* level. Thus, to me, "I
would like to use X as a Y" includes whatever contracts Y supplies *as
applied to X*. Not, "give me an instance of Y that's a copy of X".
It just so happens, however, that for a protocol whose contract includes
immutability, these two concepts overlap, just as multiplication and
addition overlap for the case of 2+2==2*2. So, IMO, for immutable types
such as tuple, str, int, and float, I believe that it's reasonable for
adapt(x,p)==p(x) iff x is not an instance of p already, and does not have a
__conform__ method that overrides this interpretation.
That such a default interpretation is redundant with p(x), I also
agree. However, for code that uses protocols dynamically, that redundancy
would eliminate the need to make a dummy protocol (e.g. 'IInteger') to use
in place of 'int'.
OTOH, if Guido decides that Python's eventual interface objects shouldn't
be types, then there will be an IInteger anyway, and the point becomes moot.
Anyway, I can only understand Alex's objection to such adaptation if he is
saying that there is no such thing as adapting to an immutable
protocol! In that case, there could never exist such a thing as IInteger,
because you could never adapt anything to it that wasn't already an
IInteger. Somehow, this seems wrong to me.
More information about the Python-Dev