W wyniku dyskusji tutaj zastanawiam się, czy możesz nauczyć się programowania funkcjonalnego w C?
W wyniku dyskusji tutaj zastanawiam się, czy możesz nauczyć się programowania funkcjonalnego w C?
Odpowiedzi:
Oczywiście można zrobić programowania funkcyjnego w teorii C., można również dowiedzieć się funkcjonalnych zasad programowania w C, ale język nie ułatwiają.
Zakładam, że masz przynajmniej trochę doświadczenia w OOP; jeśli to zrobisz, powinieneś zdawać sobie sprawę, że OOP można wykonać w C, w tym polimorfizm, metody pobierające / ustawiające, reguły widoczności itp. itp., Ale jest to dość bolesne, a musisz znać zarówno OOP, jak i C wewnątrz- wyciągnąć go. Podobnie jest z FP.
Co powinno się robić to najpierw nauczyć funkcjonalny język programowania (większość z nich ma zaskakująco prostych zasad składni, to nie jest składnia sprawia, że trudno im się nauczyć), a następnie pozwól, aby nowo nabyta wiedza wpływa na sposób zapisu C.
Zgodnie z prośbą, kilka rzeczy możesz nauczyć się od FP, a następnie zastosować, powiedzmy, C, C ++ lub Java:
C można zhakować, aby zaoferować pewne koncepcje funkcjonalne:
To pytanie StackOverflow powie ci więcej. Ale chociaż wydaje się możliwe wykonywanie programowania funkcjonalnego (lub dużej części) w języku C, włamania i rozszerzenia kompilatora i cokolwiek innego, co nie jest najlepszym sposobem na poznanie koncepcji.
Aby faktycznie nauczyć się programowania funkcjonalnego, najlepszym rozwiązaniem jest jeden z wiodących języków programowania funkcjonalnego, takich jak Lisp i jego dialekty ( Clojure , Scheme ), Erlang i Haskell . Każde z nich to doskonałe narzędzia, które działają w ramach funkcjonalnego sposobu programowania. F # jest również dobrym kandydatem, jeśli masz tło .Net, ale jest to język paradygmatu, a nie tylko funkcjonalny język programowania.
Jak zauważa tdammers w komentarzach:
W rzeczywistości LISP, clojure i schemat są również paradygmatem; Haskell, chociaż jest czysty i domyślnie leniwy, umożliwia także imperatywne programowanie w kontekście monadycznym i ma szerokie wsparcie dla jednoczesnego przetwarzania. Wszystkie te mają mechanizmy, które wdrażają duże części mądrości zgromadzonej w świecie OOP - enkapsulacja, dziedziczenie, jedna odpowiedzialność, kompozycja itp. Nie chodzi o to, czy język ZEZWALA na inne paradygmaty; chodzi o to, który paradygmat stanowi punkt wyjścia dla języka.
Zgodnie z moją najlepszą wiedzą Lisp i jego dialekty oraz Erlang są lepszymi kandydatami niż F #, ponieważ zachęcają do programowania funkcjonalnego w porównaniu z innymi paradygmatami, co tammers pięknie określa jako punkt wyjścia dla języka . F # obejmuje programowanie funkcjonalne, ale nie zachęca go do korzystania z innych obsługiwanych paradygmatów, programowania imperatywnego i oo.
Nie możesz nauczyć się wszystkich aspektów programowania funkcjonalnego w C. Ale z pewnością możesz rozpocząć programowanie w stylu funkcjonalnym z dowolnym językiem imperatywnym. Te bity początkowe to: „Jak zachować czystość podczas programowania”. I można to zrobić również C. Sprawdź ten post na blogu, aby uzyskać szczegółowe informacje-
http://www.johndcook.com/blog/2011/07/24/get-started-functional-programming/
Programowanie funkcjonalne dotyczy zamknięć i ich aplikacji. O ile ktoś nie jest w stanie pokazać biblioteki zamykającej zejście dla C, zapomnij o użyciu C do nauki programowania funkcjonalnego.
Kardynalną koncepcją programowania funkcjonalnego jest pojęcie zamknięć, które z grubsza ujmują funkcję wraz z powiązaniami zmiennych. Oprócz powszechnego użycia zamknięć, istnieje kilka innych charakterystycznych cech w programowaniu funkcjonalnym, takich jak użycie funkcji rekurencyjnych i niezmiennych wartości (obie grają dobrze razem). Te cechy są bardziej kwestią kulturową niż cokolwiek innego i nie ma technicznych przeszkód, aby używać ich w praktycznie dowolnym języku, dlatego w mojej odpowiedzi skupiam się na zamknięciach: nie każdy język pozwala na łatwe tworzenie zamknięć.
Typowym zastosowaniem zamknięć jest wdrożenie mechanizmów prywatności. Na przykład kod JavaScript - w przykładach wybrałem Javascript, ponieważ jest to język funkcjonalny o tak zwanej „składni podobnej do C”, a twoje pytanie sugeruje, że znasz C:
create_counter = function()
{
var x = 0;
var counter = function()
{
++x;
return x;
};
return counter;
}
Potem z
a = create_counter();
b = create_counter();
mamy dwie funkcje a
i b
liczenie rozłącznych kolekcji. Punktem przykładu jest to, że zmienne x
są przechwytywane przez zamknięcie definiujące counter
zamknięcie i za każdym razem, gdy jest nowe counter
zamknięcie is instantiated by the function, it gets its fresh own idea of what
x`.
Innym typowym zastosowaniem zamknięć jest definicja częściowego zastosowania funkcji. Załóżmy, że mamy funkcję raportowania podobną do syslog
implementacji funkcji
var log = function(priority, message) {
…
};
gdzie argumenty priority
i message
oczekuje się być ciągi, pierwszy będąc jednym "debug"
, "info"
i tak dalej. Możemy zdefiniować fabrykę logów w następujący sposób:
var logWithPriority = function(priority) {
return function(message) {
log(priority, message);
};
};
i użyj go do zdefiniowania specjalistycznych wersji naszego narzędzia do rejestrowania:
var debug = logWithPriority("debug");
var info = logWithPriority("info");
…
Jest to bardzo przydatne, ponieważ zamiast pisać takie podatne na błędy for
pętle
for(i = 0; i < journal.length; ++i) {
log("info", journal[i]);
}
możemy napisać czystsze, krótsze i znacznie prostsze (nie ma i
, to jest znacznie lepsze):
journal.forEach(logWithPriority("info"));
Trzecim ważnym obszarem zastosowania zamknięć jest wdrożenie leniwej oceny - należy pamiętać, że specjalne wsparcie językowe może zapewnić lepszą implementację.
Leniwa funkcja zamiast wykonywania prostych obliczeń zwraca zamknięcie, które można wywołać (lub „wymusić” w żargonie lenistwa) w celu wykonania pytania. Motywacją do tego jest oddzielenie przygotowywania obliczeń i wykonywania obliczeń. Praktycznym tego przykładem jest kompilacja wyrażeń regularnych: jeśli program skompiluje wiele wyrażeń regularnych w czasie uruchamiania, uruchomienie programu będzie wymagało dużo czasu. Jeśli zamiast tego leniwie skompilujemy wyrażenia regularne i wymuszymy je tak, jak potrzebujemy, nasz program może się szybko uruchomić. Oczywiście, wyrażenia regularne można tutaj zastąpić dowolną strukturą wymagającą znacznego czasu inicjalizacji.
Oto jak wdrożyć leniwą ocenę z zamknięciami. Rozważ klasyczną implementację funkcji arrayMax zwracającą maksimum w tablicy:
function arrayMax(array) {
return array.reduce(function(a, b) {
return Math.min(a, b);
};
}
Leniwym wariantem byłoby:
function arrayMax(array) {
var memo = null;
function actuallyCompute() {
if(memo === null) {
memo = array.reduce(function(a, b) {
return Math.min(a, b);
});
}
return memo;
}
return actuallyCompute;
}
Zwrócona wartość to zamknięcie, którego można użyć do obliczenia wartości lub odzyskania jej innym razem, jeśli została już obliczona.
Dzięki tym trzem przykładom powinniśmy być pewni, że zamknięcia i ich aplikacje są podstawą programowania funkcjonalnego.
Nauka programowania funkcjonalnego oznacza naukę programowania z zamknięciami. W związku z tym podczas wyszukiwania języka do programowania funkcjonalnego należy wziąć pod uwagę języki umożliwiające łatwą manipulację zamknięciami, a zwłaszcza częściowe zastosowanie funkcji. I odwrotnie, języki, w których nie można łatwo manipulować zamknięciami, byłyby złym wyborem.
Myślę, że narzędzia, których używasz, mają duży wpływ na naukę. Jest prawie niemożliwe, aby nauczyć się pojęć programistycznych, dla których używany język programowania nie zapewnia środków do wykorzystania. Jasne, zawsze możesz nauczyć się kilku rzeczy, ale nie możesz się tego właściwie nauczyć.
Ale to i tak akademicki, ponieważ, jak Martinho mówi w swoim komentarzu , nawet jeśli mogłyby uczyć się programowania funkcjonalne, to powinien nie spróbować to zrobić, ponieważ nie są w językach, gdzie jest to dużo łatwiejsze.
Nie powinieneś uczyć się programowania funkcjonalnego w C, ale w ścisłym języku funkcjonalnym (Haskell, Caml, Erlang itp.).
Jeśli jesteś nowy w funkcjonalnym, tak naprawdę nigdy nie dostaniesz go w niefunkcjonalnym języku. Bardziej prawdopodobne jest, że nauczysz się robić to, co uważasz za programowanie funkcjonalne i nauczysz się rzeczy w niewłaściwy sposób. I zawsze trudniej jest „nauczyć się” rzeczy we właściwy sposób, niż na początku uczyć się ich we właściwy sposób.
W każdym razie myślę, że wykonywanie funkcji w C jest dobrym ćwiczeniem dla kogoś, kto już zna funkcjonalność. Ponieważ ta osoba dowie się, co dzieje się za maską - co tak naprawdę robi komputer.