A miks dane <-> zachowania jest tak fundamentalny, że widzimy go zarówno w assemblerze jak i w haskellu.
Kodziłem zarówno w asemblerze (dużo) jak i w Haskellu (mało) i tam obiektówki raczej nie ma (no chyba, że jak robiłem okienka za pomocą win32api). Obiekt jest wtedy, kiedy za pomocą jednego uchwytu (czyli w praktyce referencji) możemy mieć dostęp zarówno do danych jak i funkcji na nich operujących.
Poniższy kod nie jest obiektowy, bo przetwarzajDane nie jest składową typu dane:
Kopiuj
var dane = posklejajDane(arg1, arg2, arg3, ..., argN);
przetwarzajDane(dane);
Poniższy kod jest obiektowy jeżeli metoda przetwarzaj jest polimorficzna (czyli de facto wirtualna):
Kopiuj
var dane = posklejajDane(arg1, arg2, arg3, ..., argN);
dane.przetwarzaj();
Gdyby w powyższym kodzie metoda przetwarzaj była metodą rozszerzającą czy też inną całkowicie statycznie wiązaną metodą to byłoby trochę dyskusyjne czy to bardziej OOP czy może cukier składniowy wyglądający jak OOP. Generalnie zapis xyz.abc() sugeruje prawie wszystkim obiektówkę, a zapis abc(xyz) kod nieobiektowy, ale to moim zdaniem zbytnie spłycanie paradygmatu obiektowego.
Rust ma typeclassy (które akurat w tym języku definiuje się za pomocą słówka kluczowego trait, a nie class jak w Haskellu), ale zamiast typowego dla Haskella zapisu np. sort list oferuje zapis list.sort(). Mimo iż ten zapis z Rusta wygląda jak obiektowy (dla kogoś kto kieruje się powierzchownością, czyli dla zdecydowanej większości programistów) to nadal (pomijając https://doc.rust-lang.org/reference/types/trait-object.html ) pozostaje nieobiektowy, bo opiera się na typeclassach (przy założeniu, że to sort jest polimorficzną metodą, czyli właśnie z typeclassy).
Typeclassy mają sens generalnie tylko przy językach statycznie typowanych (chodzi o sprawdzanie typów na etapie kompilacji, a reified generics nie mają tu znaczenia). Jednym z założeń typeclasses jest to, że się ich jawnie nie podaje (w sensie ich instancji). Zamiast tego to kompilator, na podstawie statycznie obliczonego typu, sam wyszukuje instancje typeclass i podaje je tam gdzie są potrzebne. Dzięki temu kod wygląda jakby struktury danych magicznie nabywały wbudowanych w nie metod, ale tak nie jest. Typeclassy są zadeklarowane (chodzi o interfejs) i zdefiniowane (chodzi o instancje) poza strukturami danych, więc nie ma OOPowego łączenia stanu i zachowania w jeden byt.