Saya telah berpikir banyak akhir-akhir ini tentang bagaimana cara melakukan pemrograman fungsional dalam C ( bukan C ++). Jelas, C adalah bahasa prosedural dan tidak benar-benar mendukung pemrograman fungsional secara asli.
Apakah ada ekstensi kompiler / bahasa yang menambahkan beberapa konstruksi pemrograman fungsional ke bahasa? GCC menyediakan fungsi bersarang sebagai ekstensi bahasa; fungsi bersarang dapat mengakses variabel dari kerangka tumpukan induk, tetapi ini masih jauh dari penutupan yang matang.
Sebagai contoh, satu hal yang saya pikir bisa sangat berguna dalam C adalah bahwa di mana pun di mana pointer fungsi diharapkan, Anda bisa dapat melewati ekspresi lambda, membuat penutupan yang meluruh menjadi pointer fungsi. C ++ 0x akan memasukkan ekspresi lambda (yang menurut saya mengagumkan); namun, saya mencari alat yang dapat digunakan untuk straight C.
[Sunting] Untuk memperjelas, saya tidak mencoba memecahkan masalah tertentu dalam C yang akan lebih cocok untuk pemrograman fungsional; Saya hanya ingin tahu tentang alat apa yang ada di luar sana jika saya ingin melakukannya.
sumber
Jawaban:
FFCALL memungkinkan Anda membangun penutupan di C -
callback = alloc_callback(&function, data)
mengembalikan penunjuk fungsi sedemikian rupa sehinggacallback(arg1, ...)
setara dengan panggilanfunction(data, arg1, ...)
. Anda harus menangani pengumpulan sampah secara manual.Terkait, blok telah ditambahkan ke garpu GCC Apple; mereka bukan fungsi pointer, tetapi mereka membiarkan Anda berkeliling lambdas sambil menghindari kebutuhan untuk membangun dan penyimpanan gratis untuk variabel yang ditangkap dengan tangan (secara efektif, beberapa penyalinan dan penghitungan referensi terjadi, tersembunyi di balik beberapa perpustakaan sintaksis gula dan runtime).
sumber
Anda dapat menggunakan fungsi bersarang GCC untuk mensimulasikan ekspresi lambda, pada kenyataannya, saya memiliki makro untuk melakukannya untuk saya:
Gunakan seperti ini:
sumber
__fn__
hanya nama arbitrer untuk fungsi yang didefinisikan dalam blok({
...})
, bukan ekstensi GCC atau makro yang telah ditentukan? Pilihan nama untuk__fn__
(terlihat sangat mirip dengan definisi GCC) benar-benar membuat saya menggaruk kepala saya dan mencari dokumentasi GCC tanpa efek yang baik.Pemrograman fungsional bukan tentang lambdas, itu semua tentang fungsi murni. Jadi berikut ini secara luas mempromosikan gaya fungsional:
Hanya gunakan argumen fungsi, jangan gunakan negara global.
Minimalkan efek samping yaitu printf, atau IO apa pun. Mengembalikan data yang menggambarkan IO yang dapat dieksekusi daripada menyebabkan efek samping secara langsung di semua fungsi.
Ini dapat dicapai dalam c sederhana, tidak perlu sihir.
sumber
map
, jika seseorang tidak memiliki fasilitas untuk meneruskan fungsinya?Buku Hartel & Muller, Functional C , saat ini (2012-01-02) dapat ditemukan di: http://eprints.eemcs.utwente.nl/1077/ (ada tautan ke versi PDF).
sumber
Prasyarat untuk gaya pemrograman fungsional adalah fungsi kelas satu. Itu bisa disimulasikan dalam portable C jika Anda mentolerir selanjutnya:
runtime untuk kode tersebut bisa sekecil satu di bawah ini
Intinya kita meniru fungsi kelas satu dengan penutup yang direpresentasikan sebagai pasangan fungsi / argumen plus sekelompok macroses. Kode lengkap dapat ditemukan di sini .
sumber
Hal utama yang terlintas dalam pikiran adalah penggunaan generator kode. Apakah Anda bersedia memprogram dalam bahasa yang berbeda yang menyediakan pemrograman fungsional dan kemudian menghasilkan kode C dari itu?
Jika itu bukan pilihan yang menarik, maka Anda dapat menyalahgunakan CPP untuk ikut serta dalam perjalanan ke sana. Sistem makro seharusnya membiarkan Anda meniru beberapa ide pemrograman fungsional. Saya pernah mendengar bahwa gcc diimplementasikan dengan cara ini tetapi saya tidak pernah memeriksa.
C tentu saja dapat melewati fungsi menggunakan pointer fungsi, masalah utama adalah kurangnya penutupan dan sistem tipe cenderung menghalangi. Anda dapat menjelajahi sistem makro yang lebih kuat daripada CPP seperti M4. Saya kira pada akhirnya, apa yang saya sarankan adalah bahwa C benar tidak sesuai dengan tugas tanpa usaha keras tetapi Anda bisa memperluas C untuk membuatnya sesuai dengan tugas. Ekstensi itu akan terlihat paling seperti C jika Anda menggunakan CPP atau Anda bisa pergi ke ujung lain spektrum dan menghasilkan kode C dari beberapa bahasa lain.
sumber
Jika Anda ingin menerapkan penutupan, Anda harus mengaduh dengan bahasa assembly dan menukar / menumpuk tumpukan. Tidak merekomendasikan menentangnya, hanya mengatakan itu yang harus Anda lakukan.
Tidak yakin bagaimana Anda akan menangani fungsi anonim di C. Pada mesin von Neumann, Anda bisa melakukan fungsi anonim dalam asm.
sumber
Lihatlah buku Hartel & Muller, Fungsional C
http://www.ub.utwente.nl/webdocs/ctit/1/00000084.pdf
http://www.cs.bris.ac.uk/~henkm/f2c/index.html
sumber
Bahasa Felix mengkompilasi ke C ++. Mungkin itu bisa menjadi batu langkah, jika Anda tidak keberatan C ++.
sumber
Yah beberapa bahasa pemrograman ditulis dalam C. Dan beberapa dari mereka mendukung fungsi sebagai warga negara kelas satu, bahasa di daerah itu adalah ecl (embedabble common lisp IIRC), Gnu Smalltalk (gst) (Smalltalk memiliki blok), kemudian ada perpustakaan untuk "closure" misalnya di glib2 http://library.gnome.org/devel/gobject/unstable/chapter-signal.html#closure yang setidaknya mendekati pemrograman fungsional. Jadi mungkin menggunakan beberapa implementasi tersebut untuk melakukan pemrograman fungsional dapat menjadi pilihan.
Baik atau Anda bisa belajar Ocaml, Haskell, Mozart / Oz atau sejenisnya ;-)
Salam
sumber
Cara saya melakukan pemrograman fungsional dalam bahasa C adalah menulis penerjemah bahasa fungsional dalam bahasa C. Saya menamakannya Fexl, yang merupakan kependekan dari "Function EXpression Language."
Interpreternya sangat kecil, mengkompilasi hingga 68K pada sistem saya dengan -O3 diaktifkan. Ini juga bukan mainan - saya menggunakannya untuk semua kode produksi baru yang saya tulis untuk bisnis saya (akuntansi berbasis web untuk kemitraan investasi.)
Sekarang saya menulis kode C hanya untuk (1) menambahkan fungsi built-in yang memanggil sistem rutin (misalnya fork, exec, setrlimit, dll.), Atau (2) mengoptimalkan fungsi yang dapat ditulis dalam Fexl (misalnya pencarian untuk substring).
Mekanisme modul didasarkan pada konsep "konteks". Konteks adalah fungsi (ditulis dalam Fexl) yang memetakan simbol ke definisinya. Saat Anda membaca file Fexl, Anda bisa menyelesaikannya dengan konteks apa pun yang Anda suka. Ini memungkinkan Anda membuat lingkungan khusus, atau menjalankan kode di "kotak pasir" terbatas.
http://fexl.com
sumber
Ada apa dengan C yang ingin Anda buat fungsional, sintaks atau semantik? Semantik pemrograman fungsional tentu dapat ditambahkan ke kompiler C, tetapi pada saat Anda selesai, Anda pada dasarnya akan memiliki setara dengan salah satu bahasa fungsional yang ada, seperti Skema, Haskell, dll.
Akan lebih baik menggunakan waktu untuk mempelajari sintaksis bahasa-bahasa yang secara langsung mendukung semantik tersebut.
sumber
Dont Tahu tentang C. Ada beberapa fitur fungsional di Objective-C, GCC pada OSX juga mendukung beberapa fitur, namun saya akan merekomendasikan untuk mulai menggunakan bahasa fungsional, ada banyak yang disebutkan di atas. Saya pribadi memulai dengan skema, ada beberapa buku bagus seperti The Little Schemer yang dapat membantu Anda melakukannya.
sumber