🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: pl.comp.objects
Article #15725

Re: Wartości i obiekty

#15725
From: Sektor van Skijlen
Date: Sat, 10 Mar 2007 18:47
192 lines
10593 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"
Technical Details
Message-ID: <esuufm$jfv$1@kujawiak.man.lodz.pl>
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!newsfeed.gazeta.pl!newsfeed.pionier.net.pl!news.man.lodz.pl!not-for-mail
References: <pl-comp-objects-faq-1-1166202604@ict.pwr.wroc.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> <1173310324.15622.77.camel@qrnik>

Show Full Headers
Complete Article Headers
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!newsfeed.gazeta.pl!newsfeed.pionier.net.pl!news.man.lodz.pl!not-for-mail
From: Sektor van Skijlen <ethouris@guess.if.gmail.com.is.valid.or.invalid>
Newsgroups: pl.comp.objects
Subject: Re: Wartości i obiekty
Date: Sat, 10 Mar 2007 18:47:18 +0000 (UTC)
Organization: LODMAN - Metropolitan Area Network in LODZ, Poland
Lines: 192
Sender: Michal Malecki <sektor@zly.kis.p.lodz.pl>
Message-ID: <esuufm$jfv$1@kujawiak.man.lodz.pl>
References: <pl-comp-objects-faq-1-1166202604@ict.pwr.wroc.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> <1173310324.15622.77.camel@qrnik>
NNTP-Posting-Host: zly.kis.p.lodz.pl
Mime-Version: 1.0
X-Trace: kujawiak.man.lodz.pl 1173552438 19967 212.191.89.2 (10 Mar 2007 18:47:18 GMT)
X-Complaints-To: abuse@man.lodz.pl
NNTP-Posting-Date: Sat, 10 Mar 2007 18:47:18 +0000 (UTC)
User-Agent: tin/1.6.2-20030910 ("Pabbay") (UNIX) (SunOS/5.9 (sun4u))
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit