Formalna definicja terminu „czysty język OO”?

13

Nie mogę wymyślić lepszego miejsca wśród rodzeństwa SO, aby postawić takie pytanie. Początkowo chciałem zapytać „Czy python jest czystym językiem OO?” ale biorąc pod uwagę problemy i pewien dyskomfort, jaki ludzie odczuwają, próbując zdefiniować termin, postanowiłem zacząć od uzyskania jasnej definicji samego terminu.

Byłoby raczej uczciwe zacząć od korespondencji dr Alana Kay, który wymyślił ten termin (zauważ inspirację w analogii biologicznej do komórek lub innych żywych obiektów).

Istnieją następujące sposoby podejścia do zadania:

  1. Podaj analizę porównawczą, wymieniając języki programowania, które mogą wykazywać (lub nie potrafią tego zrobić), pewne właściwości unikalne i wystarczające do zdefiniowania tego terminu (chociaż Smalltalk, Scala, Java itd. - to możliwe przykłady, ale IMO w ten sposób nie wydaje się tak naprawdę kompletne ani owocne )
  2. Podaj formalną definicję (lub blisko niej, np. W bardziej akademickim lub matematycznym stylu).
  3. Podaj filozoficzną definicję, która całkowicie opierałaby się na semantycznym kontekście konkretnego języka lub doświadczeniu programowania a priori (musi istnieć pewna szansa na skuteczne wyjaśnienie przez społeczność).

Moja obecna wersja: „Jeśli określony język programowania ( formalny ), który może ( gramatycznie ) rozróżniać operacje i operandy, a także wnioskować o typie każdego operandu, czy ten typ jest obiektem (w sensie OOP), czy nie, wówczas wywołujemy taki język jest językiem OO, o ile istnieje co najmniej jeden typ w tym języku, który jest przedmiotem. Wreszcie, jeśli wszystkie typy języka są również obiektami, definiujemy taki język jako czysty (silny) język OO. ”

Byłbym wdzięczny za każdą możliwą poprawę. Jak widać, właśnie uzależniłem definicję od terminu „obiekt” (często w pełni określany jako klasa obiektów).

[EDYTOWAĆ]

Ponadto używam (na szczęście dobrze rozumianego) pojęcia typu jak w językach pisanych na maszynie. Programowanie typu danych lub programowanie zorientowane na typ jest nie tylko interpretacją składniową (tekstu programu, tj. Jak traktować pewne wartości literałów i zmiennych danych - coś, co ewoluuje w bezpieczeństwo typu), ale można je przypisać gramatyce języka i studiować formalnie (z wykorzystaniem logiki matematycznej) jako tak zwane systemy typów . Zauważ, że wymaganie od określonego systemu typów tak zwanego typu uniwersalnego jest jednym ze sposobów określających czystość języka OO (istnieją sposoby rozszerzenia tego semantycznie).

NB

jak odpowiedzieć :

  • pomaga, jeśli podasz książkę lub odniesienie, które wspierają / wyjaśniają twoje rozumienie terminologii i pojęć (zwykle dobra definicja obejmuje lub odwołuje się do wszystkich pojęć zależnych oprócz elementarnych).
  • jeśli to możliwe, wskaż wciętą kategorię swojej odpowiedzi / definicji, jeśli nie jest jasne inaczej (patrz wyżej: 1 - według przykładu językowego, 2 - logiki matematycznej, 3 - opisu technicznego i filozofii programowania)
  • Klasyfikacja jest ważne (a także dlatego, że określenie czysta-oo, wchodzi określenie OO) odpowiadając Spróbuj unmix elementów OO paradygmatu innych dobrze znanych sposobów (i w żadnym wypadku nie mylić / pokrywają się je, na przykład zwykle elementy programowania modułowej mogą być pokryte / wcielony w programowanie OO): spróbuj odróżnić OOP od (w tym lub będącego częścią) programowania funkcjonalnego, programowania logicznego (szczególnie silnie wyspecjalizowanego), typów danych Abstarct (ADT), modułowego, metaprogramowania (generics i czas makroekspresji LISP), Kontrakty (np. Eiffel), aspektowe (AO), (różnica między klasyfikacją deklaratywną i funkcjonalną, a także historyczne definicje struktury Dijkstry są jasne)

na trudność podania formalnej definicji : co zaskakujące, bardzo łatwo jest podać matematyczny opis OOP w postaci pewnego logicznego (formalnego) systemu (najprawdopodobniej opartego na typie) i definiowania jednej koncepcji po drugiej. Można nawet spróbować zrobić coś bardziej praktycznego poprzez stosowanie tego formalizmu do kontroli bezpieczeństwa typ lub nowych aspektów projektu język niż tylko abstrakcyjnego rozrywki lub ćwiczeń (również odnośników formułowania OOP w intuicjonistycznej Type Theory , zależnych rodzaju , niezależnie, w formalizmach fol jak lambda rachunku i po prostu za pomocą teorii kategorii). Najważniejsze jest to, że nic dziwnegotakie sformułowania IMO są silnie stronnicze (błędne) przez najprawdopodobniej początkowo niepełne zrozumienie OOP (w inżynierii komputerowej), a następnie stają się prawie niedostępne (a więc prawie nie przyczyniają się wstecz do świata programowania - być może z wyjątkiem pewnego procentu znalezienie aplikacji z powrotem ze świata formalnego przez bycie zintegrowane z popularnymi językami ).

Tak, trudno jest podać dokładnie „dobrą” definicję, a nie tylko definicję. Ale jestem pewien, że pytam o to tutaj z powodu twojego doświadczenia i bezpośredniego zaangażowania, chłopaki.

Yauhen Yakimovich
źródło
2
Cóż, sam odpowiedziałeś na Python. "Nie".
psr
2
+1 za fajne pytanie, ale twoja wersja jest nieco wadliwa z powodu problemu, że typ i obiekt to różne rzeczy.
Frank
5
@JachachSSerer: W innym mailu na liście mailingowej Squeak powiedział, że „wielkim pomysłem jest Messaging” i żałuje, że kiedykolwiek nazwał to „Object-Oriented” i raczej powinien nazwać to „Oriented Message”. Na przykład Erlang jest językiem całkowicie zorientowanym obiektowo, który spełnia wszystkie kryteria dr Kay, nie mając pojęcia o „obiektach”, „metodach”, „dziedziczeniu”, „klasach”, „prototypach” ani czegoś takiego .
Jörg W Mittag,
1
To może być ładna ilustracja, że ​​składnie nie wystarczą do zdefiniowania języka OO. Jeśli można pokazać, że OOP (np. Jako narzędzie) ma charakter semantyczny (niezależny od składni), to całkowicie zmienia (odwraca) moje pytanie!
Yauhen Yakimovich
2
@YauhenYakimovich Jest to jeden z głównych problemów w omawianiu OOP, każdy i jego pies mają własne wyobrażenie o tym, co to jest. Natomiast programowanie strukturalne i programowanie funkcjonalne można zdefiniować bardzo prosto. To prowadzi mnie do pytania, czy OO ma podobne właściwości do religii zamiast do nauki.
Ricky Clarkson

Odpowiedzi:

19

OO, według Alana Kay chodzi o przekazywanie wiadomości i to wszystko. Przekonasz się, że cechy, takie jak polimorfizm i enkapsulacja, faktycznie pochodzą z przekazywania wiadomości.

Teraz ta postawa jest w rzeczywistości bardzo ekstremalna, ponieważ w zasadzie oznacza, że ​​kwalifikują się tylko Smalltalk i języki.

Myślę, że można zdefiniować OO jako budowanie systemu na bytach, które całkowicie otaczają ich stan i które są wymienialne ze względu na ich nieodłączne cechy polimorficzne. Można zatem argumentować, że język wyłącznie OO zapewnia, że ​​te dwie podstawowe cechy są zawsze spełnione. To, co czyni języki OO „nieczystymi”, to mechanizmy pozwalające na tworzenie konstrukcji niespełniających tych kryteriów, takie jak:

  • zadeklaruj pola publiczne
  • deklarują zmienne, które mogą przechowywać tylko instancje konkretnej klasy i jej podklas (tj. zmienne powinny być pisane na interfejsach, przez co komunikują się obiekty biologiczne w anologii Kay), który jest jeszcze węższy, jeśli dana klasa jest ostateczna, ponieważ co pozostawia jeszcze mniej miejsca na polimorfizm
  • deklarować prymitywy

Z drugiej strony, czystość języka IMHO jest bardziej słabością niż siłą. OO nie jest srebrną kulą. Nie ma jednego paradygmatu.

back2dos
źródło
2
+1 dla „OO nie jest srebrną kulą”.
Andres F.
1
@AndresF. Należy zauważyć, że praktyczna wartość OOP, a także inna wiedza teoretyczna związana z programowaniem, tak naprawdę nie jest częścią pytania. Oczywistym jest, że można pisać kod z dużym powodzeniem bez jakiegokolwiek głębokiego zrozumienia technik programowania lub teorii (i na odwrót). Nie omówiono też właściwości aplikacji w językach OO itp.
Yauhen Yakimovich,
@YauhenYakimovich Oh, wiem. Nie głosowałbym za odpowiedzią, gdyby była nie na temat. Mimo to podobało mi się stwierdzenie, z którym się zgadzam.
Andres F.,
@AndresF. Pewnie :-) „OO nie jest srebrną kulą” jest najprawdopodobniej prawdą, a także brak nam doskonałego języka programowania. Ale co dokładnie sprawia, że ​​OOP nie jest srebrną kulą? Uważam, że tak samo jak dobry raport o błędzie, szczegółowa i precyzyjna terminologia jest sposobem na rozwiązanie tego problemu. Zainwestowałem tyle czasu w pracę z nim, że jestem cholernie ciekawy, aby przenieść go na wyższy poziom. Czy OOP to tylko kilka pomysłów skopiowanych z jednej książki programowej do drugiej?
Yauhen Yakimovich
@ back2dos +1 za wyraźne wskazanie roli „przekazywania wiadomości” według Kay (Smalltalk, Objective-C). Najwyraźniej nigdy nie zamierzał widzieć, jak OOP rozwija się w kierunku, który ma dzisiaj. Ale naprawdę podobało mi się, że Kay miał te pomysły, aby obiekty NIE były danymi (typami). Naprawdę naciskał, aby przypisać im właściwości biologiczne, ale skończył na „przesyłaniu wiadomości”.
Yauhen Yakimovich
6

Podchodziłbym do tego, definiując go jako język, który wykorzystuje konstrukcje OOP i nic więcej (w taki sam sposób, w jaki czysty język FP używa czystych funkcji z niezmiennymi danymi i niczym więcej).

W szczególności:

  • Każda jednostka, na której działa Twój program, jest Obiektem pierwszej klasy - tj. Bez prymitywów, bez wskaźników, bez tablic itp.
  • Jedyne, co możesz zrobić z obiektem, to wywołanie na nim metody (potencjalnie polimorficznej) (== wysłanie wiadomości). Nie istnieją żadne inne operacje.
  • Wszystkie dane są hermetyzowane - tzn. Brak publicznego dostępu do pola, musisz przejść metodami na obiekcie
  • Jeśli masz funkcje pierwszej klasy, muszą to być również obiekty - więc musisz zrobić coś takiegofunctionObject.call(param1,param2)
  • Brak zmiennych globalnych - jeśli chcesz czegoś takiego, musisz użyć obiektu do przedstawienia bieżącego środowiska globalnego, np. environment.getValue("myThing")Lub umieścić zmienną w obiekcie klasy

Zauważ, że wciąż pozostawia to wiele otwartych opcji:

  • Modele obiektowe vs. prototypowe
  • Jak wdrażane jest dziedziczenie (jeśli w ogóle)
  • Niezależnie od tego, czy masz jedną, czy wiele wysyłek metodami
  • Niezależnie od tego, czy Twoje obiekty są wpisywane statycznie czy dynamicznie
  • Dokładna składnia używana w wywołaniach metod (np. Możesz mieć cukier syntaktyczny dla getterów / setterów itp.)
mikera
źródło
1
są to dobre definicje, ale nie myl rzeczywistości obiektowej ze zwykłą składnią. Tylko dlatego, że funkcje i zmienne globalne mają przyjazną składnię, mogą być obiektami w sercu.
ddyer
@ddyer - to prawda, jeśli jest to po prostu składnia, ale myślę, że jeśli ta składnia wprowadza także inną semantykę, to może złamać „czystość”. Na przykład, wrt zmienne globalne użycie globalVariableNamedo uzyskania dostępu do zmiennej globalnej jest innym semantycznym niż wywołanie metody na obiekcie, co byłoby jedynym sposobem na uzyskanie dostępu do nielokalnej wartości w czystym OOP.
mikera
Myślę, że „wszystko” wymaga kwalifikacji. Jeśli język w ogóle nie ma zdolności refleksyjnej (na przykład nie może odwoływać się do metody obiektu abstrakcyjną nazwą lub przechowywać go w zmiennej), to czy metody również muszą być obiektami? Czy obiekty referencyjne są obiektami? Czy referencje i obiekty są nawet różnymi rzeczami?
Joachim Sauer
@Jachachim - dobry punkt. Kwalifikowałem go jako „każdy byt, na którym działa Twój program”, aby odróżnić obiekty od meta-obiektów w języku, takie jak nazwy zmiennych i konstrukcje składniowe. Oczywiście, jeśli twój program faktycznie działa na takich rzeczach poprzez odbicie, wówczas trzeba je reifikować jako rzeczywiste obiekty, ale nie zawsze będzie to wymagane. W każdym razie, jeśli możesz pomyśleć o lepszych kwalifikacjach, możesz je edytować!
mikera
„Modele obiektowe oparte na klasach vs. prototypowe”: ale powiedziałbym, że w obu przypadkach istnieje pewien rodzaj klasyfikacji, tj. Grupuje się obiekty o wspólnej strukturze i zachowaniu.
Giorgio
4

Dyskusja na temat tak zwanych języków OO zawsze była nieco sprana. To znaczy:

„Ktoś powiedział mi, że język X to OO, więc język X jest równy OO, więc każdy język, który nie ma cech języka X, nie może być OO. A ponieważ piszę mój kod w języku X, wszystko co robię, to OO. „

Pojęcie projektowania obiektowego sprowadza się do 3 rzeczy:

  1. Modułowa konstrukcja z autonomicznymi obiektami, które nie znają niepotrzebnych informacji o reszcie programu, czyli tak luźne sprzężenie, jak to możliwe.
  2. Hermetyzacja danych wewnątrz obiektów w celu uniemożliwienia zewnętrznego dostępu, zarówno celowego, jak i przypadkowego.
  3. Wyraźnie określone zależności między obiektami. Aby osiągnąć luźne sprzężenie, ale także ułatwić programowi utrzymanie i rozszerzenie.

1) to czysty program, można go osiągnąć w dowolnym języku programowania. Jednak niektóre języki mają przydatne funkcje, takie jak class / struct i prywatne słowa kluczowe.

2) jest głównie projektowaniem programu, choć nie można go w pełni osiągnąć bez obsługi języka, ponieważ potrzebujesz mechanizmów językowych, takich jak prywatny / statyczny, aby zabezpieczyć się przed przypadkowym użyciem.

3) dotyczy głównie projektowania programu. Istnieją zwykle trzy różne zależności: „obiekt X zawiera obiekt Y”, „obiekt X jest rodzajem Y”, a „obiekt X współdziała z obiektem Y”. Istnieje wiele funkcji językowych pomocnych w tych zależnościach: dziedziczenie / polimorfizm, abstrakcyjne klasy podstawowe i tak dalej.

Teraz, jeśli spojrzymy na powyższe, widzimy, że ledwo potrzebujesz żadnych funkcji językowych, aby pisać programy OO. Funkcje sprawiają, że jest to o wiele łatwiejsze.

Powyższych celów nie można osiągnąć za pomocą jakiejś mętnej logiki wstecznej: tylko dlatego, że używasz słowa kluczowego class, twój program nie otrzymuje automatycznie modułowej konstrukcji. Tylko dlatego, że używasz dziedziczenia, nie oznacza to automatycznie, że zależność twoich obiektów ma sens. Język z funkcjami OO nadal pozwalałby na takie rzeczy jak class TheWholeBloodyProgram„Animal inherits Cat”.

Niestety temat dobrego projektowania obiektowego jest rzadko omawiany w tego rodzaju dyskusjach. Programiści, którzy mają pranie mózgu, patrzą tylko na składnię i ignorują takie rzeczy, jak na przykład „C ++ ma prymitywne typy danych, więc twój program C ++ nie jest OO”, a następnie zaczynają pisać wręcz okropny program w swoim ulubionym języku, bez żadnej wskazówki projektowanie programów, jak nigdy dotąd.

Aby odpowiedzieć na pytanie: bardzo niewielu, jeśli jakieś języki mają wsparcie dla prawidłowego projektowania programu OO. Dowiedz się, które języki mają pewne funkcje związane z OO, nie ma znaczenia, dopóki programista nie wie, co oznacza projektowanie obiektowe. Programista twierdzący, że niektóre języki są obiektowe, najprawdopodobniej nie zrozumiał koncepcji OO jako całości. Zapytaj przyszłego programistę OO, jak projektują programy OO. Jeśli najpierw zaczną krzyczeć słowa kluczowe w języku, możesz spokojnie założyć, że nie znają projektowania OO.

Być może istnieje jakieś fantazyjne narzędzie wysokiego poziomu UML znacznie powyżej surowego kodu źródłowego, które zmusza programistę do pisania programów tylko z dobrym projektowaniem obiektowym, ale wątpię w to. Najlepszym narzędziem do programowania OO jest najprawdopodobniej ludzki mózg i zdrowy rozsądek.


źródło
Czy możesz wyjaśnić, czym różni się twoja definicja, np. Programowanie modułowe z abstrakcyjnymi typami danych? Myślę, że jesteś na dobrej drodze, ale nie widzę jeszcze pociągu!
Jörg W Mittag,
@ JörgWMittag Niekoniecznie jest inaczej, tradycyjne ADT: s mogą być pisane przy użyciu projektowania obiektowego, z odpowiednią enkapsulacją, ustawieniami / getterami, sposobami dziedziczenia itp. Ale mogą być również napisane bez względu na projekt OO. ->
2
@ JörgWMittag Jeśli masz język taki jak C, na przykład z ograniczoną obsługą języka dla OO, trudno jest napisać ADT w sposób obiektowy. Najczęstszym błędem jest pozostawienie alokacji ADT dzwoniącemu, tzn. Nadanie im struktury publicznej z odsłoniętymi wszystkimi elementami wewnętrznymi, co przerywa enkapsulację. Właściwy sposób na zrobienie tego w C to tak zwane „typy nieprzezroczyste” (typy niekompletne), choć niewielu programistów C wie, jak z nich korzystać.
@Lundin: W artykule opublikowanym przez JörgWMittag jako komentarz do innej odpowiedzi istnieje (IMO) ciekawe porównanie między ADT i OO.
Giorgio
Pamiętam z niektórych książek UML (prawdopodobnie) dodatkowy punkt 0. Abstrakcyjność (podkreślając znaczenie abstrakcyjnego sformułowania istotnego dla relacji między obiektami, takich jak polimorfizm, dziedziczenie, agregacja itp.).
Yauhen Yakimovich
2

Nie, nie ma formalnej ani nawet użytecznej definicji i nigdy nie będzie. Dla niektórych osób OOP oznacza „uniwersalną klasę podstawową” i „należy stosować semantykę referencyjną, najlepiej z urządzeniem do wyrzucania elementów bezużytecznych” - a można nawet spierać się o składnię, jedną z najmniej istotnych rzeczy, jakie kiedykolwiek wymyślono.

Ostatecznie najpierw musisz odpowiedzieć na pytanie „Co to jest przedmiot?”. Bardziej ograniczeni będą nalegać na odziedziczenie po jakiejś bezsensownej uniwersalnej klasie bazowej i niepotrzebnie zostaną przydzieleni do śmieciarza, aby się zakwalifikować. Ale wolę znacznie bardziej przydatną definicję. Celem OOP jest posiadanie niektórych danych i niektórych funkcji, które można wywołać na tych danych. Więc

  • Obiekt posiada pewien stan i oferuje pewne funkcje w tym stanie.

W tym przypadku nawet się intkwalifikuje. W końcu, kiedy piszesz kod szablonu w C ++, który akceptuje prymitywy lub obiekty, trudno jest argumentować, że prymitywy różnią się w jakikolwiek istotny sposób. Vector v1, v2; v1 + v2;Zamiast tego nie ma nic istotnie odmiennego int v1, v2; v1 + v2;(oprócz gównianej semantyki inicjalizacji, trzeba przyznać). Ponadto pozwala to obiektom na lambdy i takie rzeczy, ponieważ utrzymują one stan - swoje przechwytywania - i oferują funkcję w tym stanie, aby wywołać lambda.

Na szczęście możemy również klasyfikować wskaźniki wolnych funkcji jako obiekty, ponieważ oba zawierają stan (adres) i funkcję w tym stanie (aby ją wywołać). Dlatego powinna być dozwolona funkcja bezpłatna - nawet gdybyś powiedział, że wszystkie funkcje bezpłatne są w rzeczywistości wskaźnikami funkcji globalnych.

DeadMG
źródło
2
Nie widzę potrzeby takiego rozróżnienia. Ale po drugie, mają taką samą tożsamość, jak każdy inny obiekt ma porównanie adresów / referencji. Fakt, że nie można rozróżnić dwóch obiektów o tym samym stanie, z wyjątkiem porównania adresów, jest daleki od nowego i dotyczy wszystkich obiektów.
DeadMG
5
-1. Zaczyna się bezużytecznym i niepotrzebnym rantem, wkrótce przechodzi na atak ad hominem i jedyne, nawet zdalnie faktyczne (definicja OOP ) jest błędne. Zapoznaj się z rozdziałem Understanding Data Abstraction, Revisited by William R. Cook, aby zobaczyć różnicę między abstrakcyjnym typem danych a obiektem.
Jörg W Mittag,
1
„Nie widzę potrzeby takiego rozróżnienia.”: Ale to rozróżnienie należy do powszechnie akceptowanych cech przedmiotów. Oczywiście możesz rozwinąć własne pojęcie obiektu, który różni się od tego, co jest powszechnie akceptowane. Możesz to zrobić całkowicie za darmo.
Giorgio
2
@ Jörg Zaczynam się różnić. Nie zgadzam się całkowicie z tym postem, ale nazywanie ostrzeżenia w pierwszym akapicie „bezużytecznym” lub „rantem” jest nieuczciwe. Nie ma powszechnie uzgodnionej definicji OOP. To prosty i powszechnie uznany fakt. Reszta postu jest definicja OOP. Z pewnością nie jest to najczęściej używany, ani ten, który podam, ale, jak powiedział DeadMG, w rzeczywistości całkiem przydatny.
Konrad Rudolph,
2
@KonradRudolph: ten akapit brzmiał zupełnie inaczej, kiedy pisałem mój komentarz, w tym porównując programistów, którym zależy na składni, z rasistami, nawet wspominając konkretnego użytkownika tej strony z nazwy.
Jörg W Mittag,
0

Możesz o tym myśleć negatywnym przykładem. Java nie jest czysto obiektowym językiem, ponieważ istnieją również prymitywne typy, które nie są obiektami. Są to liczby całkowite, podwójne, tablice i tak dalej. W czystym języku obiektowym semantyka obiektów jest dostępna na wszystko.

Pojawia się również pytanie, jak duża część języka jest zamknięta na modyfikację, nawet w ramach obiektowych. W java nie można zdefiniować nowych podklas dla niektórych klas, takich jak String lub Class.

Które języki są czyste? Jedynym kandydatem, który przychodzi na myśl, jest smalltalk.

ddyer
źródło
Czy Ruby nie jest też czystym językiem OO?
zxcdw
2
@zxcdw (i ddyer): to jest właśnie problem: nikt nie ma formalnej definicji „czystego OO”, więc nikt nie może udzielić jednoznacznej odpowiedzi na to pytanie.
Joachim Sauer