Buradaki yorum tartışmasının bir sonucu olarak, C de Fonksiyonel Programlamayı öğrenip öğrenemeyeceğinizi merak ediyorum.
Buradaki yorum tartışmasının bir sonucu olarak, C de Fonksiyonel Programlamayı öğrenip öğrenemeyeceğinizi merak ediyorum.
Yanıtlar:
Açıkçası yapabilirsiniz do C. In teoride fonksiyonel programlama, ayrıca edebilirsiniz öğrenmek C fonksiyonel programlama prensiplerini, ama dil kolay yapmaz.
OOP'de en azından biraz geçmişiniz olduğunu varsayıyorum; bunu yaparsanız, OOP'nin polimorfizm, alıcılar / ayarlayıcılar, görünürlük kuralları vb. çıkarın. FP ile aynı şey.
Yapmanız gereken ilk önce işlevsel bir programlama dili öğrenmek (çoğu şaşırtıcı derecede basit sözdizimi kurallarına sahiptir; öğrenmelerini zorlaştıran sözdizimi değildir) ve sonra yeni edinilen bilgeliğinizin C yazma şeklinizi etkilemesine izin verin.
İsteğe bağlı olarak, FP'den öğrenebileceğiniz ve sonra C, C ++ veya Java'da uygulayabileceğiniz birkaç şey:
C bazı fonksiyonel kavramlar sunmak için saldırıya uğrayabilir:
Bu StackOverflow sorusu size daha fazlasını anlatacaktır. Ancak, C, bilgisayar korsanları ve derleyici uzantıları ve bir kavram öğrenmenin en iyi yolu ne değilse, işlevsel programlama (veya büyük bir alt kümesi) yapmak mümkün gibi görünse de.
Fonksiyonel programlamayı gerçekten öğrenmek için en iyi seçeneğiniz Lisp ve lehçeleri ( Clojure , Scheme ), Erlang ve Haskell gibi önde gelen fonksiyonel programlama dillerinden biridir . Bunlardan herhangi biri, işlevsel programlama zihniyeti içinde çalışan mükemmel araçlardır. F # , aynı zamanda .Net arka planınız varsa iyi bir adaydır, ancak çok işlevsel bir programlama dili değil, çok paradigma dilidir.
Tdammers'ın açıklamalarda belirttiği gibi :
Aslında, LISP, clojure ve şema da çok paradigmadır; Haskell, saf ve varsayılan tembel olmakla birlikte, monadik bir bağlamdayken zorunlu programlamaya da izin verir ve eşzamanlı işleme için geniş bir desteğe sahiptir. Bunların hepsinin OOP dünyasında toplanan bilgeliğin büyük bölümlerini uygulayan mekanizmaları vardır - kapsülleme, miras, tek sorumluluk, kompozisyon, vb. hangi paradigmanın bir dilin başlangıç noktasını oluşturduğu ile ilgilidir.
Diğer paradigmaların üzerinde fonksiyonel programlama teşvik çünkü benim kadarıyla Lisp ve lehçeleri ve Erlang F # daha iyi adaylardır ne tdammers güzelce olarak bildiren bir dilin başlangıç noktası . F #, işlevsel programlamayı kapsar, ancak diğer desteklenen paradigmaları, zorunlu ve oo programlarını teşvik etmez.
C'de fonksiyonel programlamanın tüm yönlerini öğrenemezsiniz. Ancak elbette herhangi bir zorunlu dilde fonksiyonel stil programlamaya başlayabilirsiniz. Bu başlangıç bitleri "Programlama sırasında işleri nasıl saf tutarız" dır. Ve C de yapılabilir. Ayrıntılar için bu blog yayınına bakın
http://www.johndcook.com/blog/2011/07/24/get-started-functional-programming/
Fonksiyonel programlama, kapaklar ve uygulamaları ile ilgilidir. Birisi size C için bir iniş kapatma kütüphanesi gösteremezse, fonksiyonel programlamayı öğrenmek için C'yi kullanmayı unutun.
Fonksiyonel programlamanın temel konsepti, kabaca konuşan, değişken bağlarla birlikte bir işlevi yakalayan kapaklar kavramıdır . Kapakların yaygın kullanımının yanı sıra, fonksiyonel programlamada, özyinelemeli işlevlerin ve değişmez değerlerin kullanılması gibi her iki ayırt edici özellik de vardır (her ikisi de birlikte iyi oynar). Bu özellikler her şeyden çok kültürel bir konudur ve bunları hemen hemen her dilde kullanmanın teknik bir engeli yoktur, bu yüzden cevabımdaki kapanışlara odaklanıyorum: her dil kolayca kapanmaya izin vermiyor.
Kapakların tipik kullanımı gizlilik mekanizmalarının uygulanmasıdır. Örneğin Javascript kodu - Örneklerde Javascript'i seçtim çünkü “C benzeri bir sözdizimi” olan işlevsel bir dil ve sorunuz C'ye aşina olduğunuzu gösteriyor:
create_counter = function()
{
var x = 0;
var counter = function()
{
++x;
return x;
};
return counter;
}
Sonra ile
a = create_counter();
b = create_counter();
iki fonksiyonumuz var a
ve b
ayrık koleksiyonları sayıyoruz. Örneğin amacı, değişkenlerin x
kapağı tanımlayan kapak tarafından yakalanması counter
ve her yeni counter
kapak is instantiated by the function, it gets its fresh own idea of what
x` olduğunda.
Kapakların bir başka tipik kullanımı, işlevlerin kısmi uygulamalarının tanımlanmasıdır. syslog
Bir işlevi uygulamaya benzer bir raporlama tesisimiz olduğunu varsayın
var log = function(priority, message) {
…
};
argümanlar nerede priority
ve message
dizeleri olması bekleniyor, ilki biri olmak "debug"
, "info"
vb. Bir günlük fabrikasını şu şekilde tanımlayabiliriz:
var logWithPriority = function(priority) {
return function(message) {
log(priority, message);
};
};
ve günlük tesisimizin özel sürümlerini tanımlamak için kullanın:
var debug = logWithPriority("debug");
var info = logWithPriority("info");
…
Bunun nedeni yerine hataya yazma, çok yararlıdır for
böyle -loops
for(i = 0; i < journal.length; ++i) {
log("info", journal[i]);
}
daha temiz, daha kısa ve daha basit yazabiliriz (hayır i
, bu çok daha iyi):
journal.forEach(logWithPriority("info"));
Kapakların üçüncü önemli uygulama alanı, tembel değerlendirmenin uygulanmasıdır - özel dil desteğinin daha iyi bir uygulama sağlayabileceğini unutmayın.
Tembel bir işlev, düz bir hesaplama yapmak yerine, soruyu gerçekleştirmek için çağrılabilen (veya tembellik jargonunda “zorla”) bir kapatma döndürür. Bunu yapmak için motivasyon, bir hesaplama hazırlamak ve bir hesaplama yapmak arasında ayrım yapmaktır. Bunun pratik bir örneği düzenli ifade derlemesidir: bir program başlangıç zamanında çok sayıda düzenli ifade derlerse, başlamak için çok zaman gerekir. Bunun yerine düzenli ifadeleri tembel olarak derler ve ihtiyaç duyduğumuzda zorlarsak, programımız hızlı bir şekilde başlayabilir. Tabii ki, düzenli ifadeler burada önemli ölçüde başlatma süresi gerektiren herhangi bir yapı ile değiştirilebilir.
Tembel değerlendirmenin kapanışlarla nasıl uygulanacağı aşağıda açıklanmıştır. Bir dizideki max değerini döndüren arrayMax işlevinin klasik uygulamasını düşünün :
function arrayMax(array) {
return array.reduce(function(a, b) {
return Math.min(a, b);
};
}
Tembel varyant:
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;
}
Döndürülen değer, değeri hesaplamak veya zaten hesaplanmışsa başka bir zaman almak için kullanılabilen bir kapaktır.
Bu üç örnekle, kapakların ve uygulamalarının fonksiyonel programlamanın çekirdeği olduğundan emin olmalıyız .
Fonksiyonel programlamayı öğrenmek, kapaklarla nasıl programlanacağını öğrenmek anlamına gelir. Sonuç olarak, işlevsel programlamayı incelemek için bir dil ararken, kapakların kolayca değiştirilmesine izin veren diller ve özellikle işlevlerin kısmi uygulanması dikkate alınmalıdır. Tersine, kapakların kolayca değiştirilemediği diller kötü seçimler olacaktır.
Kullandığınız araçların öğrenmenizi çok etkilediğini düşünüyorum. Kullandığınız programlama dilinin yararlanmanın yollarını sağlamadığı programlama kavramlarını öğrenmek neredeyse imkansızdır. Elbette, her zaman birkaç şey öğrenebilirsiniz, ancak düzgün bir şekilde öğrenemezsiniz.
Olarak, çünkü Ama bu, akademik zaten olan Martinho onun yorumunda diyor sen bile olabilir fonksiyonel programlamayı öğrenmek, sen gereken bu olduğu diller olduğundan, bunu çalışmayın çok daha kolay.
İşlevsel programlamayı C dilinde değil, katı bir işlevsel dilde (Haskell, Caml, Erlang, vb.) Öğrenmelisiniz.
İşlevsel olarak yeniyseniz, bunu gerçekten işlevsel olmayan bir dille elde edemezsiniz. Büyük olasılıkla, fonksiyonel programlama olduğunu düşündüğünüz şeyi yapmak ve işleri yanlış bir şekilde öğrenmek için kendinizi eğiteceksiniz. Ve her şeyi doğru şekilde “yeniden öğrenmek”, ilk başta onları doğru şekilde öğrenmekten daha zordur.
Her neyse, C'de fonksiyonel yapmak zaten fonksiyonel bilen biri için iyi bir egzersiz. Çünkü o kişi kaputun arkasında neler olduğunu öğrenecek - bilgisayarın gerçekte ne yaptığını.