Article View: pl.comp.objects
Article #15724Wartości i obiekty
From: Marcin 'Qrczak' Kowalczyk
Date: Wed, 07 Mar 2007 23:32
Date: Wed, 07 Mar 2007 23:32
112 lines
7604 bytes
7604 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/
Technical Details
Message-ID:
<1173310324.15622.77.camel@qrnik>Path:
mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!news.rmf.pl!agh.edu.pl!news.agh.edu.pl!news.onet.pl!newsfeed.tpinternet.pl!atlantis.news.tpi.pl!news.tpi.pl!not-for-mailReferences:
<pl-comp-objects-faq-1-1166202604@ict.pwr.wroc.pl> <pan.2007.02.26.21.12.45.8078@go2.pl> <es6b6u$2ls$1@kujawiak.man.lodz.pl> <esbllu$51n$1@bandai.magma-net.pl> <esbv7t$7o$1@kujawiak.man.lodz.pl> <1172940339.25227.28.camel@qrnik> <escc9e$2h2$1@kujawiak.man.lodz.pl> <esd1k1$9bp$1@bandai.magma-net.pl> <esemb6$2r3$1@kujawiak.man.lodz.pl> <eses6u$8fm$1@inews.gazeta.pl> <esf3am$r52$1@bandai.magma-net.pl> <esfg25$b2m$1@kujawiak.man.lodz.pl> <1173137761.17765.52.camel@qrnik> <esmtmk$ii1$1@kujawiak.man.lodz.pl>Show Full Headers
Complete Article Headers
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!news.rmf.pl!agh.edu.pl!news.agh.edu.pl!news.onet.pl!newsfeed.tpinternet.pl!atlantis.news.tpi.pl!news.tpi.pl!not-for-mail From: Marcin 'Qrczak' Kowalczyk <qrczak@knm.org.pl> Newsgroups: pl.comp.objects Subject: Wartości i obiekty Date: Thu, 08 Mar 2007 00:32:04 +0100 Organization: tp.internet - http://www.tpi.pl/ Lines: 177 Message-ID: <1173310324.15622.77.camel@qrnik> References: <pl-comp-objects-faq-1-1166202604@ict.pwr.wroc.pl> <pan.2007.02.26.21.12.45.8078@go2.pl> <es6b6u$2ls$1@kujawiak.man.lodz.pl> <esbllu$51n$1@bandai.magma-net.pl> <esbv7t$7o$1@kujawiak.man.lodz.pl> <1172940339.25227.28.camel@qrnik> <escc9e$2h2$1@kujawiak.man.lodz.pl> <esd1k1$9bp$1@bandai.magma-net.pl> <esemb6$2r3$1@kujawiak.man.lodz.pl> <eses6u$8fm$1@inews.gazeta.pl> <esf3am$r52$1@bandai.magma-net.pl> <esfg25$b2m$1@kujawiak.man.lodz.pl> <1173137761.17765.52.camel@qrnik> <esmtmk$ii1$1@kujawiak.man.lodz.pl> NNTP-Posting-Host: paf87.warszawa.sdi.tpnet.pl Mime-Version: 1.0 X-Trace: nemesis.news.tpi.pl 1173310562 2531 217.96.225.87 (7 Mar 2007 23:36:02 GMT) X-Complaints-To: usenet@tpi.pl NNTP-Posting-Date: Wed, 7 Mar 2007 23:36:02 +0000 (UTC) In-Reply-To: <esmtmk$ii1$1@kujawiak.man.lodz.pl> X-Mailer: Evolution 2.8.3 PLD Linux Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit