Kto z was słyszał, że Java nie jest prawdziwym językiem OOP *dlatego*, że posiada prymitywy?

0

@koszalek-opalek: albo masz jakiegoś aktora. Aktor się wysypał i supervisor postawił nowego aktora. Czy ten nowy aktor ma teraz jakiś inny kontrakt z pozostałymi aktorami skoro Twoim zdaniem ma inną tożsamość? Przecież ma inną referencję.

4

Lepszym obrazkowym przykładem byliby chyba bliźniacy i np. transy, jeśli ktoś lubi obrazkowe przykłady :P Dwóch 100% identycznych bliźniaków ma oddzielne tożsamości, bo są osobnymi ludźmi, mimo że mają w 100% identyczną "zawartość" (tutaj upraszczam, ale załóżmy, że tak jest). Z drugiej strony, jeśli ktoś zmieni kolor skóry (jak Majkel Dżekson ;) ), płeć, obywatelstwo, itp itd to dalej pozostaje tą samą osobą, chociaż nie taką samą. Zachowuje tożsamość, na którą wskazuje np. numer PESEL czy inne identyfikatory.

https://pl.wikipedia.org/wiki/To%C5%BCsamo%C5%9B%C4%87_obiektu

Tożsamość ma sens przede wszystkim w przypadku referencji (czy innych uchwytów) do mutowalnych obiektów (mogą być nawet opakowane w monadę IO). Tożsamość obiektów wskazywanych przez dwie referencje można porównać przez porównanie samych adresów. Można też sprawdzić tożsamość eksperymentalnie, np:

Osoba jaro = ...
Osoba kaczor = ...
// assert(jaro == kaczor); // zakładamy, że nie potrafimy porównywać adresów, bo to byłoby zbyt proste :]
assert(jaro.getGender() == kaczor.getGender()); // ok, pierwszy test przeszedł
// jeśli poniższa pętla przejdzie pomyślnie to jest prawie pewne, że obie referencje wskazują na ten sam obiekt, tzn. jaro i kaczor są tożsame
for (int i = 0; i < 100; i++) {
  jaro.setGender(Random.gender());
  assert(jaro.getGender() == kaczor.getGender());
}

sorry za przykład na czasie :P

Ewentualnie można też przeanalizować sens stwierdzeń typu "ujawniono tożsamość przestępcy". Oczywiście nie chodzi w tym, że udało się określić np. wygląd przestępcy (bo wygląd może się zmienić) tylko jego jednoznaczną unikalną identyfikację, która jest niezależna od jego działań.

Ciekawym przykładem są primitive classes (wcześniej znane jako value classes czy inline classes, jak widać nie mogą się zdecydować) w Project Valhalla: https://openjdk.java.net/projects/valhalla/ wchodzący powoli np. jako https://openjdk.java.net/jeps/401 JEP 401: Primitive Objects (Preview). W tym JEPie jest napisane np. tak:

Summary
Enhance the Java object model with user-declared primitive objects, which are class instances that lack object identity and can be stored and passed directly, without object headers or indirections.

Goals
This JEP proposes substantial changes to the Java programming language and the Java virtual machine, including:
Providing for the declaration of identity-free primitive classes and specifying the behavior of these classes' instances, called primitive objects, with respect to equality, synchronization, and other operations that currently depend upon identity.
Allowing operations on both primitive value types and primitive reference types, with seamless conversions between the two. Primitive value types enable storing and passing primitive objects without indirection. Primitive reference types enable polymorphism and null references when working with primitive objects.

Instancje klas prymitywnych nie mają tożsamości, niezależnie od tego czy są zmieszczone bezpośrednio w zmiennej (są inline) czy wpakowane na stertę jako obiekt (autoboxing). Operator == porównuje zawartość, a nie adresy instancji klas prymitywnych. Klasy prymitywne są też niemutowalne. Nie ma więc jak sprawdzić tożsamości eksperymentalnie (kaczor.setGender nie ma prawa zmienić stanu obiektu wskazywanego przez kaczor jeśli jest to instancja klasy prymitywnej). Dzięki temu JVM może zdeduplikować dwa oddzielne obiekty będące instancjami klas prymitywnych - skoro nie da się ich odróżnić (stwierdzić różnicy tożsamości) to można jeden zastąpić drugim.

1
twoj_stary_pijany napisał(a):

@koszalek-opalek: albo masz jakiegoś aktora. Aktor się wysypał i supervisor postawił nowego aktora. Czy ten nowy aktor ma teraz jakiś inny kontrakt z pozostałymi aktorami skoro Twoim zdaniem ma inną tożsamość? Przecież ma inną referencję.

Kontakt ma ten sam, ale tożsamość inną...? A jeśli inni aktorzy mają do tego wysypanego dostęp przez referencję (a więc po tożsamości), do nowego nie będą mieć dostępu i już.

0

@Wibowit: masz w artykule: "Tożsamość obiektu istnieje jednak nawet wówczas, gdy nie określono żadnego identyfikatora." Nie wiem dlaczego utożsamiacie tożsamość z referencją na obiekt.

Osoba może zmienić swój PESEL, można też zrobić przeszczep kończyn. Ok, może nie zrobisz przeszczepu mózgu albo pozostałego układu nerwowego. Ale np. w samochodzie możesz wymienić wszystkie elementy na nowe i czy będzie to ten sam samochód tożsamościowo?

@koszalek-opalek inni mogą się odnosić do aktora powiedzmy przez jakąś mapę aktorów, dla nich ten obiekt pod spodem to jest ten sam obiekt, pomimo tego, że został podmieniony wielokrotnie.

2

Pomijając różnorakie formy teleportacji, tożsamość jest zjawiskiem ciągłym, to znaczy nie przeskakuje z obiektu na obiekt. Każdy obiekt ma unikalną tożsamość albo (jeśli definicja obiektu na to pozwala) nie ma jej wcale (np. w niektórych językach liczba 5 jest obiektem, ale nie da się odróżnić osobnych instancji takiego obiektu). W przypadku gdy obiekt da się podzielić na kawałki jak w statku Tezeusza, trzeba zdecydować co jest wyznacznikiem tej tożsamości. Można też stwierdzić, że czegoś już nie ma i jest coś zupełnie nowego. Dla przykładu większość atomów z których się składam kiedyś prawdopodobnie była częścią jakichś roślin czy zwierząt. Czy nimi po części jestem? Nie. Te analogie do świata rzeczywistego i tak się sypią na którymś poziomie, tak jak analogie między klasami w OOPie i obiektami w świecie rzeczywistym. Drążenie zbyt głęboko zaprowadzi od razu do statku Tezeusza i dowolnie naciąganych wniosków. Mimo wszystko i tak w statku Tezeusza jest rozróżnienie na ten sam i taki sam. Wymiana jednej deski w statku sprawia, że jest nie jest dokładnie taki sam jak wcześniej, ale dalej można z całowitą pewnością powiedzieć, że to jest dokładnie ten sam statek (czyli na pewno zachował tożsamość).

Co do referencji do aktora, który się obrócił. Skoro masz cały czas jedną i tę samą referencję, która działa, a instancja klasy ze stanem aktora się tworzy od nowa, to znaczy, że nie masz referencji bezpośrednio do stanu aktora tylko co najwyżej do pewnego pojemnika, który tym stanem zarządza. Prawdopodobnie jednak referencja do aktora w ogóle nie definiuje bezpośrednio tożsamości (bo nie musi - ale np. referencja zawierająca adres w pamięci już definiuje tożsamość). Referencja do aktora to zwykle coś a'la URI. Zarówno dwie różne referencje do aktorów jak i dwa różne URI mogą prowadzić do tego samego obiektu i można to sprawdzić eksperymentalnie, tak jak w powyższym przykładzie z setGender/getGender. Dla przykładu jeden i ten sam aktor może mieć referencje dwóch typów - lokalną (bez nazwy hosta itd.) i zdalną (z pełnym adresem sieciowym).

Warte zacytowania też jest https://pl.wikipedia.org/wiki/To%C5%BCsamo%C5%9B%C4%87_obiektu (oczywiście jest mowa o mutowalnych obiektach lub chociażby sytuacji, w której np. można porównać ich adresy)

Każdy obiekt charakteryzuje się tożsamością, dzięki której jest odróżnialny od innych obiektów występujących w systemie, niezależnie od ich stanu (w szczególnym przypadku wszystkie obiekty mogą posiadać jednakowy stan, lecz w dalszym ciągu pozostają rozróżnialne). W trakcie cyklu życia obiektu tożsamość nie ulega zmianie.

A może inaczej da się to wyjaśnić (używając wymyślonych słów, ale chyba wiadomo o co chodzi):
tożsamość == tensamość
tożsamość != takisamość
:]

Jeśli dla kogoś (na intuicję) wydaje się, że powinno być odwrotnie, to niestety jest tak jak podałem powyżej. Analogicznie słowo spolegliwy kojarzy się z kimś, kto łatwo ulega, ale de facto słownikowa (ale nie potoczna) definicja słowa spolegliwy to:

  1. «taki, który wzbudza zaufanie i można na nim polegać»

Dopiero powszechne złe użycie tego słowa (wielu ludziom kojarzy się ze słowem uległy) doprowadziło do dodania do słownika alternatywnej opcji:

  1. pot. «taki, który łatwo ustępuje i podporządkowuje się innym»

Ja akurat (przynajmniej w przypadku słowa tożsamość) trzymam się formalnej definicji, a nie czegoś wydumanego na chłopski rozum.

0

@Wibowit: zacytuję Okasakiego

Any discussion of data structures is fraught with the potential for confusion, because the term data structure has at least four distinct, but related, meanings.
...

  • A unique identity that is invariant under updates. For example, in a stack-based interpreter, we often speak informally about "the stack" as if there were only one stack, rather than different versions at different times. We will refer to this identity as a persistent identity. This issue mainly arises in the context of persistent data structures; when we speak of different versions of the same data structure, we mean that the different versions share a common persistent identity.

Ale nie musisz czytać jego książki bo możesz czuć się niekomfortowo z jego chłopskim rozumem.

Edit: Strasznie się zafiksowaliście z tą tożsamością jakoby to była jakaś cecha definiująca programowanie obiektowe i niewystępująca nigdzie indziej. A tak nie jest. Nie wiem gdzie to w ogóle wyczytaliście.

1

No to żeś wyciągnął "asa" z rękawa. Persistent data structure identity? Kto i w którym miejscu o czymś takim pisał? Wyszperałeś gdzieś jakieś egzotyczne pojęcie tożsamości i zakładasz, że inni się domyślą o co ci chodzi? W tym wątku jest mowa o standardowym pojęciu tożsamości obiektu. Zresztą, nawet gdyby pominąć ten dziwny fragment o persistent data structures, to zostaje:

A unique identity that is invariant under updates. For example, in a stack-based interpreter, we often speak informally about "the stack" as if there were only one stack, rather than different versions at different times. We will refer to this identity as a persistent identity.

Czyli coś analogicznego do poprzednio podanych definicji, przy założeniu że stos interpretera jest mutowalny (a wszędzie w praktyce stosy w środowiskach uruchomieniowych są mutowalne, no chyba że znowu tutaj jest jakaś niespodzianka).

Znalazłem jakiś artykuł, który powołuje się na ten sam fragment co ty: https://maxheiber.medium.com/es2015-const-has-something-to-do-with-mutation-227852c010df
Gość rozróżnił w nim mutable identity od persistent identity. To mutable identity to jest to standardowe pojęcie tożsamości, które jest przytaczane w tym wątku (w sensie gość sobie zmienił nazwę lekko, ale sens pozostał). Persistent identity jest dziwnym pojęciem. Jak to zgugluję to widzę (oprócz masy nieprogramistycznych rzeczy) persistent identity dla mutowalnych wierszy w bazie danych (a przecież persistent identity miało być do niemutowalnych struktur danych, no nie?) albo do śledzenia użytkowników za pomocą cookies (a to już raczej daleka rzecz od obiektów w językach programowania).

W tym artykule jest taki przykład na Persistent Identity:

let list = [1, 2]
list = list.concat(3)
console.log(list) // [1, 2, 3]

Czyli [1, 2] jest tożsame z [1, 2, 3], bo obie wartości były osiągalne z tej samej zmiennej? Wychodzi na to, że to persistent identity to po prostu użycie tej samej zmiennej. Czyli każda zmienna ma osobną, unikalną persistent identity. A skoro zmienna, to i tak mamy programowanie imperatywne, albo chociaż efekt uboczny, no nie?

Według artykułu, zarówno w mutable identity jak i w persistent identity [1, 2] może być tożsame z [1, 2, 3] (w różnych momentach), stąd tak czy siak samo porównywanie zawartości nie jest sposobem na rozstrzygnięcie tożsamości. Tylko po co wprowadzać zamieszanie przez jakieś dziwne wariacje tożsamości?

Edit: Strasznie się zafiksowaliście z tą tożsamością jakoby to była jakaś cecha definiująca programowanie obiektowe i niewystępująca nigdzie indziej. A tak nie jest. Nie wiem gdzie to w ogóle wyczytaliście.

Tożsamość przecież rozpatrujemy w kontekście mutacji, a nie w kontekście OOPa. OOP jest tu tylko przykładem, równie dobrze można by użyć np. Rusta (można nawet machnąć w nim getterki i setterki) i dyskusja nt. tożsamości byłaby taka sama.

0

Co do pierwotnego pytania w wątku, to przypomniało mi ono taką już pół-kopalną ;) książkę "Object-Oriented Software Construction" (2 wydanie), w której przy poszczególnych koncepcjach czy mechanizmach jest stopniowo opisywany "idealny" język programowania, a są też odniesienia do innych języków, w tym nowej wtedy Javy, i ich krytyka.
Ten idealny język Eiffel świata nie podbił w przeciwieństwie do Javy, a jest w nim coś takiego:

A uniform type system handling both value and reference semantics in which all types, including basic types such as INTEGER, are class-based

1

A uniform type system handling both value and reference semantics in which all types, including basic types such as INTEGER, are class-based

Bez uściślenia co oznacza to class-based to jest to tylko niuansem. Dla Javy jest zaproponowany https://openjdk.java.net/jeps/402 JEP 402: Unify the Basic Primitives with Objects (Preview)

Goals
Migrate the eight wrapper classes (java.lang.Integer, java.lang.Double, etc.) to be reference-favoring primitive classes.
In the Java programming language, treat basic primitive values as instances of the migrated wrapper classes, and the primitive type keywords (int, double, etc.) as aliases for their primitive value types. Support method invocation, primitive reference conversion, and array covariance on these types.
In the Java virtual machine, treat the basic primitive array types as equivalent to the corresponding primitive object array types.
In the core reflection API, change the behavior of the eight Class objects representing the basic primitive types (int.class, double.class, etc.) to model their class declarations.

Jak widać nastąpi pewna unifikacja np. inta z java.lang.Integer i oba będą class-based.

W C# int od dawna jest podtypem Object, ale C# sobie pokombinował z nazewnictwem i int jest strukturą, a nie klasą :] Na jedno wychodzi w sumie, bo wszystko zależy od definicji pojęć w danym kontekście.

0

7 stron wątku. To jak to w końcu z tymi prymitywami i OOP xd

1 użytkowników online, w tym zalogowanych: 0, gości: 1