Wikipedia podaje, że Ruby jest językiem funkcjonalnym, ale nie jestem do tego przekonany. Dlaczego lub dlaczego nie?
ruby
functional-programming
Esteban Araya
źródło
źródło
Odpowiedzi:
Zdecydowanie uważam, że w Rubim możesz użyć stylu funkcjonalnego.
Jednym z najbardziej krytycznych aspektów możliwości programowania w stylu funkcjonalnym jest to, czy język obsługuje funkcje wyższego rzędu ... co robi Ruby.
To powiedziawszy, łatwo jest programować w Rubim również w niefunkcjonalnym stylu. Innym kluczowym aspektem stylu funkcjonalnego jest brak stanu i rzeczywiste funkcje matematyczne, które zawsze zwracają tę samą wartość dla danego zestawu danych wejściowych. Można to zrobić w Rubim, ale nie jest to wymuszone w języku, jak coś bardziej funkcjonalnego, jak Haskell.
Więc tak, obsługuje styl funkcjonalny, ale pozwala również programować w stylu niefunkcjonalnym.
źródło
Is ruby a functional language?
a prosta odpowiedź brzmi: nie. Ruby to język zorientowany obiektowo z pewnymi funkcjami.Nie ma znaczenia, czy język jest językiem funkcjonalnym, czy też nie. Programowanie funkcyjne to teza, którą najlepiej wyjaśnili Philip Wadler (The Essence of Functional Programming) i John Hughes (Why Functional Programming Matters).
Znaczące pytanie brzmi: „Jak podatny jest Ruby na osiągnięcie tezy o programowaniu funkcyjnym?” Odpowiedź brzmi „bardzo słabo”.
Niedawno wygłosiłem wykład na ten temat. Oto slajdy.
źródło
Ruby obsługuje funkcje wyższego poziomu (zobacz Array # map, inject, & select), ale nadal jest to konieczny język obiektowy.
Jedną z kluczowych cech języka funkcjonalnego jest to, że unika on stanu zmiennego. Języki funkcjonalne nie mają pojęcia zmiennej, tak jak w Ruby, C, Javie lub jakimkolwiek innym języku imperatywnym.
Inną kluczową cechą języka funkcjonalnego jest to, że koncentruje się on na definiowaniu programu w kategoriach „co”, a nie „jak”. Podczas programowania w języku obiektowym piszemy klasy i metody, aby ukryć implementację („jak”) przed „co” (nazwa klasy / metody), ale ostatecznie metody te są nadal zapisywane przy użyciu sekwencji instrukcji. W języku funkcjonalnym nie określa się kolejności wykonywania, nawet na najniższym poziomie.
źródło
Uważam, że wspieranie, czyli umiejętność programowania w języku w stylu funkcjonalnym , nie czyni języka funkcjonalnego.
Mogę nawet napisać kod w Javie w funkcjonalnym stylu, jeśli chcę skrzywdzić moich kolegów i siebie za kilka
miesięcy.Posiadanie języka funkcjonalnego nie chodzi tylko o to, co można zrobić, takich jak funkcje wyższego rzędu, funkcji pierwszej klasy i zmiękczania. Dotyczy również tego, czego nie można zrobić, na przykład skutków ubocznych w czystych funkcjach.
Jest to ważne, ponieważ w dużej mierze jest to powód, dla którego programy funkcjonalne lub kod funkcjonalny w ogóle jest łatwiejszy do rozważenia. A kiedy łatwiej jest zrozumieć kod, błędy stają się płytsze i przenoszą się na powierzchnię koncepcyjną, gdzie można je naprawić, co z kolei daje mniej błędnego kodu.
Ruby jest w swej istocie zorientowany obiektowo, więc nawet jeśli ma dość dobre wsparcie dla stylu funkcjonalnego, sam nie jest językiem funkcjonalnym.
W każdym razie to moja nienaukowa opinia.
Edytować: Z perspektywy czasu i biorąc pod uwagę dobre komentarze, jakie otrzymałem do tej odpowiedzi do tej pory, myślę, że porównanie zorientowane obiektowo i funkcjonalnie dotyczy jabłek i pomarańczy.
Prawdziwym wyróżnikiem jest to, że w wykonaniu jest imparatywny lub nie. Języki funkcyjne mają wyrażenie jako podstawowy konstrukt językowy, a kolejność wykonywania jest często niezdefiniowana lub definiowana jako leniwa. Ścisłe wykonanie jest możliwe, ale używane tylko w razie potrzeby. W języku imparatywnym, ścisłe wykonanie jest ustawieniem domyślnym i chociaż leniwe wykonanie jest możliwe, jest to często niezdarne i może mieć nieprzewidywalne rezultaty w wielu skrajnych przypadkach.
Teraz, to jest moja opinia nienaukowe.
źródło
Ruby będzie musiał spełnić następujące wymagania, aby był "PRAWDZIWIE" funkcjonalny.
Niezmienne wartości: po ustawieniu „zmiennej” nie można jej zmienić. W Rubim oznacza to, że musisz skutecznie traktować zmienne jak stałe. Ten język nie jest w pełni obsługiwany, będziesz musiał ręcznie zablokować każdą zmienną.
Brak efektów ubocznych: po przekazaniu danej wartości funkcja musi zawsze zwracać ten sam wynik. To idzie w parze z posiadaniem niezmiennych wartości; funkcja nigdy nie może przyjąć wartości i zmienić jej, ponieważ spowodowałoby to efekt uboczny, który jest styczny do zwracania wyniku.
Funkcje wyższego rzędu: są to funkcje, które dopuszczają funkcje jako argumenty lub używają funkcji jako wartości zwracanej. Jest to prawdopodobnie jedna z najbardziej krytycznych cech każdego języka funkcjonalnego.
Currying: włączone przez funkcje wyższego rzędu, currying przekształca funkcję, która przyjmuje wiele argumentów, w funkcję, która przyjmuje jeden argument. Idzie to w parze z częściową aplikacją funkcji, która przekształca funkcję wieloargumentową w funkcję, która przyjmuje mniej argumentów niż pierwotnie.
Rekursja: zapętlenie przez wywołanie funkcji z jej wnętrza. Gdy nie masz dostępu do danych, które można modyfikować, rekurencja jest używana do tworzenia i łączenia konstrukcji danych. Dzieje się tak, ponieważ pętla nie jest koncepcją funkcjonalną, ponieważ wymaga przekazywania zmiennych w celu przechowywania stanu pętli w danym momencie.
Leniwa ocena lub opóźniona ocena: opóźnianie przetwarzania wartości do momentu, gdy jest to rzeczywiście potrzebne. Jeśli, na przykład, masz kod, który wygenerował listę liczb Fibonacciego z włączoną funkcją leniwego obliczania, nie zostanie to faktycznie przetworzone i obliczone, dopóki jedna z wartości w wyniku nie będzie wymagana przez inną funkcję, taką jak puts.
Propozycja (tylko myśl) Byłoby wspaniale mieć jakąś definicję, aby mieć plik
mode
dyrektywę do deklarowania plików z paradygmatem funkcjonalnym, przykładtryb „funkcjonalny”
źródło
Ruby to język wieloparadygmatyczny, który obsługuje funkcjonalny styl programowania.
źródło
Ruby jest językiem zorientowanym obiektowo, który może obsługiwać inne paradygmaty (funkcjonalne, imperatywne itp.). Jednak ponieważ wszystko w Rubim jest obiektem, jest to przede wszystkim język OO.
przykład:
"hello" .reverse () = "olleh", każdy łańcuch jest instancją obiektu typu string i tak dalej, i tak dalej.
Zaznajomić się tutaj lub tutaj
źródło
To zależy od twojej definicji „języka funkcjonalnego”. Osobiście uważam, że sam termin jest dość problematyczny, gdy jest używany jako absolut. Bycie „językiem funkcjonalnym” ma więcej aspektów niż zwykłe funkcje językowe, a większość zależy od tego, skąd patrzysz. Na przykład kultura otaczająca język jest pod tym względem dość ważna. Czy zachęca do funkcjonalnego stylu? A co z dostępnymi bibliotekami? Czy zachęcają do korzystania z nich w sposób funkcjonalny?
Większość ludzi nazwałaby na przykład Scheme językiem funkcjonalnym. Ale co z Common Lispem? Oprócz problemu z wielokrotną / pojedynczą przestrzenią nazw i gwarantowaną eliminacją wywołań końcowych (które również obsługują niektóre implementacje CL, w zależności od ustawień kompilatora), niewiele jest rzeczy, które sprawiają, że Scheme jako język lepiej nadaje się do programowania funkcjonalnego niż Common Lisp, i mimo to, większość Lisperów nie nazwałaby CL językiem funkcjonalnym. Czemu? Ponieważ otaczająca go kultura w dużym stopniu zależy od nadrzędnych cech CL (takich jak na przykład makro LOOP, na które większość Schemerów prawdopodobnie by się nie przejrzała).
Z drugiej strony programista C może uznać CL za język funkcjonalny. W końcu większość kodu napisanego w jakimkolwiek dialekcie Lisp jest z pewnością znacznie bardziej funkcjonalna niż zwykły blok kodu C. Podobnie Schemat jest bardzo imperatywnym językiem w porównaniu z Haskellem. Dlatego nie sądzę, aby kiedykolwiek istniała jednoznaczna odpowiedź tak / nie. To, czy nazwać język funkcjonalnym, czy nie, w dużej mierze zależy od twojego punktu widzenia.
źródło
Wydaje mi się, że Ruby również nie jest językiem wieloparadygmatycznym. Wielu paradygmat jest zwykle używany przez ludzi, którzy chcą nazwać swój ulubiony język czymś, co jest przydatne w wielu różnych dziedzinach.
Opisałbym Ruby to obiektowy język skryptowy. Tak, funkcje są obiektami pierwszej klasy (w pewnym sensie), ale to nie czyni z tego języka funkcjonalnego. IMO, dodam.
źródło
Rekursja jest powszechna w programowaniu funkcjonalnym. Prawie każdy język obsługuje rekursję, ale algorytmy rekurencyjne są często nieskuteczne, jeśli nie ma wywołania ogonowego optymalizacji (TCO).
Funkcjonalne języki programowania są zdolne do optymalizacji rekurencji ogona i mogą wykonywać taki kod w stałej przestrzeni. Niektóre implementacje Rubiego optymalizują rekurencję ogonową, inne nie, ale generalnie implementacje Rubiego nie są wymagane do osiągnięcia całkowitego kosztu posiadania. Zobacz Czy Ruby przeprowadza optymalizację wywołań ogonowych?
Tak więc, jeśli napiszesz jakiś funkcjonalny styl Rubiego i polegasz na całkowitym koszcie posiadania jakiejś konkretnej implementacji, twój kod może być bardzo nieefektywny w innym interpreterze Rubiego. Myślę, że właśnie dlatego Ruby nie jest językiem funkcjonalnym (podobnie jak Python).
źródło
Ściśle mówiąc, nie ma sensu opisywać języka jako „funkcjonalnego”; większość języków umożliwia programowanie funkcjonalne. Nawet C ++ jest.
Styl funkcjonalny jest mniej więcej podzbiorem imperatywnych funkcji języka, wspieranych przez cukier składniowy i niektóre optymalizacje kompilatora, takie jak niezmienność i spłaszczanie rekurencji ogona,
Ta ostatnia jest prawdopodobnie niewielką techniczną cechą specyficzną dla implementacji i nie ma nic wspólnego z rzeczywistym językiem. Kompilator x64 C # 4.0 optymalizuje rekurencję ogonową, podczas gdy kompilator x86 nie robi tego z jakiegoś głupiego powodu.
Cukier syntaktyczny można zwykle obejść do pewnego stopnia lub innego, zwłaszcza jeśli język ma programowalny prekompilator (np. C's #define).
Nieco bardziej sensowne może być pytanie „czy język __ obsługuje programowanie imperatywne?”, A odpowiedź, na przykład w przypadku Lispa, brzmi „nie”.
źródło
Proszę spojrzeć na początek książki: „A-Great-Ruby-eBook” . Omawia bardzo konkretny temat, o który pytasz. W Rubim możesz wykonywać różne rodzaje programowania. Jeśli chcesz programować jak funkcjonalnie, możesz to zrobić. Jeśli chcesz programować tak, jak trzeba, możesz to zrobić. Jest to pytanie definiujące, jak funkcjonalny jest ostatecznie Ruby. Zobacz odpowiedź użytkownika camflan.
źródło