Przez cały miniony rok pisałem kod Scala (pochodzący z Java). Naprawdę podobało mi się, jak można stworzyć prostszy i bardziej przejrzysty kod z vals, klasami przypadków, funkcjami map / filter / lambda, implikacjami i wnioskowanie o typie. Użyłem go głównie do aplikacji opartych na Akce .
W tym roku pracuję nad projektem Scala z nowym zespołem, który naprawdę lubi programowanie funkcjonalne. Często używają Scalaz , a kod jest wszędzie wypełniony aplikacjami, granicami kontekstu, czytnikiem / pisarzem / monadą stanu, nawet główna metoda jest „zawinięta” w monadę we / wy. Ich rozumowanie polega na tym, że kompilator „działa dla nas”, zapewniając, że kod jest poprawny, a każda funkcja jest wolna od skutków ubocznych.
Mimo to z mojego punktu widzenia cała ta składnia naprawdę przeszkadza w logice biznesowej. Na przykład rodzaj „MyBusinessObject” jest w porządku, a także typy takie jak „List [MyBusinessObject]”, „Option [MyBusinessObject]” lub nawet „Future [MyBusinessObject]”. Wszystkie mają jasne znaczenie i cel. Z drugiej strony kod taki jak:
def method[M[_]: Applicative] = {
case (a, b) => (ca[M](a) |@| cb[M](b)) {
case t @ (ra, rb) =>
if (ra.result && rb.result) t.right
else t.left
}
}
czy to dodaje złożoności programowi, czy tylko ja nie jestem przyzwyczajony do tego sposobu programowania?
źródło
>>=
i<$>
, które nic nie znaczą, dopóki ty wiedzieć, co robią. Po zapoznaniu się z ich znaczeniem czytają mi teraz bardzo naturalnie i szybko. Nie do końca odpowiedź, tylko moje obiektywne doświadczenie z takimi rzeczami. Używam również Scali, ale nie mam doświadczenia z biblioteką Scalaz.for(i=0; i<7; ++i) { trivialOperation(i); }
przy pomocy jakiejś niewygodnejtrivialOperationCount
zmiennej, prawda?) Teraz, funkcjonalne języki programowania z dopasowaniem wzorców czasami wprowadzają więcej zmiennych, w których po prostu wypiszę wywołania metody akcesora w OO. Wynik jest ogólnie bardziej zwięzły; być może nieco mniej zrozumiałe, ale przeglądanie deklaracji danych zwykle szybko to wyjaśnia. Pisanie statyczne bardzo pomaga, nie jest tak jak w APL.Odpowiedzi:
Nie ma to nic wspólnego z programowaniem funkcjonalnym - taką sytuację można znaleźć w kontekście dowolnego innego języka programowania - programiści, którzy tak bardzo lubią zaawansowane konstrukcje „swojego” języka, że ignorują zdrowy rozsądek dotyczący czytelności i prostoty. Z taką sytuacją spotkałem się w językach C, C ++, Perl, Java, C #, Basic i innych niefunkcjonalnych. To nie jest funkcjonalne programowanie, które zwiększa złożoność kodu - robią to programiści.
Nie zrozum mnie źle, nie polecam unikania zaawansowanych funkcji językowych - ale ważne jest, aby znaleźć właściwą równowagę w danym kontekście. Pisząc ogólną bibliotekę dla ponad 100 000 programistów na całym świecie, obowiązują inne środki, jak w przypadku pisania indywidualnego generatora raportów tylko dla lokalnego biura.
źródło
Powiedziałbym, że nie jesteś przyzwyczajony do sposobu, w jaki kodują, jest przynajmniej częścią obrazu. Jestem w podobnej sytuacji jak ty (wchodzę z C # do F # i pracuję z ludźmi z tłem Haskell) i chociaż uważam to za ciekawe doświadczenie, mam chwile, kiedy uderzam głową o ścianę, rozplątując szczególnie skomplikowana kompozycja funkcji bez punktów, aby po prostu zrozumieć, co się tam dzieje. To kwestia kulturowa.
Co do tego, czy ten konkretny kod dodaje programowi złożoności - nie wiem. Zgodzono się, że ogólny fragment kodu może być sam w sobie złożony. Ale to narzędzie, a nie część logiki biznesowej. Jeśli chcesz wiedzieć, czy baza kodu jest bardziej złożona, czy prostsza, musisz wyobrazić sobie, jak wyglądałaby bez tego fragmentu kodu. Często dzieje się tak w przypadku takich ogólnych konstrukcji, że same są złożone, ale jest to złożoność, którą można zmieścić na jednym ekranie. Jednocześnie upraszczają całą bazę kodu. Dotyczy to szczególnie monad.
Z drugiej strony może to być także „sztuka dla sztuki”, jak sugeruje @Doc Brown. Nie można tego również wykluczyć.
źródło
Twierdziłbym, że ogólnie programowanie funkcjonalne zmniejsza złożoność poprzez eliminację stanu zmiennego, a tym samym zmniejszenie liczby przypadków, które należy wziąć pod uwagę, próbując zrozumieć, jak działa sekcja kodu.
Jednak programowanie funkcjonalne umożliwia uzyskanie wyższego stopnia abstrakcji i chociaż wysoce abstrakcyjny kod może być niezwykle przydatny, może być również trudny do zrozumienia, ponieważ z definicji jest on oddzielony od kontekstu, który zwykle służyłby do zrozumienia. Twój komentarz „Wszystkie mają wyraźne znaczenie i cel” na temat obiektów biznesowych jest niewątpliwie prawdziwy, ale tak naprawdę odzwierciedla fakt, że ta logika jest bardzo specyficzna dla potrzeb i kontekstu, który już rozumiesz. Istnienie konstrukcji takiej jak Monada pozwala na zrobienie czegoś bardzo przydatnego przy niewielkim wysiłku, ale sieć jest pełna stron próbujących wyjaśnić, czym jest Monada. To dla ciebie abstrakcja.
Scalaz napisali także ludzie, którzy od dawna jedli i oddychali FP; chcieli wprowadzić funkcjonalność dostępną w Haskell do Scali. Czyniąc to, nie starali się być pedagogami. Scalaz używa słownictwa i stylu, które wydają się jasne i proste dla autorów, ale obce dla niewtajemniczonych. Metody, które są dla nas zastanawiające, wydawały się autorom tak oczywiste, biorąc pod uwagę ich pochodzenie z Haskell, że nawet nie uzasadnili komentarza.
Ponadto, jako funkcjonalny język programowania, Scala ma pewne niedociągnięcia (częściowo dlatego, że JVM ma wady), które w niektórych przypadkach zmusiły autorów Scalaz do napisania brzydszego kodu. Na przykład brak ogólnej eliminacji wywołań ogonkowych wymusza użycie trampolin w niektórych kodach, a brak „dobrego systemu” może komplikować podpisy typu.
I wreszcie Scalaz świetnie się wykorzystuje. Można to uznać za znak jego siły, ale dla niewtajemniczonych może uczynić źródło łamigłówką - każdy losowy fragment kodu, na który patrzysz, prawdopodobnie wykorzysta coś innego, co wygląda ci obco.
Powieś tam. I to może pomóc.
źródło
Czy to komplikuje program, czy może po prostu nie jesteś przyzwyczajony do tego sposobu programowania?
Dlaczego uważasz, że te możliwości to nie to samo?
Dobrze napisany kod mogą odczytać ludzie, którzy nie znają konkretnego języka programowania. Niektóre języki (BASIC, Pascal itp.) Mogą być czytane i rozumiane przez dzieci w wieku szkolnym, które nigdy wcześniej nie widziały żadnych języków programowania.
Jeśli ktoś, kto ma doświadczenie z innymi językami i doświadczenie ze Scalą (i który, jak zakładam, pracował ze Scalazem przez co najmniej tydzień i ma kolegów, którzy wyjaśnią trudniejsze rzeczy) jest nadal zdezorientowany; to dowód na to, że zwiększył złożoność.
źródło
"Well written code can be read by people who aren't familiar with the specific programming language."
x[⍋x←6?40]
. Jak myślisz, co to robi? Na pewno bym nie wiedział…