Szukałem w Internecie definicji definicji programowania deklaratywnego i imperatywnego, która rzuciłaby mi trochę światła. Jednak język używany w niektórych z zasobów, które znalazłem, jest zniechęcający - na przykład w Wikipedii . Czy ktoś ma przykład z prawdziwego świata, który mógłby mi pokazać, który może przynieść pewne spojrzenie na ten temat (być może w języku C #)?
541
Odpowiedzi:
Doskonałym przykładem C # programowania deklaratywnego vs. imperatywnego jest LINQ.
Dzięki programowaniu imperatywnemu krok po kroku mówisz kompilatorowi, co chcesz się wydarzyć.
Na przykład zacznijmy od tej kolekcji i wybierz liczby nieparzyste:
Dzięki programowaniu imperatywnemu krok po kroku to robimy i decydujemy, czego chcemy:
Mówimy tutaj:
Z drugiej strony w programowaniu deklaratywnym piszesz kod, który opisuje, co chcesz, ale niekoniecznie, jak go zdobyć (zadeklaruj pożądane wyniki, ale nie krok po kroku):
Mówimy tutaj: „Daj nam wszystko, co dziwne”, a nie „Przejdź przez kolekcję. Zaznacz ten element, jeśli jest dziwny, dodaj go do kolekcji wyników”.
W wielu przypadkach kod będzie również mieszanką obu projektów, więc nie zawsze jest czarno-biały.
źródło
collection.Where
nie używa deklaratywnej składni, którą zapewnia Linq - przykłady można znaleźć w msdn.microsoft.com/en-us/library/bb397906.aspxfrom item in collection where item%2 != 0 select item
. Wywołanie funkcji nie staje się programowaniem deklaratywnym tylko dlatego, że ta funkcja znajduje się w przestrzeni nazw System.Linq.Programowanie deklaratywne jest, kiedy mówisz , co chcesz, a język konieczne jest, kiedy powiedzieć jak dostać to, czego chcesz.
Prosty przykład w Pythonie:
Pierwszy przykład jest deklaratywny, ponieważ nie określamy żadnych „szczegółów implementacji” budowania listy.
Aby powiązać w przykładzie w języku C #, ogólnie, użycie LINQ daje styl deklaratywny, ponieważ nie mówisz, jak uzyskać to, co chcesz; mówisz tylko, co chcesz. To samo możesz powiedzieć o SQL.
Jedną z zalet programowania deklaratywnego jest to, że pozwala on kompilatorowi na podejmowanie decyzji, które mogą skutkować lepszym kodem niż to, co możesz zrobić ręcznie. Uruchamianie z przykładem SQL, jeśli masz takie zapytanie
„kompilator” SQL może „zoptymalizować” to zapytanie, ponieważ wie, że
id
jest to pole indeksowane - a może nie jest indeksowane, w którym to przypadku i tak będzie musiał iterować cały zestaw danych. A może silnik SQL wie, że jest to idealny czas na wykorzystanie wszystkich 8 rdzeni do szybkiego wyszukiwania równoległego. Ty , jako programista, nie są związane z żadnym z tych warunków, a nie trzeba pisać kodu do obsługi specjalnej sprawę w ten sposób.źródło
filter(lambda x: x < 5, range(20))
, jest po prostu kolejnym przekształceniem w krótszą notację. Nie różni się to w żaden znaczący sposób od wyrażenia służącego do rozumienia listy (które ma wyraźne sekcje „map” i „filter”), które zostało utworzone (patrz pep 202 ) z wyraźnym zamiarem stworzenia bardziej zwięzłej notacji. I w tym przypadku zrozumienie tej listy byłoby bardziej jasne / idiomatyczne.Deklaratywny kontra imperatywny
Programowania paradygmat jest podstawową styl programowania. Istnieją cztery główne paradygmaty: imperatywny, deklaratywny, funkcjonalny (który jest uważany za podzbiór deklaratywnego paradygmatu) i obiektowy.
Programowanie deklaratywne : to paradygmat programowania, który wyraża logikę obliczeń (Co zrobić) bez opisywania przepływu sterowania (Jak to zrobić). Niektóre dobrze znane przykłady deklaratywnych języków specyficznych dla domeny (DSL) obejmują CSS, wyrażenia regularne i podzbiór SQL (na przykład zapytania SELECT) Wiele języków znaczników, takich jak HTML, MXML, XAML, XSLT ... jest często deklaratywnych. Programowanie deklaratywne próbuje zatrzeć rozróżnienie między programem jako zestawem instrukcji a programem jako stwierdzeniem o pożądanej odpowiedzi.
Programowanie imperatywne : to paradygmat programowania opisujący obliczenia w kategoriach instrukcji zmieniających stan programu. Programy deklaratywne mogą być podwójnie postrzegane jako polecenia programowania lub twierdzenia matematyczne.
Programowanie funkcjonalne: jest paradygmatem programowania, który traktuje obliczenia jako ocenę funkcji matematycznych i unika stanu i zmiennych danych. Podkreśla zastosowanie funkcji, w przeciwieństwie do imperatywnego stylu programowania, który podkreśla zmiany stanu. W czysto funkcjonalnym języku, takim jak Haskell, wszystkie funkcje nie wywołują skutków ubocznych, a zmiany stanu są reprezentowane tylko jako funkcje przekształcające stan.
Poniższy przykład programowania imperatywnego w MSDN zapętla liczby od 1 do 10 i znajduje liczby parzyste.
Oba przykłady dają ten sam wynik, a jeden nie jest ani lepszy, ani gorszy od drugiego. Pierwszy przykład wymaga więcej kodu, ale kod można przetestować, a podejście imperatywne daje pełną kontrolę nad szczegółami implementacji. W drugim przykładzie kod jest prawdopodobnie bardziej czytelny; LINQ nie daje jednak kontroli nad tym, co dzieje się za kulisami. Musisz ufać, że LINQ zapewni żądany wynik.
źródło
Wszystkie powyższe odpowiedzi i inne posty online zawierają następujące informacje:
Nie powiedzieli nam, jak to osiągnąć . Aby część programu była bardziej deklaratywna, inne części muszą zawierać abstrakcję, aby ukryć szczegóły implementacji (które są kodami bezwzględnymi ).
list.Where()
aby uzyskać nową filtrowaną listę. Aby to zadziałało, Microsoft wykonał wszystkie ciężkie działania za abstrakcją LINQ.W rzeczywistości jednym z powodów, dla których programowanie funkcjonalne i biblioteki funkcjonalne są bardziej deklaratywne, jest to, że wyodrębniono pętle i tworzenie list, ukrywając za sceną wszystkie szczegóły implementacji (najprawdopodobniej niezbędne kody z pętlami).
W każdym programie zawsze będziesz mieć zarówno imperatywny, jak i deklaratywny kod, dlatego powinieneś dążyć do ukrycia wszystkich kodów imperatywnych za abstrakcjami, aby inne części programu mogły z nich korzystać deklaratywnie .
Wreszcie, chociaż programowanie funkcjonalne i LINQ mogą uczynić twój program bardziej deklaratywnym, zawsze możesz uczynić go jeszcze bardziej deklaratywnym, dostarczając więcej abstrakcji. Na przykład:
PS ekstremalnym celem deklaratywnego programowania jest wynalezienie nowych języków specyficznych dla domeny (DSL):
źródło
debit
,deposit
itd zamiast powtarzać imparative koduaccount.balance += depositAmount
Dodam inny przykład, który rzadko pojawia się w deklaratywnej / imperatywnej dyskusji na temat programowania: interfejs użytkownika!
W języku C # można zbudować interfejs użytkownika przy użyciu różnych technologii.
Po stronie imperatywnej możesz użyć DirectX lub OpenGL, aby bardzo koniecznie narysować przyciski, pola wyboru itp. Linia po linii (lub tak naprawdę, trójkąt po trójkącie). Od Ciebie zależy, jak narysować interfejs użytkownika.
Na końcu deklaratywnym masz WPF. Zasadniczo piszesz trochę XML (tak, tak, technicznie „XAML”), a framework działa dla Ciebie. Mówisz, jak wygląda interfejs użytkownika. To system decyduje, jak to zrobić.
W każdym razie, jeszcze jedna rzecz do przemyślenia. To, że jeden język jest deklaratywny lub imperatywny, nie oznacza, że nie ma pewnych cech drugiego.
Jedną z zalet programowania deklaratywnego jest to, że cel jest zwykle łatwiejszy do zrozumienia po przeczytaniu kodu, podczas gdy tryb imperatywny daje lepszą kontrolę nad wykonywaniem.
Istota tego wszystkiego:
Deklaratywny ->
what
chcesz zrobićTryb imperatywny ->
how
chcesz to zrobićźródło
Podobało mi się wyjaśnienie z kursu Cambridge + ich przykłady:
int x;
- co (deklaratywne)x=x+1;
- w jaki sposóbźródło
CSS
jest to zatem Imperatywny ?Różnica dotyczy głównie ogólnego poziomu abstrakcji. Z deklaratywnym, w pewnym momencie jesteś tak daleko od poszczególnych kroków, że program ma dużą swobodę w zakresie uzyskiwania wyniku.
Możesz spojrzeć na każdy fragment instrukcji jako spadający gdzieś na kontinuum:
Stopień abstrakcji:
Przykład deklaratywnego świata rzeczywistego:
Przykład imperatywnego świata rzeczywistego:
źródło
Calvert, C Kulkarni, D (2009). Niezbędny LINQ. Addison Wesley. 48.
źródło
Programowanie imperatywne mówi komputerowi wprost, co robić i jak to zrobić, na przykład określając kolejność i tym podobne
DO#:
Deklaratywna jest, gdy mówisz komputerowi, co robić, ale nie tak naprawdę, jak to zrobić. Datalog / Prolog to pierwszy język, który przychodzi na myśl w tym zakresie. Zasadniczo wszystko jest deklaratywne. Naprawdę nie możesz zagwarantować zamówienia.
C # jest znacznie bardziej imperatywnym językiem programowania, ale niektóre funkcje C # są bardziej deklaratywne, jak Linq
To samo można napisać bezwzględnie:
(przykład z wikipedii Linq)
źródło
From http://en.wikipedia.org/wiki/Declarative_programming
w skrócie deklaratywny język jest prostszy, ponieważ brakuje mu złożoności przepływu sterowania (pętle, instrukcje if itp.)
Dobrym porównaniem jest model „zakodowany” w programie ASP.Net. Masz deklaratywne pliki „.ASPX”, a następnie niezbędne pliki kodu „ASPX.CS”. Często stwierdzam, że jeśli mogę zrobić wszystko, czego potrzebuję w deklaratywnej połowie skryptu, o wiele więcej osób może obserwować, co się dzieje.
źródło
Kradzież od Philipa Robertsa tutaj :
Dwa przykłady:
1. Podwojenie wszystkich liczb w tablicy
Koniecznie:
Deklaracyjnie:
2. Zsumowanie wszystkich pozycji na liście
Bezwzględnie
Deklaratywnie
Zwróć uwagę, że przykłady imperatywne obejmują tworzenie nowej zmiennej, mutowanie jej i zwracanie tej nowej wartości (tj. Jak sprawić, by coś się stało), podczas gdy przykłady deklaratywne są wykonywane na danych wejściowych i zwracają nową wartość na podstawie danych wejściowych (tj. , co chcemy się wydarzyć).
źródło
Programowanie imperatywne
Język programowania, który wymaga dyscypliny programowania, takiej jak C / C ++, Java, COBOL, FORTRAN, Perl i JavaScript. Programiści piszący w takich językach muszą opracować odpowiednią kolejność działań w celu rozwiązania problemu, w oparciu o wiedzę na temat przetwarzania danych i programowania.
Programowanie deklaratywne
Język komputera, który nie wymaga pisania tradycyjnej logiki programowania; Użytkownicy koncentrują się na definiowaniu danych wejściowych i wyjściowych, a nie etapów programu wymaganych w proceduralnym języku programowania, takim jak C ++ lub Java.
Deklaratywnymi przykładami programowania są CSS, HTML, XML, XSLT, RegX.
źródło
program deklaratywny to tylko dane dla jego mniej lub bardziej „uniwersalnego” imperatywnego wdrożenia / vm.
plusy: określenie tylko danych, w pewnym zakodowanym (i zaznaczonym) formacie, jest prostsze i mniej podatne na błędy niż bezpośrednie określenie wariantu jakiegoś bezwzględnego algorytmu. niektóre złożone specyfikacje nie mogą być napisane bezpośrednio, tylko w jakiejś formie DSL. najlepszym i często używanym w strukturach danych DSL są zestawy i tabele. ponieważ nie masz zależności między elementami / wierszami. a kiedy nie masz zależności, masz swobodę modyfikowania i łatwość wsparcia. (porównaj na przykład moduły z klasami - z modułami, które jesteś zadowolony, a z klasami masz delikatny problem z klasą podstawową) wszystkie towary deklaratywności i DSL natychmiast czerpią korzyści z zalet tych struktur danych (tabel i zestawów). kolejny plus - możesz zmienić implementację deklaratywnego języka vm, jeśli DSL jest mniej więcej abstrakcyjnym (dobrze zaprojektowanym). na przykład wykonaj równoległą implementację.
minusy: dobrze zgadujesz. ogólna (i sparametryzowana przez DSL) implementacja algorytmu imperatywnego / vm może być wolniejsza i / lub wymagająca dużej ilości pamięci niż konkretna. w niektórych przypadkach. jeśli takie przypadki są rzadkie - po prostu zapomnij o tym, niech będzie powolne. jeśli jest to częstotliwość - zawsze możesz przedłużyć DSL / vm dla tego przypadku. gdzieś spowalniają wszystkie inne przypadki, na pewno ...
Struktury PS znajdują się w połowie drogi między DSL a trybem rozkazującym. i jak wszystkie rozwiązania w połowie drogi ... łączą wady, a nie korzyści. nie są tak bezpieczne I nie tak szybko :) spójrz na haskell typu jack-of-all-trade - jest w połowie drogi między mocnym prostym ML a elastycznym metaprogiem Prolog i ... jakim jest potworem. możesz spojrzeć na Prologa jak na Haskella z funkcjami / predykatami tylko boolowskimi. i jak prosta jest jego elastyczność w stosunku do Haskell ...
źródło
Zastanawiam się tylko, dlaczego nikt nie wspomniał o klasach atrybutów jako deklaratywnym narzędziu programistycznym w języku C #. Popularna odpowiedź na tej stronie mówi właśnie o LINQ jako deklaratywnym narzędziu programistycznym.
Według Wikipedii
Zatem LINQ, jako składnia funkcjonalna, jest zdecydowanie metodą deklaratywną, ale klasy Attribute w C #, jako narzędzie konfiguracyjne, również są deklaratywne. Oto dobry punkt wyjścia, aby przeczytać więcej na ten temat: Krótki przegląd programowania atrybutów w języku C #
źródło
Wystarczy dodać kolejny przykład w zakresie tworzenia aplikacji mobilnych. W systemach iOS i Android mamy interfejs konstruktorów, w którym możemy zdefiniować interfejs użytkownika aplikacji.
Interfejs użytkownika narysowany przy użyciu tych Konstruktorów ma charakter deklaratywny, w którym przeciągamy i upuszczamy komponenty. Rzeczywisty rysunek odbywa się pod spodem i jest wykonywany przez ramę i system.
Ale możemy również narysować całe komponenty w kodzie, co jest z natury konieczne.
Ponadto niektóre nowe języki, takie jak Angular JS, koncentrują się na deklaratywnym projektowaniu interfejsów użytkownika i możemy zobaczyć wiele innych języków oferujących to samo wsparcie. Podobnie jak Java nie ma dobrego deklaratywnego sposobu rysowania natywnych aplikacji komputerowych w Java Swing lub Java FX, ale w najbliższej przyszłości mogą to zrobić.
źródło
Z mojego zrozumienia oba terminy mają swoje korzenie w filozofii, istnieją deklaratywne i imperatywne rodzaje wiedzy. Wiedza deklaratywna to twierdzenia prawdy, stwierdzenia faktów, takie jak aksjomaty matematyczne. To ci coś mówi. Wiedza imperatywna lub proceduralna mówi krok po kroku, jak dojść do czegoś. Taka jest w istocie definicja algorytmu. Jeśli tak, porównaj komputerowy język programowania z językiem angielskim. Zdania deklaratywne określają coś. Nudny przykład, ale oto deklaratywny sposób pokazania, czy dwie liczby są sobie równe, w Javie:
Zdania rozkazujące w języku angielskim, z drugiej strony, wydają polecenie lub składają jakąś prośbę. Programowanie imperatywne jest więc tylko listą poleceń (zrób to, zrób to). Oto imperatywny sposób wyświetlania w Javie, czy dwie liczby są sobie równe, czy nie, podczas akceptowania danych wprowadzanych przez użytkownika:
Zasadniczo wiedza deklaratywna pomija pewne elementy, tworząc warstwę abstrakcji nad tymi elementami. Programowanie deklaratywne robi to samo.
źródło