🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: pl.comp.objects
Article #15287

Re: Wartości i obiekty

#15287
From: 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/

Message-ID: <1173651323.19503.18.camel@qrnik>
Path: polish.pugleaf.net!archive.newsdeef.eu!mbox2nntp-pl.comp.objects.mbox.gz!number1.nntp.dca.giganews.com!border1.nntp.dca.giganews.com!nntp.giganews.com!newsfeed00.sul.t-online.de!t-online.de!news.nask.pl!news.nask.org.pl!newsfeed.tpinternet.pl!atlantis.news.tpi.pl!news.tpi.pl!not-for-mail
References: <pl-comp-objects-faq-1-1166202604@ict.pwr.wroc.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> <esuufm$jfv$1@kujawiak.man.lodz.pl> <1173568302.9234.25.camel@qrnik> <et178b$f2o$1@kujawiak.man.lodz.pl>