Sebagai hasil dari diskusi komentar di sini , saya ingin tahu apakah Anda dapat mempelajari Pemrograman Fungsional dalam C?
Sebagai hasil dari diskusi komentar di sini , saya ingin tahu apakah Anda dapat mempelajari Pemrograman Fungsional dalam C?
Jawaban:
Jelas Anda dapat melakukan pemrograman fungsional dalam C. Secara teori, Anda juga dapat mempelajari prinsip-prinsip pemrograman fungsional dalam C, tetapi bahasa tidak membuatnya mudah.
Saya berasumsi Anda memiliki setidaknya sedikit latar belakang dalam OOP; jika Anda melakukannya, Anda harus menyadari bahwa OOP dapat dilakukan dalam C, termasuk polimorfisme, getter / setter, aturan visibilitas, dll., tetapi itu cukup menyakitkan untuk melakukannya, dan Anda perlu tahu baik OOP dan C di dalam- keluar untuk melakukannya. Ini hampir sama dengan FP.
Yang harus Anda lakukan adalah pertama-tama mempelajari bahasa pemrograman fungsional (kebanyakan dari mereka memiliki aturan sintaksis yang sangat sederhana; bukan sintaks yang membuat mereka sulit untuk dipelajari), dan kemudian biarkan kebijaksanaan Anda yang baru didapat memengaruhi cara Anda menulis C.
Sesuai permintaan, beberapa hal yang dapat Anda pelajari dari FP dan kemudian menerapkan, katakanlah, C, C ++ atau Java:
C dapat diretas untuk menawarkan beberapa konsep fungsional:
Pertanyaan StackOverflow ini akan memberi tahu Anda lebih banyak. Tetapi meskipun tampaknya mungkin untuk melakukan pemrograman fungsional (atau sebagian besar) di C, peretasan dan ekstensi kompiler dan apa pun yang bukan cara terbaik untuk mempelajari suatu konsep.
Untuk benar - benar mempelajari pemrograman fungsional, taruhan terbaik Anda adalah salah satu bahasa pemrograman fungsional terkemuka seperti Lisp dan dialek-dialeknya ( Clojure , Scheme ), Erlang , dan Haskell . Salah satunya adalah alat yang sempurna yang bekerja dalam pola pikir pemrograman fungsional. F # juga merupakan kandidat yang baik jika Anda memiliki latar belakang. Net, tetapi ini adalah bahasa multi-paradigma, bukan sepenuhnya bahasa pemrograman fungsional.
Seperti yang dicatat para komentar dalam komentar:
Sebenarnya, LISP, clojure dan skema juga multi-paradigma; Haskell, meskipun murni dan malas-bawaan, juga memungkinkan pemrograman imperatif saat berada dalam konteks monadik, dan Haskell memiliki dukungan luas untuk pemrosesan bersamaan. Semua ini memiliki mekanisme yang menerapkan sebagian besar kearifan yang terkumpul di dunia OOP - enkapsulasi, pewarisan, tanggung jawab tunggal, komposisi, dll. Ini bukan soal apakah suatu bahasa MENGIZINKAN paradigma lain; ini tentang paradigma mana yang membentuk titik awal suatu bahasa.
Sepengetahuan saya, Lisp dan dialek-dialeknya serta Erlang adalah kandidat yang lebih baik daripada F # karena mereka mendorong pemrograman fungsional di atas paradigma lain, apa yang dinyatakan oleh para pembuat indah sebagai titik awal bahasa . F # mencakup pemrograman fungsional tetapi tidak mendorongnya atas paradigma yang didukung lainnya, pemrograman imperatif dan oo.
Anda tidak dapat mempelajari semua aspek pemrograman fungsional dalam C. Tetapi tentunya Anda dapat memulai pemrograman gaya fungsional dengan bahasa imperatif apa pun. Bit-bit awal ini adalah- "Cara menjaga hal-hal tetap murni saat pemrograman." Dan itu bisa dilakukan C juga. Lihat posting blog ini untuk detail-
http://www.johndcook.com/blog/2011/07/24/get-started-functional-programming/
Pemrograman fungsional adalah tentang penutupan dan aplikasinya. Kecuali seseorang dapat menunjukkan kepada Anda perpustakaan penutupan keturunan untuk C, lupakan menggunakan C untuk mempelajari pemrograman fungsional.
Konsep utama pemrograman fungsional adalah gagasan penutupan yang secara kasar, menangkap fungsi bersama dengan variabel binding. Selain penggunaan penutupan yang luas, ada beberapa ciri khas lain dalam pemrograman fungsional, seperti penggunaan fungsi rekursif dan nilai-nilai yang tidak berubah (keduanya bermain bersama dengan baik). Ciri-ciri ini lebih merupakan masalah budaya daripada yang lainnya, dan tidak ada halangan teknis untuk menggunakannya dalam hampir semua bahasa, ini sebabnya saya fokus pada penutupan dalam jawaban saya: tidak setiap bahasa memungkinkan untuk dengan mudah membuat penutupan.
Penggunaan khas penutupan adalah penerapan mekanisme privasi. Misalnya kode Javascript - dalam contoh saya memilih Javascript karena merupakan bahasa fungsional dengan apa yang disebut "sintaks mirip C" dan pertanyaan Anda menunjukkan bahwa Anda terbiasa dengan C:
create_counter = function()
{
var x = 0;
var counter = function()
{
++x;
return x;
};
return counter;
}
Lalu dengan
a = create_counter();
b = create_counter();
kami memiliki dua fungsi a
dan b
menghitung koleksi yang terpisah. Inti dari contoh ini adalah bahwa variabel x
ditangkap oleh closure yang mendefinisikan counter
closure dan setiap kali x` counter
closure baru is instantiated by the function, it gets its fresh own idea of what
.
Penggunaan khas penutupan lainnya adalah definisi aplikasi fungsi secara parsial. Anggaplah bahwa kita memiliki fasilitas pelaporan yang mirip dengan syslog
mengimplementasikan suatu fungsi
var log = function(priority, message) {
…
};
di mana argumen priority
dan message
diharapkan menjadi string, yang pertama menjadi salah satu "debug"
, "info"
dan sebagainya. Kita dapat mendefinisikan pabrik log seperti ini:
var logWithPriority = function(priority) {
return function(message) {
log(priority, message);
};
};
dan menggunakannya untuk menentukan versi khusus dari fasilitas log kami:
var debug = logWithPriority("debug");
var info = logWithPriority("info");
…
Ini sangat berguna, karena alih-alih menulis kesalahan-cenderung- for
seperti ini
for(i = 0; i < journal.length; ++i) {
log("info", journal[i]);
}
kita dapat menulis pembersih, lebih pendek dan lebih sederhana (tidak ada i
, itu jauh lebih baik):
journal.forEach(logWithPriority("info"));
Bidang aplikasi penutupan ketiga yang penting adalah penerapan evaluasi malas - perhatikan bahwa dukungan bahasa khusus dapat memberikan implementasi yang lebih baik.
Fungsi malas, alih-alih melakukan perhitungan langsung, mengembalikan penutupan yang dapat disebut (atau "dipaksa" dalam jargon kemalasan) untuk melakukan pertanyaan. Motivasi untuk melakukan ini adalah bahwa ia memisahkan persiapan perhitungan dan melakukan perhitungan. Contoh praktis dari hal ini adalah kompilasi ekspresi reguler: jika suatu program mengkompilasi banyak ekspresi reguler pada saat startup, itu akan membutuhkan banyak waktu untuk memulai. Jika sebaliknya kita malas menyusun ekspresi reguler dan memaksanya sesuai kebutuhan, maka program kita dapat dengan cepat memulai. Tentu saja, ekspresi reguler dapat diganti di sini dengan struktur apa pun yang memerlukan waktu inisialisasi yang cukup besar.
Berikut adalah cara menerapkan evaluasi malas dengan penutupan. Pertimbangkan implementasi klasik fungsi arrayMax mengembalikan max dalam sebuah array:
function arrayMax(array) {
return array.reduce(function(a, b) {
return Math.min(a, b);
};
}
Varian yang malas adalah:
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;
}
Nilai yang dikembalikan adalah penutupan yang dapat digunakan untuk menghitung nilai atau mengambilnya di lain waktu jika telah dihitung.
Dengan ketiga contoh ini, kita harus yakin bahwa penutupan dan aplikasinya adalah inti dari pemrograman fungsional.
Mempelajari pemrograman fungsional berarti mempelajari cara memprogram dengan penutupan. Sebagai konsekuensinya, bahasa memungkinkan manipulasi penutupan yang mudah, dan terutama penerapan sebagian fungsi, harus dipertimbangkan ketika mencari bahasa untuk mempelajari pemrograman fungsional. Sebaliknya, bahasa di mana penutupan tidak dapat dengan mudah dimanipulasi akan menjadi pilihan yang buruk.
Saya pikir alat yang Anda gunakan sangat memengaruhi belajar Anda. Hampir mustahil untuk mempelajari konsep pemrograman yang bahasa pemrogramannya Anda gunakan tidak menyediakan sarana untuk memanfaatkannya. Tentu, Anda selalu dapat belajar beberapa hal, tetapi Anda tidak dapat mempelajarinya dengan benar.
Tapi itu tetap akademik, karena, seperti dikatakan Martinho dalam komentarnya , bahkan jika Anda bisa belajar pemrograman fungsional, Anda tidak boleh mencoba melakukan itu, karena ada bahasa di mana ini jauh lebih mudah.
Anda seharusnya tidak belajar pemrograman fungsional dalam C, tetapi dalam bahasa fungsional yang ketat (Haskell, Caml, Erlang, dll.).
Jika Anda baru mengenal fungsional, Anda tidak akan pernah mendapatkannya dengan bahasa yang tidak fungsional. Kemungkinan besar, Anda akan melatih diri untuk melakukan apa yang menurut Anda pemrograman fungsional dan mempelajari berbagai hal dengan cara yang salah. Dan itu selalu lebih sulit untuk «mempelajari kembali» hal-hal dengan cara yang benar daripada mempelajarinya dengan cara yang benar pada awalnya.
Bagaimanapun, saya pikir melakukan fungsional dalam C adalah latihan yang baik untuk seseorang yang sudah tahu fungsional. Karena orang itu akan mempelajari apa yang terjadi di balik tudung - apa yang sebenarnya dilakukan komputer.