why () is () and [] is [] work in other way?

Kiuhnm kiuhnm03.4t.yahoo.it
Fri Apr 27 11:01:03 EDT 2012


On 4/27/2012 1:57, Adam Skutt wrote:
> On Apr 26, 6:34 pm, Kiuhnm<kiuhnm03.4t.yahoo.it>  wrote:
>> On 4/26/2012 20:54, Adam Skutt wrote:
>>> On Apr 26, 12:02 pm, Kiuhnm<kiuhnm03.4t.yahoo.it>    wrote:
>>>> On 4/26/2012 16:00, Adam Skutt wrote:
>>>>> On Apr 26, 9:37 am, Kiuhnm<kiuhnm03.4t.yahoo.it>     wrote:
>>>> The fact that you think that that's "differing behaviour" is what makes
>>>> it a misfeature. The fact that you think that '==' can take objects as
>>>> operands confirms that Java *does* confuse programmers.
>>
>>> The equality operator can absolutely be used between two objects.  Try
>>> it if you don't believe me.  It always does identity comparison when
>>> given two objects. It can also be given two primitives, and in this
>>> case, it does value comparison.  Despite performing different
>>> operations with the same symbol, there's little risk of confusion
>>> because I can trivially figure out if a variable is an object or an
>>> primitive.
>>
>> No, it can't be used between objects but only between primitives and
>> references (which should be regarded as primitives, by the way).
>
> The only way to access an object is through a reference.
>
>>> If you
>> understand that your 'a' is not really an object but a reference to it,
>> everything becomes clear and you see that '==' always do the same thing.
>
> Yes, object identity is implemented almost? everywhere by comparing
> the value of two pointers (references)[1]. I've already said I'm not
> really sure how else one would go about implementing it.
>
>> You might tell me that that's just an implementation detail, but when an
>> implementation detail is easier to understand and makes more sense than
>> the whole abstraction which is built upon it, something is seriously wrong.
>
> I'm not sure what abstraction is being built here.  I think you have
> me confused for someone else, possibly Steven.

The abstraction is this:
- There are primitives and objects.
- Primitives are not objects. The converse is also true.
- Primitives can become objects (boxing).
- Two primitives x and y are equal iff x == y.
- Two objects x and y are equal iff x.equals(y).
- Two objects are the same object iff x == y.
- If x is a primitive, then y = x is a deep copy.
- If x is an object, then y = x is a shallow copy.
- ...

The truth:
- Primitives can be references.
- Two primitives are equal iff x == y.
- Operator '.' automatically derefences references.

So Java is just C++ plus Garbage colletion plus some automatic 
dereferencing minus a lot of other things.

On the other hand, Python regards everything as an object and that's the 
way we should go, in my opinion. Some objects are mutable and other are 
immutable. This distinction doesn't mess with references.

Therefore, modifying the behavior of 'is' would be, in my opinion, a 
huge step back.

> You're missing the big picture. The two comparisons are asking
> different questions:
>      Value equality asks if the operands 'have the same state'
> regardless of how they exist in memory.
>      Identity equality asks if the two operands are the same block of
> memory.
>
> The two are distinct because not all types support both operations.
>
> If I write a function that does a value comparison, then it should do
> value comparison on _every type that can be passed to it_, regardless
> of whether the type is a primitive or an object, whether it has value
> or reference semantics, and  regardless of how value comparison is
> actually implemented.  If I write some function:
>      f(x : T, y : U) =>  x == y
> where T and U are some unknown types, then I want the function to do a
> value comparison for every type pairing that allows the function to
> compile.  Likewise, if I write a function that does identity
> comparison, then it logically wants to do identity comparison on
> _every type that can be passed to it_.

"Value comparison" and "identity comparison" is a terminology that I 
don't agree on.

Equality or equivalence is a relation which is:
- reflexive
- symmetric
- transitive
Everything else... is something else. Call it semi-equality, 
tricky-equality or whatever, but not equality, please.

It's only natural that Python defaults to the Identity relation which is 
the (set-)intersection of all possible equality relations.

> To accomplish this, I must have a distinct way of asking each
> question.  In Python we have '==' and 'is'[2]; in Java we have
> 'Object.equals()' and '=='; in C and C++ we distinguish by the types
> of the variables being compared (T and T*).
>
> Java gives '==' a different meaning for primitive types, but that
> turns out to be OK because I can't write a function that takes both a
> primitive type and a reference type at the same position.

And as a side effect some integers are primitives and other are objects.

>  Yes, the
> reason it does this is due to what I said above, but that doesn't have
> any bearing on why we pick one operation over the other as
> programmers.
>
>> The distinction between primitives and objects is unfortunate. It is as
>> if Java tried to get rid of pointers but never completely succeeded in
>> doing that.
>
>> It's the distinction between primitives and objects that should've been
>> an implementation detail, IMO.
>>
>> Python's lack of this misfeature is what I'm really fond of.
>
> If anything, you have that backwards.  Look at Python: all variables
> in Python have pointer semantics, not value semantics.

When everything is "white", the word "white" becomes redundant.
So the fact that everything in Python have reference semantics means 
that we can't stop thinking about value and reference semantics.

>  In imperative
> languages, pointers have greater utility over value types because not
> all types can obey the rules for value types.  For example, I don't
> know how to give value semantics to something like a I/O object (e.g,
> file, C++ fstream, C FILE), since I don't know how to create
> independent copies.

By defining a copy constructor.

> One can obviously create an imperative language without pointers, but
> I/O gets rather tricky.

Python is already without pointers (*).
A world where everyone is a lawyer is a world without lawyers (really, 
there isn't any other way we can get rid of them :) ).

(*) By the way, some would argue that references are not pointers.

Kiuhnm



More information about the Python-list mailing list