🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: pl.comp.objects
79 messages
79 total messages Page 1 of 2 Started by kkoniec@mks.com. Fri, 15 Dec 2006 17:10
Page 1 of 2 • 79 total messages
pl.comp.objects FAQ (Frequently Asked Questions and more)
#15208
Author: kkoniec@mks.com.
Date: Fri, 15 Dec 2006 17:10
692 lines
25779 bytes
Posted-By: auto-faq 3.1.1.2
Archive-name: pl-comp-objects-faq

---------------------------------------------------------------------------
Zawartosc: 	pl.comp.objects FAQ (Frequently Asked Questions and Summary)
Data:		1998.08.18
Wersja:		3.2
Autorzy:	Kuba Chabik
		Kamil Konieczny  kkoniec@mks.com.pl
---------------------------------------------------------------------------

Wykorzystane materialy: poprzednia (druga) edycja FAQ, opracowana przez
	Maciej "MACiAS" Pilichowski, macias@vm.cc.uni.torun.pl
	Data opracowania: 2.05.95 - 16.05.95
        Zasoby: 6.12.94 - 12.04.95

-------

Uwagi:

[ts 2005.12.27]
To FAQ jest juz tak stare, ze chyba az przestarzale.  Ale dopoki ktos
nie wymysli nowego, to z braku innego bedzie wysylane nadal. Moze ktos
sie zlituje i napisze/poprawi?

[Kamil 1998.06.24]:
  Ze wzgledu na brak czasu edycja trzecia to glownie reorganizacja
i poprawienie poprzedniej edycji, autorstwa [MACiAS].
W miare wolnego czasu bede dodawal nowe tematy, zaczynajac od biezacych
listow az do zamierzchlej przeszlosci, czyli od roku 1998 do 1995.
Nie beda dodawane tematy, nie majace nic (albo niewiele) wspolnego
z tematyka grupy.
Postaram sie rowniez o usuwanie z archiwow listy spamow,
jak rowniez nieaktualnych ogloszen zwiazanych z obiektami.

[MACiAS 1995.05.16]:
  W znakomitej wiekszosci wszystkie informacje zostaly wziete z listow
uczestnikow grupy. Jesli zauwazycie ponizej bledy, niescislosci, luki,
etc. to bardzo prosze o listy (jesli sprawa nie jest oczywista, to
najlepiej na adres grupy).

-------
Krotki spis tematow:

T.1     Informacje ogolne (literatura, slowniczek, pojecia).
T.2     Jezyk C++.
T.3     Jezyk Smaltalk.
T.4     Inne

-------
Spis tematow:

T.1.1	Literatura.
T.1.1.1	Literatura w jezyku angielskim.
T.1.1.2	Literatura w jezyku polskim.
T.1.2	Proponowany maly slownik terminow.
T.1.3	Co to jest klasa?
T.1.4	Co to jest metoda?
T.1.5	Co to jest atrybut?
T.1.6	Co reprezentuje dziedziczenie?
T.1.7	Co to jest polimorfizm?
T.1.8	Co zyskujemy przez polimorfizm?
T.1.9	Do czego potrzebna jest hermetyzacja?
T.1.10	Co to jest klasa abstrakcyjna?
T.1.11	Co to jest metaklasa?
T.1.12	Co to jest komponent?
T.1.13	Co to sa obiektowe bazy danych?
T.1.14	Czy obiektowe bazy danych sa gorsze od relacyjnych?
T.1.15	Co to jest CORBA?
T.1.16	Czy programy obiektowe sa wolniejsze od proceduralnych?

T.2.1	Jak w prosty sposob zrozumiec opis bledu w BC++?
T.2.2	Co zrobic jesli klasa deklarowana w pliku naglowkowym uzywa typow
T.2.3	Co to sa dziwne pliki w katalogu "/usr/g++-include/gen" z
T.2.4	Jak w C++ obsluguje sie funkcje ze zmienna liczba parametrow?
T.2.5	Czy mozna zaimplementowac funkcje wirtualne w C?
T.2.6	Czy stosowanie zaprzyjazniania klas nalezy do dobrej praktyki
T.2.7	Gdzie mozna dostac gramatyke C++ (obojetnie dla jakiego narzedzia,
T.2.8	Czy przejscie do OOP wymaga odrzucenia "balastu proceduralnego"?
T.2.9	Co to jest konstruktor kopiujacy?
T.2.10	Czy istnieje domyslny konstruktor kopiujacy?
T.2.11	Jak uniknac dolaczania metod wirtualnych, z ktorych nie korzystam, a
T.2.12	Ciekawostki z historii C++.
T.2.13	Stosowac wskaznik czy referencje?
T.2.14	Co to sa sprytne wskazniki (smart pointers)?
T.2.15	Czy wszystkie metody w mojej klasie powinny byc wirtualne?
T.2.16	Czy konstruktory moga byc wirtualne?
T.2.17	Jak tworzyc klasy abstrakcyjne?

T.3.1	Czy jest dostepna darmowa implementacja Smalltalka?
T.3.2	Czy SmallTalk jest dobry w praktyce, czy tylko w teorii?
T.3.3	Gdzie mozna dowiedziec sie o jezyku Smalltalk i jego zastosowaniach?

T.4.1	Jak powinienem zabrac sie za programowanie obiektowe?
T.4.2	Czy OOP oznacza brak optymalizacji?
T.4.3	Jak rozpoznawac, czy dany program lub projekt jest dobry ?
T.4.4	Poszukuje informacji na temat rozszerzen do jezykow obiektowych

---------------------------------------------------------------------------
-------
T.1.1	Literatura.

T.1.1.1	Literatura w jezyku angielskim.

  Badouin-Lafon M., "Object-Oriented Languages"
	wyd ?, ISBN ?
  Brown W.H., Malveau R.C., McCormick H.W. III, Mowbray T.J.,
	"AntiPatterns: Refactoring Software, Architectures,
	and Projects in Crisis."
	John Wiley & Sons, ISBN 0-471-19713-0
  Buchmann et al., "A System of Patterns"
	John Wiley & Sons, ISBN 0-471-95869-7
  Budd, T., "An Introduction to Object Oriented Programming",
	Addison Wesley Publishing, ISBN 0-201-54709-0
  Coleman D., et al, "The Fusion Method"
	wyd ?, ISBN ?
  Fowler M., Scott K.,	"UML Distilled"
	Addison-Wesley, ISBN 0-201-32563-2
  Gamma E., Helm R., Johnson R., Vlissides J.	"Design Patterns"
	Addison-Wesley, ISBN 0-201-63361-2
  Graham I., "Object-Oriented Methods" 2nd ed.
	Addison-Wesley, ISBN 0-201-59371-8
	http://www2.awl.com/cseng/
  Jacobson I., Christerson M., Johnsson P., Overgaard G.,
	"Object-Oriented Software Engineering"
	Addison-Wesley, ISBN 0-201-54435-0
  Lakos J., "Large-Scale C++ Software Design"
	Addison-Wesley, ISBN 0-201-63362-0
  Lalonde W.R., Pugh J.R., "Inside Smalltalk", Volume 1 and 2,
	Prentice Hall, ISBN ?
  Rumbaugh J., Blaha M., Premerlani W.,Eddy F.,Lorensen W.,
	"Object-Oriented Modelling and Design"
	Prentince Hall, ISBN ?
  Stroustrup B., "The C++ Programming Language" 3rd. ed., 6th printing
	Addison-Wesley, ISBN 0-201-88954-4
        http://www.research.att.com/~bs/homepage.html

T.1.1.2	Literatura w jezyku polskim.

  Barteczko K., "Praktyczne wprowadzenie do programowania w jezyku C++",
	LUPUS, ISBN ISBN 83-85545-13-1
  Coad P., Yourdon E., "Analiza obiektowa" (OOA),
	README, ISBN 83-85769-17-X
  Coad P., Yourdon E., "Projektowanie obiektowe" (OOD),
	README, ISBN 83-85769-18-8
  Coad P., Nicola J., "Programowanie obiektowe" (OOP),
	README, ISBN 83-85769-16-1
  Grebosz J., grebosz@bron.ifj.edu.pl, "Symfonia C++"
	Oficyna Kallimach, ISBN 83-901689-0-1 wydanie 3,
	Oficyna Kallimach, ISBN 83-901689-1-X
  Grebosz J., "Pasja C++"
	Oficyna Kallimach, ISBN 83-901689-2-8
  Hansen T., "Zadania z jezyka C++",
	WNT, ISBN 83-204-1759-7
  Kliszewski M., "Inzynieria oprogramowania obiektowego - analiza obiektowa",
	RESPEKT, ISBN 83-901994-0-8
  Kain E., "Od C do C++"
	wyd ?, ISBN ?
  Lippman S.B., "Podstawy jezyka C++", Tlumaczenie z wydania 2,
	WNT, ISBN 83-204-1681-7
  Martin J., Odell J.J., "Podstawy metod obiektowych"
	WNT, ISBN 83-204-2116-0
  Stroustrup B., "Jezyk C++", Tlumaczenie wydania 2,
	WNT, ISBN 83-204-1697-3
  Stroustrup B., "Projektowanie i rozwoj jezyka C++",
	WNT, ISBN 83-204-2042-3

-------
T.1.2	Proponowany maly slownik terminow.

  garbage collector    - odsmiecacz
  operator overloading - przeciazanie operatora
  object persistency   - trwanie obiektu
  persistent pointer   - trwaly wskaznik
  container            - pojemnik
  template             - szablon
  reference            - odnosnik
  dereferencing        - wyluskiwanie


-----
T.1.3	Co to jest klasa?

Klasa jest abstrakcja obiektow z modelowanej dziedziny. Stanowi
wzorzec, opis, z ktorego te obiekty beda tworzone. Klasa nic nie
"robi", klasa czyms "jest". Klasy odwzorowuja przedmioty, osoby, a
takze organizacje i procesy zachodzace w swiecie rzeczywistym.
Klasa posiada jakas odpowiedzialnosc. Cos, dla czego nie potrafisz
wskazac odpowiedzialnosci, klasa nie jest (najprawdodobniej jest
jedyniem atrybutem innej klasy).

-----
T.1.4	Co to jest metoda?

Metoda, zwana takze operacja, reprezentuje czynnosc, jaka moze byc
wykonana przez dany obiekt w swiecie rzeczywistym. Metody moga
uzywane do uzyskania informacji lub do zmiany stanu danego obiektu.

-----
T.1.5	Co to jest atrybut?

Atrybut to cecha obiektu, na przyklad kolor pojazdu, dlugosc tekstu,
wzrost osoby. Atrybuty sa innymi obiektami zagniezdzonymi w danym
obiekcie.

-----
T.1.6	Co reprezentuje dziedziczenie?

Dziedziczenie reprezentuje specjalizacje. Mowimy, ze klasa
dziedziczaca (subclass) "jest rodzaju" klasy bazowej (superclass).
Innymi slowy, klasa bazowa reprezentuje pojecie bardziej ogolne, niz
klasa dziedziczaca.

-----
T.1.7	Co to jest polimorfizm?

Metody polimorficzne to takie, ktore moga zachowywac sie roznie, w
zaleznosci od tego, na rzecz jakiego konkretnego obiektu zostaly
wywolane. Metode polimorficzna mozemy przedefiniowac w klasie
implementujacej interfejs (czyli, najczesciej, dziedziczacej). Jezeli
teraz inne obiekty beda wywolywac te metode dla obiektow nowej klasy,
to bedzie wykonywala sie nowo, a nie stara metoda, choc same obiekty
wolajace nie zauwaza zmiany.

-----
T.1.8	Co zyskujemy przez polimorfizm?

Dzieki polimorfizmowi uzyskujemy elastycznosc systemow, bowiem mozemy
modyfikowac jedynie to, co rzeczywiscie nalezy zmienic, nie zas cale
"otoczenie" konkretnej metody

-----
T.1.9	Do czego potrzebna jest hermetyzacja?

Hermetyzacja, czyli ukrywanie metod i atrybutow klas, daje nam
bezpieczenstwo i przejrzystosc. Przypuscmy, ze mamy atrybut
"godzinaRozpoczecia" klasy "Wyklad". Gdyby wszyscy mieli dostep do
takiego atrybutu, mogloby sie zdarzyc, ze ktos ustawilby ja na liczbe
wieksza od 23, co oczywiscie nie ma sensu. Jednakze dzieki
hermetyzacji mozemy taka kontrole poprawnosci zawrzec w metodzie
"zmienGodzineRozpoczecia" i odmowic ustawienia nieprawidlowej
godziny.

-----
T.1.10	Co to jest klasa abstrakcyjna?

To taka klasa, ktora mozna tylko wykorzystywac przez dziedziczenie od
niej, a nie mozna tworzyc jej obiektow. Klasy abstrakcyjne
reprezentuja pojecia, ktore sa generalizacja innych pojec, ale same w
sobie nie reprezentuja zadnych obiektow w dziedzinie.

-----
T.1.11	Co to jest metaklasa?

Metaklasa to jakby klasa dla klasy, innymi slowy, egzemplarze
(instance) metaklas sa klasami. Metaklasy wystepuja nie we wszystkich
jezykach programowania, a nawet w tych, w ktorych wystepuja, trudno
wskazac ich konkretne, programistyczne zastosowanie. Jednakze czesto
stosuje sie jej nawet o tym nie wiedzac.

-----
T.1.12	Co to jest komponent?

Komponent to grupa klas, ktore sluza jednemu, konkretnemu celowi.
Klasy w komponencie charakteryzuja sie tym, ze maja silne powiazania
z innymi klasami wewnatrz tego samego komponentu i slabe poza nim.
Dzieki temu komponent moga byc rozwijane niezaleznie i podmieniane w
razie potrzeby, bez modyfikacji innych komponentow. Przykladem
komponentu moglaby byc grupa klas odpowiedzialna za obsluge wydruku.

-----
T.1.13	Co to sa obiektowe bazy danych?

Pojecie "bazy danych" nie jest szczegolnie szczesliwe. Lepiej mowic o
"obiektach trwalych". Systemy takie pozwalaja na przechowanie stanu
obiektu pomiedzy wywolaniami aplikacji, czyli tak, jak tradycyjna
baza danych przechowuje dane. Jednakze roznica miedzy nimi a takimi
bazami polega na fakcie, ze nie trzeba programowo odtwarzac stanu
aplikacji z bazy (np. zapytaniami SQL). Po prostu obiekty aplikacji i
obiekty bazy danych to to samo.

-----
T.1.14	Czy obiektowe bazy danych sa gorsze od relacyjnych?

To zalezy do czego. W przypadku odwzorowywania skomplikowanych
zaleznosci sa o niebo lepsze. W przypadku plaskich, kartotekowych
danych sa gorsze. Technologia ODBMS jest niewatpliwie mniej dojrzala
od RDBMS, jednakze swoj okres "dzieciecy" ma juz na pewno za soba.

-----
T.1.15	Co to jest CORBA?

CORBA to skrot od Common Object Request Broker Architecture. Jest to
architektura, ktore umozliwia komunikacje obiektom zlokalizowanym na
roznych maszynach, roznych systemach operacyjnych, roznych
architekturach sprzetowych komunikacje miedzy soba. W ramach
standardu CORBA istnieja takze uslugi (CORBA services), np. kolekcje,
zdarzenia (events), transakcje i inne. CORBA jest bardzo potezna
architektura, ale nie ma zbyt dobrych implementacji, szczegolnie
uslug. Ponadto organizacja OMG, ktora zdefiniowala CORBA'e, jest
cialem biurokratycznym i nieruchawym. Spowalnia to rozwoj tego
standardu.

-----
T.1.16	Czy programy obiektowe sa wolniejsze od proceduralnych?

Nie, to kompletna bzdura. Programowanie obiektowe pozwala na
zastosowanie takich technik, ktore czynia program bezpieczniejszym,
stabilniejszym, szybszym i bardziej elastycznym. Ponadto, technologia
obiektowa pozwala tworzyc system w sposob bardziej rygorystyczny, a
wiec pewniejszy i bardziej skoordynowany, niz technologia
proceduralna. Skutkiem jest generalnie wyzsza jakosc systemow,
szczegolnie tych powazniejszych, a wiec i wieksza szybkosc ich
dzialania.
Opinie taka programy obiektowe zawdzieczaja niedouczonym
programistom, ktorzy, liznawszy odrobiny C++, poczuli sie ekspertami
od obiektow i wyglaszali na prawo i lewo podobne bzdury.

---------------------------------------------------------------------------

-----
T.2.1	Jak w prosty sposob zrozumiec opis bledu w BC++?

Przeczytac opis bledu, zajrzec do "Programmer's Manual",
"Programmer's Reference", podrecznika C++.
Jesli nie pomoze, skontaktowac sie z innymi osobami piszacymi w C++.

-----
T.2.2	Co zrobic jesli klasa deklarowana w pliku naglowkowym uzywa typow
	deklarowanych w innych plikach naglowkowych?

W _kazdym_ pliku naglowkowym nalezy wpisac:

#ifndef nazwapliku_h
#define nazwapliku_h
..
#endif

I mozesz bezkarnie wlaczac potrzebne ci headery.

-----
T.2.3	Co to sa dziwne pliki w katalogu "/usr/g++-include/gen" z
	roszerzeniami ".ccP" oraz ".hP"?

Jest to po prostu biblioteka "libg++". Dowiedziec sie czegos wiecej mozesz
z dokumentacji. A pliki z rozszerzeniem ".ccP" i ".hP" sa wejsciowymy
plikami do programu "genclass". To sa pliki ze starej wersji kompilatora,
ktory nie mial wlaczonych templates, wiec uzywalo sie tego i "genclass"
specyfikujac jaki mial byc bazowy typ, "genclass" tworzyl z tego pliki
np. "<type>Vec.cc" i "<type>Vec.h" zastepujac <T> podanym typem.

-----
T.2.4	Jak w C++ obsluguje sie funkcje ze zmienna liczba parametrow?

W starym C stosowalo sie <varargs.h>, w nowym (ANSI C oraz C++)
stosuje sie <stdarg.h>.

Ponizej przyklad programu wykorzystujacy <stdarg.h>.
 va_list   - typ zmiennej pomocniczej
 va_start  - inicjalizacja listy
 va_argptr - przesuniecie wskaznika listy na nastepny element

#include <stdio.h>
#include <stdarg.h>

void pisz(char *tekst,...)
{
va_list argptr;

  va_start(argptr,tekst);
  printf("\nTo sa dane : %s",tekst);
  while(*(tekst=va_arg(argptr,char *))!=NULL)
    printf(" %s",tekst);
  va_end(argptr);
};

void main()
{
  pisz("ala","ola","kot","domek na prerii","i nic",NULL);
};

Typowo to jest tak, ze pierwszy parametr zawiera informacje o liczbie
dalszych parametrow. Moze to byc liczba, ale moze byc tak jak w "printf":
  printf("zmienna %s = %d",...)
Tu jest podane, ze tylko dwoch parametrow trzeba sie doszukac.

-----
T.2.5	Czy mozna zaimplementowac funkcje wirtualne w C?

Tak - mozna to zrobic poprzez umieszczenie wskaznikow do funkcji razem
z danymi, np:

struct ojciec {
  int daneojca;
  int *funkcjaWirtualna(char *arg);
};

struct syn {
  struct ojciec o;
  int danesyna;
  int *mojaFunkcjaWirtualna();
};

struct syn *konstuktor_syna()
{
  struct syn *s = malloc(...);
  s->mojaFunkcjaWirtualna = syn_mojaFunkcja;
  s->o.funkcjaWirtualna = s->mojaFunkcjaWirtualna; // podmiana wskaznika
                                                   // funkcji wirtualnej
}

czyli poprzez podmiane wskaznika do funkcji. Taka realizacja jednak
umozliwa jednak uzywanie tylko pseudo-wirtualnych funkcji. Jesli chcemy
uzywac naprawde takich funkcji uzyjmy jezyka obiektowego, gdyz w tych
jezykach funkcja/metoda wirtualna wyroznia sie tym, ze niezaleznie od
sposobu wywolania zawsze wykonana zostanie funkcja odpowiadajaca
rzeczywistemu typowi klasy. Tak jak w ponizszym przykladzie:

foobar( struct ojciec *o)
{
  o->mojaFunkcjaWirtualna(); // jesli o jest wskaznikiem na syna
                             // to wywolane zostanie syn_mojaFunkcja
}

-----
T.2.6	Czy stosowanie zaprzyjazniania klas nalezy do dobrej praktyki
	programisty?

Nie, gdyz dopuszcza do latwego dostepu do pol prywatnych i
chronionych. Narusza to zasade "jedyna aktywnosc systemu
obiektowego to przekazywanie wiadomosci (message passing)". Istnieje
roznica miedzy zapisaniem "kolo->radius=5;", a "kolo->setRadius(5);".

-----
T.2.7	Gdzie mozna dostac gramatyke C++ (obojetnie dla jakiego narzedzia,
	preferowane yacc(bison), lex(flex) itp), ale koniecznie AT&T 2.0
	(glownie chodzi o nested classes oraz templates)?

Powinna byc w zrodlach GNU cc.
Jest rowniez w B.Stroustrup "The C++ Programming Language", 3rd ed.,
Appendix A (niekompletna).

-----
T.2.8	Czy przejscie do OOP wymaga odrzucenia "balastu proceduralnego"?

Wczytujac sie w Stroustrupa "Jezyk C++" mozna zauwazyc jego
slowa: nowe techniki programowania nie neguja starych - uzupelniaja je.
To nie rewolucja. Tam gdzie wystarcza procedury lub moduly, nie szukamy
obiektow.
[czy ktos moze znalezc nr rozdzialu i paragrafu, lub nr strony ? Kamil]

-----
T.2.9	Co to jest konstruktor kopiujacy?

Konstruktor kopiujacy jest bardzo podobny do operatora przypisania,
tyle ze o ile operator przypisania uzywany jest dla obiektow juz
istniejacych, to konstruktor kopiujacy gdy tworzymy nowy obiekt i
jednoczesnie nadajemy mu jakas wartosc. Przyklad (bo bez przykladu
raczej malo kto zrozumie :-) ):

class A
{
 private:
   int data;

 public:
  A(int new_data=0)    : data(new_data) {};  // To jest zwykly
                                             // konstruktor

  A( A& a ) : data(a.data) {};     // A to konstruktor kopiujacy

  A& operator=(A &a) { data=a.data; return *this; } // a to
                                                    // operator przypisania
};

I teraz...

main()
{
 A a(1);       // Tu zostanie wywolany zwykly konstruktor, z argumentem 1
 A b;          // Podbnie, tyle ze argument zostanie domyslnie
               // przyjety jako 0
 A c=b;        // Tutaj konstruktor kopiujacy z argumentem b
 A d;          // A tutaj operator przypisania z tym samym argumentem
 d=b;
};
Najwazniejsze w tym wszystkim sa ostatnie trzy linijki, bo tutaj
wlasnie widac roznice, kiedy wywolywany jest operator przypisania, a
kiedy konstruktor kopiujacy. Konstruktor kopiujacy jest tylko i
wylacznie wtedy gdy przypisanie nastepuje rownoczesnie z utworzeniem.
	Dlaczego to wyroznienie? Pozwala to zaoszczedzic operacji, bo
oczywiscie moglo by byc i tak ze kazda instrukcja typu "A b=c;"
bylaby rozbijana na dwie: "A b; b=c;". Ale wtedy niepotrzebnie obiekt
"b" bylby dwa razy inicjowany (w naszym przypadku najpierw "data=0",
a potem "data=c.data").
	Taka instrukcja jak "A b=c;" jest rownowazna po prostu "A b(c);"
a nie (jak mogloby sie wydawac) parze instrukcji "A b; b=c;".
	Ponizsze przyklady takze sa ciekawe:
class klasaA {
  public:
  klasaA metoda() { return (*this); };
  ...
};
Tutaj zostanie najpierw wykonana kopia obiektu (poprzez wywolanie
kostruktora kopiujacego) i kopia zostanie zwrocona jako wynik metody;
Trzeba bardzo uwazac na brak znaczku referencji "&"!!!
class klasaA {
  public:
  klasaA& metoda()
  {
    klasaA temp;
    ....
    return temp;
  };
  ....
};
Poniewaz "temp" jest obiektem o czasie zycia tylko wewnatrz metody, wiec by
moc zwrocic referencje do niego trzeba miec kopie o zasiegu wiekszym.
Kopilator wiec wola konstruktor kopiujacy z argumentem "temp" i tworzy jego
kopie na stercie i zwraca referencje do nowego obiektu.

-----
T.2.10	Czy istnieje domyslny konstruktor kopiujacy?

Tak - kopiuje poszczegolne pola. Z tego powodu nie nadaje sie
do klas zawierajacych wskazniki - w efekcie otrzymujemy dwa obiekty
wskazujace na ten sam (trzeci) obiekt. Jezeli teraz jeden z tych
obiektow zostanie usuniety, to najprawdopodobniej zostanie tez
zniszczony obiekt przez niego wskazywany, i drugi z obiektow bedzie
wskazywal cos blednego. Dlatego tez gdy uzywamy operacji przypisania,
a dana klasa zawiera wskazniki, to trzeba konstruktor kopiujacy
zdefiniowac samemu, umieszczajac w nim operacje potrzebne do
utworzenia kopii obiektu wskazywanego przez wskaznik.

-----
T.2.11	Jak uniknac dolaczania metod wirtualnych, z ktorych nie korzystam, a
	sa zadeklaroawne w definicji objektu?

Pozne laczenie ("late binding"), ktore UMOZLIWIA tworzenie metod
wirtualnych, polega wlasnie na tym, ze program w momencie kompilacji
i linkowania _nie wie_, ktore metody beda mu potrzebne. Inna sprawa ze
zwyklymi metodami.

-------
T.2.12	Ciekawostki z historii C++.

Autorem C++ jest Bjarne Stroustrup. W swojej ksiazce "The Design and
Evolution of C++" skladajac wyrazy holdu za wplyw na powstanie jezyka C++,
Stroustrup wymienia m.in. nastepujace osoby: Briana Kernighana, Andrew
Koeniga, Douga McIlroya, Jonathana Shopiro. Kristen Nygaard (Simula 67)
i Dennis Ritchie (C) zajmuja na tej liscie miejsca szczegolnie eksponowane.
	W pazdzierniku 1979 roku istnial 1 uzytkownik C++ (C z klasami),
w  pazdzierniku  1981 C++ mial 38 uzytkownikow, w dziesiec lat pozniej -
400 000 osob przyznawalo sie do programowania w C++. A obecnie?
	Obecnie trwaja prace nad normalizacja jezyka C++,
prowadzone przez kilka cial standaryzacyjnych.
Standard jest juz zatwierdzony,
i mozna go zakupic bezposrednio w ANSI.
Bjarne Stroustrup od cwiercwiecza interesuje sie filozofia i historia.
Jego sympatie do empirystow i awersja do idealistow, "uszczesliwiajacych"
ludzkosc "tym, co dla niej dobre" (slowa Stroustrupa), wplynely na
niektore decyzje i rozwiazania projektowe w C++.

-------
T.2.13	Stosowac wskaznik czy referencje?

Istnieja zasadnicze roznice miedzy wskaznikiem, a referencja:
	1. Referencje nie moga byc puste
	2. Raz ustawionej referencji nie mozna przeniesc na inny obiek
	3. Nie mozna zrobic referencji do referencji, tak jak robi sie
	wskaznik do wskaznika.
Generalnie, lepiej jest stosowac referencje. Jednakze jezeli z wyzej
wymienionych powodow jest to niemozliwe, to nalezy zastosowac
wskaznik.

-------
T.2.14	Co to sa sprytne wskazniki (smart pointers)?

Jest to szczegolny rodzaj klas, ktore definiuja operator rzutowania
na typ pierwotny (ktory opakowuja). Z tego powodu moga byc stosowane
w programie tak, jakby byly typu pierwotnego. Najbardziej znane
przyklady sprytnych wskaznikow to string (opakowujacy wskaznik do
char) i auto_ptr (szablon parametryzowany opakowywanym typem) ze
standradowej biblioteki C++.

-------
T.2.15	Czy wszystkie metody w mojej klasie powinny byc wirtualne?

W zasadzie tak. Deklarujac metode jako niewirtualna uniemozliwiasz
zmiane jej implementacji w klasie dziedziczacej, a tym samym zawezasz
elastycznosc swojego systemu.
Jednakze w przypadku metod prostych, np. jedynie zwracajacych
referencje do atrybutu, lepiej zrobic je inline, a metoda inline nie
moze byc wirtualna.

-------
T.2.16	Czy konstruktory moga byc wirtualne?

Nie. Ale mozna stworzyc odpowiednik konstruktora wirtualnego. Opisuje
to wzorzec Abstract Factory z ksiazki "Design Patterns", Gamma et al.

-------
T.2.17	Jak tworzyc klasy abstrakcyjne?

Klasa abstrakcyjna jest kazda klasa, ktora ma choc jedna metode
czysto wirtualna (abstrakcyjna), czyli zadeklarowana, a nie
zaimplementowana. Mozna klase uczynic abstrakcyjna takze deklarujac
wszystkie jej konstruktory jako prywatne lub chronione (protected).

---------------------------------------------------------------------------
-----
T.3.1	Czy jest dostepna darmowa implementacja Smalltalka?

Tak - w ramach GNU. Znalezc go mozna w wiekszosci katalogow z GNU.

-----
T.3.2	Czy SmallTalk jest dobry w praktyce, czy tylko w teorii?

W przypadku Smalltalka o teorii mogla byc mowa jakies 10 lat temu. Teraz
jest to praktyka. Niejaki Dave Thomas z Kanady odpowiedzial na to
pytanie w bardzo ciekawym referacie. Oto, co wdrozono na Smalltalku:

1. Centrale telefoniczna dla kilkudziesieciotysiecznego miasta.
2. "Zastosowania specjalne".
3. IBM zatrudnil ostatnio (pocz.'94) okolo 300 programistow w Smalltalku.
   Chyba nie do podlewania kwiatkow.
4. System analizy jakosci programow napisanych w C.

Tyle pamietam. Inna sprawa, ze Smalltalk nie dorownuje C++
rozpowszechnieniu, wiec i produkty komercyjne nie sa tak czeste. Ja nie
potrafie podac zadnych, ale w C++ to chyba tez tylko te, w ktorych
pisaniu sam uczestniczylem.

Czytalem, ze zrobienie jednej klasy w Smalltalku zajmuje 1 osobodni, w
C++ trzy razy tyle. Oczywiscie slyszalem to od entuzjastki Smalltalka,
wiec trzeba wziac poprawke.

-----
T.3.3	Gdzie mozna dowiedziec sie o jezyku Smalltalk i jego zastosowaniach?

Pod nastepujacym adresem:

http://www.stic.org

Jest to adres Smalltalk Industry Council, instytucji zrzeszajacej
firmy produkujace oprogramowanie i narzedzia do Smalltalka. Pod tym
adresem znalezc mozna liste dostepnych kompilatorow (komercyjnych i
darmowych), firmy produkujace biblioteki i narzedzia, materialy do
nauki Smalltalka, informacje o wybranych projektach wykonanych przy
pomocy Smalltalka oraz porownanie sprawnosci Smalltalka z jezykami C i
C++.

---------------------------------------------------------------------------
-----
T.4.1	Jak powinienem zabrac sie za programowanie obiektowe?

Wykonac analize i projekt. Wybrac jezyk i zaimplementowac projekt.
Na poczatek doradzam kilka niewielkich projektow.
Nie zaszkodzi poczytac o analizie, projektowaniu i programowaniu
obiektowym.

-----
T.4.2	Czy OOP oznacza brak optymalizacji?

Ani tak, ani nie - zaden jezyk z gory nie zaklada braku optymalizacji. To
zalezy tylko i wylacznie od konkretnego programu.

-----
T.4.3	Jak rozpoznawac, czy dany program lub projekt jest dobry ?

Mozliwe kryteria:

o  dziala - dobrze, nie dziala - zle
o  stopien realizacji obiektow jako "czarnych skrzynek"
o  zbyt mala lub zbyt duza wiedza klas
o  czytelnosc
o  podatnosc na zmiany
o  powiazania miedzy modulami
o  mozliwosc powtornego uzycia

-----
T.4.4	Poszukuje informacji na temat rozszerzen do jezykow obiektowych
	(C++, Smalltalk, Eiffel), takich jak np. O++ do C++
	O++ jest rozszerzeniem C++ pozwalajacym na tworzenie obiektow
	trwalych (persistent), manipulowanie nimi, laczenie w clustery etc.

Jesli chodzi o Smalltalk, to jego rozszerzeniem jesli silnie stypizowany
Strongtalk.

---------------------------------------------------------------------------
end of pl.comp.object FAQ and Summary
---------------------------------------------------------------------------
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
#15231
Author: SasQ
Date: Thu, 22 Feb 2007 20:14
121 lines
4684 bytes
Dnia Fri, 15 Dec 2006 17:10:05 +0000, Kamil Konieczny napisa³(a):

> T.2.4	Jak w C++ obsluguje sie funkcje ze zmienna liczba parametrow?
>
> W starym C stosowalo sie <varargs.h>, w nowym (ANSI C oraz C++)
> stosuje sie <stdarg.h>

Je¶li mowa o C++, to chyba raczej <cstdarg>

> void main()

Je¶li przyk³ad by³ dla C++, to raczej int main().
Standard ANSI/ISO C++ nie dopuszcza void dla main.

> T.2.6	Czy stosowanie zaprzyjazniania klas nalezy do dobrej
>       praktyki rogramisty?
>
> Nie, gdyz dopuszcza do latwego dostepu do pol prywatnych i
> chronionych.

Ale nie ka¿demu ;)  Tylko wybranym.
Przyja¼ñ wcale nie jest "zamachem na enkapsulacjê", bo klasa
deklaruj±ca przyja¼ñ sama decyduje o tym, z kim siê przyja¼ni
i robi to z pe³n± ¶wiadomo¶ci± ;)  Poza tym je¶li ju¿ jest
deklaracja przyja¼ni, to jest ona czê¶ci± interfejsu klasy i
daje sygna³, ¿e dwie klasy s± ze sob± ¶ci¶le powi±zane i
dzia³aj± wspólnie.

> T.2.9	Co to jest konstruktor kopiujacy?
>
> Konstruktor kopiujacy jest bardzo podobny do operatora przypisania,
> tyle ze o ile operator przypisania uzywany jest dla obiektow juz
> istniejacych, to konstruktor kopiujacy gdy tworzymy nowy obiekt i
> jednoczesnie nadajemy mu jakas wartosc. Przyklad (bo bez przykladu
> raczej malo kto zrozumie :-) ):

Czemu? Po prostu chodzi o zwyczajn± inicjalizacjê nowo tworzonego
biektu warto¶ci± innego obiektu tego samego typu ;)

> main()

A typ warto¶ci zwracanej to zjad³ pies? :P

>  A d;          // A tutaj operator przypisania z tym samym argumentem

Raczej linijkê ni¿ej ;) o tu:

>  d=b;

> Konstruktor kopiujacy jest tylko i wylacznie wtedy gdy
> przypisanie nastepuje rownoczesnie z utworzeniem.

Ale wtedy to nie jest przypisanie, tylko inicjalizacja ;P
Przypisuje siê do obiektów ju¿ skonstruowanych.
Jak nie ³apiesz ró¿nicy, to spróbuj z obiektami const:
mo¿na je tylko inicjalizowaæ, ale nie mo¿na do nich ju¿
pó¼niej przypisywaæ.

> Dlaczego to wyroznienie? Pozwala to zaoszczedzic operacji,
> bo oczywiscie moglo by byc i tak ze kazda instrukcja typu
> "A b=c;" bylaby rozbijana na dwie: "A b; b=c;".

Tu akurat nie to jest najwa¿niejsze ;)
Ponownie polecam popróbowaæ z const ;)
Je¶li obiekt jest const, nie mo¿esz do niego ju¿ nic przypisaæ
po utworzeniu. Je¶li chcesz ustawiæ warto¶æ obiektu sta³ego
"na wzór" innego obiektu, to jedyny moment, gdzie jest to mo¿liwe,
jest przy konstruowaniu. Pó¼niej jest ju¿ "po ptokach" :P
I tu siê w³a¶nie przydaje konstruktor kopiuj±cy, zwany te¿
"inicjalizatorem kopiuj±cym" ;J

> Ale wtedy niepotrzebnie obiekt "b" bylby dwa razy inicjowany

Inicjuje siê czynno¶ci. Obiekty siê inicjalizuje.
I nie s³uchaj s³ownika Kopaliñskiego, jego autorzy nie wiedz±
co to jest programowanie ;)

> Najbardziej znane przyklady sprytnych wskaznikow to string
> (opakowujacy wskaznik do char)

?? :P
Tak rozumuj±c, to ka¿da klasa, która zawiera³aby w swojej
implementacji jakie¶ wska¼niki i je obs³ugiwa³a, musia³aby
byæ "sprytnym wska¼nikiem" :P  Ja bym raczej zawêzi³ ten termin
do obiektów "symuluj±cych" zwyk³e wska¼niki w widoczny sposób.

> Opisuje to wzorzec Abstract Factory z ksiazki "Design
> Patterns", Gamma et al.

"et al." to skrót od ³aciñskiego "et alii" = "i inni" ;J

> Klasa abstrakcyjna jest kazda klasa, ktora ma choc jedna metode
> czysto wirtualna (abstrakcyjna), czyli zadeklarowana, a nie
> zaimplementowana. Mozna klase uczynic abstrakcyjna takze deklarujac
> wszystkie jej konstruktory jako prywatne lub chronione (protected).

No nie wiem ;J
Uczynienie konstruktora prywatnym lub chronionym jeszcze nie
czyni klasy abstrakcyjn±, bo obiekty tej klasy wbrew pozorom
nadal mog± byæ tworzone, tylko nie ka¿demu wolno to robiæ ;J
Je¶li konstruktor jest private, to wolno tworzyæ obiekt tylko
z wnêtrza klasy, a je¶li protected, to dodatkowo z wnêtrza
klas pochodnych. Klasa "dla samej siebie" albo "dla siebie i
rodzinki" nie jest ju¿ wtedy wcale abstrakcyjna. Podobnie
je¶li klasa ma prywatny konstruktor, ale przyja¼ni siê z
jak±¶ funkcj± która mo¿e ten konstruktor prywatny wtedy wywo³aæ
i utworzyæ obiekty tej klasy, to klasa ju¿ nie mo¿e byæ traktowana
jako abstrakcyjna :P
Dlatego zawêzi³bym t± definicjê tylko dla klas, które maj±
choæ jedn± metodê czysto wirtualn±, bo tylko to daje pe³n±
gwarancjê, ¿e nie powstanie ¿aden obiekt tej klasy, choæby i
na jej w³asny u¿ytek prywatny ;J
Klasa Ssak jest dobrym przyk³adem klasy abstrakcyjnej. Je¶li
chcia³by¶ j± uzyskaæ ukrywaj±c konstruktor, to nadal klasa mo¿e
stworzyæ instancjê Ssaka :P [np. z metody statycznej albo
zaprzyja¼nionej] i co wtedy? :D  Widzia³e¶ kiedy ssaka luzem? ;)

P.S.: chodzi³em z jednym Kamilem Koniecznym do podstawówki :J
      Mo¿e to ty? :D Jeste¶ mo¿e z ¯ywca? ;J

--
SasQ
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
#15234
Author: rwt
Date: Thu, 22 Feb 2007 23:29
74 lines
2805 bytes
Odpowiedź do listu Wielce Szanownej Pani / Szanownego Pana ‹SasQ›.
Wysłannik wyższej inteligencji tako rzecze :):

>> T.2.9	Co to jest konstruktor kopiujacy?

>> Konstruktor kopiujacy jest bardzo podobny do operatora przypisania,
>> tyle ze o ile operator przypisania uzywany jest dla obiektow juz
>> istniejacych, to konstruktor kopiujacy gdy tworzymy nowy obiekt i
>> jednoczesnie nadajemy mu jakas wartosc. Przyklad (bo bez przykladu
>> raczej malo kto zrozumie :-) ):

> Czemu? Po prostu chodzi o zwyczajną inicjalizację nowo tworzonego
> biektu wartością innego obiektu tego samego typu ;)


>>  A d;          // A tutaj operator przypisania z tym samym argumentem

> Raczej linijkę niżej ;) o tu:

>>  d=b;


>> Konstruktor kopiujacy jest tylko i wylacznie wtedy gdy
>> przypisanie nastepuje rownoczesnie z utworzeniem.

> Ale wtedy to nie jest przypisanie, tylko inicjalizacja ;P
> Przypisuje się do obiektów już skonstruowanych.
> Jak nie łapiesz różnicy, to spróbuj z obiektami const:
> można je tylko inicjalizować, ale nie można do nich już
> później przypisywać.


>> Dlaczego to wyroznienie? Pozwala to zaoszczedzic operacji,
>> bo oczywiscie moglo by byc i tak ze kazda instrukcja typu
>> "A b=c;" bylaby rozbijana na dwie: "A b; b=c;".

> Tu akurat nie to jest najważniejsze ;)
> Ponownie polecam popróbować z const ;)
> Jeśli obiekt jest const, nie możesz do niego już nic przypisać
> po utworzeniu. Jeśli chcesz ustawić wartość obiektu stałego
> "na wzór" innego obiektu, to jedyny moment, gdzie jest to możliwe,
> jest przy konstruowaniu. Później jest już "po ptokach" :P
> I tu się właśnie przydaje konstruktor kopiujący, zwany też
> "inicjalizatorem kopiującym" ;J


>> Ale wtedy niepotrzebnie obiekt "b" bylby dwa razy inicjowany

> Inicjuje się czynności. Obiekty się inicjalizuje.
> I nie słuchaj słownika Kopalińskiego, jego autorzy nie wiedzą
> co to jest programowanie ;)


>> Najbardziej znane przyklady sprytnych wskaznikow to string
>> (opakowujacy wskaznik do char)

> ?? :P
> Tak rozumując, to każda klasa, która zawierałaby w swojej
> implementacji jakieś wskaźniki i je obsługiwała, musiałaby
> być "sprytnym wskaźnikiem" :P  Ja bym raczej zawęził ten termin
> do obiektów "symulujących" zwykłe wskaźniki w widoczny sposób.

Można by zauważyć, że dla zmiennych typu klasa nie zachodzą
przypisania. Tak naprawdę dla nich są tylko inicjalizacje. Natomiast
przypisania pozostały dla zmiennych prymitywnych oraz referencji,
wskaźników.


Wasz
--
/ qo   |)    :@=N%_g=v=a=g_eD_e=c()=d=8! =%!Gn@8're. w8in/ad
\    _x/ ,   ;h-%-a'hA'H4,X0'Xo~xo~xO,R`-%EXp01ITed: *-7/+eh
/    |    ng `-%__%--'__%--'__%--~__%--^%B`/$qV3r[o; &GooMee
L o_O http://tech.groups.yahoo.com/group/opRWTng O_o L"EnOF"
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
#15236
Author: Mariusz Lotko
Date: Mon, 26 Feb 2007 09:58
33 lines
1248 bytes
rwt wrote:

> Odpowied¼ do listu Wielce Szanownej Pani / Szanownego Pana ?SasQ?.
> Wys³annik wy¿szej inteligencji tako rzecze :):
>
>>> T.2.9       Co to jest konstruktor kopiujacy?
>
>>> Konstruktor kopiujacy jest bardzo podobny do operatora przypisania,
>>> tyle ze o ile operator przypisania uzywany jest dla obiektow juz
>>> istniejacych, to konstruktor kopiujacy gdy tworzymy nowy obiekt i
>>> jednoczesnie nadajemy mu jakas wartosc. Przyklad (bo bez przykladu
>>> raczej malo kto zrozumie :-) ):
>
>> Czemu? Po prostu chodzi o zwyczajn± inicjalizacjê nowo tworzonego
>> biektu warto¶ci± innego obiektu tego samego typu ;)

(...)

>
> Mo¿na by zauwa¿yæ, ¿e dla zmiennych typu klasa nie zachodz±
> przypisania. Tak naprawdê dla nich s± tylko inicjalizacje. Natomiast
> przypisania pozosta³y dla zmiennych prymitywnych oraz referencji,
> wska¼ników.

Pomimo, ¼e do¶æ uwa¿nie przeczyta³em komentarz SasQ, nie bardzo rozumiem
Twoj± odpowied¼. Czy móg³by¶ to nieco rozwin±æ?
No i pytanie podstawowe: dlaczego uwa¿asz, ¿e dla obiektów nie wystêpuj±
tutaj przypisania a jedynie "przypisania (...) dla zmiennych prymitywnych"?
Przypominam, ¿e mowa jest o C++ a nie jakim¶ zorientowanym na referencje
jêzyku jak Java czy Python.

--
Mariusz Lotko
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
#15237
Author: rwt
Date: Mon, 26 Feb 2007 20:10
49 lines
2249 bytes
Odpowiedź do listu Wielce Szanownej Pani / Szanownego Pana ‹Mariusz
Lotko›. Wysłannik wyższej inteligencji tako rzecze :):

> rwt wrote:
>> Odpowiedź do listu Wielce Szanownej Pani / Szanownego Pana ?SasQ?.
>> Wysłannik wyższej inteligencji tako rzecze :):

>>>> T.2.9       Co to jest konstruktor kopiujacy?

>>>> Konstruktor kopiujacy jest bardzo podobny do operatora przypisania,
>>>> tyle ze o ile operator przypisania uzywany jest dla obiektow juz
>>>> istniejacych, to konstruktor kopiujacy gdy tworzymy nowy obiekt i
>>>> jednoczesnie nadajemy mu jakas wartosc. Przyklad (bo bez przykladu
>>>> raczej malo kto zrozumie :-) ):

>>> Czemu? Po prostu chodzi o zwyczajną inicjalizację nowo tworzonego
>>> biektu wartością innego obiektu tego samego typu ;)

> (...)

>> Można by zauważyć, że dla zmiennych typu klasa nie zachodzą
>> przypisania. Tak naprawdę dla nich są tylko inicjalizacje. Natomiast
>> przypisania pozostały dla zmiennych prymitywnych oraz referencji,
>> wskaźników.

> Pomimo, źe dość uważnie przeczytałem komentarz SasQ, nie bardzo
> rozumiem Twoją odpowiedź. Czy mógłbyś to nieco rozwinąć? No i
> pytanie podstawowe: dlaczego uważasz, że dla obiektów nie występują
> tutaj przypisania a jedynie "przypisania (...) dla zmiennych
> prymitywnych"? Przypominam, że mowa jest o C++ a nie jakimś
> zorientowanym na referencje języku jak Java czy Python.

Być może w języku nadal pozostaje operator przypisania (jak we
wcześniejszym cytacie), ale… obiekty, które mają program wiążący z
mechanizmami języka, inny niż zformalizowany, czyli inny niż otwarty
mimo że istniejący (jak w językach funkcyjnych)— po zwykłym
skopiowaniu wartości przez sam związek z innymi obiektami tworzony przez
ten program stają się klonami a nie kopiami. Oczywiście jeszcze innego
rodzaju operacją jest ‚przypisanie’ do zmiennej typu klasy
dziedziczącej dany typ. Mimo że do wszystkiego używa się tego samego
operatora.


Wasz
--
/ qo   |)    :@=N%_g=v=a=g_eD_e=c()=d=8! =%!Gn@8're. w8in/ad
\    _x/ ,   ;h-%-a'hA'H4,X0'Xo~xo~xO,R`-%EXp01ITed: *-7/+eh
/    |    ng `-%__%--'__%--'__%--~__%--^%B`/$qV3r[o; &GooMee
L o_O http://tech.groups.yahoo.com/group/opRWTng O_o L"EnOF"
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
#15238
Author: SasQ
Date: Mon, 26 Feb 2007 22:12
75 lines
3097 bytes
Dnia Mon, 26 Feb 2007 20:10:02 +0100, rwt napisa³(a):

> Byæ mo¿e w jêzyku nadal pozostaje operator przypisania (jak we
> wcze¶niejszym cytacie), ale... obiekty, które maj± program wi±¿±cy
> z mechanizmami jêzyka, inny ni¿ zformalizowany, czyli inny ni¿
> otwarty mimo ¿e istniej±cy (jak w jêzykach funkcyjnych)- po
> zwyk³ym skopiowaniu warto¶ci przez sam zwi±zek z innymi obiektami
> tworzony przez ten program staj± siê klonami a nie kopiami.

Atak klonów ;)
Przyznam ¿e ja te¿ nie zrozumia³em poprzednio, a to "wyja¶nienie"
jeszcze bardziej mi zamiesza³o i nic z tego nie rozumiem :P
Poniewa¿ w programowaniu liczy siê precyzja, pozwolê sobie
zadaæ kilka pytañ o s³ownictwo, którego u¿ywasz, by¶my siê
dobrze rozumieli i pos³ugiwali siê tymi samymi definicjami:

1) Co to s± "zmienne typu klasa"?
Moje definicje u¿ytych tutaj s³ów przedstawiaj± siê tak:
zmienna:  typ obiektu, który mo¿e zmieniaæ swój stan.
sta³a:    typ obiektu, który nie mo¿e zmieniaæ swojego stanu.
stan:     warto¶æ ;)
obiekt:   wydzielony jednolity i ci±g³y obszar pamiêci, który
          ma jasno okre¶lony typ.
typ:      okre¶la jakie warto¶ci/stany mo¿e przyjmowaæ obiekt,
          jak te stany mog± siê zmieniaæ, oraz jakie operacje
          mo¿na na tym obiekcie wykonywaæ
klasa:    definiuje nowy typ obiektu

2) Dlaczego mia³yby nie zachodziæ dla nich przypisania?
Moja definicja przypisania:
Skopiowanie stanu [warto¶ci] jednego obiektu do drugiego,
zastêpuj±c poprzedni± warto¶æ obiektu docelowego.

3) Czemu dla nich mia³yby byæ tylko inicjalizacje?
Moja definicja inicjalizacji:
Nadanie pocz±tkowej warto¶ci obiektowi w momencie jego
utworzenia [mo¿na to zrobiæ tylko wtedy].

4) Co to s± zmienne prymitywne?
Czy chodzi³o ci mo¿e o zmienne [lub w ogólno¶ci obiekty]
typów wbudowanych?
Typy wbudowane: istniej±ce w jêzyku od pocz±tku, nie
                definiowane przez u¿ytkownika.

5) Dlaczegó¿ to tylko dla nich pozostaj± przypisania?

6) "Byæ mo¿e w jêzyku nadal pozostaje operator przypisania"
Mówisz tutaj o operatorze przypisania dla jakiego typu?
Jednego z typów wbudowanych? Bo nie wiem jak inaczej
zrozumieæ ¿e on "pozostaje w jêzyku".

7) "obiekty, które maj± program wi±¿±cy z mechanizmami jêzyka,
    inny ni¿ zformalizowany, czyli inny ni¿ otwarty"
Co to jest "program wi±¿±cy z mechanizmami jêzyka"?
A co to jest "program sformalizowany" czy "program otwarty"?
[o ile dobrze zrozumia³em sens logiczny tego zdania :P]

8) "mimo ¿e istniej±cy (jak w jêzykach funkcyjnych)- po zwyk³ym
    skopiowaniu warto¶ci przez sam zwi±zek z innymi obiektami
    tworzony przez ten program"
Tego to ju¿ nijak nie potrafiê ugry¼æ :|  Nawet nie wiem o co
zapytaæ, bo zupe³nie nie jarzê sensu tego zdania :7

9) "staj± siê klonami a nie kopiami"
Czym siê ró¿ni kopia od klonu?

10) "Oczywi¶cie jeszcze innego rodzaju operacj± jest 'przypisanie'
     do zmiennej typu klasy dziedzicz±cej dany typ."
Co to jest "zmienna typu klasy dziedzicz±cej dany typ"? :P

11) "Mimo ¿e do wszystkiego u¿ywa siê tego samego operatora."
Czyli do czego, i jakiego operatora? Bo z kontekstu tego nie
mogê wyczytaæ...

--
SasQ
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
#15239
Author: rwt
Date: Mon, 26 Feb 2007 22:29
9 lines
281 bytes
Che, che. Pełna analiza.


Wasz
--
/ qo   |)    :@=N%_g=v=a=g_eD_e=c()=d=8! =%!Gn@8're. w8in/ad
\    _x/ ,   ;h-%-a'hA'H4,X0'Xo~xo~xO,R`-%EXp01ITed: *-7/+eh
/    |    ng `-%__%--'__%--'__%--~__%--^%B`/$qV3r[o; &GooMee
L o_O http://tech.groups.yahoo.com/group/opRWTng O_o L"EnOF"
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
#15240
Author: Mariusz Lotko
Date: Mon, 26 Feb 2007 23:55
8 lines
112 bytes
rwt wrote:

> Che, che. Pe³na analiza.

Wygl±da to raczej na atak trolli ni¿ atak klonów :-)

--
Mariusz Lotko
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
#15241
Author: SasQ
Date: Tue, 27 Feb 2007 00:02
13 lines
335 bytes
Dnia Mon, 26 Feb 2007 23:55:29 +0100, Mariusz Lotko napisa³(a):

> rwt wrote:
>
>> Che, che. Pe³na analiza.
>
> Wygl±da to raczej na atak trolli ni¿ atak klonów :-)

A mo¿e bot spamerski? :) Ostatnio pojawi³y siê takie, co bior±
s³ownik z danej dziedziny i generuj± losowe zestawienia s³ów,
przypominaj±ce normalny tekst ;)

--
SasQ
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
#15246
Author: pdemb@gazeta.pl
Date: Wed, 28 Feb 2007 15:32
14 lines
413 bytes
SasQ <sasq1@go2.pl> writes:

> Dnia Mon, 26 Feb 2007 23:55:29 +0100, Mariusz Lotko napisa³(a):
>
>> rwt wrote:
>>
>>> Che, che. Pe³na analiza.
>>
>> Wygl±da to raczej na atak trolli ni¿ atak klonów :-)
>
> A mo¿e bot spamerski? :) Ostatnio pojawi³y siê takie, co bior±
> s³ownik z danej dziedziny i generuj± losowe zestawienia s³ów,
> przypominaj±ce normalny tekst ;)

Ano s±: http://pdos.csail.mit.edu/scigen/.
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
#15248
Author: Sektor van Skijl
Date: Thu, 01 Mar 2007 10:51
94 lines
4041 bytes
Dnia Mon, 26 Feb 2007 22:12:45 +0100, SasQ skrobie:
> Dnia Mon, 26 Feb 2007 20:10:02 +0100, rwt napisa³(a):

> > Byæ mo¿e w jêzyku nadal pozostaje operator przypisania (jak we
> > wcze¶niejszym cytacie), ale... obiekty, które maj± program wi±¿±cy
> > z mechanizmami jêzyka, inny ni¿ zformalizowany, czyli inny ni¿
> > otwarty mimo ¿e istniej±cy (jak w jêzykach funkcyjnych)- po
> > zwyk³ym skopiowaniu warto¶ci przez sam zwi±zek z innymi obiektami
> > tworzony przez ten program staj± siê klonami a nie kopiami.

> Atak klonów ;)

Nie ma siê co ¶miaæ.

Kopiowanie nie zachodzi dla obiektów typów niewarto¶ciowych, a jedynie dla
obiektów typów warto¶ciowych. Kopiowaniu podlega wtedy owa "warto¶æ", która
mo¿e byæ dowolnie przenoszona pomiêdzy poszczególnymi obiektami.

Natomiast obiekty niewarto¶ciowe, jak sama nazwa wskazuje, warto¶ci nie maj±,
wiêc one podlegaj± klonowaniu - tworzy siê nowy obiekt o nowej to¿samo¶ci. W
obiektach warto¶ciowych to¿samo¶ci± jest warto¶æ.

> Przyznam ¿e ja te¿ nie zrozumia³em poprzednio, a to "wyja¶nienie"
> jeszcze bardziej mi zamiesza³o i nic z tego nie rozumiem :P
> Poniewa¿ w programowaniu liczy siê precyzja, pozwolê sobie
> zadaæ kilka pytañ o s³ownictwo, którego u¿ywasz, by¶my siê
> dobrze rozumieli i pos³ugiwali siê tymi samymi definicjami:

> 1) Co to s± "zmienne typu klasa"?
> Moje definicje u¿ytych tutaj s³ów przedstawiaj± siê tak:
> zmienna:  typ obiektu, który mo¿e zmieniaæ swój stan.
> sta³a:    typ obiektu, który nie mo¿e zmieniaæ swojego stanu.
> stan:     warto¶æ ;)
Dok³adnie to bie¿±ca warto¶æ, w przypadku typów warto¶ciowych. W pozosta³ych
bêdzie to zespó³ wszystkich warto¶ci sk³adowych obiektu (je¶li sk³adow± jest
obiekt, to jeszcze i jego warto¶ci itd.)

> obiekt:   wydzielony jednolity i ci±g³y obszar pamiêci, który
>           ma jasno okre¶lony typ.
> typ:      okre¶la jakie warto¶ci/stany mo¿e przyjmowaæ obiekt,
>           jak te stany mog± siê zmieniaæ, oraz jakie operacje
>           mo¿na na tym obiekcie wykonywaæ
> klasa:    definiuje nowy typ obiektu

> 2) Dlaczego mia³yby nie zachodziæ dla nich przypisania?
> Moja definicja przypisania:
> Skopiowanie stanu [warto¶ci] jednego obiektu do drugiego,
> zastêpuj±c poprzedni± warto¶æ obiektu docelowego.

S³usznie, pod warunkiem, ¿e to jest obiekt warto¶ciowy.

> 3) Czemu dla nich mia³yby byæ tylko inicjalizacje?
> Moja definicja inicjalizacji:
> Nadanie pocz±tkowej warto¶ci obiektowi w momencie jego
> utworzenia [mo¿na to zrobiæ tylko wtedy].

Znów - w przypadku typów warto¶ciowych. W pozosta³ych jest to po prostu
inicjalizacja sk³adowych - a dalej ju¿ jak wy¿ej.

> 4) Co to s± zmienne prymitywne?
> Czy chodzi³o ci mo¿e o zmienne [lub w ogólno¶ci obiekty]
> typów wbudowanych?
> Typy wbudowane: istniej±ce w jêzyku od pocz±tku, nie
>                 definiowane przez u¿ytkownika.

Kwestia czy to s± typy wbudowane, czy nie, zale¿y od jêzyka. W Javie np. nie
ma innych typów warto¶ciowych ni¿ wbudowane - plus referencje, przy czym
warto¶ci± zmiennej referencyjnej jest referencja do okre¶lonego obiektu (lub
null). W C++ mo¿emy sobie dowolnie tworzyæ typy warto¶ciowe.

> 5) Dlaczegó¿ to tylko dla nich pozostaj± przypisania?

Dla typów warto¶ciowych.

> 6) "Byæ mo¿e w jêzyku nadal pozostaje operator przypisania"
> Mówisz tutaj o operatorze przypisania dla jakiego typu?
> Jednego z typów wbudowanych? Bo nie wiem jak inaczej
> zrozumieæ ¿e on "pozostaje w jêzyku".

Te¿ nie rozumiem ;)

> 9) "staj± siê klonami a nie kopiami"
> Czym siê ró¿ni kopia od klonu?

Tym w³a¶nie, ¿e sklonowany obiekt staje siê osobnym obiektem z w³asnym
zestawem stanów. Obiekty warto¶ciowe maj± okre¶lon± to¿samo¶æ przez warto¶æ,
wiêc po wykonaniu a = b, 'a' staje siê "tym samym" co b - dopóki kto¶ nie
przypisze mu innej warto¶ci.


--
//  _    ___         Michal "Sektor" Malecki <sektor(whirl)kis.p.lodz.pl>
\\ L_ |/ `|  /^\ ,()                         <ethouris(O)gmail.com>
// \_ |\  \/ \_/ /\ C++ bez cholesterolu: http://www.intercon.pl/~sektor/cbx
"Java is answer for a question that has never been stated"
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
#15251
Author: rwt
Date: Fri, 02 Mar 2007 09:26
19 lines
623 bytes
Odpowiedź do listu Wielce Szanownej Pani / Szanownego Pana ‹Mariusz
Lotko›. Wysłannik wyższej inteligencji tako rzecze :):

> rwt wrote:

>> Che, che. Pełna analiza.

> Wygląda to raczej na atak trolli niż atak klonów :-)

Zrozumiałeś, o czym pisałem, czy wypowiadasz się, by zaistnieć?
Nie ukrywam, że odpowiedź lub jej brak zadecyje o ignorowaniu.


Wasz
--
/ qo   |)    :@=N%_g=v=a=g_eD_e=c()=d=8! =%!Gn@8're. w8in/ad
\    _x/ ,   ;h-%-a'hA'H4,X0'Xo~xo~xO,R`-%EXp01ITed: *-7/+eh
/    |    ng `-%__%--'__%--'__%--~__%--^%B`/$qV3r[o; &GooMee
L o_O http://tech.groups.yahoo.com/group/opRWTng O_o L"EnOF"
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
#15253
Author: Mariusz Lotko
Date: Sat, 03 Mar 2007 12:19
18 lines
440 bytes
rwt wrote:


>>> Che, che. Pe³na analiza.
>
>> Wygl±da to raczej na atak trolli ni¿ atak klonów :-)
>
> Zrozumia³e¶, o czym pisa³em, czy wypowiadasz siê, by zaistnieæ?
> Nie ukrywam, ¿e odpowied¼ lub jej brak zadecyje o ignorowaniu.

Ignoruj. Czy Twoja "wypowied¼" (patrz piersza linijka) zas³uguje na co¶
wiêcej?

A co do "zaistnienia" - to nie ja wymy¶lam niestworzone teorie na temat
rzeczy prostych i zrozumia³ych.

--
Mariusz Lotko
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
#15254
Author: Mariusz Lotko
Date: Sat, 03 Mar 2007 12:26
30 lines
1208 bytes
Sektor van Skijlen wrote:

> Dnia Mon, 26 Feb 2007 22:12:45 +0100, SasQ skrobie:
>> Dnia Mon, 26 Feb 2007 20:10:02 +0100, rwt napisa³(a):
>
>> > Byæ mo¿e w jêzyku nadal pozostaje operator przypisania (jak we
>> > wcze¶niejszym cytacie), ale... obiekty, które maj± program wi±¿±cy
>> > z mechanizmami jêzyka, inny ni¿ zformalizowany, czyli inny ni¿
>> > otwarty mimo ¿e istniej±cy (jak w jêzykach funkcyjnych)- po
>> > zwyk³ym skopiowaniu warto¶ci przez sam zwi±zek z innymi obiektami
>> > tworzony przez ten program staj± siê klonami a nie kopiami.
>
>> Atak klonów ;)
>
> Nie ma siê co ¶miaæ.
>
> Kopiowanie nie zachodzi dla obiektów typów niewarto¶ciowych, a jedynie dla
> obiektów typów warto¶ciowych. Kopiowaniu podlega wtedy owa "warto¶æ",
> która mo¿e byæ dowolnie przenoszona pomiêdzy poszczególnymi obiektami.
>
> Natomiast obiekty niewarto¶ciowe, jak sama nazwa wskazuje, warto¶ci nie
> maj±, wiêc one podlegaj± klonowaniu - tworzy siê nowy obiekt o nowej
> to¿samo¶ci. W obiektach warto¶ciowych to¿samo¶ci± jest warto¶æ.

Czy mo¿esz podaæ jakie¶ ¼ród³a mówi±ce o typach warto¶ciowych i
niewarto¶ciowych? Google na takie pytanie odpowiada wy³±cznie Twoimi
postami z usenetu.

--
Mariusz Lotko
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
#15255
Author: Sektor van Skijl
Date: Sat, 03 Mar 2007 14:03
77 lines
4258 bytes
Dnia Sat, 03 Mar 2007 12:26:28 +0100, Mariusz Lotko skrobie:
> Czy mo¿esz podaæ jakie¶ ¼ród³a mówi±ce o typach warto¶ciowych i
> niewarto¶ciowych? Google na takie pytanie odpowiada wy³±cznie Twoimi
> postami z usenetu.

Problem w tym, ¿e wiedza na ten temat jest aktualnie na etapie "odkrywamy, ¿e
w jêzyku nagle jest co¶, czego twórca nie wymy¶li³".

Natomiast tak dok³adniej sprawa polega na tym, ¿e o istnieniu warto¶ci od
d³u¿szego czasu wszyscy wiedzieli, tylko ¿e nie bardzo wiedzieli, jak siê maj±
do tego zabraæ.

Przyk³adowo, od zawsze wiedziano, ¿e takie 'int' i 'Car' ró¿ni co¶ wiêcej, ni¿
tylko zestaw dozwolonych operacji. Ale w wiêkszo¶ci jêzyków niestety
sprowadzono to do specjalnego traktowania liczb ca³kowitych (tak jest w
Smalltalku i w Javie), a co za tym idzie, uniemo¿liwiono tworzenie w³asnych
typów warto¶ciowych. W Javie po prostu stwierdzono, ¿e wszystkie typy
warto¶ciowe to bêd± typy wbudowane (czyli, najpro¶ciej mówi±c, s± to wszystkie
rzeczy, których nie tworzy siê przez new) i u¿ytkownik nie mo¿e definiowaæ
w³asnych.

Tematem siê raczej nikt nie zaj±³ i raczej nikt go nie opracowa³ - wiedzia³bym
o tym, bo po takim wa³kowaniu tematu, jakie zorganizowa³em na pl.comp.lang.c,
my¶lê ¿e kto¶ dobrze obyty z ogólnie dostêpn± wiedz± nt. informatyki ju¿ by to
zg³osi³. Mo¿e nikt nie uwa¿a go za wart uwagi.

Co jeszcze ciekawsze, wiêkszo¶æ jêzyków (nie tylko Smalltalk i Java, ale
równie¿ wiele funkcjonalnych) ma dziwnie "uniwersalne" podej¶cie do tych
obiektów i usi³uje zaciemniæ ten podzia³. W Smalltalku przyk³adowo (a tak¿e
np. w OCamlu) masz ka¿dy obiekt zapisany na czterech bajtach. W tych czterech
bajtach s± jednak wyznaczone odpowiednie bity, które odró¿niaj± liczbê
ca³kowit± od wska¼nika na obiekt. W ten sposób liczba ca³kowita jest takim
samym obiektem, jak ka¿dy inny, a fakt, ¿e nie nastêpuje przydzia³ pamiêci
przy tworzeniu, jest szczegó³em implementacyjnym.

Jednak podzia³ na "warto¶ci" i "obiekty" bierze siê nie z samej konstrukcji
jêzyków, tylko z pojêæ u¿ywanych równie¿ w codziennym ¿yciu. Wszystko zale¿y
od tego, co oznacza dla nas stwierdzenie "ten sam".

Przyk³adowo, je¶li mówimy "ten sam samochód", to chodzi nam o ten sam
egzemplarz samochodu, a nie o inny samochód tylko identyczny.

Je¶li mówimy "ten sam kolor" albo "ten sam producent" (!) - chodzi o to, ¿e
samochód zosta³ pomalowany farb± o tym samym kodzie koloru, a w drugim
przypadku, ¿e identyfikator producenta jest identyczny.

Identyfikator i kolor nie mog± mieæ egzemplarzy, wiêc to s± warto¶ci.
Identyfikator akurat dodatkowo obrazuje nam co¶, co jest odpowiednikiem
"referencji", która te¿ jest typem warto¶ciowym.

Z podzia³em na typy warto¶ciowe i niewarto¶ciowe wi±¿e siê równie¿ kwestia
porównywania, nie tylko kopiowania.Przyk³adowo, porównywanie powinno siê
odbywaæ tylko dla typów warto¶ciowych, a to powinno konkretnie stwierdziæ, czy
oba obiekty posiadaj± t± sam± warto¶æ. Porównanie obiektów typów
niewarto¶ciowych nie ma sensu - albo uznajemy go za obiekt warto¶ciowy (tzn.
taki, gdzie kopiowanie z innego czyni go identycznym z tym innym), albo
niewarto¶ciowy, wiêc nie ma tu czego porównaæ.

Niestety jêzyki próbuj±ce i¶æ w poprzek tego podzia³u dostaj± nadmiernej
komplikacji. Nie pamiêtam nawet dok³adnie, jakie jêzyki to maj±, ale jest ich
wiele. Chodzi o osobne wrêcz operatory do porównania osobno warto¶ci i
to¿samo¶ci - i tu mamy wiele ró¿nych kombinacji, jak <> i != (dla nierównych),
czasem jest = i == itd. Musz± byæ wprowadzone, bo sam jêzyk nie rozró¿nia
typów obiektowych i warto¶ciowych. Programista zwykle rozró¿nia, nawet
bezwiednie, ale i tak teoretycznie da siê zrobiæ tak± g³upotê, jak obiekt
warto¶ciowy z w³asn± to¿samo¶ci±.

Ale tu ciekawostka - Java np. nie posiada takiego rozró¿nienia i to jest w
niej pozytywne. Problem z Jav± jednak le¿y gdzie indziej - jej typ String jest
typem obiektowym, a nie warto¶ciowym (podczas gdy String moim zdaniem nale¿y
w³a¶nie do typów warto¶ciowych i takim jest np. w C++).


--
//  _    ___         Michal "Sektor" Malecki <sektor(whirl)kis.p.lodz.pl>
\\ L_ |/ `|  /^\ ,()                         <ethouris(O)gmail.com>
// \_ |\  \/ \_/ /\ C++ bez cholesterolu: http://www.intercon.pl/~sektor/cbx
"Java is answer for a question that has never been stated"
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
#15257
Author: Marcin 'Qrczak'
Date: Sat, 03 Mar 2007 17:45
25 lines
938 bytes
Dnia 03-03-2007, sob o godzinie 14:03 +0000, Sektor van Skijlen
napisał(a):

> Ale w większości języków niestety
> sprowadzono to do specjalnego traktowania liczb całkowitych (tak jest w
> Smalltalku i w Javie), a co za tym idzie, uniemożliwiono tworzenie własnych
> typów wartościowych.

Nie ma potrzeby ściślejszego wyróżniania typów wartościowych niż
danie im odpowiedniej definicja równości. W języku, który nie kopiuje
niejawnie obiektów (czyli w większości poza C/C++), jedyne potrzebne
wsparcie dla typów wartościowych to definicja standardowej równości
dla tych typów uwzględniająca zawartość, a nie tożsamość obiektu.

-- 
   __("<         Marcin Kowalczyk
   \__/       qrczak@knm.org.pl
    ^^     http://qrnik.knm.org.pl/~qrczak/
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
#15258
Author: Sektor van Skijl
Date: Sat, 03 Mar 2007 17:46
43 lines
1944 bytes
Dnia Sat, 03 Mar 2007 17:45:39 +0100, Marcin 'Qrczak' Kowalczyk skrobie:
> Dnia 03-03-2007, sob o godzinie 14:03 +0000, Sektor van Skijlen
> napisa³(a):

> > Ale w wiêkszo¶ci jêzyków niestety
> > sprowadzono to do specjalnego traktowania liczb ca³kowitych (tak jest w
> > Smalltalku i w Javie), a co za tym idzie, uniemo¿liwiono tworzenie w³asnych
> > typów warto¶ciowych.

> Nie ma potrzeby ¶ci¶lejszego wyró¿niania typów warto¶ciowych ni¿
> danie im odpowiedniej definicja równo¶ci. W jêzyku, który nie kopiuje
> niejawnie obiektów (czyli w wiêkszo¶ci poza C/C++), jedyne potrzebne
> wsparcie dla typów warto¶ciowych to definicja standardowej równo¶ci
> dla tych typów uwzglêdniaj±ca zawarto¶æ, a nie to¿samo¶æ obiektu.

Mo¿liwe, ale by³bym za tym, ¿eby po prostu okre¶laæ, czy porównanie ma
porównywaæ WARTO¦Æ, czy TO¯SAMO¦Æ. Tyle, my¶lê, by wystarczy³o.

Chodzi jednak o to, ¿eby w jêzyku by³a mo¿liwa do opisania konstrukcja typu:

String s;
...

s += "\n";

Ja wiem, ¿e Javowy string to wszystko ma (przyda³oby mu siê tylko, ¿eby
operator porównania te¿ porównywa³ po warto¶ci), ale co mnie to obchodzi -
String jest w Javie dok³adnie tak samo typem wbudowanym, jak int.

Jako wsparcie dla typów warto¶ciowych, takie pe³ne, wyobra¿a³bym sobie:

 - mo¿liwo¶æ okre¶lenia, jak wykonuje siê porównanie warto¶ci (i opisaæ to
   jako standardowe porównanie dla tego typu)
 - mo¿liwo¶æ okre¶lenia, co ma siê dziaæ z obiektem, który chcemy zmodyfikowaæ
   w miejscu za po¶rednictwem takiego uchwytu, jaki akurat jest dostêpny w
   jêzyku (w Javie tym uchwytem jest referencja, wiêc i tak musi siê wtedy
   odbyæ wyprodukowanie nowego obiektu i zgubienie starego)


--
//  _    ___         Michal "Sektor" Malecki <sektor(whirl)kis.p.lodz.pl>
\\ L_ |/ `|  /^\ ,()                         <ethouris(O)gmail.com>
// \_ |\  \/ \_/ /\ C++ bez cholesterolu: http://www.intercon.pl/~sektor/cbx
"Java is answer for a question that has never been stated"
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
#15259
Author: Mariusz Lotko
Date: Sun, 04 Mar 2007 00:56
29 lines
1134 bytes
Sektor van Skijlen wrote:

> Dnia Sat, 03 Mar 2007 17:45:39 +0100, Marcin 'Qrczak' Kowalczyk skrobie:
>> Dnia 03-03-2007, sob o godzinie 14:03 +0000, Sektor van Skijlen
>> napisa³(a):
>
>> > Ale w wiêkszo¶ci jêzyków niestety
>> > sprowadzono to do specjalnego traktowania liczb ca³kowitych (tak jest w
>> > Smalltalku i w Javie), a co za tym idzie, uniemo¿liwiono tworzenie
>> > w³asnych typów warto¶ciowych.
>
>> Nie ma potrzeby ¶ci¶lejszego wyró¿niania typów warto¶ciowych ni¿
>> danie im odpowiedniej definicja równo¶ci. W jêzyku, który nie kopiuje
>> niejawnie obiektów (czyli w wiêkszo¶ci poza C/C++), jedyne potrzebne
>> wsparcie dla typów warto¶ciowych to definicja standardowej równo¶ci
>> dla tych typów uwzglêdniaj±ca zawarto¶æ, a nie to¿samo¶æ obiektu.
>
> Mo¿liwe, ale by³bym za tym, ¿eby po prostu okre¶laæ, czy porównanie ma
> porównywaæ WARTO¦Æ, czy TO¯SAMO¦Æ. Tyle, my¶lê, by wystarczy³o.

Python rozró¿nia to¿samo¶æ z warto¶ci± tzn. s± porównania

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?

--
Mariusz Lotko
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
#15260
Author: Sektor van Skijl
Date: Sun, 04 Mar 2007 14:50
36 lines
1659 bytes
Dnia Sun, 04 Mar 2007 00:56:21 +0100, Mariusz Lotko skrobie:
> Sektor van Skijlen wrote:

> > Dnia Sat, 03 Mar 2007 17:45:39 +0100, Marcin 'Qrczak' Kowalczyk skrobie:
> >> Dnia 03-03-2007, sob o godzinie 14:03 +0000, Sektor van Skijlen
> >> napisa³(a):
> >
> >> > Ale w wiêkszo¶ci jêzyków niestety
> >> > sprowadzono to do specjalnego traktowania liczb ca³kowitych (tak jest w
> >> > Smalltalku i w Javie), a co za tym idzie, uniemo¿liwiono tworzenie
> >> > w³asnych typów warto¶ciowych.
> >
> >> Nie ma potrzeby ¶ci¶lejszego wyró¿niania typów warto¶ciowych ni¿
> >> danie im odpowiedniej definicja równo¶ci. W jêzyku, który nie kopiuje
> >> niejawnie obiektów (czyli w wiêkszo¶ci poza C/C++), jedyne potrzebne
> >> wsparcie dla typów warto¶ciowych to definicja standardowej równo¶ci
> >> dla tych typów uwzglêdniaj±ca zawarto¶æ, a nie to¿samo¶æ obiektu.
> >
> > Mo¿liwe, ale by³bym za tym, ¿eby po prostu okre¶laæ, czy porównanie ma
> > porównywaæ WARTO¦Æ, czy TO¯SAMO¦Æ. Tyle, my¶lê, by wystarczy³o.

> Python rozró¿nia to¿samo¶æ z warto¶ci± tzn. s± porównania

> 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¶æ.


--
//  _    ___         Michal "Sektor" Malecki <sektor(whirl)kis.p.lodz.pl>
\\ L_ |/ `|  /^\ ,()                         <ethouris(O)gmail.com>
// \_ |\  \/ \_/ /\ C++ bez cholesterolu: http://www.intercon.pl/~sektor/cbx
"Java is answer for a question that has never been stated"
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
#15261
Author: "Adam Karpierz"
Date: Sun, 04 Mar 2007 17:30
37 lines
1236 bytes
"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¶æ.

Czyli chodzi ci ogolnie o to, aby cos bylo sp...dzielone

Jesli do porownania wartosci jak i tozsamosci istnieje
w danym jezyku ten sam operator to taki jezyk mozna sobie
usnac za syf, a nie jezyk

Podobnie z operatorem przypisania
Jelsi do skopowiania obiektu uzywa sie tego samego
operatora co do przypisania referencji to jest to rowniez syf.

Wiec jest doklandie odwrotnie niz piszesz:

Chodzi o to, ¿e maja byæ dostêpny inny oparator do porownania
wartosci a inny do porownania tozsamosci obiektow

Podobnie chodzi o to aby byl dostepny inny operator do
'clone' obiektu a inny do zmiany referencji

Porzadne jezyki tak maja (mialy nawet w latach 60-tych),
a jesli np ten syf zwany C++ tego nie ma to nazwij to zwyczajnie syfem.
i przejdz nad tym do porzadku dziennego,  a nie probuj robic
z tego syfu kamieni szlachetnych.

AK

Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
#15262
Author: Marcin 'Qrczak'
Date: Sun, 04 Mar 2007 17:46
35 lines
1421 bytes
Dnia 04-03-2007, nie o godzinie 14:50 +0000, Sektor van Skijlen
napisał(a):

> > 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ść.

To się sprawdza, ale tylko w językach, w których podstawowe wartości są
realizowane przez obiekty immutable. Jeśli tak nie jest, czyli kiedy
typ, który powinien być typem wartościowym, jest realizowany jako obiekt
ze stanem, czyli kiedy ten obiekt ze stanem tak naprawdę modeluje
zmienną tego typu, a nie wartość tego typu, to mamy konflikt: równość
zmiennych powinna porównywać zmienne jako takie, ale częściej chcemy
porównywać bieżące wartości tych zmiennych i to zazwyczaj robi operator
==. Czyli po pierwsze działa niezgodnie z ogólnymi wytycznymi, a po
drugie porównanie zmiennych w razie czego też powinno być dostępne.

-- 
   __("<         Marcin Kowalczyk
   \__/       qrczak@knm.org.pl
    ^^     http://qrnik.knm.org.pl/~qrczak/
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
#15264
Author: Mariusz Lotko
Date: Sun, 04 Mar 2007 19:37
89 lines
3103 bytes
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.
Operator == dla dwóch obiektów powinien _zawsze_ porównywaæ równo¶æ
semantyczn± ich _zawarto¶ci_, a nie kombinowaæ z ich to¿samo¶ci±.
Nie widzê szczególnego powodu, ¿eby wska¼niki nazywaæ "obiektami
niewarto¶ciowymi", skoro pe³ni± one funkcjê referencji, czy jak
kto woli, identyfikatora obiektu.
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.

> Czyli chodzi ci ogolnie o to, aby cos bylo sp...dzielone

Wszystko mo¿na zepsuæ, je¶li siê tylko za mocno kombinuje nie zwa¿aj±c
na intencje twórcy (tu: twórcy C++).

> Jesli do porownania wartosci jak i tozsamosci istnieje
> w danym jezyku ten sam operator to taki jezyk mozna sobie
> usnac za syf, a nie jezyk

Operator ten sam, pytanie na czym go u¿yjesz (na obiektach, czy na
identyfikatorach obiektów, za które w C++ mo¿na uznaæ wska¼niki).

> Podobnie z operatorem przypisania
> Jelsi do skopowiania obiektu uzywa sie tego samego
> operatora co do przypisania referencji to jest to rowniez syf.

j.w.

> Wiec jest doklandie odwrotnie niz piszesz:
>
> Chodzi o to, ¿e maja byæ dostêpny inny oparator do porownania
> wartosci a inny do porownania tozsamosci obiektow

Tak by by³o rzeczywi¶cie najlepiej. Ale uwa¿am, ¿e operator == jest
i tak lepszy w C++ ni¿ w Javie. Bo niby dlaczego logiczna równo¶æ
mia³aby dotyczyæ wy³±cznie relacji bycia tym samym obiektem?
Idealnie jest to w Pythonie: operator == jak w C++ i operator "is"
jak w Javie.

> 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++...

>
> Porzadne jezyki tak maja (mialy nawet w latach 60-tych),
> a jesli np ten syf zwany C++ tego nie ma to nazwij to zwyczajnie syfem.
> i przejdz nad tym do porzadku dziennego,  a nie probuj robic
> z tego syfu kamieni szlachetnych.

Jako fan C++ nie zgadzam siê co do syfu, ale zgadzam siê, ¿e dorabianie
teorii tu, gdzie jej nie ma i nie bêdzie, nie czyni niczego lepszym.

--
Mariusz Lotko
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
#15265
Author: "Adam Karpierz"
Date: Sun, 04 Mar 2007 20:52
12 lines
289 bytes
"Mariusz Lotko" <imie.nazwisko@wp.pl> wrote:
> Adam Karpierz wrote:

>>> 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¶æ.

Prosze mi nie przypisywac slow Sekatora :)

AK

Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
#15266
Author: Sektor van Skijl
Date: Sun, 04 Mar 2007 21:09
51 lines
2689 bytes
Dnia Sun, 04 Mar 2007 17:46:12 +0100, Marcin 'Qrczak' Kowalczyk skrobie:
> Dnia 04-03-2007, nie o godzinie 14:50 +0000, Sektor van Skijlen
> napisa³(a):

> > > 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¶æ.

> To siê sprawdza, ale tylko w jêzykach, w których podstawowe warto¶ci s±
> realizowane przez obiekty immutable. Je¶li tak nie jest, czyli kiedy
> typ, który powinien byæ typem warto¶ciowym, jest realizowany jako obiekt
> ze stanem, czyli kiedy ten obiekt ze stanem tak naprawdê modeluje
> zmienn± tego typu, a nie warto¶æ tego typu, to mamy konflikt: równo¶æ
> zmiennych powinna porównywaæ zmienne jako takie, ale czê¶ciej chcemy
> porównywaæ bie¿±ce warto¶ci tych zmiennych i to zazwyczaj robi operator
> ==. Czyli po pierwsze dzia³a niezgodnie z ogólnymi wytycznymi, a po
> drugie porównanie zmiennych w razie czego te¿ powinno byæ dostêpne.

Ha! W razie czego!

No w³a¶nie o to chodzi, ¿e nie. Je¶li okre¶lamy dany typ jako warto¶ciowy, to
to¿samo¶æ przechowuj±cego j± obiektu nie powinna nas interesowaæ w ogóle.

Je¶li jest to potrzebne do jakich¶ wewnêtrznych operacji, to powinno byæ
dostêpne w inny sposób, jakim¶ specjalnym interfejsem, dostêpnym tylko
wewn±trz implementacji. U¿ytkownik powinien dostaæ do tego standardowe API, z
operatorem porównania porównuj±cym warto¶ci.

Zauwa¿, po co w C++ stosuje siê wska¼niki i referencje do takich typów jak
int, czy std::string. Je¶li ju¿, to stosuje siê albo uogólnienie przekazywania
(const T&), albo przekazuje siê do zmodyfikowania (T&, T*). Czy widzia³e¶
kiedykolwiek w jakim¶ rzeczywistym programie, ¿eby kto¶ porównywa³ dwa
wska¼niki do int (pomijaj±c przypadek, gdy wska¼nik do int jest u¿ywany jako
iterator do tablicy int-ów - czyli zastosowanie jest inne, ni¿ warto¶æ
referencji)?

Dlatego to¿samo¶ci± dla obiektów warto¶ciowych jest warto¶æ. Obiekty mog±
sobie t± warto¶æ przekazywaæ jak chc±, a nawet - jak pamiêtasz, dyskutowali¶my
o tym - warto¶ci mog± byæ symulowane przez predefiniowane unikalne obiekty i w
takim przypadku porównanie to¿samo¶ci takich obiektów jest równowa¿ne
porównaniu warto¶ci, choæ to ju¿ jest szczegó³ implementacyjny.


--
//  _    ___         Michal "Sektor" Malecki <sektor(whirl)kis.p.lodz.pl>
\\ L_ |/ `|  /^\ ,()                         <ethouris(O)gmail.com>
// \_ |\  \/ \_/ /\ C++ bez cholesterolu: http://www.intercon.pl/~sektor/cbx
"Java is answer for a question that has never been stated"
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
#15267
Author: Sektor van Skijl
Date: Sun, 04 Mar 2007 21:21
86 lines
3110 bytes
Dnia Sun, 4 Mar 2007 17:30:21 +0100, Adam Karpierz skrobie:
> "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?æ.

> Czyli chodzi ci ogolnie o to, aby cos bylo sp...dzielone

Nie. Chodzi o to, ¿eby nie by³o zjebane.

> Jesli do porownania wartosci jak i tozsamosci istnieje
> w danym jezyku ten sam operator to taki jezyk mozna sobie
> usnac za syf, a nie jezyk

Ok, o gustach mo¿esz sobie podyskutowaæ, je¶li lubisz, ja oczywi¶cie bêdê móg³
o tym równie¿ porozmawiaæ, je¶li masz na ten temat do powiedzenia cokolwiek
wiêcej, ni¿ "syf, a nie jêzyk". Aha, plus wszelkie "ile to ja mam lat
do¶wiadczenia".

Przypomnê na marginesie, ¿e tak maj± to w³a¶nie zrobione wszystkie jêzyki
"mainstreamowe". Aha, Perl równie¿, chocia¿ wola³bym siê nim raczej podcieraæ,
ni¿ podpieraæ.

> Podobnie z operatorem przypisania

Nie pisa³em nic o operatorze przypisania.

> Jelsi do skopowiania obiektu uzywa sie tego samego
> operatora co do przypisania referencji to jest to rowniez syf.

Problem polega na tym, ¿e operator przypisania powinien byæ dostêpny i tak
tylko dla typów warto¶ciowych. Przy czym typem warto¶ciowym jest równie¿
referencja (wska¼nik w przypadku C++).

> Wiec jest doklandie odwrotnie niz piszesz:

> Chodzi o to, ¿e maja byæ dostêpny inny oparator do porownania
> wartosci a inny do porownania tozsamosci obiektow

No, dobrze, w ostateczno¶ci siê zgodzê, ¿e tak to ma byæ.

Pod jednym wszak¿e warunkiem. ¯e dla ka¿dego typu jest dostêpny wy³±cznie albo
jeden albo drugi.

W sumie na jedno wychodzi - reszta to kwestia sk³adni.

> Podobnie chodzi o to aby byl dostepny inny operator do
> 'clone' obiektu a inny do zmiany referencji

Mo¿e i tak byæ - w³±cznie z powy¿szym zastrze¿eniem. Fakt, to nie jest dobre,
¿eby stosowaæ operator przypisania do typów niewarto¶ciowych. Powinno siê
stosowaæ inne metody, tak dla rozró¿nienia.

> Porzadne jezyki tak maja (mialy nawet w latach 60-tych),

Te tzw. "porz±dne jêzyki" udostêpnia³y wszystko dla wszystkich, przy czym sam
musia³e¶ pamiêtaæ, co jest czym dla ciebie.

Dziêkujê bardzo. Gdybym nie potrzebowa³ odpowiedniego wspomagania decyzji i
uwagi, to pisa³bym w asemblerze.

> a jesli np ten syf zwany C++ tego nie ma

C++ akurat ma (Tcl te¿).

> to nazwij to zwyczajnie syfem.

Tak, i Javê, i C#, i Perla. Z najwiêksz± przyjemno¶ci± ;)

> i przejdz nad tym do porzadku dziennego,  a nie probuj robic
> z tego syfu kamieni szlachetnych.

Nie jestem chemikiem i nie znam siê na kamieniach szlachetnych.


--
//  _    ___         Michal "Sektor" Malecki <sektor(whirl)kis.p.lodz.pl>
\\ L_ |/ `|  /^\ ,()                         <ethouris(O)gmail.com>
// \_ |\  \/ \_/ /\ C++ bez cholesterolu: http://www.intercon.pl/~sektor/cbx
"Java is answer for a question that has never been stated"
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
#15268
Author: Sektor van Skijl
Date: Sun, 04 Mar 2007 22:09
204 lines
8508 bytes
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".

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¦Æ).

Po drugie, nie ma akurat kombinowania z to¿samo¶ci± - je¶li mamy np. (no,
we¼my teraz Javê dla odmiany) dwie zmienne referencyjne, to ich porównanie nie
porównuje tych zmiennych referencyjnych, tylko ich warto¶ci, a w efekcie
porównuje siê to¿samo¶ci obiektów.

> Nie widzê szczególnego powodu, ¿eby wska¼niki nazywaæ "obiektami
> niewarto¶ciowymi", skoro pe³ni± one funkcjê referencji, czy jak
> kto woli, identyfikatora obiektu.

Ale¿ wska¼niki s± jak najbardziej typami warto¶ciowymi, tylko i wy³±cznie!

Tylko obiekty, które s± przez te wska¼niki wskazywane, ju¿ niekoniecznie. W
szczególno¶ci, w idealnym projekcie powinno byæ tak, ¿eby wska¼nik nie by³
potrzebny do czegokolwiek poza przyczynami czysto jêzykowymi (czyli, inaczej,
¿eby warto¶æ tego wska¼nika w ogóle nikogo nie musia³a interesowaæ).

> 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.

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 Javie zreszt± jest to urz±dzone niemal idealnie pod tym wzglêdem, tylko z
drobnymi zastrze¿eniami:

 - Java nie pozwala na definiowanie w³asnych typów warto¶ciowych
 - Nie wprowadzono mechanizmu tupli, które mog³yby zast±piæ niemo¿liwo¶æ
   przekazania do metody zmiennej przez referencjê

> > Jesli do porownania wartosci jak i tozsamosci istnieje
> > w danym jezyku ten sam operator to taki jezyk mozna sobie
> > usnac za syf, a nie jezyk

> Operator ten sam, pytanie na czym go u¿yjesz (na obiektach, czy na
> identyfikatorach obiektów, za które w C++ mo¿na uznaæ wska¼niki).

Problem w tym, ¿e rozró¿nienie typów jest wystarczaj±ce je¶li u¿ywamy osobnej
sk³adni do okre¶lenia warto¶ci i osobnej sk³adni do oker¶lenia referencji.

Tak ma C++, pomijaj±c przypadek, gdy jawnie u¿ywamy referencji.

Tak ma te¿ Tcl - sama nazwa jest zawsze wy³±cznie referencj±, dopiero
poprzedzenie jej '$' oznacza warto¶æ. W efekcie np. jak zrobisz:

proc compare {a b} { return $a == $b }

to potem wszystko zale¿y od tego, czy napiszesz
[compare x y]
czy
[compare $x $y]


> > Wiec jest doklandie odwrotnie niz piszesz:
> >
> > Chodzi o to, ¿e maja byæ dostêpny inny oparator do porownania
> > wartosci a inny do porownania tozsamosci obiektow

> Tak by by³o rzeczywi¶cie najlepiej. Ale uwa¿am, ¿e operator == jest
> i tak lepszy w C++ ni¿ w Javie. Bo niby dlaczego logiczna równo¶æ
> mia³aby dotyczyæ wy³±cznie relacji bycia tym samym obiektem?
> Idealnie jest to w Pythonie: operator == jak w C++ i operator "is"
> jak w Javie.

Tak, tylko ¿e je¶li "wierzymy w podzia³ na obiekty warto¶ciowe i
niewarto¶ciowe" (czytaj: mamy oczy tam gdzie trzeba), to relacja 'is' w
obiektach warto¶ciowych jest nam zbêdna, a '==' w obiektach niewarto¶ciowych
równie¿ nie ma sensu.

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.

Drugie z kolei nie ma sensu dlatego, ¿e porównania obiektów, je¶li ju¿
istniej±, to zazwyczaj maj± zupe³nie inny wymiar. Je¶li ju¿ co¶ porównujemy,
to porównujemy stany, najczê¶ciej okre¶lone stany cz±stkowe. Np. mo¿emy
porównywaæ samochody pod wzglêdem tego, czy s± tego samego koloru, albo tej
samej marki, a tak¿e, czy jeden ma lepszego kopa od drugiego. Ale nie bardzo
mo¿emy "porównaæ dwa samochody", no bo jak?

Nawet w przypadku porz±dkowania obiektów, mamy do czynienia z okre¶laniem
odpowiedniego kryterium porz±dkowania. Kryterium mo¿e byæ okre¶lone nawet
wielopoziomowo (np. uszeregowaæ samochody wg marki, a jak s± tej samej marki
to wg mocy silnika, a jak s± nadal te same, to wg koloru itd.).

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.

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).

A to siê bierze st±d, ¿e to¿samo¶æ obiektu decyduje nam o widoczno¶ci zmian.
Je¶li bowiem mamy dwa wska¼niki (a i b) wskazuj±ce na jeden obiekt, to wtedy
po a->x = 10 mo¿emy byæ pewni, ¿e b->x == 10.

Dlatego te¿ porównania warto¶ci okre¶lonych stanów cz±stkowych obiektów (nawet
je¶li obiekt ma tylko jeden taki stan) odbywaj± siê tylko w ten sposób:

1. Porównanie warto¶ci stanu z jak±¶ predefiniowan± sta³±
2. Sprawdzenie, czy warto¶ci stanu z dwóch ró¿nych obiektów maj± tak± sam±
warto¶æ - ale równie¿ równ± tak¿e jakiej¶ predefiniowanej sta³êj

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?

> > 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.

BTW. akurat siê zastanawiam nad tym, czy w Ginle dopu¶ciæ tak± mo¿liwo¶æ.
Oczywi¶cie tworzenie na stosie nie wchodzi w rachubê tak czy siak, ale
chcia³bym nie zabraniaæ mo¿liwo¶ci tworzenia pod-obiektów jako pól. Czyli ¿eby
obiekty tych samych typów mog³y byæ tworzone dynamicznie, a jednocze¶nie ¿eby
te¿ mog³y byæ polami.


--
//  _    ___         Michal "Sektor" Malecki <sektor(whirl)kis.p.lodz.pl>
\\ L_ |/ `|  /^\ ,()                         <ethouris(O)gmail.com>
// \_ |\  \/ \_/ /\ C++ bez cholesterolu: http://www.intercon.pl/~sektor/cbx
"Java is answer for a question that has never been stated"
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
#15269
Author: Mariusz Lotko
Date: Mon, 05 Mar 2007 07:07
209 lines
8341 bytes
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ê?

>
> 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?

> Po drugie, nie ma akurat kombinowania z to¿samo¶ci± - je¶li mamy np. (no,
> we¼my teraz Javê dla odmiany) dwie zmienne referencyjne, to ich porównanie
> nie porównuje tych zmiennych referencyjnych, tylko ich warto¶ci, a w
> efekcie porównuje siê to¿samo¶ci obiektów.

Zgoda, z tym, ¿e ja pisa³em o C++.

>
>> Nie widzê szczególnego powodu, ¿eby wska¼niki nazywaæ "obiektami
>> niewarto¶ciowymi", skoro pe³ni± one funkcjê referencji, czy jak
>> kto woli, identyfikatora obiektu.
>
> Ale¿ wska¼niki s± jak najbardziej typami warto¶ciowymi, tylko i wy³±cznie!
>
> Tylko obiekty, które s± przez te wska¼niki wskazywane, ju¿ niekoniecznie.
> W szczególno¶ci, w idealnym projekcie powinno byæ tak, ¿eby wska¼nik nie
> by³ potrzebny do czegokolwiek poza przyczynami czysto jêzykowymi (czyli,
> inaczej, ¿eby warto¶æ tego wska¼nika w ogóle nikogo nie musia³a
> interesowaæ).
>
>> 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?

> 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.

> W Javie zreszt± jest to urz±dzone niemal idealnie pod tym wzglêdem, tylko
> z drobnymi zastrze¿eniami:
>
>  - Java nie pozwala na definiowanie w³asnych typów warto¶ciowych
>  - Nie wprowadzono mechanizmu tupli, które mog³yby zast±piæ niemo¿liwo¶æ
>    przekazania do metody zmiennej przez referencjê

Od roku programujê w Javie, jako¶ nieszczególnie mi to przeszkadza.

>> > Wiec jest doklandie odwrotnie niz piszesz:
>> >
>> > Chodzi o to, ¿e maja byæ dostêpny inny oparator do porownania
>> > wartosci a inny do porownania tozsamosci obiektow
>
>> Tak by by³o rzeczywi¶cie najlepiej. Ale uwa¿am, ¿e operator == jest
>> i tak lepszy w C++ ni¿ w Javie. Bo niby dlaczego logiczna równo¶æ
>> mia³aby dotyczyæ wy³±cznie relacji bycia tym samym obiektem?
>> Idealnie jest to w Pythonie: operator == jak w C++ i operator "is"
>> jak w Javie.
>
> Tak, tylko ¿e je¶li "wierzymy w podzia³ na obiekty warto¶ciowe i
> niewarto¶ciowe" (czytaj: mamy oczy tam gdzie trzeba), to relacja 'is' w
> obiektach warto¶ciowych jest nam zbêdna, a '==' w obiektach
> niewarto¶ciowych równie¿ nie ma sensu.
>
> 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æ.

> Drugie z kolei nie ma sensu dlatego, ¿e porównania obiektów, je¶li ju¿
> istniej±, to zazwyczaj maj± zupe³nie inny wymiar. Je¶li ju¿ co¶
> porównujemy, to porównujemy stany, najczê¶ciej okre¶lone stany cz±stkowe.
> Np. mo¿emy porównywaæ samochody pod wzglêdem tego, czy s± tego samego
> koloru, albo tej samej marki, a tak¿e, czy jeden ma lepszego kopa od
> drugiego. Ale nie bardzo mo¿emy "porównaæ dwa samochody", no bo jak?
>
> Nawet w przypadku porz±dkowania obiektów, mamy do czynienia z okre¶laniem
> odpowiedniego kryterium porz±dkowania. Kryterium mo¿e byæ okre¶lone nawet
> wielopoziomowo (np. uszeregowaæ samochody wg marki, a jak s± tej samej
> marki to wg mocy silnika, a jak s± nadal te same, to wg koloru itd.).
>
> 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.

Mimo to nie odwa¿y³bym siê na takie wyra¼ne i jednoznaczne nazwanie
pierwszych obiektów warto¶ciowymi a drugich niewarto¶ciowymi.

>
> 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.

> 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. Dziwiê siê Twoj± opini±, bo
sprawiasz wra¿enie cz³owieka, który ma do¶wiadczenie zawodowe i trochê
linii kodu wyprodukowa³.

>
>> > 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... :-)


--
Mariusz Lotko
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
#15270
Author: Mariusz Lotko
Date: Mon, 05 Mar 2007 07:07
73 lines
3428 bytes
Sektor van Skijlen wrote:

> Dnia Sun, 04 Mar 2007 17:46:12 +0100, Marcin 'Qrczak' Kowalczyk skrobie:
>> Dnia 04-03-2007, nie o godzinie 14:50 +0000, Sektor van Skijlen
>> napisa³(a):
>
>> > > 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¶æ.
>
>> To siê sprawdza, ale tylko w jêzykach, w których podstawowe warto¶ci s±
>> realizowane przez obiekty immutable. Je¶li tak nie jest, czyli kiedy
>> typ, który powinien byæ typem warto¶ciowym, jest realizowany jako obiekt
>> ze stanem, czyli kiedy ten obiekt ze stanem tak naprawdê modeluje
>> zmienn± tego typu, a nie warto¶æ tego typu, to mamy konflikt: równo¶æ
>> zmiennych powinna porównywaæ zmienne jako takie, ale czê¶ciej chcemy
>> porównywaæ bie¿±ce warto¶ci tych zmiennych i to zazwyczaj robi operator
>> ==. Czyli po pierwsze dzia³a niezgodnie z ogólnymi wytycznymi, a po
>> drugie porównanie zmiennych w razie czego te¿ powinno byæ dostêpne.
>
> Ha! W razie czego!
>
> No w³a¶nie o to chodzi, ¿e nie. Je¶li okre¶lamy dany typ jako warto¶ciowy,
> to to¿samo¶æ przechowuj±cego j± obiektu nie powinna nas interesowaæ w
> ogóle.

A zatem powszechnie stosowany "trik" polegaj±cy na sprawdzeniu to¿samo¶ci
obiektu w pierszej linijce operatora == uwa¿asz za b³êdny?
Podobnie w operatorze =, w którym zapobiega to przypisania obiektu
samemu sobie?

> Je¶li jest to potrzebne do jakich¶ wewnêtrznych operacji, to powinno byæ
> dostêpne w inny sposób, jakim¶ specjalnym interfejsem, dostêpnym tylko
> wewn±trz implementacji. U¿ytkownik powinien dostaæ do tego standardowe
> API, z operatorem porównania porównuj±cym warto¶ci.
>
> Zauwa¿, po co w C++ stosuje siê wska¼niki i referencje do takich typów jak
> int, czy std::string. Je¶li ju¿, to stosuje siê albo uogólnienie
> przekazywania (const T&), albo przekazuje siê do zmodyfikowania (T&, T*).
> Czy widzia³e¶ kiedykolwiek w jakim¶ rzeczywistym programie, ¿eby kto¶
> porównywa³ dwa wska¼niki do int (pomijaj±c przypadek, gdy wska¼nik do int
> jest u¿ywany jako iterator do tablicy int-ów - czyli zastosowanie jest
> inne, ni¿ warto¶æ referencji)?

Tak, w dowolnej konkretyzacji szablonu int'em. Nie ka¿demu chce siê
robiæ specjalne implementacje dla typów prostych.

> Dlatego to¿samo¶ci± dla obiektów warto¶ciowych jest warto¶æ. Obiekty mog±
> sobie t± warto¶æ przekazywaæ jak chc±, a nawet - jak pamiêtasz,
> dyskutowali¶my o tym - warto¶ci mog± byæ symulowane przez predefiniowane
> unikalne obiekty i w takim przypadku porównanie to¿samo¶ci takich obiektów
> jest równowa¿ne porównaniu warto¶ci, choæ to ju¿ jest szczegó³
> implementacyjny.

Nie zgadzam siê. Ka¿dy obiekt jest uproszczeniem rzeczywisto¶ci, a co za tym
idzie z du¿ym prawdopodobieñstwem mog± pojawiæ siê obiekty o tych samych
warto¶ciach, które nie s± tymi samymi obiektami.
To, ¿e mam kolor oczu jak Brad Pitt nie czyni mnie Bradem
Pitem o czym za¶wiadczy ka¿dy stosowny operator porównania - tu: kobieta ;-)

A powa¿nie: trzymajmy siê terminologii, która by³a, jest i sprawdza siê:
obiekt (zestaw warto¶ci) i identyfikator obiektu (to¿samo¶æ). Nie twórzmy
nowych teorii na temat abstrakcji, która ju¿ zosta³a odpowiednio
steoretyzowna.


--
Mariusz Lotko
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
#15271
Author: Mariusz Lotko
Date: Mon, 05 Mar 2007 07:09
17 lines
426 bytes
Adam Karpierz wrote:

> "Mariusz Lotko" <imie.nazwisko@wp.pl> wrote:
>> Adam Karpierz wrote:
>
>>>> 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¶æ.
>
> Prosze mi nie przypisywac slow Sekatora :)

Przepraszam, my¶la³em, ¿e g³êboko¶æ cytowania jest ju¿ wystarczaj±cym
rozró¿nikiem :-)

--
Mariusz Lotko
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
#15272
Author: Sektor van Skijl
Date: Mon, 05 Mar 2007 21:28
228 lines
9099 bytes
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.

> > 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;
};

> > Po drugie, nie ma akurat kombinowania z to¿samo¶ci± - je¶li mamy np. (no,
> > we¼my teraz Javê dla odmiany) dwie zmienne referencyjne, to ich porównanie
> > nie porównuje tych zmiennych referencyjnych, tylko ich warto¶ci, a w
> > efekcie porównuje siê to¿samo¶ci obiektów.

> Zgoda, z tym, ¿e ja pisa³em o C++.

Ale¿ w C++ masz to samo, tylko na wska¼nikach.

> >> 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?

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æ.

W C++ string jest typem warto¶ciowym i spe³nia wszystkie warunki dotycz±ce
typu warto¶ciowego.

> > 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.

> > Drugie z kolei nie ma sensu dlatego, ¿e porównania obiektów, je¶li ju¿
> > istniej±, to zazwyczaj maj± zupe³nie inny wymiar. Je¶li ju¿ co¶
> > porównujemy, to porównujemy stany, najczê¶ciej okre¶lone stany cz±stkowe.
> > Np. mo¿emy porównywaæ samochody pod wzglêdem tego, czy s± tego samego
> > koloru, albo tej samej marki, a tak¿e, czy jeden ma lepszego kopa od
> > drugiego. Ale nie bardzo mo¿emy "porównaæ dwa samochody", no bo jak?
> >
> > Nawet w przypadku porz±dkowania obiektów, mamy do czynienia z okre¶laniem
> > odpowiedniego kryterium porz±dkowania. Kryterium mo¿e byæ okre¶lone nawet
> > wielopoziomowo (np. uszeregowaæ samochody wg marki, a jak s± tej samej
> > marki to wg mocy silnika, a jak s± nadal te same, to wg koloru itd.).
> >
> > 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?

> > 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.

> > 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ê :)

> 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.

> >> > 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 ;)


--
//  _    ___         Michal "Sektor" Malecki <sektor(whirl)kis.p.lodz.pl>
\\ L_ |/ `|  /^\ ,()                         <ethouris(O)gmail.com>
// \_ |\  \/ \_/ /\ C++ bez cholesterolu: http://www.intercon.pl/~sektor/cbx
"Java is answer for a question that has never been stated"
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
#15273
Author: Sektor van Skijl
Date: Mon, 05 Mar 2007 21:38
85 lines
3641 bytes
Dnia Mon, 05 Mar 2007 07:07:55 +0100, Mariusz Lotko skrobie:
> > No w³a¶nie o to chodzi, ¿e nie. Je¶li okre¶lamy dany typ jako warto¶ciowy,
> > to to¿samo¶æ przechowuj±cego j± obiektu nie powinna nas interesowaæ w
> > ogóle.

> A zatem powszechnie stosowany "trik" polegaj±cy na sprawdzeniu to¿samo¶ci
> obiektu w pierszej linijce operatora == uwa¿asz za b³êdny?

Tak.

> Podobnie w operatorze =, w którym zapobiega to przypisania obiektu
> samemu sobie?

Tu ju¿ nie, ale to jest zwi±zane z tzw. kwesti± jêzykow±. W przypadku C++ jest
to konieczne, je¿eli obiekt podawany jako argument operatora = jest
przekazywany przez referencjê.

Nie by³oby natomiast tego problemu w przypadku, gdyby ten obiekt by³ tam
przekazywany przez warto¶æ.

Gdyby hipotetycznie w Javie by³a mo¿liwo¶æ zrobienia czego¶ podobnego, to tam
te¿ nie ma konieczno¶ci dodawania takiego sprawdzenia:

class K
{
	private String s;
	public void copyFrom( K x )
	{
		s = x.s;
	}
	...
}

Wywo³anie K.copyFrom( this ) nie spowoduje b³êdu w tym przypadku.

> > Zauwa¿, po co w C++ stosuje siê wska¼niki i referencje do takich typów jak
> > int, czy std::string. Je¶li ju¿, to stosuje siê albo uogólnienie
> > przekazywania (const T&), albo przekazuje siê do zmodyfikowania (T&, T*).
> > Czy widzia³e¶ kiedykolwiek w jakim¶ rzeczywistym programie, ¿eby kto¶
> > porównywa³ dwa wska¼niki do int (pomijaj±c przypadek, gdy wska¼nik do int
> > jest u¿ywany jako iterator do tablicy int-ów - czyli zastosowanie jest
> > inne, ni¿ warto¶æ referencji)?

> Tak, w dowolnej konkretyzacji szablonu int'em. Nie ka¿demu chce siê
> robiæ specjalne implementacje dla typów prostych.

Przy uogólnianiu oczywi¶cie jest to prawda, z t± tylko ró¿nic±, ¿e tam typ
parametryczny T traktuje siê prawdopodobnie zawsze jak typ obiektowy, wiêc
sprawa konkretyzacji na int nie ma i tak znaczenia.

Ale je¶li jest traktowany jako typ obiektowy, a nie warto¶ciowy, to równie¿
istnieje przekazywanie przez referencjê, czy nieu¿ywanie operatora == (bo nie
wiadomo, czy zdefiniowany) itd. - czyli typu T nie uwa¿a siê za warto¶ciowy.

> > Dlatego to¿samo¶ci± dla obiektów warto¶ciowych jest warto¶æ. Obiekty mog±
> > sobie t± warto¶æ przekazywaæ jak chc±, a nawet - jak pamiêtasz,
> > dyskutowali¶my o tym - warto¶ci mog± byæ symulowane przez predefiniowane
> > unikalne obiekty i w takim przypadku porównanie to¿samo¶ci takich obiektów
> > jest równowa¿ne porównaniu warto¶ci, choæ to ju¿ jest szczegó³
> > implementacyjny.

> Nie zgadzam siê. Ka¿dy obiekt jest uproszczeniem rzeczywisto¶ci, a co za tym
> idzie z du¿ym prawdopodobieñstwem mog± pojawiæ siê obiekty o tych samych
> warto¶ciach, które nie s± tymi samymi obiektami.

Je¶li mówimy ju¿ o rzeczywisto¶ci - podaj mi przyk³ad obiektu z
rzeczywisto¶ci, który posiada jednocze¶nie warto¶æ i to¿samo¶æ.

> To, ¿e mam kolor oczu jak Brad Pitt nie czyni mnie Bradem
> Pitem o czym za¶wiadczy ka¿dy stosowny operator porównania - tu: kobieta ;-)

Ale kolor oczu nie stanowi o warto¶ci cz³owieka, o czym równie¿ mo¿e
za¶wiadczyæ wspomniany operator porównania ;)

> A powa¿nie: trzymajmy siê terminologii, która by³a, jest i sprawdza siê:
> obiekt (zestaw warto¶ci) i identyfikator obiektu (to¿samo¶æ). Nie twórzmy
> nowych teorii na temat abstrakcji, która ju¿ zosta³a odpowiednio
> steoretyzowna.

Ja nie tworzê ¿adnych nowych teorii - ja tylko obserwujê rzeczywisto¶æ.

--
//  _    ___         Michal "Sektor" Malecki <sektor(whirl)kis.p.lodz.pl>
\\ L_ |/ `|  /^\ ,()                         <ethouris(O)gmail.com>
// \_ |\  \/ \_/ /\ C++ bez cholesterolu: http://www.intercon.pl/~sektor/cbx
"Java is answer for a question that has never been stated"
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
#15274
Author: Mariusz Lotko
Date: Mon, 05 Mar 2007 23:58
86 lines
3711 bytes
Sektor van Skijlen wrote:

> Dnia Mon, 05 Mar 2007 07:07:55 +0100, Mariusz Lotko skrobie:
>> > No w³a¶nie o to chodzi, ¿e nie. Je¶li okre¶lamy dany typ jako
>> > warto¶ciowy, to to¿samo¶æ przechowuj±cego j± obiektu nie powinna nas
>> > interesowaæ w ogóle.
>
>> A zatem powszechnie stosowany "trik" polegaj±cy na sprawdzeniu to¿samo¶ci
>> obiektu w pierszej linijce operatora == uwa¿asz za b³êdny?
>
> Tak.

Wybacz, ale powy¿szym stwierdzeniem sk³aniasz mnie do stwierdzenia u Ciebie
paranoi... Przecie¿ stosowanie tego jest oczywiste. Po co mam sprawdzaæ,
czy mam tyle samo pieniêdzy w swoim portfelu co... w swoim?

>
>> Podobnie w operatorze =, w którym zapobiega to przypisania obiektu
>> samemu sobie?
>
> Tu ju¿ nie, ale to jest zwi±zane z tzw. kwesti± jêzykow±. W przypadku C++
> jest to konieczne, je¿eli obiekt podawany jako argument operatora = jest
> przekazywany przez referencjê.
>
> Nie by³oby natomiast tego problemu w przypadku, gdyby ten obiekt by³ tam
> przekazywany przez warto¶æ.
>
> Gdyby hipotetycznie w Javie by³a mo¿liwo¶æ zrobienia czego¶ podobnego, to
> tam te¿ nie ma konieczno¶ci dodawania takiego sprawdzenia:

Z tym, ¿e w obu przypadkach nie chodzi o "przykr± konieczno¶æ", a
o "wspania³± mo¿liwo¶æ" szybkiego stwierdzenia, ¿e chodzi o "te same"
a wiêc na pewno "takie same" obiekty.

>> > Zauwa¿, po co w C++ stosuje siê wska¼niki i referencje do takich typów
>> > jak int, czy std::string. Je¶li ju¿, to stosuje siê albo uogólnienie
>> > przekazywania (const T&), albo przekazuje siê do zmodyfikowania (T&,
>> > T*). Czy widzia³e¶ kiedykolwiek w jakim¶ rzeczywistym programie, ¿eby
>> > kto¶ porównywa³ dwa wska¼niki do int (pomijaj±c przypadek, gdy wska¼nik
>> > do int jest u¿ywany jako iterator do tablicy int-ów - czyli
>> > zastosowanie jest inne, ni¿ warto¶æ referencji)?
>
>> Tak, w dowolnej konkretyzacji szablonu int'em. Nie ka¿demu chce siê
>> robiæ specjalne implementacje dla typów prostych.
>
> Przy uogólnianiu oczywi¶cie jest to prawda, z t± tylko ró¿nic±, ¿e tam typ
> parametryczny T traktuje siê prawdopodobnie zawsze jak typ obiektowy, wiêc
> sprawa konkretyzacji na int nie ma i tak znaczenia.

"Prawdopodobnie" to dla mnie trochê za ma³o. Szczególnie w przypadku
szablonów, które wed³ug mojej praktyki z regu³y s± po prostu przeznaczone
dla obiektów oferuj±cych okre¶lony interfejs. I innych ograniczeñ w ich
u¿yciu w³a¶ciwie nie ma.

> Ale je¶li jest traktowany jako typ obiektowy, a nie warto¶ciowy, to
> równie¿ istnieje przekazywanie przez referencjê, czy nieu¿ywanie operatora
> == (bo nie wiadomo, czy zdefiniowany) itd. - czyli typu T nie uwa¿a siê za
> warto¶ciowy.

Takich za³o¿eñ raczej te¿ siê nie podejmuje w C++. Je¶li co¶ nie jest
zdefiniowane, to poinformuje nas o tym kompilator w czasie konkretyzacji
szablonu.

>> > Dlatego to¿samo¶ci± dla obiektów warto¶ciowych jest warto¶æ. Obiekty
>> > mog± sobie t± warto¶æ przekazywaæ jak chc±, a nawet - jak pamiêtasz,
>> > dyskutowali¶my o tym - warto¶ci mog± byæ symulowane przez
>> > predefiniowane unikalne obiekty i w takim przypadku porównanie
>> > to¿samo¶ci takich obiektów jest równowa¿ne porównaniu warto¶ci, choæ to
>> > ju¿ jest szczegó³ implementacyjny.
>
>> Nie zgadzam siê. Ka¿dy obiekt jest uproszczeniem rzeczywisto¶ci, a co za
>> tym idzie z du¿ym prawdopodobieñstwem mog± pojawiæ siê obiekty o tych
>> samych warto¶ciach, które nie s± tymi samymi obiektami.
>
> Je¶li mówimy ju¿ o rzeczywisto¶ci - podaj mi przyk³ad obiektu z
> rzeczywisto¶ci, który posiada jednocze¶nie warto¶æ i to¿samo¶æ.

Konto bankowe. To¿samo¶æ: numer, warto¶æ: saldo.
Nie chcia³bym mieæ konta w banku, który ma k³opot z odró¿nieniem
warto¶ci mojego konta od jego to¿samo¶ci.




--
Mariusz Lotko
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
#15275
Author: Mariusz Lotko
Date: Tue, 06 Mar 2007 00:15
247 lines
9421 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
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
#15276
Author: Marcin 'Qrczak'
Date: Tue, 06 Mar 2007 00:36
84 lines
3583 bytes
Dnia 04-03-2007, nie o godzinie 22:09 +0000, Sektor van Skijlen
napisał(a):

> Tak, tylko że jeśli "wierzymy w podział na obiekty wartościowe i
> niewartościowe" (czytaj: mamy oczy tam gdzie trzeba), to relacja 'is' w
> obiektach wartościowych jest nam zbędna, a '==' w obiektach niewartościowych
> również nie ma sensu.

Ten idealistyczny obraz, teoretycznie słuszny, sprawia pewne trudności
w językach, w których wiele podstawowych typów jest zmienialnych.

(Wyjątkowo nie dotyczy to C++, które pracuje w innym paradygmacie:
powszechnie niejawnie kopiuje obiekty, przez co zmienialność obiektów
ma węższe konsekwencje. Przy innym stylu programowania analogie między
językami przestają działać.)

Trudności polegają na tym, że jeśli np. jedyny typ stringów jest
zmienialny, to formalnie przestaje być typem wartościowym. Sam
napisałeś: „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ą”. Tyle że w takim języku on jest
również powszechnie używany w roli typu wartościowego! Prawdopodobnie
częściej niż jako „zmienna stringowa”. Większość użyć wykorzystuje
zmienialność najwyżej w trakcie konstrukcji, a później taki obiekt już
nie jest zmieniany — za to różne moduły swobodnie przechowują wskaźniki
do niego, zakładając, że już się nie zmieni. Porównanie jego zawartości
staje się powszechne.

Stąd część języków wychodzi z założenia, że będzie to bardziej
praktycznie, jeśli domyślna równość w takim przypadku porówna zawartość.
Czyli dla takich obiektów mamy dwa sensowne warianty równości.

Zwłaszcza że tożsamość różnych prostych typów, np. kolekcji, częściej
istnieje na poziomie koncepcyjnym (klonujemy obiekt, kiedy mamy ochotę
zapamiętać jego bieżący stan, ale jeszcze go zmieniać, i pilnujemy się,
w które miejsce przekazujemy którego klona) niż w sensie jawnego
porównania tożsamości dwóch obiektów nieznanego pochodzenia.

Tak jest na przykład w Pythonie w przypadku list i słowników (ale nie
stringów, które są immutable).

Lisp i Scheme są zgodne z ogólną teorią, jeśli za podstawową równość
(czy też równoważność) przyjąć EQL / eqv?; ona nie zmienia się w czasie
i zmienialne obiekty porównuje po tożsamości, a liczby i znaki po
wartości (niestety nie można robić własnych typów wartościowych).
Ale ponieważ stringi, listy i tablice są dostępne wyłącznie w wersji
zmienialnej, mamy też EQUAL / equal?, które schodzi do ich elementów,
w dodatku rekurencyjnie z tą samą operacją.

-- 
   __("<         Marcin Kowalczyk
   \__/       qrczak@knm.org.pl
    ^^     http://qrnik.knm.org.pl/~qrczak/
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
#15277
Author: Sektor van Skijl
Date: Wed, 07 Mar 2007 17:00
213 lines
8969 bytes
Dnia Tue, 06 Mar 2007 00:15:37 +0100, Mariusz Lotko skrobie:
> >> 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.

To¿samo¶ci obiektów wskazywanych przez te wska¼niki. To nie zmienia faktu, ¿e
wska¼niki s± warto¶ciami i ich porównanie jest porównaniem warto¶ci.

> Czy to¿samo¶æ przeradza siê  w warto¶æ je¶li
> obiekt jest inteligentny (smart)? ;-)

Nic takiego nie napisa³em. Przecie¿ te warto¶ci to równie¿ wska¼niki.

Nie pomerda³y ci siê czasem obiekty wskazuj±ce i obiekty wskazywane?

> >> > 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?

W ¿adnym z tych przypadków.

> >> ¯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ê.

Teoretycznie mo¿na - ale w za³o¿eniu obiekty warto¶ciowe s± obiektami ma³ymi,
bo w obiektach du¿ych nie op³aca siê tak okre¶laæ warto¶ci.

Obiekty warto¶ciowe powinny byæ szczególnie przeznaczone do tego, ¿eby
identyfikowaæ siê przez warto¶æ, a co za tym idzie, tanio siê porównywaæ i
tanio kopiowaæ.

Nie ma ¶ci¶le okre¶lone, co to znaczy, ¿e obiekt jest du¿y, ale je¶li
porównanie to¿samo¶ci obiektów porównywanych przed porównaniem ich warto¶ci
jest op³acalne, to znaczy, ¿e obiekt jest "za du¿y" jak na obiekt warto¶ciowy.

> > 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?

Moja teoria ma odniesienie do projektowania, a nie do jêzyka.

Nie zabrania ona u¿ywania wska¼ników do obiektów warto¶ciowych, ale pod
warunkiem, ¿e ich u¿ywanie jest spraw± czysto jêzykow± (typu przekazanie przez
wska¼nik/referencjê, czy konieczno¶æ weryfikacji w operatorze przypisania),
nie mo¿e natomiast s³u¿yæ do wydawania decyzji na podstawie okre¶lania
to¿samo¶ci obiektu. To ostatnie mo¿e byæ brane pod uwagê tylko przez metody
danej klasy z uwagi na konieczno¶æ posiadania dostêpu do ró¿nych detali
implementacyjnych. Zewnêtrze tego nie powinno potrzebowaæ.

> >> > 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æ.

To lepiej sobie przypomnij - bo sytuacji, ¿eby ktokolwiek w jakim¶ programie
sprawdza³, czy "a.x == b.x, ale ile wynosi a.x nie mam zielonego pojêcia", ja
sobie nie przypominam.

> >> > 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.

A co maj± do tego 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ê.

Bo modyfikacja w obiekcie typu StringBuilder jest widziana w ka¿dym miejscu,
gdzie jest trzymana referencja do tego obiektu.

W przypadku typu String z przyczyn oczywistych ta zale¿no¶æ nie zachodzi.

> >> > 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.

Czyli w³a¶nie strzeli³e¶ sobie gola ;)

Jak najbardziej chcemy sprawdziæ, czy dziewczyna.stan == "wolny".

Ale nie ma sensu sprawdzanie, czy dziewczyna.stan == me.stan, je¶li nie wiemy
jaki jest stan jednego z tych obiektów.

> >> 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?

To jest zupe³nie inna sprawa - to nie jest porównywanie, tylko porz±dkowanie
(zgodnie z terminologi± STL - operator <).


--
//  _    ___         Michal "Sektor" Malecki <sektor(whirl)kis.p.lodz.pl>
\\ L_ |/ `|  /^\ ,()                         <ethouris(O)gmail.com>
// \_ |\  \/ \_/ /\ C++ bez cholesterolu: http://www.intercon.pl/~sektor/cbx
"Java is answer for a question that has never been stated"
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
#15278
Author: Sektor van Skijl
Date: Wed, 07 Mar 2007 17:44
98 lines
4975 bytes
Dnia Tue, 06 Mar 2007 00:36:01 +0100, Marcin 'Qrczak' Kowalczyk skrobie:
> Dnia 04-03-2007, nie o godzinie 22:09 +0000, Sektor van Skijlen
> napisa³(a):

> > Tak, tylko ¿e je¶li "wierzymy w podzia³ na obiekty warto¶ciowe i
> > niewarto¶ciowe" (czytaj: mamy oczy tam gdzie trzeba), to relacja 'is' w
> > obiektach warto¶ciowych jest nam zbêdna, a '==' w obiektach niewarto¶ciowych
> > równie¿ nie ma sensu.

> Ten idealistyczny obraz, teoretycznie s³uszny, sprawia pewne trudno¶ci
> w jêzykach, w których wiele podstawowych typów jest zmienialnych.

> (Wyj±tkowo nie dotyczy to C++, które pracuje w innym paradygmacie:
> powszechnie niejawnie kopiuje obiekty, przez co zmienialno¶æ obiektów
> ma wê¿sze konsekwencje. Przy innym stylu programowania analogie miêdzy
> jêzykami przestaj± dzia³aæ.)

Zgadza siê - ale nie tylko dlatego. Obiekty niewarto¶ciowe jak najbardziej
wystêpuj± w C++. Chodzi tylko o to, ¿e w C++ - w odró¿nieniu od wiêkszo¶ci
jêzyków - mo¿na tworzyæ w³asne typy warto¶ciowe. Fakt, ¿e ka¿dy typ ma
domy¶lne traktowanie jako warto¶ciowy, jest przykr± konsekwencj± drobnego
uogólnienia (jego brak zwykle oznacza, ¿e nie da siê tworzyæ w³asnych typów
warto¶ciowych; w C# zrobili dobr± przymiarkê na udostêpnienie tego inn±
metod±, tylko niestety sprawê spartolili).

> Trudno¶ci polegaj± na tym, ¿e je¶li np. jedyny typ stringów jest
> zmienialny, to formalnie przestaje byæ typem warto¶ciowym. Sam
> napisa³e¶: ?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±?. Tyle ¿e w takim jêzyku on jest
> równie¿ powszechnie u¿ywany w roli typu warto¶ciowego!

Ha! Wynika to z faktu, ¿e string z natury jest typem warto¶ciowym. Je¶li
jêzyk nie umo¿liwia zrobienia takiego typu warto¶ciowego, to trzeba robiæ
obej¶cia w postaci obiektu niemodyfikowalnego.

> Prawdopodobnie
> czê¶ciej ni¿ jako ?zmienna stringowa?. Wiêkszo¶æ u¿yæ wykorzystuje
> zmienialno¶æ najwy¿ej w trakcie konstrukcji, a pó¼niej taki obiekt ju¿
> nie jest zmieniany ? za to ró¿ne modu³y swobodnie przechowuj± wska¼niki
> do niego, zak³adaj±c, ¿e ju¿ siê nie zmieni. Porównanie jego zawarto¶ci
> staje siê powszechne.

Zgadza siê - ale skoro jest to obiekt niemodyfikowalny, to mo¿e byæ traktowany
jako typ warto¶ciowy, gdy¿ zmienno¶æ w tym przypadku nie powoduje konsekwencji
wchodzenia zmienno¶ci w interakcjê z to¿samo¶ci±. De facto zatem, to¿samo¶æ
takich obiektów nie ma dla nas znaczenia, co wystarcza do stwierdzenia, ¿e
jest to typ warto¶ciowy.

Ale skoro tak, to i porównywanie tego obiektu powinno porównywaæ warto¶æ, a
nie to¿samo¶æ. I tak w³a¶nie jest w C#.

> St±d czê¶æ jêzyków wychodzi z za³o¿enia, ¿e bêdzie to bardziej
> praktycznie, je¶li domy¶lna równo¶æ w takim przypadku porówna zawarto¶æ.
> Czyli dla takich obiektów mamy dwa sensowne warianty równo¶ci.

Ale tylko jeden z tych wariantów ma sens. To¿samo¶æ dwóch obiektów typu
string, je¶li to s± obiekty niezmienialne, jest nieistotna - program nie
powinien w ¿adnym przypadku polegaæ na tej to¿samo¶ci.

To¿samo¶æ jest wa¿na, je¶li obiekt jest zmienialny.

> Zw³aszcza ¿e to¿samo¶æ ró¿nych prostych typów, np. kolekcji, czê¶ciej
> istnieje na poziomie koncepcyjnym (klonujemy obiekt, kiedy mamy ochotê
> zapamiêtaæ jego bie¿±cy stan, ale jeszcze go zmieniaæ, i pilnujemy siê,
> w które miejsce przekazujemy którego klona) ni¿ w sensie jawnego
> porównania to¿samo¶ci dwóch obiektów nieznanego pochodzenia.

> Tak jest na przyk³ad w Pythonie w przypadku list i s³owników (ale nie
> stringów, które s± immutable).

Nie rozumiem.

> Lisp i Scheme s± zgodne z ogóln± teori±, je¶li za podstawow± równo¶æ
> (czy te¿ równowa¿no¶æ) przyj±æ EQL / eqv?; ona nie zmienia siê w czasie
> i zmienialne obiekty porównuje po to¿samo¶ci, a liczby i znaki po
> warto¶ci (niestety nie mo¿na robiæ w³asnych typów warto¶ciowych).
> Ale poniewa¿ stringi, listy i tablice s± dostêpne wy³±cznie w wersji
> zmienialnej, mamy te¿ EQUAL / equal?, które schodzi do ich elementów,
> w dodatku rekurencyjnie z t± sam± operacj±.

O ile sobie przypominasz, w której¶ z naszych wcze¶niejszych dyskusji nawet
zgodzili¶my siê co do tego.

Ró¿nica polega jedynie na tym, czy mo¿na tworzyæ w³asne typy warto¶ciowe i czy
mo¿na obiekty warto¶ciowe modyfikowaæ w miejscu. Ale te sprawy s± ju¿ ¶ci¶le
zwi±zane z okre¶lonymi ficzerami jêzykowymi.

Je¶li jêzyk umo¿liwia³by tylko chocia¿by mo¿liwo¶æ definiowania w³asnych typów
warto¶ciowych, to rozró¿nianie porównania to¿samo¶ci i porównania warto¶ci nie
by³oby potrzebne. ¦miem wrêcz twierdziæ, ¿e wystarczy³aby do tego konstrukcja
jêzykowa, która tak stanowi i jednocze¶nie uniemo¿liwia modyfikacjê takiego
obiektu.

--
//  _    ___         Michal "Sektor" Malecki <sektor(whirl)kis.p.lodz.pl>
\\ L_ |/ `|  /^\ ,()                         <ethouris(O)gmail.com>
// \_ |\  \/ \_/ /\ C++ bez cholesterolu: http://www.intercon.pl/~sektor/cbx
"Java is answer for a question that has never been stated"
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
#15279
Author: Sektor van Skijl
Date: Wed, 07 Mar 2007 17:52
118 lines
5228 bytes
Dnia Mon, 05 Mar 2007 23:58:08 +0100, Mariusz Lotko skrobie:
> Sektor van Skijlen wrote:

> > Dnia Mon, 05 Mar 2007 07:07:55 +0100, Mariusz Lotko skrobie:
> >> > No w³a¶nie o to chodzi, ¿e nie. Je¶li okre¶lamy dany typ jako
> >> > warto¶ciowy, to to¿samo¶æ przechowuj±cego j± obiektu nie powinna nas
> >> > interesowaæ w ogóle.
> >
> >> A zatem powszechnie stosowany "trik" polegaj±cy na sprawdzeniu to¿samo¶ci
> >> obiektu w pierszej linijce operatora == uwa¿asz za b³êdny?
> >
> > Tak.

> Wybacz, ale powy¿szym stwierdzeniem sk³aniasz mnie do stwierdzenia u Ciebie
> paranoi... Przecie¿ stosowanie tego jest oczywiste. Po co mam sprawdzaæ,
> czy mam tyle samo pieniêdzy w swoim portfelu co... w swoim?

Portfel nie jest typem warto¶ciowym.

Ilo¶æ pieniêdzy w portfelu jest jedynie jednym ze stanów tego obiektu,
podobnie jak ilo¶æ kart kredytowych w ¶rodku, kolor portfela i materia³, z
którego go wykonano.

Typem warto¶ciowym mo¿e byæ kolor. Porównanie dwóch obiektów typu kolor mo¿na
porównaæ ze sprawdzeniem, czy na dwóch kartkach papieru zapisany tam kod
koloru jest ten sam. Ty chcesz, ¿eby przed odczytaniem numeru z ka¿dej kartki
najpierw sprawdziæ, czy te obie kartki to czasem nie jest jedna i ta sama
kartka. Jaki to ma sens?

> >> Podobnie w operatorze =, w którym zapobiega to przypisania obiektu
> >> samemu sobie?
> >
> > Tu ju¿ nie, ale to jest zwi±zane z tzw. kwesti± jêzykow±. W przypadku C++
> > jest to konieczne, je¿eli obiekt podawany jako argument operatora = jest
> > przekazywany przez referencjê.
> >
> > Nie by³oby natomiast tego problemu w przypadku, gdyby ten obiekt by³ tam
> > przekazywany przez warto¶æ.
> >
> > Gdyby hipotetycznie w Javie by³a mo¿liwo¶æ zrobienia czego¶ podobnego, to
> > tam te¿ nie ma konieczno¶ci dodawania takiego sprawdzenia:

> Z tym, ¿e w obu przypadkach nie chodzi o "przykr± konieczno¶æ", a
> o "wspania³± mo¿liwo¶æ" szybkiego stwierdzenia, ¿e chodzi o "te same"
> a wiêc na pewno "takie same" obiekty.

To jest przykra konieczno¶æ. Musisz to po prostu zrobiæ, bo inaczej bêdzie
wylot.

Ta "wspania³a mo¿liwo¶æ" z kolei powoduje dro¿sze porównanie.

> >> > Zauwa¿, po co w C++ stosuje siê wska¼niki i referencje do takich typów
> >> > jak int, czy std::string. Je¶li ju¿, to stosuje siê albo uogólnienie
> >> > przekazywania (const T&), albo przekazuje siê do zmodyfikowania (T&,
> >> > T*). Czy widzia³e¶ kiedykolwiek w jakim¶ rzeczywistym programie, ¿eby
> >> > kto¶ porównywa³ dwa wska¼niki do int (pomijaj±c przypadek, gdy wska¼nik
> >> > do int jest u¿ywany jako iterator do tablicy int-ów - czyli
> >> > zastosowanie jest inne, ni¿ warto¶æ referencji)?
> >
> >> Tak, w dowolnej konkretyzacji szablonu int'em. Nie ka¿demu chce siê
> >> robiæ specjalne implementacje dla typów prostych.
> >
> > Przy uogólnianiu oczywi¶cie jest to prawda, z t± tylko ró¿nic±, ¿e tam typ
> > parametryczny T traktuje siê prawdopodobnie zawsze jak typ obiektowy, wiêc
> > sprawa konkretyzacji na int nie ma i tak znaczenia.

> "Prawdopodobnie" to dla mnie trochê za ma³o. Szczególnie w przypadku
> szablonów, które wed³ug mojej praktyki z regu³y s± po prostu przeznaczone
> dla obiektów oferuj±cych okre¶lony interfejs. I innych ograniczeñ w ich
> u¿yciu w³a¶ciwie nie ma.

Tak, dok³adnie. Ale typy warto¶ciowe zwykle maj± inny interfejs, ni¿ typy
obiektowe.

> > Ale je¶li jest traktowany jako typ obiektowy, a nie warto¶ciowy, to
> > równie¿ istnieje przekazywanie przez referencjê, czy nieu¿ywanie operatora
> > == (bo nie wiadomo, czy zdefiniowany) itd. - czyli typu T nie uwa¿a siê za
> > warto¶ciowy.

> Takich za³o¿eñ raczej te¿ siê nie podejmuje w C++. Je¶li co¶ nie jest
> zdefiniowane, to poinformuje nas o tym kompilator w czasie konkretyzacji
> szablonu.

Powoduj±c, ¿e dla danego typu nie da siê tego szablonu zastosowaæ, wiêc nie ma
tematu.

> >> > Dlatego to¿samo¶ci± dla obiektów warto¶ciowych jest warto¶æ. Obiekty
> >> > mog± sobie t± warto¶æ przekazywaæ jak chc±, a nawet - jak pamiêtasz,
> >> > dyskutowali¶my o tym - warto¶ci mog± byæ symulowane przez
> >> > predefiniowane unikalne obiekty i w takim przypadku porównanie
> >> > to¿samo¶ci takich obiektów jest równowa¿ne porównaniu warto¶ci, choæ to
> >> > ju¿ jest szczegó³ implementacyjny.
> >
> >> Nie zgadzam siê. Ka¿dy obiekt jest uproszczeniem rzeczywisto¶ci, a co za
> >> tym idzie z du¿ym prawdopodobieñstwem mog± pojawiæ siê obiekty o tych
> >> samych warto¶ciach, które nie s± tymi samymi obiektami.
> >
> > Je¶li mówimy ju¿ o rzeczywisto¶ci - podaj mi przyk³ad obiektu z
> > rzeczywisto¶ci, który posiada jednocze¶nie warto¶æ i to¿samo¶æ.

> Konto bankowe. To¿samo¶æ: numer, warto¶æ: saldo.

Oraz warto¶æ: w³a¶ciciel (mo¿na go potem kiedy¶ zmieniæ)
Oraz obiekt: historia transakcji
Oraz...

Czy ty w ogóle wiesz, co to jest "warto¶æ"?

> Nie chcia³bym mieæ konta w banku, który ma k³opot z odró¿nieniem
> warto¶ci mojego konta od jego to¿samo¶ci.

Na razie to masz problem z odró¿nieniem warto¶ci od stanu.


--
//  _    ___         Michal "Sektor" Malecki <sektor(whirl)kis.p.lodz.pl>
\\ L_ |/ `|  /^\ ,()                         <ethouris(O)gmail.com>
// \_ |\  \/ \_/ /\ C++ bez cholesterolu: http://www.intercon.pl/~sektor/cbx
"Java is answer for a question that has never been stated"
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
#15280
Author: Mariusz Lotko
Date: Wed, 07 Mar 2007 19:59
132 lines
5590 bytes
Sektor van Skijlen wrote:

> Dnia Mon, 05 Mar 2007 23:58:08 +0100, Mariusz Lotko skrobie:
>> Sektor van Skijlen wrote:
>
>> > Dnia Mon, 05 Mar 2007 07:07:55 +0100, Mariusz Lotko skrobie:
>> >> > No w³a¶nie o to chodzi, ¿e nie. Je¶li okre¶lamy dany typ jako
>> >> > warto¶ciowy, to to¿samo¶æ przechowuj±cego j± obiektu nie powinna nas
>> >> > interesowaæ w ogóle.
>> >
>> >> A zatem powszechnie stosowany "trik" polegaj±cy na sprawdzeniu
>> >> to¿samo¶ci obiektu w pierszej linijce operatora == uwa¿asz za b³êdny?
>> >
>> > Tak.
>
>> Wybacz, ale powy¿szym stwierdzeniem sk³aniasz mnie do stwierdzenia u
>> Ciebie paranoi... Przecie¿ stosowanie tego jest oczywiste. Po co mam
>> sprawdzaæ, czy mam tyle samo pieniêdzy w swoim portfelu co... w swoim?
>
> Portfel nie jest typem warto¶ciowym.
>
> Ilo¶æ pieniêdzy w portfelu jest jedynie jednym ze stanów tego obiektu,
> podobnie jak ilo¶æ kart kredytowych w ¶rodku, kolor portfela i materia³, z
> którego go wykonano.

I w _ka¿dym_ systemie tak to modelujesz? Z pe³n± otoczk±? Piêkny przyk³ad
wzorca "swiss army knife".

> Typem warto¶ciowym mo¿e byæ kolor. Porównanie dwóch obiektów typu kolor
> mo¿na porównaæ ze sprawdzeniem, czy na dwóch kartkach papieru zapisany tam
> kod koloru jest ten sam. Ty chcesz, ¿eby przed odczytaniem numeru z ka¿dej
> kartki najpierw sprawdziæ, czy te obie kartki to czasem nie jest jedna i
> ta sama kartka. Jaki to ma sens?

Id±c Twoj± logik±: niekoniecznie. Obiekt kolor ma jeszcze atrybuty: data
naniesienia, technika wykonania i stopieñ nas³onecznienia, które pozwalaj±
obliczyæ rzeczywisty kolor w czasie :> Wtedy nie da siê porównaæ dwóch
"czerwonych". Odsy³am do ekspertów - lakierników samochodowych.

>> >> Podobnie w operatorze =, w którym zapobiega to przypisania obiektu
>> >> samemu sobie?
>> >
>> > Tu ju¿ nie, ale to jest zwi±zane z tzw. kwesti± jêzykow±. W przypadku
>> > C++ jest to konieczne, je¿eli obiekt podawany jako argument operatora >> > jest przekazywany przez referencjê.
>> >
>> > Nie by³oby natomiast tego problemu w przypadku, gdyby ten obiekt by³
>> > tam przekazywany przez warto¶æ.
>> >
>> > Gdyby hipotetycznie w Javie by³a mo¿liwo¶æ zrobienia czego¶ podobnego,
>> > to tam te¿ nie ma konieczno¶ci dodawania takiego sprawdzenia:
>
>> Z tym, ¿e w obu przypadkach nie chodzi o "przykr± konieczno¶æ", a
>> o "wspania³± mo¿liwo¶æ" szybkiego stwierdzenia, ¿e chodzi o "te same"
>> a wiêc na pewno "takie same" obiekty.
>
> To jest przykra konieczno¶æ. Musisz to po prostu zrobiæ, bo inaczej bêdzie
> wylot.

W operatorze porównania? Nie s±dzê...

> Ta "wspania³a mo¿liwo¶æ" z kolei powoduje dro¿sze porównanie.

W pewnych przypadkach mo¿e tak byæ. Implementuj±c operator warto
oszacowaæ prawdopodobieñstwo porównywania tych samych obiektów.
Generalnie jednak - nie zgadzam siê.

>> >> > Zauwa¿, po co w C++ stosuje siê wska¼niki i referencje do takich
>> >> > typów jak int, czy std::string. Je¶li ju¿, to stosuje siê albo
>> >> > uogólnienie przekazywania (const T&), albo przekazuje siê do
>> >> > zmodyfikowania (T&, T*). Czy widzia³e¶ kiedykolwiek w jakim¶
>> >> > rzeczywistym programie, ¿eby kto¶ porównywa³ dwa wska¼niki do int
>> >> > (pomijaj±c przypadek, gdy wska¼nik do int jest u¿ywany jako iterator
>> >> > do tablicy int-ów - czyli zastosowanie jest inne, ni¿ warto¶æ
>> >> > referencji)?
>> >
>> >> Tak, w dowolnej konkretyzacji szablonu int'em. Nie ka¿demu chce siê
>> >> robiæ specjalne implementacje dla typów prostych.
>> >
>> > Przy uogólnianiu oczywi¶cie jest to prawda, z t± tylko ró¿nic±, ¿e tam
>> > typ parametryczny T traktuje siê prawdopodobnie zawsze jak typ
>> > obiektowy, wiêc sprawa konkretyzacji na int nie ma i tak znaczenia.
>
>> "Prawdopodobnie" to dla mnie trochê za ma³o. Szczególnie w przypadku
>> szablonów, które wed³ug mojej praktyki z regu³y s± po prostu przeznaczone
>> dla obiektów oferuj±cych okre¶lony interfejs. I innych ograniczeñ w ich
>> u¿yciu w³a¶ciwie nie ma.
>
> Tak, dok³adnie. Ale typy warto¶ciowe zwykle maj± inny interfejs, ni¿ typy
> obiektowe.

Znowu ogólnik: "zwykle"... "Sprzedajesz" nam teoriê, która ma dzia³aæ w
praktyce, u³atwiaæ j±. Chcia³by¶, ¿eby Twój samochód "zwykle" dzia³a³?

>
>> > Je¶li mówimy ju¿ o rzeczywisto¶ci - podaj mi przyk³ad obiektu z
>> > rzeczywisto¶ci, który posiada jednocze¶nie warto¶æ i to¿samo¶æ.
>
>> Konto bankowe. To¿samo¶æ: numer, warto¶æ: saldo.
>
> Oraz warto¶æ: w³a¶ciciel (mo¿na go potem kiedy¶ zmieniæ)
> Oraz obiekt: historia transakcji
> Oraz...

Jak wy¿ej: zale¿y od kontekstu. Mo¿emy nie wi±zaæ obiektów transakcji do
konta, a zrobiæ wi±zanie odwrotne: ka¿da transakcja ma referencjê do konta.
I podobnie z w³a¶cicielem. Krótko mówi±c "konto jest anonimowe" i
przechowuje jedynie swoje saldo (warto¶æ) oraz numer (to¿samo¶æ).
Nie wiem, czy to ma sens, ale nie mo¿esz chyba wykluczyæ, ¿e w jakim¶
tam systemie mo¿e mieæ.

> Czy ty w ogóle wiesz, co to jest "warto¶æ"?

Element ze zbioru (tu: typ, klasa).

>> Nie chcia³bym mieæ konta w banku, który ma k³opot z odró¿nieniem
>> warto¶ci mojego konta od jego to¿samo¶ci.
>
> Na razie to masz problem z odró¿nieniem warto¶ci od stanu.

Hmm, mam na ten temat "swoj± teoriê". Na razie przyjmijmy, ¿e jestem
betonem zamkniêtym na Twoj± ¶wiat³± my¶l. Na pocieszenie powiem Ci, ¿e je¶li
Twoja teoria siê przyjmie i w kilku ksi±¿kach pojawi± siê
sformu³owania w rodzaju "s³ynny obiektolog prof. van Skijlen opisuje to w
swojej pracy...", to zg³oszê siê do Ciebie po autograf :-)

A tymczasem pozwolê sobie zakoñczyæ, bo ju¿ chyba nikt nas nie czyta,
a i argumenty jakby zaczê³y siê powtarzaæ.


--
Mariusz Lotko
Wartości i obiekty
#15281
Author: Marcin 'Qrczak'
Date: Thu, 08 Mar 2007 00:32
176 lines
7528 bytes
Dnia 07-03-2007, śro o godzinie 17:44 +0000, Sektor van Skijlen
napisał(a):

> > Trudności polegają na tym, że jeśli np. jedyny typ stringów jest
> > zmienialny, to formalnie przestaje być typem wartościowym. Sam
> > napisałeś: ?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ą?. Tyle że w takim języku on jest
> > również powszechnie używany w roli typu wartościowego!
> 
> Ha! Wynika to z faktu, że string z natury jest typem wartościowym. Jeśli
> język nie umożliwia zrobienia takiego typu wartościowego, to trzeba robić
> obejścia w postaci obiektu niemodyfikowalnego.

To nie jest obejście. W językach, w których obiekt jest podstawowym
pojęciem pierwotnym, kwintesencją typu wartościowego jest obiekt
niemodyfikowalny.

(Można też wyjść od wartości jako pojęcia pierwotnego, a obiekty budować
z pogrupowanych w rekordy i inne struktury zmiennych zawierających
wartości. Takie podejście wydaje się właściwym sposobem opisu SML-a
i Erlanga, gdzie współdzielenie fragmentów wartości jest nieobserwowalne
z poziomu języka źródłowego, mimo że implementacyjnie może ono wystąpić
bądź nie. Ale w większości języków wygodniej jest zacząć od obiektów.)

Jeśli odstawić na bok nietypowy punkt widzenia C++, to wartości dzielą
się na te, które są reprezentowane przez niezmienialne obiekty
o nieistotnej tożsamości, i na te, które są wskaźnikami na zmienialne
obiekty. Jest jeszcze trzecia kategoria leżąca pomiędzy tymi dwiema:
wskaźniki na singletony, czyli na jedyne obiekty danego rodzaju,
np. true / false / nil. Te obiekty są niezmienialne, ale tożsamość
tych obiektów jest dobrze zdefiniowana; rozróżnianie ich po tożsamości
jest równoważne rozróżnianiu po cechach wewnętrznych.

Wartości można umieszczać w zmiennych. Dana zmienna może zawierać różne
wartości w różnym czasie.

Jeśli spróbować dopasować do tego modelu C++, to się okaże, że zmienną
C++ zawierającą obiekt można rozumieć na dwa sposoby:

a) Jako zmienialny obiekt, przywiązany na stałe do swojej nazwy.
   To tłumaczenie jest odpowiednie w przypadku obiektów z tożsamością,
   zwłaszcza złożonych, bo pozwala wymodelować możliwość zmiany
   indywidualnych pól obiektu z zachowaniem tożsamości całego obiektu.
   Takie obiekty są zwykle przekazywane przez referencje C++ albo
   wskaźniki C++, co odpowiada przekazaniu wskaźnika na obiekt
   w modelu, a więc odpowiada naturalnemu sposobowi przekazania
   wartości w modelu.

b) Jako zmienną zawierającą wartość, która sama jest niezmienialna.
   To tłumaczenie jest lepsze dla atomowych typów wartościowych,
   bo pozwala wymodelować wartość wyabstrahowaną od miejsca
   przechowywania. Takie obiekty są w C++ zwykle kopiowane,
   co odpowiada przekazaniu odczytanej bieżącej wartości zmiennej
   w modelu, czyli znowu jest naturalnym sposobem przekazania wartości,
   mimo że w C++ jest inne niż tamto.

   Użycie do atomowych typów wartościowych mapowania a) zamiast b)
   wymagałoby klonowania obiektów, co jest nienaturalne i niewygodne,
   normalnie nie jest wspierane składniowo. Z drugiej strony, użycie do
   złożonych obiektów mapowania b) zamiast a) wymagałoby wymodelowania
   przekazania wskaźnika za pomocą wskaźnika na zmienną, co w wielu
   językach nie jest nawet wspierane. Dlatego zdecydowanie się na jeden
   sposób mapowania prowadziłoby do nienaturalnego kodu w modelu
   w części przypadków.

Istnienie dwóch możliwych mapowań z nieoczywistym wyborem między nimi
powoduje, że realizacje zadań nie przekładają się między C++ a innymi
językami dosłownie ani konsekwentnie.

W C++ jest grupa typów, które mają złożoną strukturę wewnętrzną, ale
których kopiowanie ma sens, np. string albo vector. Takie obiekty czasem
są kopiowane, czyli przekazywane przez wartość, a czasem są przekazywane
referencje do nich. Tutaj wybór mapowania jest szczególnie nieoczywisty,
bo można traktować te obiekty albo jako wartości (i zrealizować je jako
obiekty niezmienialne, swobodnie przekazywane między zmiennymi, ale
tworzone na nowo przy obliczeniach), albo jako obiekty z tożsamością
(i zrealizować je jako obiekty zmienialne, jawnie klonowane w razie
potrzeby).

To wszystko dotyczyło obiektów zawartych w zmiennych. W C++ jeszcze są
obiekty alokowane na stercie i przekazywane przez wskaźniki. One mają
jednoznaczne przełożenie na ten model, które jest podobne do wersji a).
Przy tłumaczeniu w drugą stronę, na C++, ten wybór teoretycznie byłby
uniwersalny, tyle że C++ unika takich obiektów z powodu braku
odśmiecania, więc jest tendencja do umieszczenia obiektu od razu
w zmiennej.

> > Prawdopodobnie
> > częściej niż jako ?zmienna stringowa?. Większość użyć wykorzystuje
> > zmienialność najwyżej w trakcie konstrukcji, a później taki obiekt już
> > nie jest zmieniany ? za to różne moduły swobodnie przechowują wskaźniki
> > do niego, zakładając, że już się nie zmieni. Porównanie jego zawartości
> > staje się powszechne.
> 
> Zgadza się - ale skoro jest to obiekt niemodyfikowalny, to może być traktowany
> jako typ wartościowy, gdyż zmienność w tym przypadku nie powoduje konsekwencji
> wchodzenia zmienności w interakcję z tożsamością..

Pisałem tutaj o zmienialnym stringu, zakładając, że to jest jedyny
string w danym języku. Czyli kiedy złożony typ pełniący rolę typu
wartościowego jest jednak zmienialny. Taka sytuacja jest kłopotliwa.
Mój model w wersji czystej wymaga zdecydowania się, który styl użycia
jest tutaj dominujący. Pomieszanie styli grozi błędami aliasowania albo
niepotrzebnymi kopiami. Jeśli w różnych miejscach programu ten sam typ
jest używany w różnym stylu, to trudno zrobić jeden operator porównania,
który pasuje do obu.

-- 
   __("<         Marcin Kowalczyk
   \__/       qrczak@knm.org.pl
    ^^     http://qrnik.knm.org.pl/~qrczak/
Re: =?ISO-8859-2?Q?Warto¶ci?= i obiekty
#15282
Author: Sektor van Skijl
Date: Sat, 10 Mar 2007 18:47
191 lines
8595 bytes
Dnia Thu, 08 Mar 2007 00:32:04 +0100, Marcin 'Qrczak' Kowalczyk skrobie:
> To nie jest obej¶cie. W jêzykach, w których obiekt jest podstawowym
> pojêciem pierwotnym, kwintesencj± typu warto¶ciowego jest obiekt
> niemodyfikowalny.

No wtedy tak.

Nie twierdzê, ¿e tak jest dobrze, czy ¼le - to jest szczegó³. Po prostu
konsekwencj± nieistnienia naturalnych typów warto¶ciowych jest to, ¿e typy
warto¶ciowe nale¿y definiowaæ jako sta³e obiekty.

> Je¶li odstawiæ na bok nietypowy punkt widzenia C++, to warto¶ci dziel±
> siê na te, które s± reprezentowane przez niezmienialne obiekty
> o nieistotnej to¿samo¶ci, i na te, które s± wska¼nikami na zmienialne
> obiekty.

O istniej±cej to¿samo¶ci. :)

> Jest jeszcze trzecia kategoria le¿±ca pomiêdzy tymi dwiema:
> wska¼niki na singletony, czyli na jedyne obiekty danego rodzaju,
> np. true / false / nil. Te obiekty s± niezmienialne, ale to¿samo¶æ
> tych obiektów jest dobrze zdefiniowana; rozró¿nianie ich po to¿samo¶ci
> jest równowa¿ne rozró¿nianiu po cechach wewnêtrznych.

Nie tworzy³bym specjalnej kategorii dla tych obiektów.

Po pierwsze, s± one sta³e, wiêc bez problemów mo¿na je zaliczyæ do typów
warto¶ciowych.

Po drugie, kwestia sposobu ich porównania mo¿e byæ kwesti± czysto
implementacyjn±.

O ile sobie przypominasz, wskazywa³em ci ju¿ kiedy¶, ¿e jest mo¿liwe takie
zorganizowanie warto¶ci ca³kowitych, ¿e ka¿dej liczbie odpowiada obiekt. Ka¿da
nowo powsta³a liczba bêdzie albo nowo utworzonym obiektem, a je¶li jest ju¿
obiekt, który symbolizuje dan± liczbê, to siê go znajduje i zwraca. W takim
przypadku mo¿emy ¶mia³o stwierdziæ, ¿e ka¿dy obiekt symbolizuj±cy liczbê
ca³kowit± jest unikalny - nie ma dwóch obiektów o takiej samej zawarto¶ci.

Jest to oczywi¶cie nieoptymalne i nikt tego jak najbardziej nie robi, ale jest
to przyk³ad na to, ¿e liczby mog± byæ takimi w³a¶nie "singletonami". Wiêc
je¶li mamy pewno¶æ, ¿e istnieje tylko jeden obiekt okre¶lonej klasy w ca³ym
systemie, który posiada okre¶lon± zawarto¶æ, to jest oczywiste, ¿e porównanie
to¿samo¶ci tych obiektów da ten sam wynik, co porównanie ich zawarto¶ci.

Ale sposób porównywania tych obiektów, które s± typami warto¶ciowymi, powinien
zale¿eæ ju¿ od implementacji.

Efekt jest taki, ¿e nawet je¶li zrobimy ten podzia³ wedle tego, co mówisz, to
potrzebujemy nastêpuj±cych typów i odpowiadaj±cych im domy¶lnych metod
porównania:

1. Obiektów modyfikowalnych, które s± porównywane po to¿samo¶ci
2. Obiektów sta³ych, które s± porównywane po zawarto¶ci
3. Obiektów sta³ych unikalnych, które s± porównywane po to¿samo¶ci

I do ¿adnego z rodzajów typów tych obiektów nie potrzebujemy nigdy dwóch
osobnych operatorów porównania.

> Warto¶ci mo¿na umieszczaæ w zmiennych. Dana zmienna mo¿e zawieraæ ró¿ne
> warto¶ci w ró¿nym czasie.

Tak.

> Je¶li spróbowaæ dopasowaæ do tego modelu C++, to siê oka¿e, ¿e zmienn±
> C++ zawieraj±c± obiekt mo¿na rozumieæ na dwa sposoby:

> a) Jako zmienialny obiekt, przywi±zany na sta³e do swojej nazwy.
>    To t³umaczenie jest odpowiednie w przypadku obiektów z to¿samo¶ci±,
>    zw³aszcza z³o¿onych, bo pozwala wymodelowaæ mo¿liwo¶æ zmiany
>    indywidualnych pól obiektu z zachowaniem to¿samo¶ci ca³ego obiektu.
>    Takie obiekty s± zwykle przekazywane przez referencje C++ albo
>    wska¼niki C++, co odpowiada przekazaniu wska¼nika na obiekt
>    w modelu, a wiêc odpowiada naturalnemu sposobowi przekazania
>    warto¶ci w modelu.

> b) Jako zmienn± zawieraj±c± warto¶æ, która sama jest niezmienialna.
>    To t³umaczenie jest lepsze dla atomowych typów warto¶ciowych,
>    bo pozwala wymodelowaæ warto¶æ wyabstrahowan± od miejsca
>    przechowywania. Takie obiekty s± w C++ zwykle kopiowane,
>    co odpowiada przekazaniu odczytanej bie¿±cej warto¶ci zmiennej
>    w modelu, czyli znowu jest naturalnym sposobem przekazania warto¶ci,
>    mimo ¿e w C++ jest inne ni¿ tamto.

Szczerze mówi±c to nic z tego nie rozumiem.

>    U¿ycie do atomowych typów warto¶ciowych mapowania a) zamiast b)
>    wymaga³oby klonowania obiektów, co jest nienaturalne i niewygodne,
>    normalnie nie jest wspierane sk³adniowo. Z drugiej strony, u¿ycie do
>    z³o¿onych obiektów mapowania b) zamiast a) wymaga³oby wymodelowania
>    przekazania wska¼nika za pomoc± wska¼nika na zmienn±, co w wielu
>    jêzykach nie jest nawet wspierane. Dlatego zdecydowanie siê na jeden
>    sposób mapowania prowadzi³oby do nienaturalnego kodu w modelu
>    w czê¶ci przypadków.

Jeszcze raz - tylko pro¶ciej ;)

> Istnienie dwóch mo¿liwych mapowañ z nieoczywistym wyborem miêdzy nimi
> powoduje, ¿e realizacje zadañ nie przek³adaj± siê miêdzy C++ a innymi
> jêzykami dos³ownie ani konsekwentnie.

Ale to nie ma wiêkszego znaczenia.

> W C++ jest grupa typów, które maj± z³o¿on± strukturê wewnêtrzn±, ale
> których kopiowanie ma sens, np. string albo vector.

Vector moim zdaniem niespecjalnie.

> Takie obiekty czasem
> s± kopiowane, czyli przekazywane przez warto¶æ, a czasem s± przekazywane
> referencje do nich.

Ale przekazywanie stringa przez referncjê robi siê wy³±cznie ze wzglêdów
optymalizacyjnych. Nie ma ¿adnych przes³anek czysto jêzykowych, które by
nakazywa³y inne przekazywanie, ni¿ przez warto¶æ.

> Tutaj wybór mapowania jest szczególnie nieoczywisty,
> bo mo¿na traktowaæ te obiekty albo jako warto¶ci (i zrealizowaæ je jako
> obiekty niezmienialne, swobodnie przekazywane miêdzy zmiennymi, ale
> tworzone na nowo przy obliczeniach), albo jako obiekty z to¿samo¶ci±
> (i zrealizowaæ je jako obiekty zmienialne, jawnie klonowane w razie
> potrzeby).

Tu siê nie zgadzam.

String zawsze powinien byæ traktowany jak warto¶æ, natomiast wektor zawsze jak
obiekt.

> To wszystko dotyczy³o obiektów zawartych w zmiennych. W C++ jeszcze s±
> obiekty alokowane na stercie i przekazywane przez wska¼niki. One maj±
> jednoznaczne prze³o¿enie na ten model, które jest podobne do wersji a).
> Przy t³umaczeniu w drug± stronê, na C++, ten wybór teoretycznie by³by
> uniwersalny, tyle ¿e C++ unika takich obiektów z powodu braku
> od¶miecania, wiêc jest tendencja do umieszczenia obiektu od razu
> w zmiennej.

Przyczyny wydajno¶ciowe równie¿ jednak istniej± :). Z tego przecie¿ powodu
podobno IBM-owska Java ma taki trik optymalizacyjny (którym mia³a podobno
pognêbiæ C#), ¿e je¶li obiekt jest tworzony w funkcji i nigdzie nie
przekazywany na zewn±trz tej funkcji (tzn. metody), to jest tworzony w ca³o¶ci
na stosie.

> > > Prawdopodobnie
> > > czê¶ciej ni¿ jako ?zmienna stringowa?. Wiêkszo¶æ u¿yæ wykorzystuje
> > > zmienialno¶æ najwy¿ej w trakcie konstrukcji, a pó¼niej taki obiekt ju¿
> > > nie jest zmieniany ? za to ró¿ne modu³y swobodnie przechowuj± wska¼niki
> > > do niego, zak³adaj±c, ¿e ju¿ siê nie zmieni. Porównanie jego zawarto¶ci
> > > staje siê powszechne.
> >
> > Zgadza siê - ale skoro jest to obiekt niemodyfikowalny, to mo¿e byæ traktowany
> > jako typ warto¶ciowy, gdy¿ zmienno¶æ w tym przypadku nie powoduje konsekwencji
> > wchodzenia zmienno¶ci w interakcjê z to¿samo¶ci±.

> Pisa³em tutaj o zmienialnym stringu, zak³adaj±c, ¿e to jest jedyny
> string w danym jêzyku. Czyli kiedy z³o¿ony typ pe³ni±cy rolê typu
> warto¶ciowego jest jednak zmienialny. Taka sytuacja jest k³opotliwa.

Oj... nie bardzo to widzê.

Takie co¶ jest mo¿liwe w C++, który w naturalny sposób obs³uguje typy
warto¶ciowe i pozwala typom definiowaæ operatory. W ten sposób mo¿na zrobiæ
typ warto¶ciowy, którego obiekt jest modyfikowalny w miejscu.

Je¶li jêzyk nie udostêpnia takiego mechanizmu, to jest skazany na zrobienie
takiego tricku, jak obiekt, którego nie mo¿na modyfikowaæ po utworzeniu (bo
nie ma operacji, które na to pozwalaj±).

Jêzyk zatem powinien umo¿liwiaæ albo:
 - jak C++, zrobienie wszystkiego i przedefiniowanie wszystkich operatorów
 - pozwoliæ tylko na wybrane definicje - ale niech one umo¿liwi± programi¶cie
   zrobienie równie¿ typów warto¶ciowyych

> Mój model w wersji czystej wymaga zdecydowania siê, który styl u¿ycia
> jest tutaj dominuj±cy. Pomieszanie styli grozi b³êdami aliasowania albo
> niepotrzebnymi kopiami.

No w³a¶nie - ale nie mo¿esz zrobiæ tak, ¿e w ca³ym jêzyku jeden model
obowi±zuje wszystkie obiekty.

> Je¶li w ró¿nych miejscach programu ten sam typ
> jest u¿ywany w ró¿nym stylu, to trudno zrobiæ jeden operator porównania,
> który pasuje do obu.

To wtedy trzeba zrobiæ osobne typy. Tak jak w Javie jest String i
StringBuilder.


--
//  _    ___         Michal "Sektor" Malecki <sektor(whirl)kis.p.lodz.pl>
\\ L_ |/ `|  /^\ ,()                         <ethouris(O)gmail.com>
// \_ |\  \/ \_/ /\ C++ bez cholesterolu: http://www.intercon.pl/~sektor/cbx
"Java is answer for a question that has never been stated"
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
#15283
Author: Sektor van Skijl
Date: Sat, 10 Mar 2007 19:17
205 lines
8652 bytes
Dnia Wed, 07 Mar 2007 19:59:52 +0100, Mariusz Lotko skrobie:
> Sektor van Skijlen wrote:

> > Dnia Mon, 05 Mar 2007 23:58:08 +0100, Mariusz Lotko skrobie:
> >> Sektor van Skijlen wrote:
> >
> >> > Dnia Mon, 05 Mar 2007 07:07:55 +0100, Mariusz Lotko skrobie:
> >> >> > No w³a¶nie o to chodzi, ¿e nie. Je¶li okre¶lamy dany typ jako
> >> >> > warto¶ciowy, to to¿samo¶æ przechowuj±cego j± obiektu nie powinna nas
> >> >> > interesowaæ w ogóle.
> >> >
> >> >> A zatem powszechnie stosowany "trik" polegaj±cy na sprawdzeniu
> >> >> to¿samo¶ci obiektu w pierszej linijce operatora == uwa¿asz za b³êdny?
> >> >
> >> > Tak.
> >
> >> Wybacz, ale powy¿szym stwierdzeniem sk³aniasz mnie do stwierdzenia u
> >> Ciebie paranoi... Przecie¿ stosowanie tego jest oczywiste. Po co mam
> >> sprawdzaæ, czy mam tyle samo pieniêdzy w swoim portfelu co... w swoim?
> >
> > Portfel nie jest typem warto¶ciowym.
> >
> > Ilo¶æ pieniêdzy w portfelu jest jedynie jednym ze stanów tego obiektu,
> > podobnie jak ilo¶æ kart kredytowych w ¶rodku, kolor portfela i materia³, z
> > którego go wykonano.

> I w _ka¿dym_ systemie tak to modelujesz? Z pe³n± otoczk±? Piêkny przyk³ad
> wzorca "swiss army knife".

Nie u¿ywaj pojêæ, których znaczenia nie rozumiesz.

Swiss army knife to by by³o, gdyby ten portfel móg³ przechowywaæ pieni±dze,
laptopy, meble, samochody, kontenery i elektrownie.

Ilo¶æ pieniêdzy nie jest warto¶ci± portfela. Jest jego stanem. Portfel nie
mo¿e mieæ warto¶ci - i to nie dlatego, ¿e poza tym mo¿e mieæ jeszcze wiele
innych stanów i atrytbutów.

> > Typem warto¶ciowym mo¿e byæ kolor. Porównanie dwóch obiektów typu kolor
> > mo¿na porównaæ ze sprawdzeniem, czy na dwóch kartkach papieru zapisany tam
> > kod koloru jest ten sam. Ty chcesz, ¿eby przed odczytaniem numeru z ka¿dej
> > kartki najpierw sprawdziæ, czy te obie kartki to czasem nie jest jedna i
> > ta sama kartka. Jaki to ma sens?

> Id±c Twoj± logik±: niekoniecznie. Obiekt kolor ma jeszcze atrybuty: data
> naniesienia, technika wykonania i stopieñ nas³onecznienia, które pozwalaj±
> obliczyæ rzeczywisty kolor w czasie :> Wtedy nie da siê porównaæ dwóch
> "czerwonych". Odsy³am do ekspertów - lakierników samochodowych.

Nie przypominam sobie, ¿ebym mówi³ o lakierze samochodowym. Mówi³em o kolorze.
Kolor mo¿e byæ równie¿ atrybutem (a nie warto¶ci±, acz przypadkiem te¿ nie
stanem) lakieru.

No to jak, zrozumia³e¶ ju¿, co to takiego jest warto¶æ, czy douczysz siê i
zg³osisz za tydzieñ?

> >> Z tym, ¿e w obu przypadkach nie chodzi o "przykr± konieczno¶æ", a
> >> o "wspania³± mo¿liwo¶æ" szybkiego stwierdzenia, ¿e chodzi o "te same"
> >> a wiêc na pewno "takie same" obiekty.
> >
> > To jest przykra konieczno¶æ. Musisz to po prostu zrobiæ, bo inaczej bêdzie
> > wylot.

> W operatorze porównania? Nie s±dzê...

W operatorze przypisania.

> > Ta "wspania³a mo¿liwo¶æ" z kolei powoduje dro¿sze porównanie.

> W pewnych przypadkach mo¿e tak byæ.

Statystycznie jest to 99% przypadków.

> Implementuj±c operator warto
> oszacowaæ prawdopodobieñstwo porównywania tych samych obiektów.

Zrób sobie ma³± statystykê u¿ycia takiego typu i ilo¶æ porównañ, dla których
trafiasz na równo¶æ i dla których trafiasz na nierówno¶æ.

Prosty przyk³ad - iteratory. Masz pêtlê, w której przechodzisz przez wszystkie
iteratory w zakresie od jednego do drugiego. Ile masz w tym momencie porównañ,
które wyjd± równe, a ile, które wyjd± nierówne? Tu policzyæ bardzo ³atwo:

Dla zakresu o d³ugo¶ci N, bêdziesz mia³ N-1 porównañ, które siê oka¿±
nierówno¶ci±, i jedno, które oka¿e sie równo¶ci±. Ró¿nica ro¶nie wraz z
d³ugo¶ci± zakresu i tylko w przypadku gdy zakres ma 1 element porównanie jest
szybsze. Dla dwóch elemmentów jest ju¿ mniej wiêcej tak samo kosztowne, wraz z
powiêkszaniem siê d³ugo¶ci zakresu porównanie, które najpierw sprawdza
to¿samo¶æ, jest kosztowniejsze.

Poda³em ci tylko przyk³ad, jak nale¿y prowadziæ tak± analizê - to, ¿e ten
przyk³ad jest negatywny dla twojej tezy, nie ma znaczenia. My¶lê, ¿e da³oby
siê znale¼æ przyk³ad, który by twoj± tezê potwierdza³, ale to nie ma wiêkszego
znaczenia.

W odró¿nieniu od ciebie jednak, ja rozumiem konieczno¶æ wykonania analizy,
która dowiedzie, czy to siê nam op³aca, czy nie. Ty przyjmujesz "w ciemno", ¿e
sprawdzanie najpierw to¿samo¶ci bêdzie zawsze bardziej op³acalne. W
ostateczno¶ci zgadzasz siê nawet, ¿e "najczê¶ciej".

No to podaj mi przyk³ad typu warto¶ciowego, w którym to siê op³aca, i oszacuj
ilo¶æ porównañ trafionych i nietrafionych w typowych algorytmach, które go
u¿ywaj±. Wtedy bêdziemy wiedzieli, o czym rozmawiamy.

> Generalnie jednak - nie zgadzam siê.

Ale¿ masz pe³ne prawo siê nie zgadzaæ. Ja w odró¿nieniu od ciebie potrafiê to
uzasadniæ.

> >> >> > Zauwa¿, po co w C++ stosuje siê wska¼niki i referencje do takich
> >> >> > typów jak int, czy std::string. Je¶li ju¿, to stosuje siê albo
> >> >> > uogólnienie przekazywania (const T&), albo przekazuje siê do
> >> >> > zmodyfikowania (T&, T*). Czy widzia³e¶ kiedykolwiek w jakim¶
> >> >> > rzeczywistym programie, ¿eby kto¶ porównywa³ dwa wska¼niki do int
> >> >> > (pomijaj±c przypadek, gdy wska¼nik do int jest u¿ywany jako iterator
> >> >> > do tablicy int-ów - czyli zastosowanie jest inne, ni¿ warto¶æ
> >> >> > referencji)?
> >> >
> >> >> Tak, w dowolnej konkretyzacji szablonu int'em. Nie ka¿demu chce siê
> >> >> robiæ specjalne implementacje dla typów prostych.
> >> >
> >> > Przy uogólnianiu oczywi¶cie jest to prawda, z t± tylko ró¿nic±, ¿e tam
> >> > typ parametryczny T traktuje siê prawdopodobnie zawsze jak typ
> >> > obiektowy, wiêc sprawa konkretyzacji na int nie ma i tak znaczenia.
> >
> >> "Prawdopodobnie" to dla mnie trochê za ma³o. Szczególnie w przypadku
> >> szablonów, które wed³ug mojej praktyki z regu³y s± po prostu przeznaczone
> >> dla obiektów oferuj±cych okre¶lony interfejs. I innych ograniczeñ w ich
> >> u¿yciu w³a¶ciwie nie ma.
> >
> > Tak, dok³adnie. Ale typy warto¶ciowe zwykle maj± inny interfejs, ni¿ typy
> > obiektowe.

> Znowu ogólnik: "zwykle"... "Sprzedajesz" nam teoriê, która ma dzia³aæ w
> praktyce, u³atwiaæ j±. Chcia³by¶, ¿eby Twój samochód "zwykle" dzia³a³?

Oczywi¶cie teoretycznie mo¿e istnieæ taki wzorzec, który typom nie stawia
¿adnych wymagañ, ale w praktyce nie spotka³em siê z takim.

Wymagania co do typów zawsze okre¶laj± poszczególne operacje, które na typie
mo¿na wykonaæ. I te operacje ¶wiadcz± te¿ o tym, czy typ jest warto¶ciowy, czy
nie.

Przyk³adowo, typ przechowywany w std::list musi byæ typem warto¶ciowym.
Niestety, tak jest skonstruowany szablon std::list. ¦wiadcz± o tym nastêpuj±ce
wymagania wzglêdem typu:
 - przypisywalny
 - kopiowalny
 - domy¶lnie-konstruowalny

Poza tym wiele algorytmów STL, które mog³yby pracowaæ równie¿ na zakresie
wziêtym z listy, wymagaj± dodatkowo, ¿eby by³ porównywalny.

Dostarczaj±c do swojego typu wszystkie mo¿liwe rzeczy, ¿eby spe³niæ wymagania,
de facto czynisz z niego typ warto¶ciowy - co mo¿e siê niekoniecznie zgadzaæ z
logik± twojego programu.

> >> > Je¶li mówimy ju¿ o rzeczywisto¶ci - podaj mi przyk³ad obiektu z
> >> > rzeczywisto¶ci, który posiada jednocze¶nie warto¶æ i to¿samo¶æ.
> >
> >> Konto bankowe. To¿samo¶æ: numer, warto¶æ: saldo.
> >
> > Oraz warto¶æ: w³a¶ciciel (mo¿na go potem kiedy¶ zmieniæ)
> > Oraz obiekt: historia transakcji
> > Oraz...

> Jak wy¿ej: zale¿y od kontekstu.

Nic nie zale¿y od ¿adnego kontekstu.

Saldo jest stanem (cz±stkowym) konta. Saldo jest warto¶ci±. Konto jest
obiektem.

> Mo¿emy nie wi±zaæ obiektów transakcji do
> konta, a zrobiæ wi±zanie odwrotne: ka¿da transakcja ma referencjê do konta.

Ale co to ma do rzeczy?

Transakcja te¿ jest obiektem, tzw. "warto¶æ transakcji" jest atrybutem obiektu
transakcji, a ilo¶æ pieniêdzy, na któr± opiewa transakcja, jest warto¶ci±.

> I podobnie z w³a¶cicielem. Krótko mówi±c "konto jest anonimowe" i
> przechowuje jedynie swoje saldo (warto¶æ) oraz numer (to¿samo¶æ).

Numer jest atrybutem obiektu (unikalnym, wiêc jest ¶ci¶le zwi±zany z
to¿samo¶ci±), w³a¶ciciel te¿ jest obiektem (w bazie banku jest osobnym
obiektem, który mo¿e byæ podmapowany do kilku kont). Saldo jest stanem konta,
a warto¶æ salda to ilo¶æ pieniêdzy znajduj±cych siê na koncie.

> Nie wiem, czy to ma sens, ale nie mo¿esz chyba wykluczyæ, ¿e w jakim¶
> tam systemie mo¿e mieæ.

Niestety nie. Przykro mi.

> > Czy ty w ogóle wiesz, co to jest "warto¶æ"?

> Element ze zbioru (tu: typ, klasa).

To znaczy?


--
//  _    ___         Michal "Sektor" Malecki <sektor(whirl)kis.p.lodz.pl>
\\ L_ |/ `|  /^\ ,()                         <ethouris(O)gmail.com>
// \_ |\  \/ \_/ /\ C++ bez cholesterolu: http://www.intercon.pl/~sektor/cbx
"Java is answer for a question that has never been stated"
Re: Wartości i obiekty
#15284
Author: Marcin 'Qrczak'
Date: Sun, 11 Mar 2007 00:11
171 lines
6695 bytes
Dnia 10-03-2007, sob o godzinie 18:47 +0000, Sektor van Skijlen
napisał(a):

> > Jest jeszcze trzecia kategoria leżąca pomiędzy tymi dwiema:
> > wskaźniki na singletony, czyli na jedyne obiekty danego rodzaju,
> > np. true / false / nil. Te obiekty są niezmienialne, ale tożsamość
> > tych obiektów jest dobrze zdefiniowana; rozróżnianie ich po tożsamości
> > jest równoważne rozróżnianiu po cechach wewnętrznych.
> 
> Nie tworzyłbym specjalnej kategorii dla tych obiektów.

Zwykle można je traktować razem z wartościowymi. Różnica objawia
się tylko wtedy, kiedy w języku mamy do dyspozycji operację jawnie
porównującą dwa obiekty po tożsamości. Tę operację można uznać za
niskopoziomową i rzadko się jej wprost używa, ale w wielu językach
jest dostępna, bo może być tańsza od domyślnego porównania, a dla
pewnego zbioru obiektów jest mu równoważna (Lisp: EQ, Scheme: eq?,
Python: is, Kogut: Is, OCaml: ==). Na przykład w Pythonie porównanie
"x is None" jest praktyczne, a "x is 5" nie jest.

> > Jeśli spróbować dopasować do tego modelu C++, to się okaże, że zmienną
> > C++ zawierającą obiekt można rozumieć na dwa sposoby:
> 
> > a) Jako zmienialny obiekt, przywiązany na stałe do swojej nazwy.
> >    To tłumaczenie jest odpowiednie w przypadku obiektów z tożsamością,
> >    zwłaszcza złożonych, bo pozwala wymodelować możliwość zmiany
> >    indywidualnych pól obiektu z zachowaniem tożsamości całego obiektu.
> >    Takie obiekty są zwykle przekazywane przez referencje C++ albo
> >    wskaźniki C++, co odpowiada przekazaniu wskaźnika na obiekt
> >    w modelu, a więc odpowiada naturalnemu sposobowi przekazania
> >    wartości w modelu.
> 
> > b) Jako zmienną zawierającą wartość, która sama jest niezmienialna.
> >    To tłumaczenie jest lepsze dla atomowych typów wartościowych,
> >    bo pozwala wymodelować wartość wyabstrahowaną od miejsca
> >    przechowywania. Takie obiekty są w C++ zwykle kopiowane,
> >    co odpowiada przekazaniu odczytanej bieżącej wartości zmiennej
> >    w modelu, czyli znowu jest naturalnym sposobem przekazania wartości,
> >    mimo że w C++ jest inne niż tamto.
> 
> Szczerze mówiąc to nic z tego nie rozumiem.

Bo opisałem odpowiedniki zmiennej w C++ językiem (ludzkim)
przystosowanym do opisywania innych języków (programowania).
Jesteś przyzwyczajony do języka (ludzkiego) przystosowanego
do opisywania C++.

Jeśli w C++ mamy zmienną zawierającą obiekt udostępniający jakieś metody
(w tym metody zmieniające jego stan), to w innym języku odpowiednik tej
konstrukcji wygląda z reguły na jeden z dwóch sposobów, zależnie od
stylu, w jakim przeważnie wygodnie jest używać obiektów danego typu:

a) Typowy przykład: tablica.

   Zmienna wskazuje na obiekt udostępniający analogiczne operacje jak
   w C++. Obiekt jest tworzony na stercie. Do tej zmiennej nie jest
   nigdy przypisywany wskaźnik na inny obiekt.

   Tam, gdzie w C++ obiekt jest przekazywany przez referencję, w innym
   języku przekazywana jest wartość tej zmiennej (wskazująca na ten
   obiekt). Tam, gdzie w C++ obiekt jest przekazywany przez wartość,
   w innym języku obiekt jest klonowany (czymś w rodzaju metody Clone).

b) Typowy przykład: liczba.

   Zmienna wskazuje na niezmienialny obiekt innego języka reprezentujący
   bieżący stan obiektu C++. Metodom C++, które zmieniały stan obiektu,
   odpowiadają operacje zwracające nowy obiekt, który jest przypisywany
   z powrotem tej zmiennej.

   Tam, gdzie w C++ obiekt jest przekazywany przez wartość, w innym
   języku przekazywana jest bieżąca wartość zmiennej. Tam, gdzie
   w C++ obiekt jest przekazywany przez referencję, w innym języku
   przekazywana jest referencja na zmienną.

> String zawsze powinien być traktowany jak wartość, natomiast wektor zawsze
> jak obiekt.

Zgodzę się, że zazwyczaj. Nie zgadzam się, że zawsze.

A wektor znaków? Z jednej strony to jest wektor. Z drugiej strony to
jest w zasadzie to samo, co string. Różnice są w dodatkowych metodach,
ale one są raczej poboczne, nie wpływają na istotę rzeczy.

> > Pisałem tutaj o zmienialnym stringu, zakładając, że to jest jedyny
> > string w danym języku. Czyli kiedy złożony typ pełniący rolę typu
> > wartościowego jest jednak zmienialny. Taka sytuacja jest kłopotliwa.
> 
> Oj... nie bardzo to widzę.

No i właśnie mówię, że to jest kłopotliwe. Lepiej tego unikać.

W to C++ pasuje. W Perlu też; to jest jeden z nielicznych języków
(obok Pascala, C i C++), który kopiuje zawartość stringa przy
przypisaniu, choć przy przekazaniu jako argument funkcji formalnie
już nie (ale w praktyce zwykle tak, bo większość funkcji zaczyna się
od skopiowania argumentów do osobnych lokalnych zmiennych - specyfika
Perla).

Przykłady języków, które mają wyłącznie zmienialne stringi mimo
paradygmatu, który do tego nie pasuje: Lisp, Scheme, OCaml, Ruby
(czasem są zmienialne łącznie ze zmianą długości, a czasem nie).

> > Mój model w wersji czystej wymaga zdecydowania się, który styl użycia
> > jest tutaj dominujący. Pomieszanie styli grozi błędami aliasowania albo
> > niepotrzebnymi kopiami.
> 
> No właśnie - ale nie możesz zrobić tak, że w całym języku jeden model
> obowiązuje wszystkie obiekty.

Oczywiście, tego nie proponowałem. Byle był ustalony styl dla danego
typu.

-- 
   __("<         Marcin Kowalczyk
   \__/       qrczak@knm.org.pl
    ^^     http://qrnik.knm.org.pl/~qrczak/
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
#15285
Author: Marcin 'Qrczak'
Date: Sun, 11 Mar 2007 01:40
143 lines
5771 bytes
Dnia 10-03-2007, sob o godzinie 19:17 +0000, Sektor van Skijlen
napisał(a):

> Zrób sobie małą statystykę użycia takiego typu i ilość porównań, dla których
> trafiasz na równość i dla których trafiasz na nierówność.

Zrób statystykę, ile można stracić i ile można zaoszczędzić.

Sprawa nie jest oczywista. Jest wiele czynników wpływających na
opłacalność: statyczne bądź dynamiczne typowanie, statyczna wiedza
kompilatora niekoniecznie wynikająca z systemu typów, reprezentacja
obiektów czy zgoła wymagania semantyki operacji porównania w danym
języku.

Przykład. W OCamlu jest funkcja =, która porównuje zawartość dwóch
obiektów tego samego, dowolnego typu. Porównuje głęboko, nie zważając na
to, które fragmenty są zmienialne. Kompilator generuje specjalny kod dla
pewnych typów (np. liczby różnego rodzaju albo typy wyliczeniowe). Jest
też zmaterializowana w jednym miejscu uniwersalna funkcja porównująca,
zaimplementowana w C, używana dla różnych złożonych typów oraz tam,
gdzie typ nie jest statycznie znany (bo kod jest parametryzowany typem).

Ta funkcja do niedawna zaczynała od porównania fizycznej reprezentacji
argumentów, czyli albo wartości bezpośrednich, albo wskaźników. Jeśli
były równe, to zwracała true bez wchodzenia do środka, a jeśli nie były
równe, to dopiero sprawdzała, czy oba są wartościami bezpośrednimi albo
oba wskaźnikami i czy mają ten sam numer konstruktora. Z punktu widzenia
efektywności uznano, że warto.

Zostało to zmienione z powodu typu float, który jest porównywany przez =
zgodnie z arytmetyką IEEE: nan jest różne od samego siebie. Z tego
wynika, że dowolna struktura zawierająca nan, np. lista [1.0; nan; 2.0],
jest różna od samej siebie. Tymczasem w starej implementacji była równa
albo różna w zależności od tego, czy była zaalokowana osobno, czy nie,
co w przypadku listy nie powinno było mieć znaczenia. Co śmieszniejsze,
ta sama samodzielna wartość nan była równa sobie albo nierówna
w zależności od tego, czy miejsce aplikacji funkcji = było kompilowane
ze świadomością, że argumenty są typu float (wtedy było generowane tylko
zmiennoprzecinkowe porównanie zawartości), czy nie (wtedy używana była
wspomniana uniwersalna implementacja, która najpierw porównywała adres).

Tak więc zarzucono to z powodów semantycznych.

Inny przykład. W Kogucie jest funkcja Is, która porównuje dwie wartości
i z założenia jest najmniejszą relacją równoważności, która nie bierze
pod uwagę fizycznej tożsamości tam gdzie nie musi (czyli przy większości
obiektów niezmienialnych).

Problemu z NaN nie ma, bo równość arytmetyczna, w której NaN jest różne
od siebie, to osobna funkcja.

Reprezentacja wartości jest taka, że małe liczby całkowite są oznaczone
najmłodszym bitem równym 1, a wszystkie pozostałe wartości są
wskaźnikami na obiekt, którego pierwsze słowo jest wskaźnikiem na
tzw. deskryptor, którego jednym z pól jest wskaźnik na typ.

Kompilator generuje specjalny kod dla aplikacji Is, jeśli jeden
z argumentów jest znaną mu stałą. Poza tym jest jedna uniwersalna
implementacja Is, która robi co następuje:

1. Jeśli wartości są fizycznie równe (taka sama mała liczba całkowita
   albo taki sam wskaźnik), to wynikiem jest True.

2. Jeśli któryś z argumentów jest małą liczbą całkowitą, to wynikiem
   jest False.

3. Jeśli wartości są różnych typów, to wynikiem jest False.

4. Wybierana i wykonywana jest implementacja Is zależna od typu
   (wspólnego dla obu argumentów), wyszukiwana w słowniku (standardowy
   mechanizm funkcji generycznych).

Zauważmy, że 3 nie wprowadza dodatkowego kosztu, skoro tak czy siak
czeka nas 4 (dzięki 3 w 4 wystarczy wziąć jeden typ), a 2 nie wprowadza
dodatkowego kosztu, skoro czeka nas 3 (trzeba sprawdzić, czy dana
wartość nie jest małą liczbą całkowitą, zanim sprawdzi się jej typ).

W tej sytuacji punkt 1 narzuca się w sposób naturalny. Porównanie
równych liczb całkowitych jest szybsze (wystarczy pierwszy punkt)..
Porównanie różnych liczb całkowitych jest tak samo szybkie (dwa proste
punkty potrzebne tak czy siak). Porównanie innych wartości jest albo
nieznacznie wolniejsze (jedno dodatkowe porównanie, kiedy są już co
najmniej dwa inne), albo znacznie szybsze (oszczędzenie punktów od 2
do 4 przy porównaniu np. Null z Null albo równych znaków mieszczących
się w ISO-8859-1, a czasem i równych innych stringów, jeśli to ten sam
obiekt).

-- 
   __("<         Marcin Kowalczyk
   \__/       qrczak@knm.org.pl
    ^^     http://qrnik.knm.org.pl/~qrczak/
Re: =?ISO-8859-2?Q?Warto¶ci?= i obiekty
#15286
Author: Sektor van Skijl
Date: Sun, 11 Mar 2007 15:29
190 lines
8989 bytes
Dnia Sun, 11 Mar 2007 00:11:42 +0100, Marcin 'Qrczak' Kowalczyk skrobie:
> Dnia 10-03-2007, sob o godzinie 18:47 +0000, Sektor van Skijlen
> napisa³(a):

> > > Jest jeszcze trzecia kategoria le¿±ca pomiêdzy tymi dwiema:
> > > wska¼niki na singletony, czyli na jedyne obiekty danego rodzaju,
> > > np. true / false / nil. Te obiekty s± niezmienialne, ale to¿samo¶æ
> > > tych obiektów jest dobrze zdefiniowana; rozró¿nianie ich po to¿samo¶ci
> > > jest równowa¿ne rozró¿nianiu po cechach wewnêtrznych.
> >
> > Nie tworzy³bym specjalnej kategorii dla tych obiektów.

> Zwykle mo¿na je traktowaæ razem z warto¶ciowymi. Ró¿nica objawia
> siê tylko wtedy, kiedy w jêzyku mamy do dyspozycji operacjê jawnie
> porównuj±c± dwa obiekty po to¿samo¶ci. Tê operacjê mo¿na uznaæ za
> niskopoziomow± i rzadko siê jej wprost u¿ywa, ale w wielu jêzykach
> jest dostêpna, bo mo¿e byæ tañsza od domy¶lnego porównania, a dla
> pewnego zbioru obiektów jest mu równowa¿na (Lisp: EQ, Scheme: eq?,
> Python: is, Kogut: Is, OCaml: ==). Na przyk³ad w Pythonie porównanie
> "x is None" jest praktyczne, a "x is 5" nie jest.

Qrczak - to wszystko prawda, ale to wci±¿ nie zmienia faktu:

Obojêtnie, jak mamy zaimplementowany sposób porównania warto¶ci i to¿samo¶ci,
obojêtnie te¿, czy typ jest warto¶ciowy, czy obiektowy, dla ka¿dego typu
istnieje tylko i wy³±cznie jeden sensowny sposób porównania.

Skoro tak, to nie potrzebujemy osobnych operatorów porównania - powinien byæ
dostêpny jeden operator porównania.

> > > Je¶li spróbowaæ dopasowaæ do tego modelu C++, to siê oka¿e, ¿e zmienn±
> > > C++ zawieraj±c± obiekt mo¿na rozumieæ na dwa sposoby:
> >
> > > a) Jako zmienialny obiekt, przywi±zany na sta³e do swojej nazwy.
> > >    To t³umaczenie jest odpowiednie w przypadku obiektów z to¿samo¶ci±,
> > >    zw³aszcza z³o¿onych, bo pozwala wymodelowaæ mo¿liwo¶æ zmiany
> > >    indywidualnych pól obiektu z zachowaniem to¿samo¶ci ca³ego obiektu.
> > >    Takie obiekty s± zwykle przekazywane przez referencje C++ albo
> > >    wska¼niki C++, co odpowiada przekazaniu wska¼nika na obiekt
> > >    w modelu, a wiêc odpowiada naturalnemu sposobowi przekazania
> > >    warto¶ci w modelu.
> >
> > > b) Jako zmienn± zawieraj±c± warto¶æ, która sama jest niezmienialna.
> > >    To t³umaczenie jest lepsze dla atomowych typów warto¶ciowych,
> > >    bo pozwala wymodelowaæ warto¶æ wyabstrahowan± od miejsca
> > >    przechowywania. Takie obiekty s± w C++ zwykle kopiowane,
> > >    co odpowiada przekazaniu odczytanej bie¿±cej warto¶ci zmiennej
> > >    w modelu, czyli znowu jest naturalnym sposobem przekazania warto¶ci,
> > >    mimo ¿e w C++ jest inne ni¿ tamto.
> >
> > Szczerze mówi±c to nic z tego nie rozumiem.

> Bo opisa³em odpowiedniki zmiennej w C++ jêzykiem (ludzkim)
> przystosowanym do opisywania innych jêzyków (programowania).
> Jeste¶ przyzwyczajony do jêzyka (ludzkiego) przystosowanego
> do opisywania C++.

Nie do koñca siê zgodzê, w szczególno¶ci nie zgodzê siê, ¿e opisa³e¶ to
jêzykiem ludzkim :)

> Je¶li w C++ mamy zmienn± zawieraj±c± obiekt udostêpniaj±cy jakie¶ metody
> (w tym metody zmieniaj±ce jego stan), to w innym jêzyku odpowiednik tej
> konstrukcji wygl±da z regu³y na jeden z dwóch sposobów, zale¿nie od
> stylu, w jakim przewa¿nie wygodnie jest u¿ywaæ obiektów danego typu:

> a) Typowy przyk³ad: tablica.

>    Zmienna wskazuje na obiekt udostêpniaj±cy analogiczne operacje jak
>    w C++. Obiekt jest tworzony na stercie. Do tej zmiennej nie jest
>    nigdy przypisywany wska¼nik na inny obiekt.

Ale mówisz o tablicy surowej, tworzonej jako zmienna lokalna w funkcji.

Pomówmy raczej o vectorze.

>    Tam, gdzie w C++ obiekt jest przekazywany przez referencjê, w innym
>    jêzyku przekazywana jest warto¶æ tej zmiennej (wskazuj±ca na ten
>    obiekt). Tam, gdzie w C++ obiekt jest przekazywany przez warto¶æ,
>    w innym jêzyku obiekt jest klonowany (czym¶ w rodzaju metody Clone).

Tak - pod warunkiem, ¿e pozwala siê na klonowanie obiektów.

> b) Typowy przyk³ad: liczba.

>    Zmienna wskazuje na niezmienialny obiekt innego jêzyka reprezentuj±cy
>    bie¿±cy stan obiektu C++. Metodom C++, które zmienia³y stan obiektu,
>    odpowiadaj± operacje zwracaj±ce nowy obiekt, który jest przypisywany
>    z powrotem tej zmiennej.

Pod warunkiem, ¿e mamy mo¿liwo¶æ "zakodowania" przypisania do zmiennej
trzymaj±cej ten niezmienialny obiekt.

Tak zreszt± jest to w Javie i Javowe rozwi±zanie ma tylko jedn± wadê: operator
porównania :).

>    Tam, gdzie w C++ obiekt jest przekazywany przez warto¶æ, w innym
>    jêzyku przekazywana jest bie¿±ca warto¶æ zmiennej. Tam, gdzie
>    w C++ obiekt jest przekazywany przez referencjê, w innym jêzyku
>    przekazywana jest referencja na zmienn±.

A co z porównywaniem?

> > String zawsze powinien byæ traktowany jak warto¶æ, natomiast wektor zawsze
> > jak obiekt.

> Zgodzê siê, ¿e zazwyczaj. Nie zgadzam siê, ¿e zawsze.

Zgodzê siê co najwy¿ej, ¿e nie zawsze, tzn. wektor mo¿e s³u¿yæ jako szczegó³
implementacyjny jakiego¶ typu warto¶ciowego. Ale nie sam wektor, bo to jest
mniej wiêcej co¶ takiego jak void* do przechowywania dynamicznych danych.

> A wektor znaków? Z jednej strony to jest wektor. Z drugiej strony to
> jest w zasadzie to samo, co string.

Ró¿nica polega na tym, czym siê ró¿ni "to samo" od "w zasadzie to samo" ;)

Nie, Qrczak. String to nie jest tablica znaków - jak ju¿ siê czepiamy
skrzywionego my¶lenia, to i ja siê poczepiam: twoje my¶lenie jest skrzywione
przez jêzyki, w których string jest reprezentowany przez listê znaków (jak np.
Haskell).

String charakteryzuje siê tym, ¿e posiada warto¶æ; napis jest po prostu jednym
napisem, który mo¿e byæ taki sam jak inny lub ró¿ny od niego, napisy mo¿emy
te¿ porz±dkowaæ po warto¶ci (bo maj± warto¶æ), "ten sam napis" oznacza nam
napis sk³adaj±cy siê z dok³adnie takich samych znaków w tej samej kolejno¶ci.

Vector natomiast jest zbiorem elementów - ich kolejno¶æ nie jest czêsto
specjalnie istotna (je¶li ju¿, to najwy¿ej kwestie
uporz±dkowany-nieuporz±dkowany), elementy czêsto przestawia siê w inne
miejsce, wykonuje siê czêsto operacje na ka¿dym elemencie po kolei. W
przypadku stringa te operacje s± w mniejszo¶ci, a sortowanie znaków w stringu
uwa¿a³bym za powiew ezoteryki.

To nie jest kwestia implementacji (string, vector), tylko kwestia logiki
programu. Jasne, mo¿emy sobie obs³ugiwaæ napisy jako vector<char>, ale to bêd±
dla nas i tak napisy (jêzyk C przecie¿ i tak obs³uguje napisy jako tablice
znaków). Implementacja jest wiêc nieistotna - wa¿ne jest to, co to dla nas
oznacza w programie.

Dlatego dobre jêzyki programowania pozwalaj± na stworzenie osobnych typów,
które maj± nawet wspólne podstawy implementacyjne, ale które logicznie
oznaczaj± zupe³nie co innego. W³a¶nie dlatego, ¿e to narzuca nam sposób
operowania takim typem.

Mo¿na tablicê char'ów u¿ywaæ jako zbiór znaków i jako napis, oczywi¶cie. Ale
wtedy trzeba samemu pamiêtaæ o tym, co jest czym i jak co mamy traktowaæ.
Je¶li jêzyk jest s³aby i nie potrafi daæ mo¿liwo¶ci rozró¿nienia tych rzeczy
po statycznym typie (jak w C), to musi jako¶ zapewniæ mo¿liwo¶æ alternatywnych
sposobów porównañ za pomoc± osobnych operacji.

> Ró¿nice s± w dodatkowych metodach,
> ale one s± raczej poboczne, nie wp³ywaj± na istotê rzeczy.

Dobrze, Qrczak, niech ci ju¿ bêdzie, bo w tym momencie rêce mi opad³y.

> > > Pisa³em tutaj o zmienialnym stringu, zak³adaj±c, ¿e to jest jedyny
> > > string w danym jêzyku. Czyli kiedy z³o¿ony typ pe³ni±cy rolê typu
> > > warto¶ciowego jest jednak zmienialny. Taka sytuacja jest k³opotliwa.
> >
> > Oj... nie bardzo to widzê.

> No i w³a¶nie mówiê, ¿e to jest k³opotliwe. Lepiej tego unikaæ.

> W to C++ pasuje.

Tak, ale w C++ zmiana stringa zmienia tylko t± zmienn±, która aktualnie
przechowuje warto¶æ. Inaczej mówi±c, nadaje now± warto¶æ zmiennej.

Mo¿na te¿ odnie¶æ siê czê¶ciowo do tego, ¿e niektóre implementacje stringa
wspó³dziel± tablicê znaków. Wiêc dwie ró¿ne zmienne mog³yby wskazywaæ na ró¿ne
tablice, co bardzo przypomina³oby wskazywanie na dwa obiekty przez dwie
zmienne referencyjne. Ale w takim przypadku przyda³oby siê te¿ jakie¶ sprytne
COW, które by powodowa³o, ¿e w razie zmiany przez jedn± z tych zmiennych,
ka¿da z nich bêdzie mia³a od teraz w³asn± kopiê. Inaczej mówi±c, nawet je¶li
jaka¶ zmienna wspó³dzieli obiekt tablicy z innymi zmiennymi, to modyfikacja
tej zmiennej nie zmienia warto¶ci w pozosta³ych zmiennych (a jedynie traci z
nimi powi±zanie).

> Przyk³ady jêzyków, które maj± wy³±cznie zmienialne stringi mimo
> paradygmatu, który do tego nie pasuje: Lisp, Scheme, OCaml, Ruby
> (czasem s± zmienialne ³±cznie ze zmian± d³ugo¶ci, a czasem nie).

Tzn. jak? Musisz jawnie skopiowaæ string, je¶li chcesz, ¿eby ¼ród³owy siê nie
zmieni³?


--
//  _    ___         Michal "Sektor" Malecki <sektor(whirl)kis.p.lodz.pl>
\\ L_ |/ `|  /^\ ,()                         <ethouris(O)gmail.com>
// \_ |\  \/ \_/ /\ C++ bez cholesterolu: http://www.intercon.pl/~sektor/cbx
"Java is answer for a question that has never been stated"
Re: Wartości i obiekty
#15287
Author: Marcin 'Qrczak'
Date: Sun, 11 Mar 2007 23:15
158 lines
6139 bytes
Dnia 11-03-2007, nie o godzinie 15:29 +0000, Sektor van Skijlen
napisał(a):

> Obojętnie, jak mamy zaimplementowany sposób porównania wartości i tożsamości,
> obojętnie też, czy typ jest wartościowy, czy obiektowy, dla każdego typu
> istnieje tylko i wyłącznie jeden sensowny sposób porównania.

To jest prawie prawda.

Po pierwsze, co tłumaczę od paru postów, zdarza się, że typ ma
niejednoznaczny charakter i czasem jest używany w roli typu
wartościowego, a czasem typu z tożsamością. Zgadzam się, że to
jest kłopotliwe, ale to bywa faktem.

Po drugie czasem (rzadko) chcemy porównać tożsamość obiektów typów
wartościowych dla niskopoziomowych optymalizacji. Na przykład jeśli
rekurencyjna funkcja przekształcająca drzewo ma tę własność, że dla
wielu podfragmentów wynikiem jest sam argument, to można uniknąć
alokacji węzła wyniku w sytuacji, kiedy wywołania rekurencyjne nic nie
zmieniły i my też nie zamierzamy nic zmieniać. Przykład funkcji o tej
własności: uproszczenie wyrażenia algebraicznego.

Po trzecie są relacje, które - jeśli się uprzeć - można nazwać inaczej
niż równość, ale potocznie są to jakieś odmiany równości. Na przykład
sprawdzenie, czy dwa ciągi mają równe odpowiadające sobie elementy, bez
sprawdzenia, czy te ciągi w ogóle są tego samego typu.

Po czwarte tradycyjna równość zmiennoprzecinkowa nie jest relacją
równoważności (z powodu NaN) ani nie jest zachowywana przez operacje
arytmetyczne (z powodu -0.0). Jest więc powód, żeby traktować ją jako
osobną operację niż podstawowa równość.

A to jeszcze nie wszystko.

> > a) Typowy przykład: tablica.
> 
> >    Zmienna wskazuje na obiekt udostępniający analogiczne operacje jak
> >    w C++. Obiekt jest tworzony na stercie. Do tej zmiennej nie jest
> >    nigdy przypisywany wskaźnik na inny obiekt.
> 
> Ale mówisz o tablicy surowej, tworzonej jako zmienna lokalna w funkcji.
> 
> Pomówmy raczej o vectorze.

Miałem na myśli vector (tworzony jako zmienna lokalna w funkcji).

> >    w innym języku obiekt jest klonowany (czymś w rodzaju metody Clone).
> 
> Tak - pod warunkiem, że pozwala się na klonowanie obiektów..

Zawsze "się pozwala", bo nie ma czego zabraniać - to jest operacja jak
każda inna, jeśli się nie oczekuje, że będzie automatycznie dostępna
dla dowolnego typu.

> > b) Typowy przykład: liczba.
> 
> >    Zmienna wskazuje na niezmienialny obiekt innego języka reprezentujący
> >    bieżący stan obiektu C++. Metodom C++, które zmieniały stan obiektu,
> >    odpowiadają operacje zwracające nowy obiekt, który jest przypisywany
> >    z powrotem tej zmiennej.
> 
> Pod warunkiem, że mamy możliwość "zakodowania" przypisania do zmiennej
> trzymającej ten niezmienialny obiekt.

Jasne; miałem na myśli imperatywną, przypisywalną zmienną. Słowo
"zmienna" jest niestety wieloznaczne i część języków programowania,
tak jak matematyka, używa go w znaczeniu lokalnej nazwy jakiejś
wartości, niekoniecznie zmieniającej się w czasie.

> >    Tam, gdzie w C++ obiekt jest przekazywany przez wartość, w innym
> >    języku przekazywana jest bieżąca wartość zmiennej. Tam, gdzie
> >    w C++ obiekt jest przekazywany przez referencję, w innym języku
> >    przekazywana jest referencja na zmienną.
> 
> A co z porównywaniem?

Nie rozumiem pytania. Dla obiektów tej kategorii porównanie jest dość
podstawową operacją, zdefiniowaną zależnie od typu. No i normalnie jest
oferowane, najczęściej w formie wspólnego interfejsu dla różnych typów.

> Nie, Qrczak. String to nie jest tablica znaków - jak już się czepiamy
> skrzywionego myślenia, to i ja się poczepiam: twoje myślenie jest skrzywione
> przez języki, w których string jest reprezentowany przez listę znaków (jak np.
> Haskell).

Etam. W C string też jest w zasadzie tablicą znaków, a w C++ mało do
tego brakuje. Szablon basic_string jest nawet parametryzowany typem
znaku. Ten typ ma trochę więcej wymagań niż typ elementu wektora, ale
poza tym różnica jest mała.

W Kogucie, podobnie jak w Pythonie i Perlu, w ogóle nie ma osobnego
typu znakowego. Kiedy znak jest materializowany w programie, jest
reprezentowany przez string długości 1. Na pewno więc string jako
tablica znaków nie jest moim skrzywieniem.

> > Przykłady języków, które mają wyłącznie zmienialne stringi mimo
> > paradygmatu, który do tego nie pasuje: Lisp, Scheme, OCaml, Ruby
> > (czasem są zmienialne łącznie ze zmianą długości, a czasem nie).
> 
> Tzn. jak? Musisz jawnie skopiować string, jeśli chcesz, żeby źródłowy się nie
> zmienił?

Tak. Nie jest to aż tak błędogenne, jak mogłoby się wydawać, jeśli się
stosuje konwencję, że zmienia się tylko te stringi, które się przed
chwilą utworzyło. Czyli string jest w zasadzie traktowany jako typ
niezmienialny, imperatywne jest tylko jego tworzenie.

-- 
   __("<         Marcin Kowalczyk
   \__/       qrczak@knm.org.pl
    ^^     http://qrnik.knm.org.pl/~qrczak/
Re: =?ISO-8859-2?Q?Warto¶ci?= i obiekty
#15288
Author: Sektor van Skijl
Date: Mon, 12 Mar 2007 21:28
250 lines
11777 bytes
Dnia Sun, 11 Mar 2007 23:15:23 +0100, Marcin 'Qrczak' Kowalczyk skrobie:
> Dnia 11-03-2007, nie o godzinie 15:29 +0000, Sektor van Skijlen
> napisa³(a):

> > Obojêtnie, jak mamy zaimplementowany sposób porównania warto¶ci i to¿samo¶ci,
> > obojêtnie te¿, czy typ jest warto¶ciowy, czy obiektowy, dla ka¿dego typu
> > istnieje tylko i wy³±cznie jeden sensowny sposób porównania.

> To jest prawie prawda.

> Po pierwsze, co t³umaczê od paru postów, zdarza siê, ¿e typ ma
> niejednoznaczny charakter i czasem jest u¿ywany w roli typu
> warto¶ciowego, a czasem typu z to¿samo¶ci±. Zgadzam siê, ¿e to
> jest k³opotliwe, ale to bywa faktem.

A ja równie¿ t³umaczê od paru postów, ¿e na tak± okoliczno¶æ powinny zostaæ
stworzone osobne typy statyczne.

To prawda, ¿e mo¿esz u¿ywaæ tego samego typu jêzyka jako logicznego typu
warto¶ciowego i niewarto¶ciowego, tyle ¿e to sprowadza jêzyk do
niskopoziomowego rozwi±zania, w którym tego samego typu mo¿na u¿ywaæ do
przechowywania logicznie ró¿nych rzeczy.

Je¶li mamy jêzyk taki, jak C, to rozumiem, ¿e za bardzo nie mamy wyj¶cia.
Dlatego tam u¿ywa siê tego samego typu - tablicy char - jako ³añcucha
tekstowego i jako tablicy o elementach typu char.

Natomiast dla jêzyka wysokopoziomowego to po prostu wstyd, ¿eby nie zrobiæ
tego na osobnych typach. Rozumieli to zarówno twórcy C++, jak i Javy, i C#
(nb. Tcl-a te¿, dlatego te¿ tam trzeba stosowaæ pewne myki, ¿eby móc
przekszta³ciæ napis na listê znaków). Najwyra¼niej nie zrozumieli tego twórcy
jêzyków Haskell i D.

Je¶li taki typ ma osobne specyfiki dla ró¿nych przypadków, to i tak
przynajmniej jednej specyfiki zawsze trzyma siê jeden obiekt (czyli nie
zmienia siê nagle z typu obiektowego w warto¶ciowy w trakcie dzia³ania). Je¶li
tak, to mo¿na u¿yæ osobnych definicji typów dla ka¿dego obiektu u¿ywaj±cego
okre¶lonej specyfiki.

> Po drugie czasem (rzadko) chcemy porównaæ to¿samo¶æ obiektów typów
> warto¶ciowych dla niskopoziomowych optymalizacji.

Rozumiem - ale taka niskopoziomowa optymalizacja powinna byæ operacj±
szczególnego rodzaju, byæ dostêpna tylko dla operacji bezpo¶rednio operuj±cych
na takim typie (lub specjalnie do tego dozwolonych), a przynajmniej powinna
byæ wykonywalna za pomoc± osobnych funkcji porównania.

Nie chodzi mi przecie¿ o to, ¿eby ca³kowicie zabroniæ mo¿liwo¶ci sprawdzania
to¿samo¶ci obiektów typów warto¶ciowych. Chodzi o to, ¿eby ka¿dy typ posiada³
operator porównania, który porównuje w sposób adekwatny do rodzaju typu.

> Po trzecie s± relacje, które - je¶li siê uprzeæ - mo¿na nazwaæ inaczej
> ni¿ równo¶æ, ale potocznie s± to jakie¶ odmiany równo¶ci. Na przyk³ad
> sprawdzenie, czy dwa ci±gi maj± równe odpowiadaj±ce sobie elementy, bez
> sprawdzenia, czy te ci±gi w ogóle s± tego samego typu.

Mo¿na, owszem, ale to nie jest porównanie warto¶ci, tylko porównanie
zawarto¶ci zbiorników (operacja specyficzna dla zbiornika, bo nie da siê
takiej operacji uogólniæ na "po prostu obiekt"). Powinna byæ zatem dozwolona,
ale jako specyficzna operacja, a nie porównanie.

Dlaczego w C++ zbiorniki nie posiadaj± zdefiniowanego operatora porównania,
tylko tego typu porównania wykonuje siê algorytmami equal i mismatch?

> Po czwarte tradycyjna równo¶æ zmiennoprzecinkowa nie jest relacj±
> równowa¿no¶ci (z powodu NaN) ani nie jest zachowywana przez operacje
> arytmetyczne (z powodu -0.0). Jest wiêc powód, ¿eby traktowaæ j± jako
> osobn± operacjê ni¿ podstawowa równo¶æ.

Nie no równo¶æ warto¶ci zmiennoprzecinkowych to jest ju¿ osobna bajka. Jest to
drobny wy³om w systemie typów warto¶ciowych/obiektowych. Problem jest w³a¶nie
z tym NaN, bo gdyby nie to, to jeszcze na upartego zachowa³aby siê zasada, ¿e
warto¶æ a skopiowana z b jest równa b.

Nie wiem w tym momencie, czy typy zmiennoprzecinkowe mo¿na traktowaæ jak
warto¶ci. Dla mnie najsensowniejszym rozwi±zaniem by³oby zdefiniowanie jako
operatora porównania porównania "wewnêtrznego", czyli z zachowaniem zale¿no¶ci
miêdzy przypisaniem a porównaniem. Natomiast osobno do tego nale¿a³oby
stworzyæ funkcjê porównuj±c± dwie liczby zmiennoprzecinkowe z zadanym
epsilonem.

Ci, co wymy¶lili ten numer z NaN, najwyra¼niej nie zdawali sobie sprawy z
tego, jakie zamieszanie tym zrobi±.

Zastanawiam siê nawet, czy nie by³oby znacznie sensowniejsze uznanie liczb
zmiennoprzecinkowych za typy niewarto¶ciowe. To¿samo¶æ przez obiekt lepiej by
siê dla nich sprawdza³a.

> A to jeszcze nie wszystko.

No to co jeszcze?

Przecie¿ mo¿na by do tej wyliczanki do³o¿yæ stringa, którego mo¿esz porównywaæ
np. bez case'a, z pominiêciem znaków kontrolnych itp.

Powtarzam: nie zaprzeczam, ¿e powinny byæ zdefiniowane ró¿ne metody
porównywania dostêpne dla danego obiektu, ale powinna byæ zawsze JEDNA
operacja najw³a¶ciwszego porównania zdefiniowana dla danego typu.

> > >    w innym jêzyku obiekt jest klonowany (czym¶ w rodzaju metody Clone).
> >
> > Tak - pod warunkiem, ¿e pozwala siê na klonowanie obiektów.

> Zawsze "siê pozwala", bo nie ma czego zabraniaæ - to jest operacja jak
> ka¿da inna, je¶li siê nie oczekuje, ¿e bêdzie automatycznie dostêpna
> dla dowolnego typu.

Niestety, bzdury opowiadasz. Istnieje co¶ takiego, jak unikalne warto¶ci -
warto¶æ jednego pola, która w ka¿dym obiekcie musi byæ inna. Czêsto s± to
nawet obiekty generowane na rzecz innych, istniej±cych obiektów. Efekt jest
taki, ¿e ¿eby¶ móg³ poprawnie tworzyæ obiekt przez klonowanie, to musia³by¶
podczas klonowania uwzglêdniæ fakt, ¿e warto¶ci niektórych jego pól nie mog±
byæ skopiowane, tylko musz± zostaæ wygenerowane na nowo. Czy taki obiekt
bêdzie jeszcze klonem?

Klonowanie zreszt± to nie jest taka prosta sprawa. Pamiêtam, jak w mudzie by³a
funkcja klonuj±ca moba. Trzeba by³o tam uwzglêdniæ mnóstwo rzeczy: je¶li
postaæ by³a wierzchowcem, to nowa postaæ by³a "nieosiod³ana". Je¶li postaæ
dosiada³a wierzchowca, to nowa postaæ by³a tworzona na ziemi. Je¶li postaæ
zajmowa³a mebel, to nowa postaæ musia³a równie¿ staæ obok (tzn. tak by³o po
wniesieniu mojej poprawki do buga, bo poprzednio nowa postaæ by³a tworzona na
tym samym meblu - autor najwyra¼niej zapomnia³, ¿e meble maj± te¿ swoj±
pojemno¶æ i niekoniecznie dwie postacie bêd± mog³y siedzieæ na jednym
krze¶le). Kolejnym problemem jest to, czy klonowanie postaci powinno poci±gaæ
za sob± klonowanie posiadanych przez ni± przedmiotów, czy te¿ nowa postaæ ma
byæ stworzona "na golasa" (nie pamiêtam ju¿, jak to rozwi±zano). Gdyby
poci±gaæ za sob± tworzenie przedmiotów, to dodatkowo niektóre mudy maj±
wprowadzon± ekonomiê - czyli takie sklonowanie poci±ga za sob± dodatkowo
deflacjê. I tak mo¿na by wyliczaæ bez koñca.

Co wiêcej, czêsto ¼ród³em danych dla tworzenia nowego obiektu s± jakie¶
specyficzne dane, które trzeba odpowiednio pobraæ (byæ mo¿e zarejestrowaæ,
skojarzyæ z czym¶). W takim przypadku nie da siê stworzyæ obiektu na podstawie
danych z innego obiektu, bo dane, które posiada ten hipotetyczny obiekt
¼ród³owy s± przygotowane tylko i wy³±cznie dla niego.

Jak ty sobie wyobra¿asz np. sklonowanie obiektu oznaczaj±cego plik, gniazdo,
sesjê, czy zbiornik w³a¶cicielski (zbiornik z dynamicznie tworzonymi
obiektami, które zbiornik posiada na w³asno¶æ, tzn. usuwa je razem ze sob±)?

Wiêc co oznacza "zawsze siê pozwala"? Nie mówi±c o tym, ¿e w dalszej czê¶ci
zdania twierdzisz, ¿e mo¿na zabroniæ, wiêc nie rozumiem...

> > > b) Typowy przyk³ad: liczba.
> >
> > >    Zmienna wskazuje na niezmienialny obiekt innego jêzyka reprezentuj±cy
> > >    bie¿±cy stan obiektu C++. Metodom C++, które zmienia³y stan obiektu,
> > >    odpowiadaj± operacje zwracaj±ce nowy obiekt, który jest przypisywany
> > >    z powrotem tej zmiennej.
> >
> > Pod warunkiem, ¿e mamy mo¿liwo¶æ "zakodowania" przypisania do zmiennej
> > trzymaj±cej ten niezmienialny obiekt.

> Jasne; mia³em na my¶li imperatywn±, przypisywaln± zmienn±. S³owo
> "zmienna" jest niestety wieloznaczne i czê¶æ jêzyków programowania,
> tak jak matematyka, u¿ywa go w znaczeniu lokalnej nazwy jakiej¶
> warto¶ci, niekoniecznie zmieniaj±cej siê w czasie.

Wiem, o co chodzi ze zmienn± w obu przypadkach.

Problem tylko w tym, czy jêzyk pozwala zrobiæ jaki¶ trik, który zakoduje
operacjê modyfikuj±c± obiekt tak, ¿eby wygl±da³a jak modyfikuj±ca, a w
rzeczywisto¶ci bêdzie tworzyæ now± kopiê obiektu.

> > >    Tam, gdzie w C++ obiekt jest przekazywany przez warto¶æ, w innym
> > >    jêzyku przekazywana jest bie¿±ca warto¶æ zmiennej. Tam, gdzie
> > >    w C++ obiekt jest przekazywany przez referencjê, w innym jêzyku
> > >    przekazywana jest referencja na zmienn±.
> >
> > A co z porównywaniem?

> Nie rozumiem pytania. Dla obiektów tej kategorii porównanie jest do¶æ
> podstawow± operacj±, zdefiniowan± zale¿nie od typu. No i normalnie jest
> oferowane, najczê¶ciej w formie wspólnego interfejsu dla ró¿nych typów.

No w³a¶nie. A co z implementacj±?

> > Nie, Qrczak. String to nie jest tablica znaków - jak ju¿ siê czepiamy
> > skrzywionego my¶lenia, to i ja siê poczepiam: twoje my¶lenie jest skrzywione
> > przez jêzyki, w których string jest reprezentowany przez listê znaków (jak np.
> > Haskell).

> Etam. W C string te¿ jest w zasadzie tablic± znaków,

Ale Haskel, w odró¿nieniu od C, nie jest jêzykiem niskopoziomowym, z
siermiê¿nymi w³a¶ciwo¶ciami umo¿liwiaj±cymi ledwie co zrobienie struktur, ¿eby
jako¶ operowaæ w³asnymi typami.

> a w C++ ma³o do
> tego brakuje.

Nawet je¶li mo¿na trochê ponaci±gaæ fakty, ¿eby to stwierdziæ, to nie zmienia
faktu, ¿e jednak zrobiono do tego osobne typy.

> Szablon basic_string jest nawet parametryzowany typem
> znaku.

Complex te¿ jest parametryzowany typem warto¶ci zmiennoprzecinkowej, i co z
tego?

> Ten typ ma trochê wiêcej wymagañ ni¿ typ elementu wektora, ale
> poza tym ró¿nica jest ma³a.

Ró¿nica jest zasadnicza. Gdyby nie to, nikt by siê nie sili³ na robienie
osobnego typu dla stringa i vectora. Popatrz na jêzyk D - tam nie ma osobnego
typu dla stringa, a string jest jednocze¶nie tablic± znaków (czyli, inaczej
mówi±c, tablica znaków posiada ca³± funkcjonalno¶æ potrzebn± dla stringa).

> W Kogucie, podobnie jak w Pythonie i Perlu, w ogóle nie ma osobnego
> typu znakowego. Kiedy znak jest materializowany w programie, jest
> reprezentowany przez string d³ugo¶ci 1.

W Tcl-u te¿ tak jest, wiêc to chyba nic niezwyk³ego jak na jêzyk skryptowy.

> Na pewno wiêc string jako
> tablica znaków nie jest moim skrzywieniem.

Rozumiem, ¿e musisz siê jako¶ broniæ ;).

Ale na powa¿nie - fakt, ¿e w wielu jêzykach string jest to¿samy z tablic±
znaków, uwa¿am za pomy³kê. Tablica znaków jest czym¶ koncepcyjnie innym od
stringa, a je¶li co¶ jest koncepcyjnie inne, to system typów powinien pozwalaæ
na wyra¿enie tego osobnym typem. Jêzyk, który tego nie ma, ma "nalecia³o¶ci
asemblerowe".

> > > Przyk³ady jêzyków, które maj± wy³±cznie zmienialne stringi mimo
> > > paradygmatu, który do tego nie pasuje: Lisp, Scheme, OCaml, Ruby
> > > (czasem s± zmienialne ³±cznie ze zmian± d³ugo¶ci, a czasem nie).
> >
> > Tzn. jak? Musisz jawnie skopiowaæ string, je¶li chcesz, ¿eby ¼ród³owy siê nie
> > zmieni³?

> Tak. Nie jest to a¿ tak b³êdogenne, jak mog³oby siê wydawaæ, je¶li siê
> stosuje konwencjê, ¿e zmienia siê tylko te stringi, które siê przed
> chwil± utworzy³o.

Ale¿ jaja sobie robisz. Nie jest to a¿ tak b³êdogenne, je¶li siê pamiêta. Nie
zapominaj, ¿e bardzo czêsto u¿ywasz tego argumentu przeciwko C++.

> Czyli string jest w zasadzie traktowany jako typ
> niezmienialny, imperatywne jest tylko jego tworzenie.

Bardzo dobrze - ale niech w takim razie jêzyk sam zadba o to, ¿eby tego
stringa nie da³o siê zmieniæ po jego utworzeniu.


--
//  _    ___         Michal "Sektor" Malecki <sektor(whirl)kis.p.lodz.pl>
\\ L_ |/ `|  /^\ ,()                         <ethouris(O)gmail.com>
// \_ |\  \/ \_/ /\ C++ bez cholesterolu: http://www.intercon.pl/~sektor/cbx
"Java is answer for a question that has never been stated"
Re: =?ISO-8859-2?Q?Warto¶ci?= i obiekty
#15289
Author: Sektor van Skijl
Date: Tue, 13 Mar 2007 08:43
16 lines
641 bytes
Dnia Mon, 12 Mar 2007 21:28:52 +0000 (UTC), Sektor van Skijlen skrobie:
> > Szablon basic_string jest nawet parametryzowany typem
> > znaku.

> Complex te¿ jest parametryzowany typem warto¶ci zmiennoprzecinkowej, i co z
> tego?

Zapomnia³em dopisaæ:

Dlaczego complex ma swój w³asny osobny typ, zamiast ¿eby u¿ywa³o siê do tego
celu np. pair<double,double> ?

--
//  _    ___         Michal "Sektor" Malecki <sektor(whirl)kis.p.lodz.pl>
\\ L_ |/ `|  /^\ ,()                         <ethouris(O)gmail.com>
// \_ |\  \/ \_/ /\ C++ bez cholesterolu: http://www.intercon.pl/~sektor/cbx
"Java is answer for a question that has never been stated"
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
#15291
Author: Mariusz Lotko
Date: Tue, 13 Mar 2007 19:24
221 lines
8119 bytes
Sektor van Skijlen wrote:

>> > Portfel nie jest typem warto¶ciowym.
>> >
>> > Ilo¶æ pieniêdzy w portfelu jest jedynie jednym ze stanów tego obiektu,
>> > podobnie jak ilo¶æ kart kredytowych w ¶rodku, kolor portfela i
>> > materia³, z którego go wykonano.
>
>> I w _ka¿dym_ systemie tak to modelujesz? Z pe³n± otoczk±? Piêkny przyk³ad
>> wzorca "swiss army knife".
>
> Nie u¿ywaj pojêæ, których znaczenia nie rozumiesz.

Nie czyñ za³o¿eñ, na które nie masz dowodów.

> Swiss army knife to by by³o, gdyby ten portfel móg³ przechowywaæ
> pieni±dze, laptopy, meble, samochody, kontenery i elektrownie.

Nie. Swiss army knife oznacza, ¿e modelujesz wszystkie elementy
rzeczywisto¶ci czy tego wymaga system czy nie. Dlatego nie ma np.
uniwersalnej implementacji portfela, która jest dobra w ka¿dym
systemie.
Gdyby tak by³o, jak grzyby po deszczu powstawa³yby biblioteki, które
implementuj± obiekty naszej codzienno¶ci.

> Ilo¶æ pieniêdzy nie jest warto¶ci± portfela. Jest jego stanem. Portfel nie
> mo¿e mieæ warto¶ci - i to nie dlatego, ¿e poza tym mo¿e mieæ jeszcze wiele
> innych stanów i atrytbutów.

Wychodz±c z tego za³o¿enia stanem "obiektu" "klasy" int jest np. 2. Stan
ten mo¿na zmieniæ "funkcj±" zmiany stanu, np. ++.
Kto z nas nie rozró¿nia warto¶ci od stanu?

>
>> > Typem warto¶ciowym mo¿e byæ kolor. Porównanie dwóch obiektów typu kolor
>> > mo¿na porównaæ ze sprawdzeniem, czy na dwóch kartkach papieru zapisany
>> > tam kod koloru jest ten sam. Ty chcesz, ¿eby przed odczytaniem numeru z
>> > ka¿dej kartki najpierw sprawdziæ, czy te obie kartki to czasem nie jest
>> > jedna i ta sama kartka. Jaki to ma sens?
>
>> Id±c Twoj± logik±: niekoniecznie. Obiekt kolor ma jeszcze atrybuty: data
>> naniesienia, technika wykonania i stopieñ nas³onecznienia, które
>> pozwalaj± obliczyæ rzeczywisty kolor w czasie :> Wtedy nie da siê
>> porównaæ dwóch "czerwonych". Odsy³am do ekspertów - lakierników
>> samochodowych.
>
> Nie przypominam sobie, ¿ebym mówi³ o lakierze samochodowym. Mówi³em o
> kolorze. Kolor mo¿e byæ równie¿ atrybutem (a nie warto¶ci±, acz
> przypadkiem te¿ nie stanem) lakieru.

Ja tylko poszed³em Twoj± logik±. Zwa¿, ¿e w systemie, o którym pisa³em
przy portfelu nie wspomina³em o istnieniu kart kredytowych.

> No to jak, zrozumia³e¶ ju¿, co to takiego jest warto¶æ, czy douczysz siê i
> zg³osisz za tydzieñ?

Do kogo mia³bym siê zg³osiæ?

>
>> >> Z tym, ¿e w obu przypadkach nie chodzi o "przykr± konieczno¶æ", a
>> >> o "wspania³± mo¿liwo¶æ" szybkiego stwierdzenia, ¿e chodzi o "te same"
>> >> a wiêc na pewno "takie same" obiekty.
>> >
>> > To jest przykra konieczno¶æ. Musisz to po prostu zrobiæ, bo inaczej
>> > bêdzie wylot.
>
>> W operatorze porównania? Nie s±dzê...
>
> W operatorze przypisania.

Co mia³oby sprawiæ "wylot" w operatorze przypisania?

>> > Ta "wspania³a mo¿liwo¶æ" z kolei powoduje dro¿sze porównanie.
>
>> W pewnych przypadkach mo¿e tak byæ.
>
> Statystycznie jest to 99% przypadków.

Statystycznie, to ja bijê swoj± ¿onê co miesi±c. Ty, je¶li jeste¶ ¿onaty
równie¿. Takie szacunki trzeba robiæ dla konkretnych klas a nie
generalizowaæ.

>> Implementuj±c operator warto
>> oszacowaæ prawdopodobieñstwo porównywania tych samych obiektów.
>
> Zrób sobie ma³± statystykê u¿ycia takiego typu i ilo¶æ porównañ, dla
> których trafiasz na równo¶æ i dla których trafiasz na nierówno¶æ.
>
> Prosty przyk³ad - iteratory. Masz pêtlê, w której przechodzisz przez
(...)
>
> Poda³em ci tylko przyk³ad, jak nale¿y prowadziæ tak± analizê - to, ¿e ten
> przyk³ad jest negatywny dla twojej tezy, nie ma znaczenia. My¶lê, ¿e
> da³oby siê znale¼æ przyk³ad, który by twoj± tezê potwierdza³, ale to nie
> ma wiêkszego znaczenia.

Nie bêdê ani analizowa³ Twojego przyk³adu, ani mu zaprzecza³. Zak³adam,
¿e jest s³uszny. To jednak tylko przyk³ad, z którego do sformu³owania
regu³y jeszcze daleko.

> W odró¿nieniu od ciebie jednak, ja rozumiem konieczno¶æ wykonania analizy,
> która dowiedzie, czy to siê nam op³aca, czy nie. Ty przyjmujesz "w
> ciemno", ¿e sprawdzanie najpierw to¿samo¶ci bêdzie zawsze bardziej
> op³acalne. W ostateczno¶ci zgadzasz siê nawet, ¿e "najczê¶ciej".

Ty dla odmiany uwa¿asz, ¿e najczê¶ciej nie. Na razie jednak nie potrafisz
udowodniæ dlaczego Twoja teza jest lepsza od mojej.

> No to podaj mi przyk³ad typu warto¶ciowego, w którym to siê op³aca, i
> oszacuj ilo¶æ porównañ trafionych i nietrafionych w typowych algorytmach,
> które go u¿ywaj±. Wtedy bêdziemy wiedzieli, o czym rozmawiamy.

Nie chodzi o sam typ, tylko kontekst u¿ycia.

>
>> Generalnie jednak - nie zgadzam siê.
>
> Ale¿ masz pe³ne prawo siê nie zgadzaæ. Ja w odró¿nieniu od ciebie potrafiê
> to uzasadniæ.

W odró¿nieniu od Ciebie unikam jednoznacznych stwierdzeñ na temat swoich
umiejêtno¶ci. Pozwalam to oceniæ innym. Równie¿ Tobie, choæ przyznam, ¿e
nie odbieram tych ocen zbyt serio.

Daj szansê innym pochwaliæ Twoje umiejêtno¶ci. Mo¿e kiedy¶ to nast±pi.

>> >> "Prawdopodobnie" to dla mnie trochê za ma³o. Szczególnie w przypadku
>> >> szablonów, które wed³ug mojej praktyki z regu³y s± po prostu
>> >> przeznaczone dla obiektów oferuj±cych okre¶lony interfejs. I innych
>> >> ograniczeñ w ich u¿yciu w³a¶ciwie nie ma.
>> >
>> > Tak, dok³adnie. Ale typy warto¶ciowe zwykle maj± inny interfejs, ni¿
>> > typy obiektowe.
>
>> Znowu ogólnik: "zwykle"... "Sprzedajesz" nam teoriê, która ma dzia³aæ w
>> praktyce, u³atwiaæ j±. Chcia³by¶, ¿eby Twój samochód "zwykle" dzia³a³?
>
> Oczywi¶cie teoretycznie mo¿e istnieæ taki wzorzec, który typom nie stawia
> ¿adnych wymagañ, ale w praktyce nie spotka³em siê z takim.
>
> Wymagania co do typów zawsze okre¶laj± poszczególne operacje, które na
> typie mo¿na wykonaæ. I te operacje ¶wiadcz± te¿ o tym, czy typ jest
> warto¶ciowy, czy nie.
>
> Przyk³adowo, typ przechowywany w std::list musi byæ typem warto¶ciowym.
> Niestety, tak jest skonstruowany szablon std::list. ¦wiadcz± o tym
> nastêpuj±ce wymagania wzglêdem typu:
>  - przypisywalny
>  - kopiowalny
>  - domy¶lnie-konstruowalny

Rozumiem, ¿e je¶li stworzê sobie jaki¶ widget, powiedzmy combo-box, który
spe³nia powy¿sze wymagania, to nie bêdê móg³, go przechowywaæ w std::list,
bo pogwa³cê Twoj± teoriê?

>> >> > Je¶li mówimy ju¿ o rzeczywisto¶ci - podaj mi przyk³ad obiektu z
>> >> > rzeczywisto¶ci, który posiada jednocze¶nie warto¶æ i to¿samo¶æ.
>> >
>> >> Konto bankowe. To¿samo¶æ: numer, warto¶æ: saldo.
>> >
>> > Oraz warto¶æ: w³a¶ciciel (mo¿na go potem kiedy¶ zmieniæ)
>> > Oraz obiekt: historia transakcji
>> > Oraz...
>
>> Jak wy¿ej: zale¿y od kontekstu.
>
> Nic nie zale¿y od ¿adnego kontekstu.
>
> Saldo jest stanem (cz±stkowym) konta. Saldo jest warto¶ci±. Konto jest
> obiektem.

Niepotrzebnie wi±¿esz terminy z ¿ycia (stan konta) z terminami
informatycznymi (stan obiektu). Osobom z ma³ym do¶wiadczeniem to siê
czêsto zdarza, nie przejmuj siê.

>
>> Mo¿emy nie wi±zaæ obiektów transakcji do
>> konta, a zrobiæ wi±zanie odwrotne: ka¿da transakcja ma referencjê do
>> konta.
>
> Ale co to ma do rzeczy?

To, ¿e obiekt konto nie musi przechowywaæ historii, je¶li tylko zechcê tak
to zamodelowaæ.

>
> Transakcja te¿ jest obiektem, tzw. "warto¶æ transakcji" jest atrybutem
> obiektu transakcji, a ilo¶æ pieniêdzy, na któr± opiewa transakcja, jest
> warto¶ci±.

Otó¿ to!

>
>> I podobnie z w³a¶cicielem. Krótko mówi±c "konto jest anonimowe" i
>> przechowuje jedynie swoje saldo (warto¶æ) oraz numer (to¿samo¶æ).
>
> Numer jest atrybutem obiektu (unikalnym, wiêc jest ¶ci¶le zwi±zany z
> to¿samo¶ci±), w³a¶ciciel te¿ jest obiektem (w bazie banku jest osobnym
> obiektem, który mo¿e byæ podmapowany do kilku kont). Saldo jest stanem
> konta, a warto¶æ salda to ilo¶æ pieniêdzy znajduj±cych siê na koncie.

Dlaczego "ilo¶æ" nie jest wed³ug Ciebie "warto¶ci±"?

>> Nie wiem, czy to ma sens, ale nie mo¿esz chyba wykluczyæ, ¿e w jakim¶
>> tam systemie mo¿e mieæ.
>
> Niestety nie. Przykro mi.

Cieszê siê, ¿e choæ raz przyznajesz mi racjê i nie próbujesz tego wykluczyæ.

>
>> > Czy ty w ogóle wiesz, co to jest "warto¶æ"?
>
>> Element ze zbioru (tu: typ, klasa).
>
> To znaczy?

Odsy³am do ksi±¿ki "Matematyka dla klas drugich".

--
Mariusz Lotko
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
#15293
Author: Sektor van Skijl
Date: Wed, 14 Mar 2007 00:13
299 lines
11858 bytes
Dnia Tue, 13 Mar 2007 19:24:26 +0100, Mariusz Lotko skrobie:
> Sektor van Skijlen wrote:

> >> > Portfel nie jest typem warto¶ciowym.
> >> >
> >> > Ilo¶æ pieniêdzy w portfelu jest jedynie jednym ze stanów tego obiektu,
> >> > podobnie jak ilo¶æ kart kredytowych w ¶rodku, kolor portfela i
> >> > materia³, z którego go wykonano.
> >
> >> I w _ka¿dym_ systemie tak to modelujesz? Z pe³n± otoczk±? Piêkny przyk³ad
> >> wzorca "swiss army knife".
> >
> > Nie u¿ywaj pojêæ, których znaczenia nie rozumiesz.

> Nie czyñ za³o¿eñ, na które nie masz dowodów.

> > Swiss army knife to by by³o, gdyby ten portfel móg³ przechowywaæ
> > pieni±dze, laptopy, meble, samochody, kontenery i elektrownie.

> Nie. Swiss army knife oznacza, ¿e modelujesz wszystkie elementy
> rzeczywisto¶ci czy tego wymaga system czy nie.

Nie wiem, jak ty, ale ja pojêcie "swiss army knife" znam jako jeden z b³êdów
OO, który polega na stworzeniu klasy o zbyt du¿ym zakresie odpowiedzialno¶ci.

Dok³adno¶æ modelowania to zupe³nie inna sprawa.

Zreszt±, je¶li dla ciebie programowanie obiektowe jest modelowaniem
rzeczywisto¶ci, to obawiam siê, ¿e mo¿emy nasz± dyskusjê wznowiæ za parê lat,
jak bêdziesz ju¿ mówi³ jêzykiem w³asnego do¶wiadczenia, a nie ksi±¿kowym.

(Na marginesie: to bardzo dobrze, ¿e literatura do OO twierdzi, ¿e
programowanie obiektowe jest modelowaniem rzeczywisto¶ci. Tak bowiem nale¿y t±
sprawê t³umaczyæ pocz±tkuj±cym. Im wiêcej jednak cz³owiek programuje
obiektowo, tym bardziej siê przekonuje, ¿e to nie ma nic wspólnego z prawd±.
To jest jeden ze znaków rozpoznawczych, czy kto¶ potrafi my¶leæ samodzielnie
rzeczywi¶cie dysponuje do¶wiadczeniem zawodowym, czy recytuje z pamiêci wiedzê
ksi±¿kow±.)

Cofaj±c jednak t± ca³± dygresjê, któr± nie wiem po co wprowadzi³e¶ - poda³em
ci tylko przyk³ad, dlaczego portfel nie mo¿e byæ typem warto¶ciowym.

Je¶li nie zrozumia³e¶ nadal, to wyt³umaczê ci bardziej ³opatologicznie:
portfel zawieraj±cy tyle samo pieniêdzy, to nie ten sam portfel (mówiê tak, bo
twierdzi³e¶, ¿e ilo¶æ pieniêdzy mo¿e byæ warto¶ci± potrfela).

> > Ilo¶æ pieniêdzy nie jest warto¶ci± portfela. Jest jego stanem. Portfel nie
> > mo¿e mieæ warto¶ci - i to nie dlatego, ¿e poza tym mo¿e mieæ jeszcze wiele
> > innych stanów i atrytbutów.

> Wychodz±c z tego za³o¿enia stanem "obiektu" "klasy" int jest np. 2. Stan
> ten mo¿na zmieniæ "funkcj±" zmiany stanu, np. ++.
> Kto z nas nie rozró¿nia warto¶ci od stanu?

int x = 2;
int y = 2;

Powiedz mi teraz, czy "x jest y".

> >> > Typem warto¶ciowym mo¿e byæ kolor. Porównanie dwóch obiektów typu kolor
> >> > mo¿na porównaæ ze sprawdzeniem, czy na dwóch kartkach papieru zapisany
> >> > tam kod koloru jest ten sam. Ty chcesz, ¿eby przed odczytaniem numeru z
> >> > ka¿dej kartki najpierw sprawdziæ, czy te obie kartki to czasem nie jest
> >> > jedna i ta sama kartka. Jaki to ma sens?
> >
> >> Id±c Twoj± logik±: niekoniecznie. Obiekt kolor ma jeszcze atrybuty: data
> >> naniesienia, technika wykonania i stopieñ nas³onecznienia, które
> >> pozwalaj± obliczyæ rzeczywisty kolor w czasie :> Wtedy nie da siê
> >> porównaæ dwóch "czerwonych". Odsy³am do ekspertów - lakierników
> >> samochodowych.
> >
> > Nie przypominam sobie, ¿ebym mówi³ o lakierze samochodowym. Mówi³em o
> > kolorze. Kolor mo¿e byæ równie¿ atrybutem (a nie warto¶ci±, acz
> > przypadkiem te¿ nie stanem) lakieru.

> Ja tylko poszed³em Twoj± logik±. Zwa¿, ¿e w systemie, o którym pisa³em
> przy portfelu nie wspomina³em o istnieniu kart kredytowych.

Nie poszed³e¶ moj± logik±. Mówi³em o kolorze, a ty wzi±³e¶ sobie nie wiem po
co lakier samochodowy.

Podobnie typem warto¶ciowym mog± byæ "pieni±dze". Ale nie kieszeñ, portfel,
konto, sejf, czy gdzie to tam jeszcze chcesz przechowywaæ.

> > No to jak, zrozumia³e¶ ju¿, co to takiego jest warto¶æ, czy douczysz siê i
> > zg³osisz za tydzieñ?

> Do kogo mia³bym siê zg³osiæ?

No có¿, wydawa³o mi siê, ¿e ka¿dy, kto studiowa³, s³ysza³ to s³ynne
okre¶lenie. W czym¶ siê widaæ pomyli³em.

> >> >> Z tym, ¿e w obu przypadkach nie chodzi o "przykr± konieczno¶æ", a
> >> >> o "wspania³± mo¿liwo¶æ" szybkiego stwierdzenia, ¿e chodzi o "te same"
> >> >> a wiêc na pewno "takie same" obiekty.
> >> >
> >> > To jest przykra konieczno¶æ. Musisz to po prostu zrobiæ, bo inaczej
> >> > bêdzie wylot.
> >
> >> W operatorze porównania? Nie s±dzê...
> >
> > W operatorze przypisania.

> Co mia³oby sprawiæ "wylot" w operatorze przypisania?

Sprawdzenie, czy nie przypisujemy samego siebie. Fakt, ¿e musisz u¿yæ
operatora porównania dla to¿samo¶ci jest przykr± konieczno¶ci±, bo bez tego
usun±³by¶ czê¶æ obiektu, z którego za chwilê masz zamiar czytaæ.

> >> > Ta "wspania³a mo¿liwo¶æ" z kolei powoduje dro¿sze porównanie.
> >
> >> W pewnych przypadkach mo¿e tak byæ.
> >
> > Statystycznie jest to 99% przypadków.

> Statystycznie, to ja bijê swoj± ¿onê co miesi±c. Ty, je¶li jeste¶ ¿onaty
> równie¿. Takie szacunki trzeba robiæ dla konkretnych klas a nie
> generalizowaæ.

No widzisz. A ja mogê sobie pozwoliæ na generalizacjê.

Chodzi o bardzo prost± rzecz: jakiej wielko¶ci jest zwykle typ warto¶ciowy?
Niewielkiej. Musi byæ niewielki, bo im wiêkszy, tym wiêcej zasobów zajmuje
jego warto¶æ, d³u¿ej siê kopiuje, a i porównanie warto¶ci - dosæ czêsta
operacja - trwa do¶æ d³ugo. Dlatego w³a¶nie typy warto¶ciowe robi siê z
za³o¿enia JAK NAJMNIEJSZE - w³a¶nie po to, ¿eby te operacje by³y jak
najszybsze. Skoro istnieje taka presja na obiekty warto¶ciowe, to gdzie masz w
takim razie pole dla obiektów, w których porównanie mo¿na "przyspieszyæ"
poprzez najpierw sprawdzanie to¿samo¶ci?

> >> Implementuj±c operator warto
> >> oszacowaæ prawdopodobieñstwo porównywania tych samych obiektów.
> >
> > Zrób sobie ma³± statystykê u¿ycia takiego typu i ilo¶æ porównañ, dla
> > których trafiasz na równo¶æ i dla których trafiasz na nierówno¶æ.
> >
> > Prosty przyk³ad - iteratory. Masz pêtlê, w której przechodzisz przez
> (...)
> >
> > Poda³em ci tylko przyk³ad, jak nale¿y prowadziæ tak± analizê - to, ¿e ten
> > przyk³ad jest negatywny dla twojej tezy, nie ma znaczenia. My¶lê, ¿e
> > da³oby siê znale¼æ przyk³ad, który by twoj± tezê potwierdza³, ale to nie
> > ma wiêkszego znaczenia.

> Nie bêdê ani analizowa³ Twojego przyk³adu, ani mu zaprzecza³. Zak³adam,
> ¿e jest s³uszny. To jednak tylko przyk³ad, z którego do sformu³owania
> regu³y jeszcze daleko.

To by³ przyk³ad wykonania analizy, który pokaza³, ¿e siê nie op³aca. Czy
jeste¶w stanie podaæ mi kontrprzyk³ad - czyli taki, który udowodni, ¿e siê
op³aca?

> > W odró¿nieniu od ciebie jednak, ja rozumiem konieczno¶æ wykonania analizy,
> > która dowiedzie, czy to siê nam op³aca, czy nie. Ty przyjmujesz "w
> > ciemno", ¿e sprawdzanie najpierw to¿samo¶ci bêdzie zawsze bardziej
> > op³acalne. W ostateczno¶ci zgadzasz siê nawet, ¿e "najczê¶ciej".

> Ty dla odmiany uwa¿asz, ¿e najczê¶ciej nie. Na razie jednak nie potrafisz
> udowodniæ dlaczego Twoja teza jest lepsza od mojej.

Potrafiê, tylko ty nie potrafisz jej zrozumieæ, albo uparcie zaprzeczasz
faktom.

Moja teza jest lepsza, bo jest oparta na rzetelnej analizie (nb. analiza
Qrczaka równie¿). Twoja teza, ¿e to jest "oczywiste, ¿e tak siê powinno zawsze
robiæ" nie jest poparta niczym.

> > No to podaj mi przyk³ad typu warto¶ciowego, w którym to siê op³aca, i
> > oszacuj ilo¶æ porównañ trafionych i nietrafionych w typowych algorytmach,
> > które go u¿ywaj±. Wtedy bêdziemy wiedzieli, o czym rozmawiamy.

> Nie chodzi o sam typ, tylko kontekst u¿ycia.

Brawo! Zatem s³ucham.

> >> Generalnie jednak - nie zgadzam siê.
> >
> > Ale¿ masz pe³ne prawo siê nie zgadzaæ. Ja w odró¿nieniu od ciebie potrafiê
> > to uzasadniæ.

> W odró¿nieniu od Ciebie unikam jednoznacznych stwierdzeñ na temat swoich
> umiejêtno¶ci.

Z t± "oczywisto¶ci±", ¿e operator porównania powinien najpierw sprawdziæ
to¿samo¶æ, niespecjalnie ci to wysz³o.

> Pozwalam to oceniæ innym. Równie¿ Tobie, choæ przyznam, ¿e
> nie odbieram tych ocen zbyt serio.

> Daj szansê innym pochwaliæ Twoje umiejêtno¶ci. Mo¿e kiedy¶ to nast±pi.

Ju¿ nast±pi³o, o to siê nie martw.

> >> >> "Prawdopodobnie" to dla mnie trochê za ma³o. Szczególnie w przypadku
> >> >> szablonów, które wed³ug mojej praktyki z regu³y s± po prostu
> >> >> przeznaczone dla obiektów oferuj±cych okre¶lony interfejs. I innych
> >> >> ograniczeñ w ich u¿yciu w³a¶ciwie nie ma.
> >> >
> >> > Tak, dok³adnie. Ale typy warto¶ciowe zwykle maj± inny interfejs, ni¿
> >> > typy obiektowe.
> >
> >> Znowu ogólnik: "zwykle"... "Sprzedajesz" nam teoriê, która ma dzia³aæ w
> >> praktyce, u³atwiaæ j±. Chcia³by¶, ¿eby Twój samochód "zwykle" dzia³a³?
> >
> > Oczywi¶cie teoretycznie mo¿e istnieæ taki wzorzec, który typom nie stawia
> > ¿adnych wymagañ, ale w praktyce nie spotka³em siê z takim.
> >
> > Wymagania co do typów zawsze okre¶laj± poszczególne operacje, które na
> > typie mo¿na wykonaæ. I te operacje ¶wiadcz± te¿ o tym, czy typ jest
> > warto¶ciowy, czy nie.
> >
> > Przyk³adowo, typ przechowywany w std::list musi byæ typem warto¶ciowym.
> > Niestety, tak jest skonstruowany szablon std::list. ¦wiadcz± o tym
> > nastêpuj±ce wymagania wzglêdem typu:
> >  - przypisywalny
> >  - kopiowalny
> >  - domy¶lnie-konstruowalny

> Rozumiem, ¿e je¶li stworzê sobie jaki¶ widget, powiedzmy combo-box, który
> spe³nia powy¿sze wymagania, to nie bêdê móg³, go przechowywaæ w std::list,
> bo pogwa³cê Twoj± teoriê?

Nie. Bo jak wykonasz na nim algorytm std::remove, to zdrowo siê zdziwisz, co
po tym powsta³o.

> >> >> > Je¶li mówimy ju¿ o rzeczywisto¶ci - podaj mi przyk³ad obiektu z
> >> >> > rzeczywisto¶ci, który posiada jednocze¶nie warto¶æ i to¿samo¶æ.
> >> >
> >> >> Konto bankowe. To¿samo¶æ: numer, warto¶æ: saldo.
> >> >
> >> > Oraz warto¶æ: w³a¶ciciel (mo¿na go potem kiedy¶ zmieniæ)
> >> > Oraz obiekt: historia transakcji
> >> > Oraz...
> >
> >> Jak wy¿ej: zale¿y od kontekstu.
> >
> > Nic nie zale¿y od ¿adnego kontekstu.
> >
> > Saldo jest stanem (cz±stkowym) konta. Saldo jest warto¶ci±. Konto jest
> > obiektem.

> Niepotrzebnie wi±¿esz terminy z ¿ycia (stan konta) z terminami
> informatycznymi (stan obiektu). Osobom z ma³ym do¶wiadczeniem to siê
> czêsto zdarza, nie przejmuj siê.

Parafrazuj±c, "Skoñczy³ siê czas argumentów. Teraz jest czas inwektyw".

A mo¿e tak co¶ do tematu?

> >> Mo¿emy nie wi±zaæ obiektów transakcji do
> >> konta, a zrobiæ wi±zanie odwrotne: ka¿da transakcja ma referencjê do
> >> konta.
> >
> > Ale co to ma do rzeczy?

> To, ¿e obiekt konto nie musi przechowywaæ historii, je¶li tylko zechcê tak
> to zamodelowaæ.

No mo¿e, i nadal, co z tego?

> >
> > Transakcja te¿ jest obiektem, tzw. "warto¶æ transakcji" jest atrybutem
> > obiektu transakcji, a ilo¶æ pieniêdzy, na któr± opiewa transakcja, jest
> > warto¶ci±.

> Otó¿ to!

No w³a¶nie. Wiêc co tu mo¿e, a co nie mo¿e byæ warto¶ci±?

> >> I podobnie z w³a¶cicielem. Krótko mówi±c "konto jest anonimowe" i
> >> przechowuje jedynie swoje saldo (warto¶æ) oraz numer (to¿samo¶æ).
> >
> > Numer jest atrybutem obiektu (unikalnym, wiêc jest ¶ci¶le zwi±zany z
> > to¿samo¶ci±), w³a¶ciciel te¿ jest obiektem (w bazie banku jest osobnym
> > obiektem, który mo¿e byæ podmapowany do kilku kont). Saldo jest stanem
> > konta, a warto¶æ salda to ilo¶æ pieniêdzy znajduj±cych siê na koncie.

> Dlaczego "ilo¶æ" nie jest wed³ug Ciebie "warto¶ci±"?

Widzê, ¿e ca³kiem siê ju¿ pogubi³e¶ ;)

Oczywi¶cie, ¿e jest.

> >> > Czy ty w ogóle wiesz, co to jest "warto¶æ"?
> >
> >> Element ze zbioru (tu: typ, klasa).
> >
> > To znaczy?

> Odsy³am do ksi±¿ki "Matematyka dla klas drugich".

Có¿, osobliwy masz wybór literatury do nauki programowania, ale to ju¿ nie
moja sprawa.


--
//  _    ___         Michal "Sektor" Malecki <sektor(whirl)kis.p.lodz.pl>
\\ L_ |/ `|  /^\ ,()                         <ethouris(O)gmail.com>
// \_ |\  \/ \_/ /\ C++ bez cholesterolu: http://www.intercon.pl/~sektor/cbx
"Java is answer for a question that has never been stated"
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
#15294
Author: Mariusz Lotko
Date: Thu, 15 Mar 2007 06:12
323 lines
12310 bytes
Sektor van Skijlen wrote:

>> > Swiss army knife to by by³o, gdyby ten portfel móg³ przechowywaæ
>> > pieni±dze, laptopy, meble, samochody, kontenery i elektrownie.
>
>> Nie. Swiss army knife oznacza, ¿e modelujesz wszystkie elementy
>> rzeczywisto¶ci czy tego wymaga system czy nie.
>
> Nie wiem, jak ty, ale ja pojêcie "swiss army knife" znam jako jeden z
> b³êdów OO, który polega na stworzeniu klasy o zbyt du¿ym zakresie
> odpowiedzialno¶ci.

Ja te¿. Dlaczego uwa¿asz, ¿e modelowanie wiêkszej czê¶ci rzeczywisto¶ci
od wymaganej nie jest "zbyt du¿ym zakresem odpowiedzialno¶ci"?

> Dok³adno¶æ modelowania to zupe³nie inna sprawa.

Inny bêdzie poziom szczegó³owo¶ci klasy Samochód w kartotece
samochodów w Urzêdzie Miasta, a inny w kartotece warsztatu
samochodowego.

Mój kolega jaki¶ czas temu wymy¶li³ dobry polski odpowiednik
swiss army knife: "przyda¶". Bierze siê to z podej¶cia "przyda siê,
zaimplementujê".

> Zreszt±, je¶li dla ciebie programowanie obiektowe jest modelowaniem
> rzeczywisto¶ci, to obawiam siê, ¿e mo¿emy nasz± dyskusjê wznowiæ za parê
> lat, jak bêdziesz ju¿ mówi³ jêzykiem w³asnego do¶wiadczenia, a nie
> ksi±¿kowym.

I znowu za³o¿enia... Za³ó¿ przez chwilê, ¿e nie jeste¶ jednak
nieomylny.

> (Na marginesie: to bardzo dobrze, ¿e literatura do OO twierdzi, ¿e
> programowanie obiektowe jest modelowaniem rzeczywisto¶ci. Tak bowiem
> nale¿y t± sprawê t³umaczyæ pocz±tkuj±cym. Im wiêcej jednak cz³owiek
> programuje obiektowo, tym bardziej siê przekonuje, ¿e to nie ma nic
> wspólnego z prawd±. To jest jeden ze znaków rozpoznawczych, czy kto¶
> potrafi my¶leæ samodzielnie rzeczywi¶cie dysponuje do¶wiadczeniem
> zawodowym, czy recytuje z pamiêci wiedzê ksi±¿kow±.)

Dla mnie odnoszenie siê do rzeczywisto¶ci jest wygodn± praktyk±
w takich bezsensownych dyskusjach jak ta. Podobnie jak to siê czyni
w literaturze. Niektórzy jednak przyjmuj± ksi±¿kowe przyk³ady
za pewnik: "tak nale¿y modelowaæ rzeczywiste systemy". I to jest
rzeczywi¶cie smutne.

>
> Cofaj±c jednak t± ca³± dygresjê, któr± nie wiem po co wprowadzi³e¶ -
> poda³em ci tylko przyk³ad, dlaczego portfel nie mo¿e byæ typem
> warto¶ciowym.
>
> Je¶li nie zrozumia³e¶ nadal, to wyt³umaczê ci bardziej ³opatologicznie:
> portfel zawieraj±cy tyle samo pieniêdzy, to nie ten sam portfel (mówiê
> tak, bo twierdzi³e¶, ¿e ilo¶æ pieniêdzy mo¿e byæ warto¶ci± potrfela).

Mo¿e byæ. Je¶li zastanawia³bym siê "czy to ten sam portfel" to rozwa¿a³bym
to¿samo¶æ a nie warto¶æ portfela. Rozumiesz?

>> > Ilo¶æ pieniêdzy nie jest warto¶ci± portfela. Jest jego stanem. Portfel
>> > nie mo¿e mieæ warto¶ci - i to nie dlatego, ¿e poza tym mo¿e mieæ
>> > jeszcze wiele innych stanów i atrytbutów.

Taki poda³e¶ wcze¶niej argument. Dla mnie podzia³ na obiekty warto¶ciowe
i niewarto¶ciowe jest sztuczny, ¿eby nie powiedzieæ nieistniej±cy, wiêc
nie dziw siê, ¿e opornie pod±¿am za t± teori±.

>> Wychodz±c z tego za³o¿enia stanem "obiektu" "klasy" int jest np. 2. Stan
>> ten mo¿na zmieniæ "funkcj±" zmiany stanu, np. ++.
>> Kto z nas nie rozró¿nia warto¶ci od stanu?
>
> int x = 2;
> int y = 2;
>
> Powiedz mi teraz, czy "x jest y".

W C++? Nie. Odsy³am do Stroustrupa jakie mechanizmy tego jêzyka tutaj
zadzia³a³y, a przestaniesz zadawaæ takie pytania.

>> >> > Typem warto¶ciowym mo¿e byæ kolor. Porównanie dwóch obiektów typu
>> >> > kolor mo¿na porównaæ ze sprawdzeniem, czy na dwóch kartkach papieru
>> >> > zapisany tam kod koloru jest ten sam. Ty chcesz, ¿eby przed
>> >> > odczytaniem numeru z ka¿dej kartki najpierw sprawdziæ, czy te obie
>> >> > kartki to czasem nie jest jedna i ta sama kartka. Jaki to ma sens?
>> >
>> >> Id±c Twoj± logik±: niekoniecznie. Obiekt kolor ma jeszcze atrybuty:
>> >> data naniesienia, technika wykonania i stopieñ nas³onecznienia, które
>> >> pozwalaj± obliczyæ rzeczywisty kolor w czasie :> Wtedy nie da siê
>> >> porównaæ dwóch "czerwonych". Odsy³am do ekspertów - lakierników
>> >> samochodowych.
>> >
>> > Nie przypominam sobie, ¿ebym mówi³ o lakierze samochodowym. Mówi³em o
>> > kolorze. Kolor mo¿e byæ równie¿ atrybutem (a nie warto¶ci±, acz
>> > przypadkiem te¿ nie stanem) lakieru.
>
>> Ja tylko poszed³em Twoj± logik±. Zwa¿, ¿e w systemie, o którym pisa³em
>> przy portfelu nie wspomina³em o istnieniu kart kredytowych.
>
> Nie poszed³e¶ moj± logik±. Mówi³em o kolorze, a ty wzi±³e¶ sobie nie wiem
> po co lakier samochodowy.

Oj, lakier to ju¿ by³a taka wisienka na torcie. Ka¿dy kolor p³owieje
w rzeczywisto¶ci, a wiêc... (odsy³am parê akapitów wy¿ej).

> Podobnie typem warto¶ciowym mog± byæ "pieni±dze". Ale nie kieszeñ,
> portfel, konto, sejf, czy gdzie to tam jeszcze chcesz przechowywaæ.
>
>> > No to jak, zrozumia³e¶ ju¿, co to takiego jest warto¶æ, czy douczysz
>> > siê i zg³osisz za tydzieñ?
>
>> Do kogo mia³bym siê zg³osiæ?
>
> No có¿, wydawa³o mi siê, ¿e ka¿dy, kto studiowa³, s³ysza³ to s³ynne
> okre¶lenie. W czym¶ siê widaæ pomyli³em.

Nie mierz innych swoj± miar±. Nie przypominam sobie, ¿eby który¶ z
wyk³adowców musia³ siê w ten sposób nade mn± litowaæ.

>
>> >> >> Z tym, ¿e w obu przypadkach nie chodzi o "przykr± konieczno¶æ", a
>> >> >> o "wspania³± mo¿liwo¶æ" szybkiego stwierdzenia, ¿e chodzi o "te
>> >> >> same" a wiêc na pewno "takie same" obiekty.
>> >> >
>> >> > To jest przykra konieczno¶æ. Musisz to po prostu zrobiæ, bo inaczej
>> >> > bêdzie wylot.
>> >
>> >> W operatorze porównania? Nie s±dzê...
>> >
>> > W operatorze przypisania.
>
>> Co mia³oby sprawiæ "wylot" w operatorze przypisania?
>
> Sprawdzenie, czy nie przypisujemy samego siebie. Fakt, ¿e musisz u¿yæ
> operatora porównania dla to¿samo¶ci jest przykr± konieczno¶ci±, bo bez
> tego usun±³by¶ czê¶æ obiektu, z którego za chwilê masz zamiar czytaæ.

Zagadnienie pomocnicze

int a;

a = a;

Pytanie: co nast±pi wcze¶niej odczyt czy zapis warto¶ci a?
Ponawiam pytanie podstawowe: jaki wylot masz na my¶li?

>
>> >> > Ta "wspania³a mo¿liwo¶æ" z kolei powoduje dro¿sze porównanie.
>> >
>> >> W pewnych przypadkach mo¿e tak byæ.
>> >
>> > Statystycznie jest to 99% przypadków.
>
>> Statystycznie, to ja bijê swoj± ¿onê co miesi±c. Ty, je¶li jeste¶ ¿onaty
>> równie¿. Takie szacunki trzeba robiæ dla konkretnych klas a nie
>> generalizowaæ.
>
> No widzisz. A ja mogê sobie pozwoliæ na generalizacjê.

Mo¿esz. Ale nie wpieraj, ¿e jest ona poprawna.

> Chodzi o bardzo prost± rzecz: jakiej wielko¶ci jest zwykle typ
> warto¶ciowy? Niewielkiej. Musi byæ niewielki, bo im wiêkszy, tym wiêcej
> zasobów zajmuje jego warto¶æ, d³u¿ej siê kopiuje, a i porównanie warto¶ci
> - dosæ czêsta operacja - trwa do¶æ d³ugo. Dlatego w³a¶nie typy warto¶ciowe
> robi siê z za³o¿enia JAK NAJMNIEJSZE - w³a¶nie po to, ¿eby te operacje
> by³y jak najszybsze. Skoro istnieje taka presja na obiekty warto¶ciowe, to
> gdzie masz w takim razie pole dla obiektów, w których porównanie mo¿na
> "przyspieszyæ" poprzez najpierw sprawdzanie to¿samo¶ci?

To jest przypadek szczególny a nie ogólny. Nie twierdzê jednak, ¿e przypadek
odwrotny, czyli taki jest ogólny, uniwersalny i najlepszy.

>
>> >> Implementuj±c operator warto
>> >> oszacowaæ prawdopodobieñstwo porównywania tych samych obiektów.
>> >
>> > Zrób sobie ma³± statystykê u¿ycia takiego typu i ilo¶æ porównañ, dla
>> > których trafiasz na równo¶æ i dla których trafiasz na nierówno¶æ.
>> >
>> > Prosty przyk³ad - iteratory. Masz pêtlê, w której przechodzisz przez
>> (...)
>> >
>> > Poda³em ci tylko przyk³ad, jak nale¿y prowadziæ tak± analizê - to, ¿e
>> > ten przyk³ad jest negatywny dla twojej tezy, nie ma znaczenia. My¶lê,
>> > ¿e da³oby siê znale¼æ przyk³ad, który by twoj± tezê potwierdza³, ale to
>> > nie ma wiêkszego znaczenia.
>
>> Nie bêdê ani analizowa³ Twojego przyk³adu, ani mu zaprzecza³. Zak³adam,
>> ¿e jest s³uszny. To jednak tylko przyk³ad, z którego do sformu³owania
>> regu³y jeszcze daleko.
>
> To by³ przyk³ad wykonania analizy, który pokaza³, ¿e siê nie op³aca. Czy
> jeste¶w stanie podaæ mi kontrprzyk³ad - czyli taki, który udowodni, ¿e siê
> op³aca?

Proponujê przypomnieæ sobie na czym polega³ _dowód_, a nie przyk³ad
potwierdzaj±cy s³uszno¶æ danego twierdzenia.

>> > W odró¿nieniu od ciebie jednak, ja rozumiem konieczno¶æ wykonania
>> > analizy, która dowiedzie, czy to siê nam op³aca, czy nie. Ty
>> > przyjmujesz "w ciemno", ¿e sprawdzanie najpierw to¿samo¶ci bêdzie
>> > zawsze bardziej op³acalne. W ostateczno¶ci zgadzasz siê nawet, ¿e
>> > "najczê¶ciej".

Je¶li przyjmowanie w ciemno to f(n), to jeste¶ zaledwie na etapie f(n)-1.
Warto by³o siê napracowaæ?

>> Ty dla odmiany uwa¿asz, ¿e najczê¶ciej nie. Na razie jednak nie potrafisz
>> udowodniæ dlaczego Twoja teza jest lepsza od mojej.
>
> Potrafiê, tylko ty nie potrafisz jej zrozumieæ, albo uparcie zaprzeczasz
> faktom.

Nie zaprzeczam, tylko wskazujê, ¿e s± to zaledwie pojedyncze fakty, a nie
ogólna zale¿no¶æ. Nawet nie: nie zaprzeczam zale¿no¶ci, ale Twojemu
sposobowi pseudodowodzenia.

> Moja teza jest lepsza, bo jest oparta na rzetelnej analizie (nb. analiza
> Qrczaka równie¿). Twoja teza, ¿e to jest "oczywiste, ¿e tak siê powinno
> zawsze robiæ" nie jest poparta niczym.

Nic takiego nie napisa³em. Oczywiste jest dla mnie, ¿e nie zawsze powinno
siê robiæ tak jak Ty piszesz.

>> > No to podaj mi przyk³ad typu warto¶ciowego, w którym to siê op³aca, i
>> > oszacuj ilo¶æ porównañ trafionych i nietrafionych w typowych
>> > algorytmach, które go u¿ywaj±. Wtedy bêdziemy wiedzieli, o czym
>> > rozmawiamy.
>
>> Nie chodzi o sam typ, tylko kontekst u¿ycia.
>
> Brawo! Zatem s³ucham.

U¿ycie typu jako klucza w hash mapie.

>> >> Generalnie jednak - nie zgadzam siê.
>> >
>> > Ale¿ masz pe³ne prawo siê nie zgadzaæ. Ja w odró¿nieniu od ciebie
>> > potrafiê to uzasadniæ.
>
>> W odró¿nieniu od Ciebie unikam jednoznacznych stwierdzeñ na temat swoich
>> umiejêtno¶ci.
>
> Z t± "oczywisto¶ci±", ¿e operator porównania powinien najpierw sprawdziæ
> to¿samo¶æ, niespecjalnie ci to wysz³o.

W wiêkszo¶ci przypadków, je¶li analiza wyka¿e, ¿e siê op³aca. Nie przekrêcaj
moich s³ów.

>> > Przyk³adowo, typ przechowywany w std::list musi byæ typem warto¶ciowym.
>> > Niestety, tak jest skonstruowany szablon std::list. ¦wiadcz± o tym
>> > nastêpuj±ce wymagania wzglêdem typu:
>> >  - przypisywalny
>> >  - kopiowalny
>> >  - domy¶lnie-konstruowalny
>
>> Rozumiem, ¿e je¶li stworzê sobie jaki¶ widget, powiedzmy combo-box, który
>> spe³nia powy¿sze wymagania, to nie bêdê móg³, go przechowywaæ w
>> std::list, bo pogwa³cê Twoj± teoriê?
>
> Nie. Bo jak wykonasz na nim algorytm std::remove, to zdrowo siê zdziwisz,
> co po tym powsta³o.

Nie pisa³em nic o chêci u¿ycia któregokolwiek z algorytmów.

>> >> >> > Je¶li mówimy ju¿ o rzeczywisto¶ci - podaj mi przyk³ad obiektu z
>> >> >> > rzeczywisto¶ci, który posiada jednocze¶nie warto¶æ i to¿samo¶æ.
>> >> >
>> >> >> Konto bankowe. To¿samo¶æ: numer, warto¶æ: saldo.
>> >> >
>> >> > Oraz warto¶æ: w³a¶ciciel (mo¿na go potem kiedy¶ zmieniæ)
>> >> > Oraz obiekt: historia transakcji
>> >> > Oraz...
>> >
>> >> Jak wy¿ej: zale¿y od kontekstu.
>> >
>> > Nic nie zale¿y od ¿adnego kontekstu.
>> >
>> > Saldo jest stanem (cz±stkowym) konta. Saldo jest warto¶ci±. Konto jest
>> > obiektem.
>
>> Niepotrzebnie wi±¿esz terminy z ¿ycia (stan konta) z terminami
>> informatycznymi (stan obiektu). Osobom z ma³ym do¶wiadczeniem to siê
>> czêsto zdarza, nie przejmuj siê.
>
> Parafrazuj±c, "Skoñczy³ siê czas argumentów. Teraz jest czas inwektyw".

Trafi³em widzê na wra¿liwca.

> A mo¿e tak co¶ do tematu?
>
>> >> Mo¿emy nie wi±zaæ obiektów transakcji do
>> >> konta, a zrobiæ wi±zanie odwrotne: ka¿da transakcja ma referencjê do
>> >> konta.
>> >
>> > Ale co to ma do rzeczy?
>
>> To, ¿e obiekt konto nie musi przechowywaæ historii, je¶li tylko zechcê
>> tak to zamodelowaæ.
>
> No mo¿e, i nadal, co z tego?

Guzik. Polecam lecytynkê, bo nie pamiêtasz ju¿ co napisa³e¶ kilka postów
temu i dlaczego staram siê uwaliæ pomys³, ¿e konto _musi_ przechowywaæ to
tamto i sramto.

>
>> >> > Czy ty w ogóle wiesz, co to jest "warto¶æ"?
>> >
>> >> Element ze zbioru (tu: typ, klasa).
>> >
>> > To znaczy?
>
>> Odsy³am do ksi±¿ki "Matematyka dla klas drugich".
>
> Có¿, osobliwy masz wybór literatury do nauki programowania, ale to ju¿ nie
> moja sprawa.

Widzê, ¿e pozycja, o której wspomnia³em jest Ci obca. W przeciwnym razie
wiedzia³by¶, ¿e nie ma tam s³owa o programowaniu.

--
Mariusz Lotko
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
#15297
Author: Sektor van Skijl
Date: Fri, 16 Mar 2007 16:39
435 lines
17389 bytes
Dnia Thu, 15 Mar 2007 06:12:44 +0100, Mariusz Lotko skrobie:
> Sektor van Skijlen wrote:

> >> > Swiss army knife to by by³o, gdyby ten portfel móg³ przechowywaæ
> >> > pieni±dze, laptopy, meble, samochody, kontenery i elektrownie.
> >
> >> Nie. Swiss army knife oznacza, ¿e modelujesz wszystkie elementy
> >> rzeczywisto¶ci czy tego wymaga system czy nie.
> >
> > Nie wiem, jak ty, ale ja pojêcie "swiss army knife" znam jako jeden z
> > b³êdów OO, który polega na stworzeniu klasy o zbyt du¿ym zakresie
> > odpowiedzialno¶ci.

> Ja te¿. Dlaczego uwa¿asz, ¿e modelowanie wiêkszej czê¶ci rzeczywisto¶ci
> od wymaganej nie jest "zbyt du¿ym zakresem odpowiedzialno¶ci"?

Bo odpowiedzialno¶æ jest jedna, niezale¿nie od dok³adno¶ci modelowania.

> > Dok³adno¶æ modelowania to zupe³nie inna sprawa.

> Inny bêdzie poziom szczegó³owo¶ci klasy Samochód w kartotece
> samochodów w Urzêdzie Miasta, a inny w kartotece warsztatu
> samochodowego.

To nie ma znaczenia.

> > Zreszt±, je¶li dla ciebie programowanie obiektowe jest modelowaniem
> > rzeczywisto¶ci, to obawiam siê, ¿e mo¿emy nasz± dyskusjê wznowiæ za parê
> > lat, jak bêdziesz ju¿ mówi³ jêzykiem w³asnego do¶wiadczenia, a nie
> > ksi±¿kowym.

> I znowu za³o¿enia... Za³ó¿ przez chwilê, ¿e nie jeste¶ jednak
> nieomylny.

Ja tylko stwierdzam fakt.

> > (Na marginesie: to bardzo dobrze, ¿e literatura do OO twierdzi, ¿e
> > programowanie obiektowe jest modelowaniem rzeczywisto¶ci. Tak bowiem
> > nale¿y t± sprawê t³umaczyæ pocz±tkuj±cym. Im wiêcej jednak cz³owiek
> > programuje obiektowo, tym bardziej siê przekonuje, ¿e to nie ma nic
> > wspólnego z prawd±. To jest jeden ze znaków rozpoznawczych, czy kto¶
> > potrafi my¶leæ samodzielnie rzeczywi¶cie dysponuje do¶wiadczeniem
> > zawodowym, czy recytuje z pamiêci wiedzê ksi±¿kow±.)

> Dla mnie odnoszenie siê do rzeczywisto¶ci jest wygodn± praktyk±
> w takich bezsensownych dyskusjach jak ta.

Wygodn±, ale niekoniecznie w³a¶ciw±. Bo wiele systemów i szczegó³ów
definicyjnych nie posiada odniesienia w rzeczywisto¶ci. Mo¿na wiêc
rzeczywisto¶æ przywo³ywaæ dla porównania ("przypowie¶ci"), ale nie do
dowodzenia.

> > Cofaj±c jednak t± ca³± dygresjê, któr± nie wiem po co wprowadzi³e¶ -
> > poda³em ci tylko przyk³ad, dlaczego portfel nie mo¿e byæ typem
> > warto¶ciowym.
> >
> > Je¶li nie zrozumia³e¶ nadal, to wyt³umaczê ci bardziej ³opatologicznie:
> > portfel zawieraj±cy tyle samo pieniêdzy, to nie ten sam portfel (mówiê
> > tak, bo twierdzi³e¶, ¿e ilo¶æ pieniêdzy mo¿e byæ warto¶ci± potrfela).

> Mo¿e byæ. Je¶li zastanawia³bym siê "czy to ten sam portfel" to rozwa¿a³bym
> to¿samo¶æ a nie warto¶æ portfela. Rozumiesz?

To ty nie rozumiesz.

Typ warto¶ciowy jest typem, którego obiekt jest identyfikowany zawsze przez
warto¶æ. Wiêc je¶li portfel z t± sam± ilo¶ci± pieniêdzy nie jest tym samym
portfelem, to portfel nie jest typem warto¶ciowym.

> >> > Ilo¶æ pieniêdzy nie jest warto¶ci± portfela. Jest jego stanem. Portfel
> >> > nie mo¿e mieæ warto¶ci - i to nie dlatego, ¿e poza tym mo¿e mieæ
> >> > jeszcze wiele innych stanów i atrytbutów.

> Taki poda³e¶ wcze¶niej argument. Dla mnie podzia³ na obiekty warto¶ciowe
> i niewarto¶ciowe jest sztuczny, ¿eby nie powiedzieæ nieistniej±cy, wiêc
> nie dziw siê, ¿e opornie pod±¿am za t± teori±.

To jest wyja¶nienie, nie argument. Je¶li jeste¶ betonowy na t± teoriê, to ja
ci nic nie poradzê. Nie powiem, ¿eby mnie to martwi³o.

> >> Wychodz±c z tego za³o¿enia stanem "obiektu" "klasy" int jest np. 2. Stan
> >> ten mo¿na zmieniæ "funkcj±" zmiany stanu, np. ++.
> >> Kto z nas nie rozró¿nia warto¶ci od stanu?
> >
> > int x = 2;
> > int y = 2;
> >
> > Powiedz mi teraz, czy "x jest y".

> W C++? Nie. Odsy³am do Stroustrupa jakie mechanizmy tego jêzyka tutaj
> zadzia³a³y, a przestaniesz zadawaæ takie pytania.

No i jakie twoim zdaniem mechanizmy jêzyka tu zadzia³a³y?

Oczywi¶cie, ¿e x to jest y. Dowód:

int f( int ); // dowolna funkcja deterministyczna i bezstanowa
f( x ) == f( y ) // zawsze prawdziwe

> >> >> > Typem warto¶ciowym mo¿e byæ kolor. Porównanie dwóch obiektów typu
> >> >> > kolor mo¿na porównaæ ze sprawdzeniem, czy na dwóch kartkach papieru
> >> >> > zapisany tam kod koloru jest ten sam. Ty chcesz, ¿eby przed
> >> >> > odczytaniem numeru z ka¿dej kartki najpierw sprawdziæ, czy te obie
> >> >> > kartki to czasem nie jest jedna i ta sama kartka. Jaki to ma sens?
> >> >
> >> >> Id±c Twoj± logik±: niekoniecznie. Obiekt kolor ma jeszcze atrybuty:
> >> >> data naniesienia, technika wykonania i stopieñ nas³onecznienia, które
> >> >> pozwalaj± obliczyæ rzeczywisty kolor w czasie :> Wtedy nie da siê
> >> >> porównaæ dwóch "czerwonych". Odsy³am do ekspertów - lakierników
> >> >> samochodowych.
> >> >
> >> > Nie przypominam sobie, ¿ebym mówi³ o lakierze samochodowym. Mówi³em o
> >> > kolorze. Kolor mo¿e byæ równie¿ atrybutem (a nie warto¶ci±, acz
> >> > przypadkiem te¿ nie stanem) lakieru.
> >
> >> Ja tylko poszed³em Twoj± logik±. Zwa¿, ¿e w systemie, o którym pisa³em
> >> przy portfelu nie wspomina³em o istnieniu kart kredytowych.
> >
> > Nie poszed³e¶ moj± logik±. Mówi³em o kolorze, a ty wzi±³e¶ sobie nie wiem
> > po co lakier samochodowy.

> Oj, lakier to ju¿ by³a taka wisienka na torcie.

Jasne, bagatelizuj i konfabuluj, bo ¿adne argumenty ci ju¿ nie zosta³y.

> Ka¿dy kolor p³owieje
> w rzeczywisto¶ci, a wiêc... (odsy³am parê akapitów wy¿ej).

Kolory nie p³owiej±. P³owiej± substancje koloruj±ce, czyli zmieniaj± one
kolory.

Ju¿ widzê, z czym masz problem. Ty przede wszystkim nie wiesz, czym jest
kolor, albo czym jest liczba. Skoro tak, to nigdy nie zrozumiesz, co to
takiego typ warto¶ciowy.

> > Podobnie typem warto¶ciowym mog± byæ "pieni±dze". Ale nie kieszeñ,
> > portfel, konto, sejf, czy gdzie to tam jeszcze chcesz przechowywaæ.
> >
> >> > No to jak, zrozumia³e¶ ju¿, co to takiego jest warto¶æ, czy douczysz
> >> > siê i zg³osisz za tydzieñ?
> >
> >> Do kogo mia³bym siê zg³osiæ?
> >
> > No có¿, wydawa³o mi siê, ¿e ka¿dy, kto studiowa³, s³ysza³ to s³ynne
> > okre¶lenie. W czym¶ siê widaæ pomyli³em.

> Nie mierz innych swoj± miar±. Nie przypominam sobie, ¿eby który¶ z
> wyk³adowców musia³ siê w ten sposób nade mn± litowaæ.

Zale¿y na jakiej uczelni studiowa³e¶.

> >> >> >> Z tym, ¿e w obu przypadkach nie chodzi o "przykr± konieczno¶æ", a
> >> >> >> o "wspania³± mo¿liwo¶æ" szybkiego stwierdzenia, ¿e chodzi o "te
> >> >> >> same" a wiêc na pewno "takie same" obiekty.
> >> >> >
> >> >> > To jest przykra konieczno¶æ. Musisz to po prostu zrobiæ, bo inaczej
> >> >> > bêdzie wylot.
> >> >
> >> >> W operatorze porównania? Nie s±dzê...
> >> >
> >> > W operatorze przypisania.
> >
> >> Co mia³oby sprawiæ "wylot" w operatorze przypisania?
> >
> > Sprawdzenie, czy nie przypisujemy samego siebie. Fakt, ¿e musisz u¿yæ
> > operatora porównania dla to¿samo¶ci jest przykr± konieczno¶ci±, bo bez
> > tego usun±³by¶ czê¶æ obiektu, z którego za chwilê masz zamiar czytaæ.

> Zagadnienie pomocnicze

> int a;

> a = a;

> Pytanie: co nast±pi wcze¶niej odczyt czy zapis warto¶ci a?
> Ponawiam pytanie podstawowe: jaki wylot masz na my¶li?

W ogólno¶ci zale¿y to od definicji operatora przypisania.

W przypadku int argument przyjmowany jest przez warto¶æ. Ale to nie musi byæ
regu³a, nawet dla typów warto¶ciowych. Np. std::string jest typem
warto¶ciowym, a jego operator przypisania przyjmuje argument przez referencjê.
I wtedy musisz sprawdziæ.

> >> >> > Ta "wspania³a mo¿liwo¶æ" z kolei powoduje dro¿sze porównanie.
> >> >
> >> >> W pewnych przypadkach mo¿e tak byæ.
> >> >
> >> > Statystycznie jest to 99% przypadków.
> >
> >> Statystycznie, to ja bijê swoj± ¿onê co miesi±c. Ty, je¶li jeste¶ ¿onaty
> >> równie¿. Takie szacunki trzeba robiæ dla konkretnych klas a nie
> >> generalizowaæ.
> >
> > No widzisz. A ja mogê sobie pozwoliæ na generalizacjê.

> Mo¿esz. Ale nie wpieraj, ¿e jest ona poprawna.

Nie wpieram, tylko twierdzê.

> > Chodzi o bardzo prost± rzecz: jakiej wielko¶ci jest zwykle typ
> > warto¶ciowy? Niewielkiej. Musi byæ niewielki, bo im wiêkszy, tym wiêcej
> > zasobów zajmuje jego warto¶æ, d³u¿ej siê kopiuje, a i porównanie warto¶ci
> > - dosæ czêsta operacja - trwa do¶æ d³ugo. Dlatego w³a¶nie typy warto¶ciowe
> > robi siê z za³o¿enia JAK NAJMNIEJSZE - w³a¶nie po to, ¿eby te operacje
> > by³y jak najszybsze. Skoro istnieje taka presja na obiekty warto¶ciowe, to
> > gdzie masz w takim razie pole dla obiektów, w których porównanie mo¿na
> > "przyspieszyæ" poprzez najpierw sprawdzanie to¿samo¶ci?

> To jest przypadek szczególny a nie ogólny. Nie twierdzê jednak, ¿e przypadek
> odwrotny, czyli taki jest ogólny, uniwersalny i najlepszy.

Zgadza siê - bo takiego tutaj nie ma. Wszystkie przypadki tutaj s± szczególne.

Ale przypadek, o którym ja wspomnia³em, mimo szczególno¶ci, wystêpuje w
przewa¿aj±cej wiêkszo¶ci sytuacji, a to, co ty poda³e¶, jest akurat do niego
odwrotny - co w zupe³no¶ci nie przeszkadza ci twierdziæ, ¿e jest przypadkiem
ogólnym.

> >> >> Implementuj±c operator warto
> >> >> oszacowaæ prawdopodobieñstwo porównywania tych samych obiektów.
> >> >
> >> > Zrób sobie ma³± statystykê u¿ycia takiego typu i ilo¶æ porównañ, dla
> >> > których trafiasz na równo¶æ i dla których trafiasz na nierówno¶æ.
> >> >
> >> > Prosty przyk³ad - iteratory. Masz pêtlê, w której przechodzisz przez
> >> (...)
> >> >
> >> > Poda³em ci tylko przyk³ad, jak nale¿y prowadziæ tak± analizê - to, ¿e
> >> > ten przyk³ad jest negatywny dla twojej tezy, nie ma znaczenia. My¶lê,
> >> > ¿e da³oby siê znale¼æ przyk³ad, który by twoj± tezê potwierdza³, ale to
> >> > nie ma wiêkszego znaczenia.
> >
> >> Nie bêdê ani analizowa³ Twojego przyk³adu, ani mu zaprzecza³. Zak³adam,
> >> ¿e jest s³uszny. To jednak tylko przyk³ad, z którego do sformu³owania
> >> regu³y jeszcze daleko.
> >
> > To by³ przyk³ad wykonania analizy, który pokaza³, ¿e siê nie op³aca. Czy
> > jeste¶w stanie podaæ mi kontrprzyk³ad - czyli taki, który udowodni, ¿e siê
> > op³aca?

> Proponujê przypomnieæ sobie na czym polega³ _dowód_, a nie przyk³ad
> potwierdzaj±cy s³uszno¶æ danego twierdzenia.

Nie przypominam sobie ¿adnego dowodu.

> >> > W odró¿nieniu od ciebie jednak, ja rozumiem konieczno¶æ wykonania
> >> > analizy, która dowiedzie, czy to siê nam op³aca, czy nie. Ty
> >> > przyjmujesz "w ciemno", ¿e sprawdzanie najpierw to¿samo¶ci bêdzie
> >> > zawsze bardziej op³acalne. W ostateczno¶ci zgadzasz siê nawet, ¿e
> >> > "najczê¶ciej".

> Je¶li przyjmowanie w ciemno to f(n), to jeste¶ zaledwie na etapie f(n)-1.
> Warto by³o siê napracowaæ?

A jeste¶ w stanie to udowodniæ? To s³ucham.

> >> Ty dla odmiany uwa¿asz, ¿e najczê¶ciej nie. Na razie jednak nie potrafisz
> >> udowodniæ dlaczego Twoja teza jest lepsza od mojej.
> >
> > Potrafiê, tylko ty nie potrafisz jej zrozumieæ, albo uparcie zaprzeczasz
> > faktom.

> Nie zaprzeczam, tylko wskazujê, ¿e s± to zaledwie pojedyncze fakty, a nie
> ogólna zale¿no¶æ. Nawet nie: nie zaprzeczam zale¿no¶ci, ale Twojemu
> sposobowi pseudodowodzenia.

To nie jest dowód, a przedstawiona teoria nie jest zale¿no¶ci±.

Jest to tylko stwierdzenie poprawne w statystycznej wiêkszo¶ci przypadków -
ale to nie ma znaczenia. Ty uparcie twierdzisz, ¿e odwrotne postêpowanie jest
przypadkiem ogólnym, wiêc w ogólno¶ci ¿eby twoje bzdury obaliæ wystarczy mi
podaæ jeden przyk³ad. Fakt, ¿e ten przyk³ad reprezentuje wiêkszo¶æ
statystyczn± nie ma tu nawet znaczenia.

> > Moja teza jest lepsza, bo jest oparta na rzetelnej analizie (nb. analiza
> > Qrczaka równie¿). Twoja teza, ¿e to jest "oczywiste, ¿e tak siê powinno
> > zawsze robiæ" nie jest poparta niczym.

> Nic takiego nie napisa³em. Oczywiste jest dla mnie, ¿e nie zawsze powinno
> siê robiæ tak jak Ty piszesz.

Dobra, dyskusja zaczyna mi siê nudziæ, skoro zaczynasz zaprzeczaæ swoim
niedawnym stanowczym wypowiedziom (równie stanowczo zreszt±).

> >> > No to podaj mi przyk³ad typu warto¶ciowego, w którym to siê op³aca, i
> >> > oszacuj ilo¶æ porównañ trafionych i nietrafionych w typowych
> >> > algorytmach, które go u¿ywaj±. Wtedy bêdziemy wiedzieli, o czym
> >> > rozmawiamy.
> >
> >> Nie chodzi o sam typ, tylko kontekst u¿ycia.
> >
> > Brawo! Zatem s³ucham.

> U¿ycie typu jako klucza w hash mapie.

No fajnie - czyli, jak rozumiem, masz taki klucz, którego porównanie z
istniej±cym zaczynasz od sprawdzenia to¿samo¶ci klucza? No dobrze. Jak zatem
wygl±da definicja typu klucza?

> >> >> Generalnie jednak - nie zgadzam siê.
> >> >
> >> > Ale¿ masz pe³ne prawo siê nie zgadzaæ. Ja w odró¿nieniu od ciebie
> >> > potrafiê to uzasadniæ.
> >
> >> W odró¿nieniu od Ciebie unikam jednoznacznych stwierdzeñ na temat swoich
> >> umiejêtno¶ci.
> >
> > Z t± "oczywisto¶ci±", ¿e operator porównania powinien najpierw sprawdziæ
> > to¿samo¶æ, niespecjalnie ci to wysz³o.

> W wiêkszo¶ci przypadków, je¶li analiza wyka¿e, ¿e siê op³aca. Nie przekrêcaj
> moich s³ów.

O analizie to dopiero ja zacz±³em mówiæ, wiêc nie wmawiaj, ¿e cokolwiek
takiego twierdzi³e¶.

Jestem i tak za leniwy, ¿eby zajrzeæ do wcze¶niejszych wiadomo¶ci i
skompromitowaæ ciê twoimi wcze¶niejszymi wypowiedziami.

Poza tym, podoba mi siê to: w wiêkszo¶ci przypadków, je¶li analiza wyka¿e, ¿e
siê op³aca. Super. Analiza mo¿e wykazaæ, ¿e w 90% przypadków siê nie op³aca,
ale to i tak te 10% to bêdzie dla ciebie wiêkszo¶æ.

> >> > Przyk³adowo, typ przechowywany w std::list musi byæ typem warto¶ciowym.
> >> > Niestety, tak jest skonstruowany szablon std::list. ¦wiadcz± o tym
> >> > nastêpuj±ce wymagania wzglêdem typu:
> >> >  - przypisywalny
> >> >  - kopiowalny
> >> >  - domy¶lnie-konstruowalny
> >
> >> Rozumiem, ¿e je¶li stworzê sobie jaki¶ widget, powiedzmy combo-box, który
> >> spe³nia powy¿sze wymagania, to nie bêdê móg³, go przechowywaæ w
> >> std::list, bo pogwa³cê Twoj± teoriê?
> >
> > Nie. Bo jak wykonasz na nim algorytm std::remove, to zdrowo siê zdziwisz,
> > co po tym powsta³o.

> Nie pisa³em nic o chêci u¿ycia któregokolwiek z algorytmów.

Dobrze, zrób sobie cokolwiek - nawet sortowanie (sortowanie listy jest
algorytmem wewnêtrznym listy, a nie ogólnym), scalanie z inn± list±, czy
cokolwiek innego.

Pomijaj±c ju¿ fakt, jak zamierzasz okre¶liæ "kopiowalno¶æ" wid¿etu, oraz jak
zamierzasz okre¶liæ jego porównywalno¶æ (potrzebn± do find) i porz±dkowalno¶æ
(potrzebn± do sort).

W ró¿nych przypadkach, przy ró¿nych operacjach, funkcje operuj±ce na li¶cie
potrafi± ci skopiowaæ okre¶lony obiekt, przechowaæ kopiê w obiekcie
tymczasowym i wrzuciæ do listy, a stary usun±æ - tak w³a¶nie dzia³a np.
sortowanie, czy odwracanie (w szczególno¶ci wszystkie algorytmy zmieniaj±ce, w
tym równie¿ algorytmy zaimplementowane jako metody listy).

> >> >> >> > Je¶li mówimy ju¿ o rzeczywisto¶ci - podaj mi przyk³ad obiektu z
> >> >> >> > rzeczywisto¶ci, który posiada jednocze¶nie warto¶æ i to¿samo¶æ.
> >> >> >
> >> >> >> Konto bankowe. To¿samo¶æ: numer, warto¶æ: saldo.
> >> >> >
> >> >> > Oraz warto¶æ: w³a¶ciciel (mo¿na go potem kiedy¶ zmieniæ)
> >> >> > Oraz obiekt: historia transakcji
> >> >> > Oraz...
> >> >
> >> >> Jak wy¿ej: zale¿y od kontekstu.
> >> >
> >> > Nic nie zale¿y od ¿adnego kontekstu.
> >> >
> >> > Saldo jest stanem (cz±stkowym) konta. Saldo jest warto¶ci±. Konto jest
> >> > obiektem.
> >
> >> Niepotrzebnie wi±¿esz terminy z ¿ycia (stan konta) z terminami
> >> informatycznymi (stan obiektu). Osobom z ma³ym do¶wiadczeniem to siê
> >> czêsto zdarza, nie przejmuj siê.
> >
> > Parafrazuj±c, "Skoñczy³ siê czas argumentów. Teraz jest czas inwektyw".

> Trafi³em widzê na wra¿liwca.

A ja, jak widzê, trafi³em na kogo¶ zakompleksionego, kto musi siê
dowarto¶ciowaæ przez pomiatanie innymi.

> > A mo¿e tak co¶ do tematu?

Czyli, jak rozumiem, nie masz nic do powiedzenia "do tematu"?

> >> >> Mo¿emy nie wi±zaæ obiektów transakcji do
> >> >> konta, a zrobiæ wi±zanie odwrotne: ka¿da transakcja ma referencjê do
> >> >> konta.
> >> >
> >> > Ale co to ma do rzeczy?
> >
> >> To, ¿e obiekt konto nie musi przechowywaæ historii, je¶li tylko zechcê
> >> tak to zamodelowaæ.
> >
> > No mo¿e, i nadal, co z tego?

> Guzik. Polecam lecytynkê, bo nie pamiêtasz ju¿ co napisa³e¶ kilka postów
> temu i dlaczego staram siê uwaliæ pomys³, ¿e konto _musi_ przechowywaæ to
> tamto i sramto.

No ok. I nadal, co z tego?

Czy chcesz mo¿e doj¶æ do tego, ¿eby konto nie przechowywa³o niczego, co nie
jest niezbêdne, ¿eby mog³o byæ typem warto¶ciowym? Ju¿ ci powiedzia³em: konto
nie bêdzie nigdy typem warto¶ciowym, ¿eby¶ siê nawet zesra³.

> >> >> > Czy ty w ogóle wiesz, co to jest "warto¶æ"?
> >> >
> >> >> Element ze zbioru (tu: typ, klasa).
> >> >
> >> > To znaczy?
> >
> >> Odsy³am do ksi±¿ki "Matematyka dla klas drugich".
> >
> > Có¿, osobliwy masz wybór literatury do nauki programowania, ale to ju¿ nie
> > moja sprawa.

> Widzê, ¿e pozycja, o której wspomnia³em jest Ci obca. W przeciwnym razie
> wiedzia³by¶, ¿e nie ma tam s³owa o programowaniu.

Jest mi, owszem, obca. Kiedy ja chodzi³em do "klasy drugiej", ta pozycja
nazywa³a siê inaczej.


Móg³bym siê jeszcze trochê na tobie powy¿ywaæ, bo póki co rozmowa z tob± nadal
mnie bawi, ale spróbujmy wróciæ do tematu - im bli¿ej tematu tym zawsze siê
bardziej kompromitujesz.

No wiêc, co to takiego jest "warto¶æ"?


--
//  _    ___         Michal "Sektor" Malecki <sektor(whirl)kis.p.lodz.pl>
\\ L_ |/ `|  /^\ ,()                         <ethouris(O)gmail.com>
// \_ |\  \/ \_/ /\ C++ bez cholesterolu: http://www.intercon.pl/~sektor/cbx
"Java is answer for a question that has never been stated"
Page 1 of 2 • 79 total messages
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads