Modele mentalne lub rzeczywiste metafory programowania funkcjonalnego

16

Czy ktoś ma dobry model mentalny lub metaforę programowania funkcjonalnego, która odwołuje się do czegoś w prawdziwym świecie?

Intuicyjne programowanie obiektowe ma dla mnie sens. Są rzeczy, które mają właściwości, a czasem mogą także wykonywać różne czynności lub wykonywać obliczenia dotyczące ich właściwości (metod). (Np .: samochód, kształt, kot).

Noszę programowanie funkcjonalne, które nie jest złe i nie jestem zainteresowany debatą na temat zalet tych dwóch. Potrzebuję tylko metafory lub modelu mentalnego do pracy, tak jak w przypadku programowania obiektowego.

Jakie są dobre modele mentalne lub metafory świata rzeczywistego do programowania w funkcjonalnym paradygmacie? Jest coś w funkcjach składających się z funkcji przetwarzających funkcje, które pozostawiają jedną bez mocnego miejsca, aby stać i zastanawiać się.

Guido Anselmi
źródło
Które konkretne znaczenie „programowania funkcjonalnego” ma na myśli „brak efektów ubocznych / deklaratywny” lub „pierwszorzędne funkcje / skład funkcji”? Lub oba?
acelent
Interesujące pytanie. Z moją obecną niewielką wiedzą na temat „programowania funkcjonalnego” i niewielkim doświadczeniem w programowaniu, nie mogę w sposób znaczący odpowiedzieć na to pytanie. Gdybym miał zgadywać, powiedziałbym jedno i drugie.
Guido Anselmi
13
Model „świata rzeczywistego” jest często motywowany do programowania obiektowego. Myślę, że jest to podejście, które powinieneś w końcu wyrosnąć, ponieważ obiekty w OOP nie zawsze powinny odpowiadać obiektom ze świata rzeczywistego, a nawet gdy to robią, korespondencja jest często niekompletna; na przykład relacje „jest-a” nie zawsze są takie same. Z drugiej strony, kiedy powiesz, że chcesz model lub metaforę języka programowania opartego na czymś w „prawdziwym świecie”, myślę, że zasadniczo ograniczyłeś się do tej ograniczonej formy OOP.
David K
Naprawdę dobrym modelem mentalnym, jeśli masz doświadczenie w korzystaniu z systemów uniksopodobnych (lub PowerShell we współczesnym systemie Windows), jest powłoka jednowarstwowa. Nie są dokładnie takie same, ponieważ potoki są technicznie programowaniem opartym na przepływach, a nie funkcjonalne, ale mają takie same „odczucia” jak programista.
slebetman
1
Podczas nauki języków funkcjonalnych przekonasz się również, że w programowaniu funkcjonalnym zorientowanie obiektowe jest traktowane jako narzędzie, na przykład wyrażenia regularne. Coś, co możesz wykorzystać, jeśli chcesz, ale nie musisz. W niektórych językach, takich jak lisp i tcl i dalej, OO nie jest funkcją wbudowaną w język, ale biblioteką, z której możesz korzystać (lub możesz nawet pisać własne OO, jeśli czujesz się odważny). Tak więc problemy, które naturalnie mają rozwiązanie OO, można rozwiązać za pomocą OO w większości języków funkcjonalnych. Ludzie po prostu nie traktują OO jako religii.
slebetman

Odpowiedzi:

32

Programowanie funkcjonalne polega na sklejeniu mniejszych funkcji, aby osiągnąć swoje wyniki. Przyzwoity model mentalny (przynajmniej dla mnie) to linia montażowa. Każda funkcja, która się skomponuje, to kolejny krok w procesie montażu. Rozważ tę funkcję tutaj:

smallest  = head . sort

W Haskell ta funkcja zwróci najmniejszy element na liście. Linia montażowa najpierw sortuje dane wejściowe, a następnie zwraca pierwszy element (zakładając, że jest on posortowany od najmniejszej do największej). Jeśli chcielibyśmy uzyskać tylko najmniejszą parzystą wartość, możemy zmienić linię montażową, aby wyglądała następująco:

smallestEven = head . sort . filter even

To tylko jeden krok na przenośniku taśmowym.

W skrócie, funkcje opisują tylko kroki podjęte w celu przekształcenia surowego wejścia (części) w przetworzony towar (wynik).

bstamour
źródło
2
W czysto funkcjonalnym języku bez zmiennych globalnych jedna linia montażowa nie może wpływać na drugą (chyba że zasila drugą linię wejściową). Teoretycznie wszystkie linie montażowe, które nie zależą od siebie, mogą być wykonywane równolegle, ale ja nie jestem pewnie, jeśli zrobią to kompilatory.
bstamour
3
@GuidoAnselmi Jednym ze sposobów myślenia o tym jest to, że linia montażowa w programowaniu funkcjonalnym buduje nowe wyjścia, pozostawiając nienaruszone dane wejściowe, podczas gdy linia montażowa w tradycyjnym OOP przekształca dane wejściowe.
Doval
2
Ta metafora ma sens tylko w „pierwszorzędnych funkcjach / składzie funkcji” w znaczeniu „programowania funkcji”, a nie w „braku efektów ubocznych / deklaratywnych”. Ponadto programowanie obiektowe niekoniecznie ma skutki uboczne, więc możesz zaimplementować destrukcyjną lub konstruktywną linię montażową z OOP lub z takim znaczeniem FP. W OOP chodzi bardziej o enkapsulację, przekazywanie wiadomości i polimorfizm niż o skutki uboczne, zależy to od tego, jak modelujesz rzeczy. Np. Czy potrzebujesz tożsamości referencyjnej od początku do końca?
acelent
3
@bstamour: Aby być precyzyjnym, należałoby napisać, że (f . g) (x)środki f(g(x))lub f . gśrodki \x -> f (g (x)).
Giorgio
3
@MarjanVenema Rzeczy płyną w tym przykładzie tylko dlatego, że tak .to zdefiniowano; nie tak ogólnie działa Haskell . Równie dobrze możesz zdefiniować operator potoku F # ( |>) w Haskell i zapisywać, smallest x = (sort x) |> heada dane będą płynąć poprawnie. Pomyślałem, że zwrócę na to uwagę.
Doval
18

Czy ktoś ma dobry model mentalny do programowania funkcjonalnego?

Matematyka. Programowanie funkcjonalne jest inspirowane matematyką i wzorowane na niej. Funkcje matematyczne nie mają stanu, nie mają skutków ubocznych itp., Tak samo jest z FP. Jeśli myślisz o FP w kategoriach funkcji matematycznych, a nie w stylu „OO”, jak mam to zrobić, to będziesz w dobrej formie. Jeśli jednak spróbujesz zwiększyć wrażliwość OO na FP, będziesz pływać pod prąd.

Caleb
źródło
1
Dzięki. Potrzebuję jednak metafory ze świata rzeczywistego (np. Nie z komputerów czy matematyki).
Guido Anselmi
3
@GuidoAnselmi: Funkcja to czarna skrzynka. Umieszczasz coś na jednej stronie, a potem coś nowego wychodzi na drugą stronę. Jeśli wkładasz te same rzeczy, zawsze dostajesz te same rzeczy. Możesz wziąć wiele tych małych pudełek i połączyć je w różnych zamówieniach, aby zbudować fabrykę, która może przyjmować surowe metale i produkować samochód. Wewnątrz proces jest podzielony na wiele części, ale z zewnątrz jest to po prostu kolejna funkcja.
Daenyth,
16

Co powiesz na flipbook ?

W flipcharcie każda strona przedstawia świat taki, jaki istnieje w danym momencie. W naszym programie świat jest reprezentowany jako pewna złożona struktura danych (np. Mamy banana, który jest w ręku goryla, który jest na drzewie w dżungli). Każda kolejna strona rozwija historię, nieznacznie modyfikując poprzednią reprezentację. W FP trwałe struktury danych zostały zaprojektowane w celu efektywnego ponownego wykorzystania poprzednich struktur, dzięki czemu zmiana zapewnia tylko różnicę, a nie całkowicie nową wersję.

To, co może nie być oczywiste, to to, że strona w naszej książce również reprezentowałaby wartości niematerialne. Na przykład, jeśli goryl upuści banana, możemy zacząć oddziaływać grawitacją na jego przyzwoitość i przyspieszenie w kierunku podłogi dżungli. Aby to uwzględnić, przypisujemy do banana takie atrybuty, jak prędkość i trajektoria.

W naszym programie istniałaby funkcja, która przyjmuje jako stronę argument strony z książką (zwany też stanem świata) i daje nową stronę . W ten sposób nasza historia jest opowiedziana bez zmiany stanu istniejących obiektów. Po prostu zastępujemy każdą stronę nowszą, używając efektywnego obliczenia.

Mario T. Lanza
źródło
3

Relacje.

Przyjaciel: Biorąc pod uwagę dwie osoby, związek z przyjacielem jest zgodny z tymi ogólnymi prawami

  1. Miejcie dobrą wolę wobec siebie
  2. Myślą, że są dla nich przyjacielem (więc obaj członkowie muszą przestrzegać praw w tym związku)
  3. Lubi spędzać czas ze sobą

Monoid: Biorąc pod uwagę wiele przedmiotów i funkcję, która przyjmuje 2 przedmioty i zwraca 1, związek monoidalny jest zgodny z tymi ogólnymi prawami

  1. Jest jeden z tych elementów (tylko jeden, zwany tożsamością), który przekazano do funkcji z dowolnym innym elementem, zapewni, że funkcja zawsze zwróci drugi element (0 + 1 = 1, zatem 0 to tożsamość, gdy elementy są liczbami, a funkcja jest dodatkiem)
  2. Funkcja nie może działać na elementach spoza zestawu, z którymi ma związek monoidalny, ani na nie zwracać
  3. Funkcja jest asocjacyjna i może być używana z elementami w sposób nieco niezależny od porządku, co oznacza a * (b * c) = (a * b) * c, co oznacza, że ​​możesz pomnożyć a przez wynik b * c lub c przez wynik a * b, a wynik będzie taki sam, niezależnie od tego, co zrobisz najpierw.

Programowanie funkcjonalne polega na uogólnianiu, przyjaciel jest bardzo ogólną relacją, którą można zaobserwować w wielu scenariuszach, ale we wszystkich różnych formatach ogólnie jest zgodny z powyższymi prawami.

Uznając prawa rządzące relacjami między rzeczami, możesz tworzyć ogólne implementacje, które działają na dowolnym formacie rzeczy, które mają ten rodzaj relacji. W programowaniu funkcjonalnym próbujesz zidentyfikować relacje między rzeczami, aby można je było ogólnie klasyfikować i traktować.

Chcesz metaforę z prawdziwego świata? Spójrz, jak rzeczy są powiązane i spróbuj zidentyfikować ogólne prawa (jak w przypadku wielu scenariuszy, w których rzeczy inne niż przepisy mogą się różnić). Istnieje związek między urzędnikiem rejestrującym a klientem w sklepie, ma on pewne ogólne prawa, opracowano oprogramowanie ułatwiające osiągnięcie celów ludzi w tym ogólnym związku na drodze systemów POS. Podobnie, gdy zaczniesz widzieć te ogólne prawa dyktujące, jak rzeczy są powiązane, możesz zacząć polegać na prawach tych relacji podczas pisania oprogramowania, a nie na konkretnych szczegółach wystąpienia relacji.

Jimmy Hoffa
źródło
2

Wszystko jest wartością, a Ty stosujesz funkcje do wartości (które mogą być funkcjami), aby tworzyć nowe wartości, najlepiej bez żadnych skutków ubocznych.

Doval
źródło
Dzięki. Niestety, to brzmi bardziej jak opis niż model mentalny lub metafora. Potrzebuję metafory z prawdziwego świata (nie z komputerów).
Guido Anselmi
1
Jak zauważa Caleb , funkcjonalne modele programowania matematyki, a nie rzeczywisty świat. Może modelować świat rzeczywisty przez pryzmat matematyki, ale prawdopodobnie nie znajdziesz metafory, która by cię satysfakcjonowała, ponieważ FP odrzuca pojęcie rzeczy o trwałej tożsamości i stanie zmiennym. Jeśli chcesz, mogę wskazać, w jaki sposób OOP konstruuje mapę do FP, ale nadal nie będzie to odpowiedź, której chcesz.
Doval
Ale matematyka opiera się na prawdziwym świecie. 1 słońce, 9 planet. 2 jabłka plus 2 jabłka to cztery jabłka.
Guido Anselmi
A w programowaniu funkcjonalnym możesz również mieć typ dla słońc, planet i jabłek, a następnie utworzyć jedną wartość typu słońce, 9 wartości typu planeta i zdefiniować dodatek dla typu jabłka.
Doval
3
@GuidoAnselmi masz go całkowicie do tyłu, ludzie analizują prawdziwy świat za pomocą matematyki, nie ma on podstaw do prawdziwego świata. Matematyka służy do analizowania i definiowania relacji między różnymi rzeczami, prawdziwymi i nie. 9 planet to zastosowanie konstrukcji matematycznej (zbioru liczb naturalnych) do konstrukcji świata rzeczywistego (planet) z funkcją analizy matematycznej (liczba). Świat rzeczywisty nie ma 9 planet, ma to, co ma, matematyka mówi jedynie o symbolicznych reprezentacjach rzeczy, w których symbole mają między sobą relacje.
Jimmy Hoffa
1

Kluczową rzeczą do zrealizowania w programowaniu funkcjonalnym jest to, że wszystko jest wartością - nawet sam kod to „wartości”.

Najlepszym przykładem prostego funkcjonalnego środowiska programistycznego jest ulubione narzędzie biznesowe każdego użytkownika - arkusz kalkulacyjny. Każda komórka w arkuszu kalkulacyjnym to albo dane, albo wynik funkcji. Co więcej, ta funkcja nie może się wyłączyć i zmodyfikować innej komórki.

Kiedy jeden przenosi się do języków funkcyjnych, zamiast w kartezjańskim grid of A1a B42funkcje mają nazwy. To wszystko, czym tak naprawdę jest.

Są jeszcze inne aspekty, które można dodać poza tym ... ale to funkcjonalne programowanie u jego podstaw. Nie trzeba się martwić o strukturę list lub grupowanie rzeczy. Programowanie funkcjonalne polega na przekazywaniu wartości do funkcji i odzyskiwaniu wartości bez konieczności szukania gdzie indziej w pamięci.

Otóż ​​to. Programowanie funkcjonalne to arkusz kalkulacyjny z nazwami, a nie siatka.


źródło
0

Możesz myśleć o programowaniu funkcjonalnym jak o zachowaniach . Program to opis zachowania, które ma zostać wprowadzone w komputerze. Funkcje są podstawową jednostką zachowania, a ich składanie jest jednym ze sposobów budowania większych zachowań z mniejszych.

W OOP obiekt kodowy ma być stanem obiektu w domenie problemowej; zmienia się w czasie, aby odzwierciedlić zmiany w tym obiekcie domeny. W FP wartość reprezentuje stan obiektu domeny; nigdy się nie zmienia, po prostu tworzysz różne wartości reprezentujące różne stany.

Uważam, że model funkcjonalny jest nieco bardziej uczciwy w kwestii tego, co faktycznie robią komputery - reprezentując. W końcu nie mogę po prostu wyczarować new Tesla()powietrza. :)

Jon Purdy
źródło
-5

Zdania są bardziej funkcjonalne niż zorientowane obiektowo, zakładając, że je rozbicie mniej więcej w następujący sposób ...

The brown cow is in the meadow across the deep river.

Musimy więc znaleźć frazy, a następnie resztę:

The cow (brown)
the meadow (across)
the river (deep)

Za jednym razem:

sentence: The cow ((the meadow (the river (deep)) (across)) brown)

Przetwarzaj drzewo:

|                     sentence
|                      /         
|                  The cow
|                 /       \
|            the meadow   brown
|            /         \
|      the river      across
|              \
|              deep

Parsimony infekuje myślenie funkcjonalne;

Czapki z głów przed Gottlieb Frege 1890, Alan Turing (entschiedungsprobleme) 1930, Noam Chomsky (1960).

KTys
źródło
4
To mylące wyjaśnienie i na początek znam FP.
Daenyth,
Wygląda jak naśladowanie formy Lisp bez zrozumienia znaczenia
Izkata