Interesuję się programowaniem funkcjonalnym i postanowiłem zmierzyć się z Haskellem. Boli mnie głowa ... ale w końcu to dostanę ... Mam jednak jedną ciekawość, dlaczego składnia jest tak tajemnicza (bez innego słowa)?
Czy istnieje powód, dla którego nie jest on bardziej wyrazisty , bliższy ludzkiemu językowi?
Rozumiem, że FP jest dobra w modelowaniu pojęć matematycznych i zapożyczyła niektóre ze swoich zwięzłych środków wyrazu, ale wciąż nie jest to matematyka ... to język.
Odpowiedzi:
Języki funkcjonalne, takie jak Haskell i jego poprzedniczka Miranda, wyrosły z matematycznej koncepcji rachunku lambda . Ze strony Wikipedii:
Z powodu tej historii na składnie tych języków funkcjonalnych (i elementów funkcjonalnych bardziej imperatywnych języków) duży wpływ ma notacja matematyczna stosowana w rachunku lambda.
Dokładność, z jaką zarówno zapisy matematyczne, jak i języki komputerowe mogą opisywać wymagania, oraz precyzja, z jaką komputery wymagają, aby ich instrukcje były pisane, dobrze ze sobą korelują. Niedokładność języka naturalnego stanowi jednak ogromną barierę w jego używaniu do programowania komputerów. Nawet (prawdopodobnie) najbardziej udane środowiska programowania w języku naturalnym, takie jak Wolfram Alpha, wymagają znacznego doświadczenia w dziedzinie, aby mogły być skutecznie wykorzystywane.
źródło
Składnia Haskella jest zbliżona do ludzkiego języka. Jest specjalnie zaprojektowany, aby przypominać notację matematyczną, która jest językiem zaprojektowanym przez ludzi (a więc ludzkim językiem ), aby dokładnie wyrażać te pojęcia, na których zbudowany jest Haskell.
Możesz pokazać kawałek kodu Haskell każdemu matematykowi lub logikowi, a on będzie w stanie go zrozumieć, nawet jeśli nigdy nie słyszał o Haskell i nie wie absolutnie nic o programowaniu, informatyce, a nawet komputerach.
Z drugiej strony, możesz pokazać każdemu matematykowi lub logikowi taki kod:
i będzie całkowicie zdezorientowany, mówiąc: „To nie ma sensu, nie ma
x
takiego, któryx
równałby sięx
plus1
”.To, czy jakiś konkretny zapis jest „tajemniczy”, czy nie, jest kwestią opinii i znajomości.
źródło
where
pozwala na zagęszczenie treści funkcja w jednym wierszu.x = infinity
to rzeczywiście rozwiązuje równanie.Myślę, że jedną rzeczą, na którą prawdopodobnie natrafisz, jest coś, na co wpadłem również podczas nauki programowania funkcjonalnego, to znaczy, że dzięki programowaniu funkcjonalnemu możesz (i prawie musisz) myśleć / pracować na wyższym poziomie niż w przypadku programowania imperatywnego.
Wydaje mi się, że to, co wydaje się mniej wyraziste, jest w rzeczywistości bardziej wyraziste: nie musisz opisywać każdego najmniejszego szczegółu i możesz zrobić więcej przy mniejszym kodowaniu w programowaniu funkcjonalnym - masz więcej mocy do pisania.
Na przykład, mógłbym napisać koniecznie:
który jest całkowicie czytelny jako angielski.
Wersja Haskell może być (i to nie jest prawidłowy Haskell, ale służy jedynie do porównania składniowego):
co wymaga mniej kodu i mniej szczegółowego przekręcania - nie muszę rozkładać rzeczy na pętlę i jej zmienne () zmienne
for each (...)
,map
funkcja zajmuje się tym za mnie.Praca na tym poziomie może zająć trochę czasu. Jeśli to pomoże, Haskell był prawdopodobnie najtrudniejszym momentem w nauce nowego języka, odkąd zacząłem programować, i znam> 10 języków (w tym Lisp). Warto było się jednak nauczyć.
źródło
Obecnie zajmuję się Scalą, więc mogę współczuć. Przynajmniej ze Scalą mogę wrócić do imperatywnego stylu, gdy sytuacja staje się zbyt trudna.
Myślę, że gra tu kilka sił:
Projektanci języków funkcjonalnych z konieczności mają silne zaplecze matematyczne, więc zapożyczają zapis matematyczny, który jest dla nich naturalny.
Większa ekspresja (tj. Siła wypowiedzi, a nie bliskość języka angielskiego) dowolnego języka ma (IMO) odpowiednią cenę pod względem nachylenia krzywej uczenia się. Terseness to bardzo ceniona jakość w Scali, a wiele rzeczy jest opcjonalnych.
Języki funkcjonalne po prostu robią wszystko inaczej, więc podstawowe operacje nie są odwzorowywane na konstrukcje imperatywne.
źródło
Jeśli dobrze zrozumiałem twój ostatni komentarz, twoje pytanie brzmi: dlaczego Haskell często używa operatorów symbolicznych w miejscach, w których równie dobrze mógłby używać alfanumerycznych słów kluczowych (lub nazw funkcji)?
Jeśli chodzi o słowa kluczowe, jedną z odpowiedzi byłoby to, że słowa kluczowe uniemożliwiają używanie niektórych słów jako nazw zmiennych. Na przykład ja zawsze irytowało, gdy chcę zadzwonić moje zmienne
from
ito
w ciągu językach, gdzie jeden z nich jest to słowa kluczowe - jak w Pythonie.Innym powodem dla operatorów symbolicznych w ogólności jest zwięzłość. To tak naprawdę nie dotyczy twoich konkretnych przykładów list (
<-
nie jest krótszy niżin
), ale w wielu przypadkach tak jest.Jeszcze innym powodem jest czytelność. Może się to wydawać sprzeczne z intuicją, ponieważ operatory symboliczne są często trudniejsze do nauczenia się, ponieważ ich „nazwy” tak naprawdę nie mówią nic o tym, co robią (podczas gdy nazwa funkcji zwykle tak robi), ale gdy już wiesz, co robi dany operator, wyrażenia z operatorami symbolicznymi w postaci infixów są często łatwiejsze do analizy dla człowieka niż w przypadku wielu wywołań funkcji prefiksu alfanumerycznego, ponieważ operatory łatwiej wizualnie odróżniają się od operandów w ten sposób. Na przykład większość ludzi zgodzi się, że
2 * 3 + 4
jest łatwiejsza do odczytania niżadd (mult 2 3) 4
lubadd(mult(2, 3), 4)
.źródło
Imperatywne języki komputerowe w większości nie są bliżej języków naturalnych niż, powiedzmy, Haskell.
Jednak niektóre są zaprojektowane tak, aby bardziej przypominały angielski: na przykład Cobol i Hypercard. Lekcje, które wyciągnę z tych przykładów, to:
Podobno język komputerowy Perla został zaprojektowany z myślą o bardziej subtelnych aspektach języka naturalnego . Oceniłbym, że Perl radzi sobie lepiej niż Cobol czy Hypercard pod względem ogólnej użyteczności, ale ludzie mają różne opinie na temat Perla.
źródło
Myślę, że Haskell staje się tak podobny do ludzkiego języka, jak to tylko możliwe, bez wprowadzania szalonej składni. Naprawdę robi to bardzo długo, na przykład z
where
klauzulą odkładania definicji i ze składnią rozumienia listy, która jest dokładnie tym, co napisałbym na tablicy. Unika także obcych postaci, takich jak aparat ortodontyczny, i ma swobodne stosowanie wcięć. Typowym przykładem jest quicksort:Wprawdzie jest to prosty przykład, ale nie znam żadnego innego języka, który uczyniłby go tak czytelnym.
Robienie bardziej skomplikowanych rzeczy może być trudne do odczytania w Haskell, ale ma to związek z systemem typów, ograniczonym IO, a nie ze składnią w ogóle.
W ogóle powiedziałbym, że Haskell poświęcił prostotę składniową, aby dostosować się do składni bardziej zbliżonej do języka ludzkiego. Schemat podobny do języka ma składnię, która jest bardzo daleka od tego, co napisałby człowiek, ale naprawdę łatwo jest wyjaśnić jego zasady.
źródło
++ [p] ++
?Myślę, że różnica ma związek ze sposobem, w jaki programowanie funkcjonalne / deklaratywne wypowiada się na temat problemu, tak jakby to był problem matematyczny, podczas gdy programowanie imperatywne opisuje proces . W świecie biznesu programy komputerowe owijają lub zastępują procesy fizyczne, więc możesz znaleźć język, który odzwierciedla to, jako bardziej intuicyjny.
Okazuje się, że styl funkcjonalny nadaje się do bezpiecznego korzystania z wielu procesorów (ponieważ minimalizuje zmienność i skutki uboczne) - coś, czego zobaczymy więcej w przyszłości. Ponadto większość współczesnych języków funkcjonalnych ma kolekcje z iteratorami, do których można przekazywać funkcje. Te metody mogą bardzo skutecznie podzielić obciążenie pracą na wiele procesorów, nawet o tym nie wiedząc.
źródło