Od jakiegoś czasu jestem programistą WWW, a ostatnio zacząłem uczyć się programowania funkcjonalnego. Podobnie jak inni, miałem poważne problemy z zastosowaniem wielu z tych koncepcji w mojej pracy zawodowej. Dla mnie głównym powodem tego jest to, że widzę konflikt między celem FP, jakim jest pozostanie bezpaństwowcem, wydaje się zupełnie sprzeczne z faktem, że większość prac związanych z tworzeniem stron internetowych, które wykonałem, była mocno związana z bazami danych, które są bardzo skoncentrowane na danych.
Jedną rzeczą, która sprawiła, że stałem się znacznie bardziej produktywnym programistą po stronie OOP, było odkrycie obiektów mapowania relacyjnego, takich jak MyGeneration d00dads dla .Net, Class :: DBI dla perla, ActiveRecord dla ruby itp. To pozwoliło mi trzymać się z daleka. od pisania instrukcji wstawiania i wybierania przez cały dzień i skupiania się na łatwej pracy z danymi jako obiektami. Oczywiście nadal mogłem pisać zapytania SQL, gdy potrzebna była ich moc, ale poza tym było to ładnie abstrakcyjne za kulisami.
Teraz, przechodząc do programowania funkcjonalnego, wydaje się, że wiele frameworków internetowych FP, takich jak Links, wymaga napisania wielu standardowych kodów sql, jak w tym przykładzie . Weblocks wydaje się trochę lepszy, ale wydaje się, że używa pewnego rodzaju modelu OOP do pracy z danymi i nadal wymaga ręcznego napisania kodu dla każdej tabeli w twojej bazie danych, jak w tym przykładzie . Przypuszczam, że używasz generowania kodu do pisania tych funkcji mapujących, ale wydaje się to zdecydowanie nie do lispa.
(Uwaga: nie przyjrzałem się bardzo uważnie blokom stron internetowych ani łączom, może po prostu nie rozumiem, jak są one używane).
Tak więc pytanie brzmi: w przypadku części dostępu do bazy danych (które moim zdaniem są dość duże) aplikacji internetowej lub innych programów wymagających interfejsu z bazą danych sql, wydaje się, że jesteśmy zmuszeni przejść jedną z następujących ścieżek:
- Nie używaj programowania funkcyjnego
- Uzyskaj dostęp do danych w irytujący, nieabstrakcyjny sposób, który obejmuje ręczne pisanie dużej ilości kodu SQL lub podobnego do SQL ala Linki
- Zmusić nasz język funkcjonalny do paradygmatu pseudo-OOP, usuwając w ten sposób część elegancji i stabilności prawdziwego programowania funkcjonalnego.
Oczywiście żadna z tych opcji nie wydaje się idealna. Znalazłeś sposób na obejście tych problemów? Czy naprawdę jest jakiś problem?
Uwaga: Osobiście najlepiej znam LISP na froncie FP, więc jeśli chcesz podać jakieś przykłady i znać wiele języków FP, prawdopodobnie preferowanym językiem byłby lisp
PS: W przypadku problemów specyficznych dla innych aspektów tworzenia stron internetowych zobacz to pytanie .
źródło
Odpowiedzi:
Przede wszystkim nie powiedziałbym, że CLOS (Common Lisp Object System) to „pseudo-OO”. Jest to pierwsza klasa OO.
Po drugie, uważam, że powinieneś użyć paradygmatu, który pasuje do twoich potrzeb.
Nie można przechowywać danych bezstanowych, podczas gdy funkcja jest przepływem danych i tak naprawdę nie potrzebuje stanu.
Jeśli masz kilka potrzeb połączonych, wymieszaj swoje paradygmaty. Nie ograniczaj się tylko do korzystania z prawego dolnego rogu skrzynki narzędziowej.
źródło
Patrząc na to z perspektywy osoby zajmującej się bazą danych, uważam, że programiści front-end zbyt mocno starają się znaleźć sposoby, aby bazy danych pasowały do ich modelu, zamiast rozważać najskuteczniejsze sposoby korzystania z bazy danych, która nie jest zorientowana obiektowo lub funkcjonalna, ale relacyjna i używa teoria mnogości. Widziałem, że generalnie powoduje to słaby kod. Ponadto tworzy kod, który jest trudny do dostrojenia.
Rozważając dostęp do bazy danych, należy wziąć pod uwagę trzy główne kwestie - integralność danych (dlaczego wszystkie reguły biznesowe powinny być egzekwowane na poziomie bazy danych, a nie za pośrednictwem interfejsu użytkownika), wydajność i bezpieczeństwo. SQL został napisany w celu efektywniejszego zarządzania dwoma pierwszymi zagadnieniami niż jakikolwiek język front-end. Ponieważ jest specjalnie do tego zaprojektowany. Zadanie bazy danych znacznie różni się od zadania interfejsu użytkownika. Czy można się zatem dziwić, że typ kodu, który jest najskuteczniejszy w zarządzaniu zadaniem, jest koncepcyjnie inny?
A bazy danych zawierają informacje krytyczne dla przetrwania firmy. Nic dziwnego, że firmy nie chcą eksperymentować z nowymi metodami, gdy stawką jest ich przetrwanie. Do diabła, wiele firm nie chce nawet uaktualnić do nowych wersji swojej istniejącej bazy danych. Tak więc w projektowaniu baz danych tkwi nieodłączny konserwatyzm. I to celowo w ten sposób.
Nie próbowałbym pisać T-SQL lub używać koncepcji projektowania baz danych do tworzenia interfejsu użytkownika, dlaczego miałbyś próbować używać języka interfejsu i koncepcji projektowych, aby uzyskać dostęp do mojej bazy danych? Ponieważ uważasz, że SQL nie jest wystarczająco wyszukany (lub nowy)? Albo nie czujesz się z tym dobrze? To, że coś nie pasuje do modelu, z którym czujesz się najbardziej komfortowo, nie oznacza, że jest złe lub złe. Oznacza to, że jest inny i prawdopodobnie inny z uzasadnionego powodu. Używasz innego narzędzia do innego zadania.
źródło
Powinieneś spojrzeć na artykuł „Out of the Tar Pit” autorstwa Bena Moseleya i Petera Marksa, dostępny tutaj: „Out of the Tar Pit” (6 lutego 2006)
Jest to nowoczesny klasyk, który szczegółowo opisuje paradygmat / system programowania zwany programowaniem funkcjonalno-relacyjnym. Chociaż nie odnosi się bezpośrednio do baz danych, omawia, jak oddzielić interakcje ze światem zewnętrznym (na przykład bazami danych) od funkcjonalnego rdzenia systemu.
W artykule omówiono również sposób implementacji systemu, w którym stan wewnętrzny aplikacji jest definiowany i modyfikowany za pomocą algebry relacyjnej, co oczywiście wiąże się z relacyjnymi bazami danych.
Ten artykuł nie da dokładnej odpowiedzi na temat integracji baz danych i programowania funkcjonalnego, ale pomoże zaprojektować system tak, aby zminimalizować problem.
źródło
Języki funkcjonalne nie mają na celu pozostania bezpaństwowymi, ich celem jest jawne zarządzanie państwem. Na przykład w Haskell można uznać monadę stanu za serce „normalnego” stanu, a monadę IO za reprezentację stanu, który musi istnieć poza programem. Obie te monady pozwalają (a) jawnie reprezentować akcje stanowe i (b) budować akcje stanowe poprzez komponowanie ich przy użyciu referencyjnie przezroczystych narzędzi.
Odwołujesz się do wielu ORMów, które, zgodnie z nazwą, są abstrakcyjnymi bazami danych jako zestawami obiektów. Doprawdy, nie to reprezentują informacje w relacyjnej bazie danych! Zgodnie ze swoją nazwą reprezentuje dane relacyjne. SQL jest algebrą (językiem) do obsługi relacji w relacyjnym zbiorze danych i sam w sobie jest całkiem „funkcjonalny”. Podnoszę to, aby wziąć pod uwagę, że (a) ORMy nie są jedynym sposobem mapowania informacji z bazy danych, (b) SQL jest w rzeczywistości całkiem przyjemnym językiem dla niektórych projektów baz danych oraz (c) że języki funkcjonalne często mają algebrę relacyjną odwzorowania, które ujawniają moc SQL w idiomatyczny (aw przypadku Haskella, sprawdzony typowo) sposób.
Powiedziałbym, że większość seplenienia to język funkcjonalny biedaka. Jest w pełni zdolny do używania zgodnie z nowoczesnymi praktykami funkcjonalnymi, ale ponieważ nie wymaga ich, społeczność jest mniej skłonna do ich używania. Prowadzi to do szeregu metod, które mogą być bardzo przydatne, ale z pewnością przesłaniają, jak czyste interfejsy funkcjonalne mogą nadal w znaczący sposób wykorzystywać bazy danych.
źródło
Nie sądzę, aby bezpaństwowa natura języków FP stanowiła problem z łączeniem się z bazami danych. Lisp nie jest czysto funkcjonalnym językiem programowania, więc nie powinien mieć problemu ze stanem. A czysto funkcjonalne języki programowania, takie jak Haskell, mają sposoby radzenia sobie z danymi wejściowymi i wyjściowymi, które można zastosować do korzystania z baz danych.
Z twojego pytania wygląda na to, że twój główny problem polega na znalezieniu dobrego sposobu na wyodrębnienie danych opartych na rekordach, które otrzymujesz z bazy danych, do czegoś, co jest lisp-y (lisp-ish?) Bez konieczności pisania dużej ilości SQL kod. Wygląda to bardziej na problem z narzędziami / bibliotekami niż problem z paradygmatem językowym. Jeśli chcesz robić czyste FP, być może seplenienie nie jest dla ciebie odpowiednim językiem. Zwykłe lisp wydaje się bardziej polegać na integracji dobrych pomysłów z oo, fp i innych paradygmatów niż na czystym fp. Może powinieneś używać Erlanga lub Haskella, jeśli chcesz przejść czystą trasę FP.
Myślę, że pomysły „pseudo-oo” w seplenie też mają swoje zalety. Możesz je wypróbować. Jeśli nie pasują do sposobu, w jaki chcesz pracować z danymi, możesz spróbować utworzyć warstwę na wierzchu Weblocks, która pozwoli ci pracować z danymi tak, jak chcesz. To może być łatwiejsze niż samodzielne pisanie wszystkiego.
Zastrzeżenie: nie jestem ekspertem od Lispa. Interesuję się głównie językami programowania i bawiłem się Lisp / CLOS, Scheme, Erlang, Python i trochę Ruby. W codziennym życiu programistycznym wciąż jestem zmuszony do używania C #.
źródło
Jeśli twoja baza danych nie niszczy informacji, możesz pracować z nią w sposób funkcjonalny zgodny z wartościami programowania „czysto funkcjonalnego”, pracując w funkcjach całej bazy danych jako wartości.
Jeśli w czasie T baza danych stwierdza, że "Bob lubi Suzie", a miałeś funkcję lubię, która zaakceptowała bazę danych i podobną, to dopóki możesz odzyskać bazę danych w czasie T, masz czysty program funkcjonalny, który zawiera bazę danych . na przykład
Aby to zrobić, nie możesz nigdy wyrzucić informacji, których możesz użyć (co w praktyce oznacza, że nie możesz wyrzucić informacji), więc Twoje potrzeby przechowywania będą rosły monotonnie. Ale możesz zacząć pracować z bazą danych jako liniową serią dyskretnych wartości, gdzie kolejne wartości są powiązane z poprzednimi poprzez transakcje.
Na przykład to główna idea stojąca za Datomic .
źródło
Ani trochę. Istnieje gatunek baz danych znany jako „Funkcjonalne bazy danych”, z których Mnesia jest prawdopodobnie najbardziej dostępnym przykładem. Podstawową zasadą jest to, że programowanie funkcjonalne jest deklaratywne, więc można je zoptymalizować. Łączenie można zaimplementować za pomocą funkcji List Compression na trwałych kolekcjach, a optymalizator zapytań może zautomatyzować sposób implementacji dostępu do dysku.
Mnesia jest napisana w Erlang i istnieje co najmniej jeden framework sieciowy ( Erlyweb ) dostępny dla tej platformy. Erlang jest z natury równoległy do modelu wątków typu „nic wspólnego”, więc pod pewnymi względami nadaje się do skalowalnych architektur.
źródło
Baza danych to doskonały sposób na śledzenie stanu w bezstanowym interfejsie API. Jeśli subskrybujesz REST, Twoim celem jest napisanie bezstanowego kodu, który współdziała z magazynem danych (lub innym zapleczem), który śledzi informacje o stanie w przejrzysty sposób, tak aby Twój klient nie musiał tego robić.
Pomysł Object-Relational Mapper, w którym importujesz rekord bazy danych jako obiekt, a następnie modyfikujesz go, jest tak samo przydatny i przydatny w programowaniu funkcjonalnym, jak w programowaniu obiektowym. Jedynym zastrzeżeniem jest to, że programowanie funkcjonalne nie modyfikuje obiektu w miejscu, ale interfejs API bazy danych umożliwia modyfikowanie rekordu w miejscu. Przepływ kontroli Twojego klienta wyglądałby mniej więcej tak:
Baza danych zaktualizuje rekord wprowadzonymi zmianami. Programowanie czysto funkcjonalne może uniemożliwić ponowne przypisywanie zmiennych w zakresie programu , ale interfejs API bazy danych nadal może zezwalać na aktualizacje w miejscu.
źródło
Najwygodniej jest z Haskellem. Najbardziej znanym frameworkiem sieciowym Haskell (porównywalnym z Railsami i Django) jest Yesod. Wygląda na to, że ma całkiem fajny, bezpieczny dla typów, multi-backendowy ORM. Zajrzyj do rozdziału Wytrwałość w ich książce.
źródło
Bazy danych i programowanie funkcjonalne można łączyć.
na przykład:
Clojure to funkcjonalny język programowania oparty na teorii relacyjnych baz danych.
Uwaga: w najnowszej specyfikacji spec2 bardziej przypomina RMDB. zobacz: spec-alpha2 wiki: Schema-and-select
Opowiadam się za: budowaniem relacyjnego modelu danych na szczycie mapy skrótów, aby osiągnąć kombinację zalet NoSQL i RMDB. W rzeczywistości jest to odwrotna implementacja posgtresql.
Duck Typing: Jeśli wygląda jak kaczka i kwacze jak kaczka, musi to być kaczka.
Jeśli model danych clojure jest taki jak RMDB, obiekty clojure, takie jak RMDB i manipulowanie danymi clojure, takie jak RMDB, clojure musi być RMDB.
Clojure to funkcjonalny język programowania oparty na teorii relacyjnych baz danych
Wszystko jest w RMDB
Wdrażaj relacyjny model danych i programowanie w oparciu o mapę skrótów (NoSQL)
źródło