... i prawdopodobnie jest jednym z tych artykułów, na których oparto OOP.
Nie do końca, ale dodało to dyskusji, szczególnie dla praktyków, którzy w tym czasie byli szkoleni w zakresie rozkładania systemów według pierwszych kryteriów opisanych w artykule.
Najpierw chcę wiedzieć, czy moja ocena jest poprawna. Czy paradygmat FP i ten artykuł filozoficznie się nie zgadzają?
Nie. Ponadto, moim zdaniem, opis tego, jak wygląda program FP, nie różni się od żadnego innego, który wykorzystuje procedury lub funkcje:
Dane są przekazywane z funkcji do funkcji, przy czym każda funkcja jest ściśle świadoma danych i „zmienia je” po drodze.
... z wyjątkiem części „intymności”, ponieważ możesz (i często masz) funkcje działające na abstrakcyjnych danych, właśnie po to, aby uniknąć intymności. Tak więc masz pewną kontrolę nad tą „intymnością” i możesz ją regulować w dowolny sposób, konfigurując interfejsy (tj. Funkcje) dla tego, co chcesz ukryć.
Nie widzę więc żadnego powodu, dla którego nie moglibyśmy przestrzegać kryteriów ukrywania informacji Parnasa za pomocą programowania funkcjonalnego i skończyć na implementacji indeksu KWIC o podobnych wskazanych korzyściach jak jego druga implementacja.
Zakładając, że się zgadzają, chciałbym wiedzieć, czym jest implementacja ukrywania danych przez FP. Widać to wyraźnie w OOP. Możesz mieć prywatne pole, do którego nikt poza klasą nie ma dostępu. W FP nie ma dla mnie oczywistej analogii.
Jeśli chodzi o dane, możesz opracować abstrakcje danych i abstrakcje typów danych za pomocą FP. Każda z nich ukrywa konstrukcje betonowe i manipuluje nimi, wykorzystując funkcje jako abstrakcje.
EDYTOWAĆ
Coraz więcej twierdzeń mówi, że „ukrywanie danych” w kontekście FP nie jest tak przydatne (lub OOP-ish (?)). Pozwólcie, że wytłoczę tutaj bardzo prosty i jasny przykład z SICP:
Załóżmy, że Twój system musi działać z liczbami wymiernymi. Jednym ze sposobów przedstawienia ich jest para lub lista dwóch liczb całkowitych: licznika i mianownika. A zatem:
(define my-rat (cons 1 2)) ; here is my 1/2
Jeśli zignorujesz abstrakcję danych, najprawdopodobniej otrzymasz licznik i mianownik za pomocą car
i cdr
:
(... (car my-rat)) ; do something with the numerator
Zgodnie z tym podejściem wszystkie części systemu, które manipulują liczbami wymiernymi, będą wiedziały, że liczba wymierna to cons
- będą cons
numerować, aby tworzyć racjonalne liczby i wyodrębniać je za pomocą operatorów list.
Jednym z problemów, z którymi możesz się spotkać, jest konieczność zredukowania liczby racjonalnych liczb - konieczne będą zmiany w całym systemie. Ponadto, jeśli zdecydujesz się zmniejszyć w czasie tworzenia, możesz później odkryć, że zmniejszenie przy dostępie do jednego z racjonalnych warunków jest lepsze, co daje kolejną zmianę na pełną skalę.
Innym problemem jest to, że hipotetycznie preferowana jest alternatywna reprezentacja dla nich i użytkownik zdecyduje się porzucić cons
reprezentację - zmiana w pełnej skali ponownie.
Każdy rozsądny wysiłek w radzeniu sobie z tymi sytuacjami prawdopodobnie zacznie ukrywać reprezentację racjonalności za interfejsami. Na koniec możesz otrzymać coś takiego:
(make-rat <n> <d>)
zwraca liczbę wymierną, której licznikiem jest liczba całkowita, <n>
a której mianownikiem jest liczba całkowita <d>
.
(numer <x>)
zwraca licznik liczby wymiernej <x>
.
(denom <x>)
zwraca mianownik liczby wymiernej <x>
.
i system nie będzie już (i nie powinien) wiedzieć, z czego są racjonalne. Wynika to z faktu cons
, car
i cdr
nie są nierozerwalnie związane z wymiernych, ale make-rat
, numer
i denom
to . Oczywiście może to być z łatwością system FP. Zatem „ukrywanie danych” (w tym przypadku lepiej znane jako abstrakcja danych lub próba enkapsulacji reprezentacji i konkretnych struktur) stanowi istotną koncepcję i technikę szeroko stosowaną i badaną, czy to w kontekście OO, programowania funkcjonalnego czy cokolwiek.
Chodzi o to ... chociaż można próbować rozróżnić, jaki rodzaj ukrywania lub enkapsulacji dokonują (czy ukrywają decyzję projektową, czy struktury danych lub algorytmy - w przypadku abstrakcji proceduralnych), wszystkie mają ten sam motyw: są motywowane przez jeden lub więcej punktów, które Parnas wyraził wyraźnie. To jest:
- Możliwość zmiany: czy wymagane zmiany mogą być wprowadzone lokalnie, czy rozłożone w systemie.
- Niezależny rozwój: w jakim stopniu dwie części systemu mogą być rozwijane równolegle.
- Zrozumiałość: jaka część systemu musi być znana, aby zrozumieć jedną z jego części.
Powyższy przykład został zaczerpnięty z książki SICP, więc w celu pełnej dyskusji i prezentacji tych koncepcji w książce bardzo polecam sprawdzenie rozdziału 2 . Polecam również zapoznanie się z abstrakcyjnymi typami danych w kontekście FP, co przedstawia inne problemy.