🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: pl.comp.objects
Article #15720

Re: pl.comp.objects FAQ (Frequently Asked Questions and more)

#15720
From: Mariusz Lotko
Date: Mon, 05 Mar 2007 23:15
247 lines
11400 bytes
Sektor van Skijlen wrote:

> Dnia Mon, 05 Mar 2007 07:07:47 +0100, Mariusz Lotko skrobie:
>> Sektor van Skijlen wrote:
> 
>> > Dnia Sun, 04 Mar 2007 19:37:50 +0100, Mariusz Lotko skrobie:
>> >> Adam Karpierz wrote:
>> > 
>> >> > "Sektor van Skijlen"
>> >> > <ethouris@guess.if.gmail.com.is.valid.or.invalid> wrote:
>> >> >>> if obj is anotherObj : # sprawdza czy to te same obiekty
>> >> >>> if obj == anotherObj : # sprawdza czy zawartość obiektów jest
>> >> >>> równa.
>> >> >>
>> >> >>> Czy o to Ci chodzi?
>> >> >>
>> >> >> Właśnie NIE o to mi chodzi.
>> >> >> Chodzi o to, że ma być dostępny TYLKO operator ==,
>> >> >> natomiast od definicji typu zależy czy porównuje on tożsamość,
>> >> >> czy wartość.
>> > 
>> >> Tu się nie zgodzę. W przypadku C++ porównuje się zawsze wartość
>> >> obiektu. W przypadku wskaźnika wartością jest adres obiektu na
>> >> jaki wskaźnik wskazuje.
>> > 
>> > No tak, ale jeśli porównujesz wartości wskaźnikowe, to de facto
>> > porównujesz tożsamości dwóch obiektów.
>> > 
>> > Np. porównując "a == b" nie porównujesz "a" z "b", tylko porównujesz
>> > "tożsamość obiektu widocznego pod a" i "tożsamość obiektu widocznego
>> > pod b".
> 
>> A jeśli obiektami są smart pointery, to co porównuję?
> 
> To samo. Przecież ich wartości również są wskaźnikami.

Ale napisałeś (parę linijek wyżej), że porównywanie wskaźników, to
porównywanie tożsamości. Czy tożsamość przeradza się  w wartość jeśli
obiekt jest inteligentny (smart)? ;-)

> 
>> > Zresztą to się odnosi, jak słusznie zauważyłeś, ogólnie do wartości.
>> > Jeśli porównujesz dowolne dwa a i b tego samego typu, to porównanie
>> > określa ci, czy pod tymi dwiema zmiennymi siedzą te same wartości. W
>> > przypadku wskaźników będzie to oznaczało tylko to, czy te dwie zmienne
>> > wskaźnikowe wskazują na ten sam obiekt (czy na dwa różne). Jest to więc
>> > w efekcie porównanie tożsamości.
>> > 
>> >> Operator == dla dwóch obiektów powinien _zawsze_ porównywać równość
>> >> semantyczną ich _zawartości_, a nie kombinować z ich tożsamością.
>> > 
>> > Moment.
>> > 
>> > Po pierwsze, równość dwóch obiektów powinna wynikać z równości ich
>> > wartości. Jeśli obiekt nie ma wartości, to nie powinien mieć określonej
>> > porównywalności, bo po prostu nie ma czego porównać. Porównujemy więc
>> > WARTOŚĆ (a nie za-WARTOŚĆ).
> 
>> OK, w takim razie jakiś przykład obiektu bez wartości?
> 
> struct X
> {
> int a;
> int* b;
> };

Czyli tak: jak mam wskaźnik osobno, to mogę go porównać, jak mam int osobno
to również mogę porównać, a jak je wezmę razem do kupy to już nie?

>> >> Każdą dowolną parę obiektów można w prosty sposób zweryfikować
>> >> pod kątem "czy to te same obiekty" mając do nich referencję, np.
>> > 
>> >> bool teSame(const Klasa& a, const Klasa& b)
>> >> {
>> >>         return &a == &b;
>> >> }
>> > 
>> >> lub czy to równe obiekty
>> >> a == b
>> > 
>> >> Co odpowiada konstrukcjom z Pythona jakie podalem w poprzednim poście.
>> > 
>> > Można - tyle że tej pierwszej konstrukcji nikt nie stosuje.
> 
>> Że jak? Piersza linijka większości porządnych operatorów == ! Po co
>> porównywać zawartość tego samego obiektu?
> 
> A niby po co chcesz to sprawdzać? Jesteś pewny, że w każdym przypadku
> będzie to tańsze?

Mogę domniemywać, szczególnie jeśli obiekt składa się nie tylko z typów
prostych, a więc "rekursywnie" będą wywołane inne operatory porównania jeśli
tego nie zrobię.

> 
> Jeśli w danym obiekcie w operatorze == nastąpi porównanie tylko jednej
> wartości, to oszczędzasz tylko w przypadku, gdy masz ten sam obiekt. Jeśli
> nie, to masz dodatkowe, niepotrzebne porównanie. Czyli koszt jest mniejszy
> w przypadku równości, ale większy w przypadku nierówności.
> 
>> > W Javie np. masz:
>> > 
>> > Klasa a, b;
>> > int c, d;
>> > 
>> > i masz
>> > a == b
>> > c == d
>> > 
>> > i bez różnicy. Szkoda tylko, że dla "String t, s" jest to samo ;)
>> > 
>> > Nie możesz jednak w żaden sposob (inny niż przez odpowiednie metody)
>> > porównać wartości a i b, ani porównać referencji c i d.
> 
>> W C++ też musisz wiedzieć co porównujesz. Bo jeśli a i b są wskażnikami,
>> to masz analogiczny problem. Z tym, że zamiast equals() używasz * do
>> wyłuskania wartości.
> 
> Nieprawda. Jeśli c i d są typami wartościowymi, to ich wskaźniki w ogóle
> nie powinny cię interesować.

Ale mogą i język C++ tego nie zabrania. Jaki więc sens ma Twoja teoria w
odniesieniu do tego języka?

>> > Pierwsze nie ma sensu dlatego, że jeśli w typach wartościowych liczy
>> > się dla nas wartość, to nie liczy się tożsamość. Porównując wartość do
>> > wspomnianego koloru, interesuje nas kolor, a nie np. czy kartki
>> > papieru, na których zapisano kod koloru, są te same, czy inne.
> 
>> W szczególności może się zdarzyć, że będziemy chcieli porównać kolor tego
>> samego egzemplarza kartki. Wówczas porównanie będzie prostsze i wykonalne
>> nawet dla daltonisty. Stąd chyba nie warto od tożsamości się odcinać.
> 
> Ale PO CO?
> 
> Zwróć uwagę na to, co napisałem poniżej: nigdy nie porównuje się dwóch
> wartości stanów z dwóch różnych obiektów, jeśli nie mamy z innego źródła
> informacji o tym, jaka ta wartość jest.

Twoja teoria stoi na glinianych nóżkach. Wprawdzie nie mam pamięci
absolutnej, ale gdzieś mi kołacze po głowie, że kilka Twoich "nigdy"
już mi się w życiu zdarzyło. A że nie pamiętam, to chyba nie skończyło
się to żadną katastrofą programistyczną, którą trzebaby w pośpiechu
naprawiać.

>> > Dlatego właśnie obiekty nie mają zwykle takiej ogólnej "wartości", mają
>> > ich zwykle wiele i różne wartości mogą nas interesować przy
>> > porównaniach.
> 
>> Piszesz trochę w kontekście bazodanowym, gdzie jest np. poszukiwanie
>> obiektów spełniających określone kryteria. Jest jednak cała gama klas,
>> dla których bez większych trudności można zdefiniować operatory
>> porównania.
> 
> To są to wtedy typy wartościowe.
> 
> Java próbuje symulować to poprzez wprowadzanie obiektów niezmienialnych,
> jak właśnie String (w C# wyszło to o tyle lepiej, że tam jest dla tego
> typu poprawnie zdefiniowany operator porównania). Niestety z przyczyn
> wydajnościowych wymaga to dodatkowych wygibasów jak StringBuilder.
> 
>> Mimo to nie odważyłbym się na takie wyraźne i jednoznaczne nazwanie
>> pierwszych obiektów wartościowymi a drugich niewartościowymi.
> 
> Dlaczego?

Bo świat to nie tylko bazy danych.

> 
>> > Ja wiem, że zaraz ktoś rzuci szczególnym przypadkiem, że co z
>> > obiektami, które mają jedno pole, a zatem tylko jeden stan cząstkowy?
>> > 
>> > Otóż tutaj właśnie odgrywa rolę kwestia tożsamości obiektów. Jeśli
>> > bowiem interesuje nas tożsamość obiektu, to nie interesuje nas jego
>> > wartość (jeśli nie podlega ona bieżącemu przetwarzaniu, tzn. np.
>> > właśnie chcielibyśmy tą wartość porównać z odpowiadającym temu czemuś
>> > stanem w innym obiekcie).
> 
>> Weźmy obiekty w rodzaju mutable string. Da się jednoznacznie zdefiniować
>> operator porównania, w pewnej chwili dwa obiekty będą równe, a za chwilę
>> nie, więc trudno tu mówić o tożsamości.
> 
> Tak, ale mutable string - jeśli mówimy o czymś takim, jak StringBuilder -
> nie jest już typem wartościowym, gdyż zmienność obiektu wchodzi w
> interakcję z jego tożsamością.
> 
> Porównanie tego typu z innym mogłoby się odbywać tylko poprzez -
> najczęściej niejawne - pozyskanie String'a - czyli typu już wartościowego
> - i porównanie go z innym stringiem.

Rozumiem, że String jest niezmienialny a SB zmienialny, ale dlaczego jeden
jest wartościowy, a drugi już nie - wstyd się przyznać, ale nie mogę.

>> > Natomiast porównanie stanów dwóch obiektów nie ma po prostu sensu. Co
>> > na przykład da ci informacja, że pewne dwa samochody są "tego samego
>> > koloru", dopóki nie wiesz, jaki to kolor?
> 
>> Uwierz mi, w wielu sytuacjach ma to sens.
> 
> Nie wierzę :)

Znowu zrobię niecodzienną w świecie informatyki wycieczkę: załóżmy jesteś na
dyskotece i jesteś stanu wolnego. Jeśli nie zainteresujesz się stanem
obiektu "kobieta" (czy też jest "wolny") przed zagajeniem, to ryzykujesz
stratę zębów od jej chłopaka-dresiarza.

> 
>> Dziwię się Twoją opinią, bo sprawiasz wrażenie człowieka, który ma
>> doświadczenie zawodowe i trochę linii kodu wyprodukował.
> 
> I mówię to właśnie na podstawie tego :)
> 
> Jeśli chcemy stwierdzić, czy dwa obiekty są w "tym samym stanie", to
> musimy mieć chociaż przybliżone pojęcie o tym, jaki ten stan jest.

A jeśli chcemy je tylko pogrupować według stanu?

> 
>> >> > Podobnie chodzi o to aby byl dostepny inny operator do
>> >> > 'clone' obiektu a inny do zmiany referencji
>> > 
>> >> To też jest w C++ rozgraniczone:
>> >> C o1 = inny; // kopiowanie obiektu
>> >> C* o2 = &inny; // przypisywanie "referencji".
>> >> C& o3 = inny; // przypisywanie referencji.
>> > 
>> >> Schody zaczynają się, gdybyśmy napisali
>> >> o3 = jeszcze_inny; // ... bo to już znowu jest kopiowanie, a nie
>> >> zmiana
>> >>                         // referencji
>> > 
>> >> No ale taki już jest ten C++...
>> > 
>> > Ale w C++ zwykle - poza szczególnymi przypadkami - nie stosuje się dla
>> > tego samego typu operowania statycznego i dynamicznego. Czyli, jeśli
>> > używamy wskaźników i new, to obiektów tego samego typu już nie tworzymy
>> > na stosie.
> 
>> A "my" stosujemy, jeśli jest taka potrzeba... :-)
> 
> I to prowadzi potem do ciekawych kwiatków ;)

Jeden z moich kolegów komentując efekt nieprzemyślanego wymagania
powiedział: "trzeba wiedzieć o co się prosi...".

-- 
Mariusz Lotko
Technical Details
Message-ID: <esi7ve$5ia$1@bandai.magma-net.pl>
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!newsfeed.gazeta.pl!news.magma-net.pl!not-for-mail
References: <pl-comp-objects-faq-1-1166202604@ict.pwr.wroc.pl> <pan.2007.02.26.21.12.45.8078@go2.pl> <es6b6u$2ls$1@kujawiak.man.lodz.pl> <esbllu$51n$1@bandai.magma-net.pl> <esbv7t$7o$1@kujawiak.man.lodz.pl> <1172940339.25227.28.camel@qrnik> <escc9e$2h2$1@kujawiak.man.lodz.pl> <esd1k1$9bp$1@bandai.magma-net.pl> <esemb6$2r3$1@kujawiak.man.lodz.pl> <eses6u$8fm$1@inews.gazeta.pl> <esf3am$r52$1@bandai.magma-net.pl> <esfg25$b2m$1@kujawiak.man.lodz.pl> <esgboa$8i2$1@bandai.magma-net.pl> <esi21l$skh$1@kujawiak.man.lodz.pl>

Show Full Headers
Complete Article Headers
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!newsfeed.gazeta.pl!news.magma-net.pl!not-for-mail
From: Mariusz Lotko <imie.nazwisko@wp.pl>
Newsgroups: pl.comp.objects
Subject: Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
Date: Tue, 06 Mar 2007 00:15:37 +0100
Organization: Magma Systemy Komputerowe
Lines: 248
Message-ID: <esi7ve$5ia$1@bandai.magma-net.pl>
References: <pl-comp-objects-faq-1-1166202604@ict.pwr.wroc.pl> <pan.2007.02.26.21.12.45.8078@go2.pl> <es6b6u$2ls$1@kujawiak.man.lodz.pl> <esbllu$51n$1@bandai.magma-net.pl> <esbv7t$7o$1@kujawiak.man.lodz.pl> <1172940339.25227.28.camel@qrnik> <escc9e$2h2$1@kujawiak.man.lodz.pl> <esd1k1$9bp$1@bandai.magma-net.pl> <esemb6$2r3$1@kujawiak.man.lodz.pl> <eses6u$8fm$1@inews.gazeta.pl> <esf3am$r52$1@bandai.magma-net.pl> <esfg25$b2m$1@kujawiak.man.lodz.pl> <esgboa$8i2$1@bandai.magma-net.pl> <esi21l$skh$1@kujawiak.man.lodz.pl>
NNTP-Posting-Host: 192.168.21.22
Mime-Version: 1.0
X-Trace: bandai.magma-net.pl 1173136174 5706 192.168.21.22 (5 Mar 2007 23:09:34 GMT)
X-Complaints-To: usenet@news.magma-net.pl
NNTP-Posting-Date: Mon, 5 Mar 2007 23:09:34 +0000 (UTC)
User-Agent: KNode/0.10.4
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit