Apa keuntungan menggunakan C # vs F # atau F # vs C #? [Tutup]

93

Saya bekerja untuk perusahaan teknologi yang melakukan lebih banyak pembuatan prototipe daripada pengiriman produk. Saya baru saja ditanya apa perbedaan antara C # dan F #, mengapa MS membuat F # dan skenario apa yang lebih baik daripada C #.

Saya telah menggunakan bahasa untuk sementara waktu sekarang dan saya menyukainya sehingga saya dapat dengan mudah melanjutkan tentang fitur-fitur hebat F # namun saya kurang pengalaman dalam C # untuk mengatakan mengapa kita harus menggunakan salah satu dari yang lain.

Apa keuntungan menggunakan C # vs F # atau F # vs C #?

gradbot
sumber
4
Tampak bagi saya bahwa ada cukup banyak pertanyaan yang sudah ada di SO yang setidaknya sebagian menjawab pertanyaan Anda. Sudahkah Anda mencoba menelusuri menggunakan "[F #] kata kunci" daripada "f # kata kunci"? ("[f #] keuntungan", misalnya)
Benjol

Jawaban:

86

Manfaat umum dari pemrograman fungsional dibandingkan bahasa imperatif:

Anda dapat merumuskan banyak masalah dengan lebih mudah, lebih dekat dengan definisinya dan lebih ringkas dalam bahasa pemrograman fungsional seperti F # dan kode Anda tidak terlalu rentan terhadap kesalahan (kekekalan, sistem tipe yang lebih kuat, algoritme rekurif intuitif). Anda dapat membuat kode apa yang Anda maksud alih-alih apa yang komputer ingin Anda katakan ;-) Anda akan menemukan banyak diskusi seperti ini ketika Anda mencari di Google atau bahkan mencarinya di SO.

Kekurangan F # khusus:

  • Pemrograman asinkron sangat mudah dan intuitif dengan async {}-ekspresi - Bahkan dengan ParallelFX, kode-C yang sesuai jauh lebih besar

  • Integrasi yang sangat mudah dari kompiler kompiler dan bahasa khusus domain

  • Memperluas bahasa saat Anda membutuhkannya: LOP

  • Satuan ukuran

  • Sintaks yang lebih fleksibel

  • Seringkali solusi yang lebih pendek dan lebih elegan

Lihat dokumen ini

Keuntungan dari C # adalah sering kali lebih akurat untuk aplikasi "imperatif" (Antarmuka pengguna, algoritme imperatif) daripada bahasa pemrograman fungsional, bahwa .NET-Framework yang digunakannya dirancang secara imperatif dan lebih tersebar luas.

Selain itu, Anda dapat menggabungkan F # dan C # dalam satu solusi, sehingga Anda dapat menggabungkan keunggulan kedua bahasa dan menggunakannya di tempat yang dibutuhkan.

Dario
sumber
16
Mereka bergabung dengan cara yang sangat aneh. Misalnya, Anda dapat membebani operator> di F #. Pengembang C # kemudian dapat menggunakannya. Namun, pengembang F # tidak bisa. Benar, F # dapat mengeluarkan kelebihan beban operator yang tidak dapat dikonsumsi.
Jonathan Allen
Tautan "dokumen ini" rusak ...
Eduardo Brites
36

Ini seperti menanyakan apa manfaat palu dibandingkan obeng. Pada tingkat yang sangat tinggi, keduanya pada dasarnya melakukan hal yang sama, tetapi pada tingkat implementasi, penting untuk memilih alat yang optimal untuk apa yang ingin Anda capai. Ada tugas-tugas yang sulit dan memakan waktu di c # tetapi mudah di f # - seperti mencoba menancapkan paku dengan obeng. Anda pasti bisa melakukannya - itu tidak ideal.

Manipulasi data adalah salah satu contoh yang secara pribadi dapat saya tunjukkan di mana f # benar-benar bersinar dan c # berpotensi menjadi sulit digunakan. Di sisi lain, saya akan mengatakan (secara umum) UI stateful kompleks lebih mudah di OO (c #) daripada fungsional (f #). (Mungkin akan ada beberapa orang yang tidak setuju dengan ini karena "keren" sekarang untuk "membuktikan" betapa mudahnya melakukan sesuatu di F #, tapi saya mendukungnya). Ada banyak orang lain yang tak terhitung jumlahnya.

Rex M
sumber
22
Jika yang Anda miliki hanyalah palu, semuanya terlihat seperti paku. -Maslow
Charlie Salts
20
Saya tidak akan memilih ini karena tidak memberikan spesifik yang sebenarnya kecuali untuk satu contoh data. Saya tahu mereka adalah alat yang berbeda. Saya bertanya pekerjaan apa yang terbaik dan terburuk dari kedua alat ini dibandingkan satu sama lain. Saya tahu philips sering kali merupakan alat terbaik untuk pekerjaan itu meskipun flathead yang lebih kecil bisa digunakan.
gradbot
3
Jika dia tidak mau mendukung Anda, saya akan melakukannya. : P +1
Spencer Ruport
14
Jika yang Anda miliki hanyalah palu, semuanya terlihat seperti jempol.
Ed Power
6
Saya setuju dengan gradbot, ini adalah jawaban yang bagus sehingga tidak ada downvote dari saya, namun tidak benar-benar membahas secara spesifik pertanyaan asli. Jawaban ini hanyalah penjelasan konseptual yang samar-samar, tetapi benar-benar melenceng dari menjawab pertanyaan dengan tepat.
Stan R.
27
  • F # Memiliki Kinerja Lebih Baik daripada C # dalam Matematika
  • Anda dapat menggunakan proyek F # dalam solusi yang sama dengan C # (dan panggilan dari satu ke yang lain)
  • F # sangat baik untuk pemrograman algoritmik yang kompleks, aplikasi keuangan dan ilmiah
  • F # secara logis sangat baik untuk eksekusi paralel (lebih mudah membuat kode F # dieksekusi pada inti paralel, daripada C #)
Rinat Abdullin
sumber
6
Tentang F # memiliki kinerja yang lebih baik daripada C # untuk matematika: Ternyata, itu tidak benar. Lihat thoughtfulcode.wordpress.com/2010/12/30/…
Joh
3
@Joh: inlineadalah contoh nyata dari sesuatu yang dapat memberikan peningkatan kinerja besar-besaran di F # yang tidak dapat diungkapkan oleh C #.
JD
@Jon Harrop: Saya secara khusus mengacu pada entri blog Rinat. Tampaknya pengaturan waktu yang mendukung F # yang didapatnya disebabkan oleh kode C # yang kurang optimal.
Joh
27

Untuk menjawab pertanyaan Anda seperti yang saya pahami: Mengapa menggunakan C #? (Anda mengatakan Anda sudah dijual di F #.)

Pertama. Ini bukan hanya "fungsional versus OO". Ini adalah "Fungsional + OO versus OO". Fitur fungsional C # sangat sederhana. F # tidak. Sementara itu, F # melakukan hampir semua fitur OO C #. Untuk sebagian besar, F # berakhir sebagai superset dari fungsionalitas C #.

Namun, ada beberapa kasus di mana F # mungkin bukan pilihan terbaik:

  • Interop. Ada banyak perpustakaan yang tidak akan terlalu nyaman dari F #. Mungkin mereka mengeksploitasi C # OO tertentu yang F # tidak melakukan hal yang sama, atau mungkin mereka mengandalkan internal compiler C #. Misalnya, Ekspresi. Meskipun Anda dapat dengan mudah mengubah kutipan F # menjadi Ekspresi, hasilnya tidak selalu persis seperti yang akan dibuat oleh C #. Perpustakaan tertentu bermasalah dengan ini.

    • Ya, interop adalah jaringan yang cukup besar dan dapat menyebabkan sedikit gesekan dengan beberapa perpustakaan.

    • Saya mempertimbangkan interop untuk juga disertakan jika Anda memiliki basis kode yang besar. Mungkin tidak masuk akal untuk mulai menulis bagian di F #.

  • Alat desain. F # tidak punya. Tidak berarti tidak dapat memilikinya, tetapi saat ini Anda tidak dapat menyiapkan aplikasi WinForms dengan F # codebehind. Meskipun didukung, seperti di halaman ASPX, saat ini Anda tidak mendapatkan IntelliSense. Jadi, Anda perlu mempertimbangkan dengan hati-hati di mana batasan Anda akan untuk kode yang dihasilkan. Pada proyek yang sangat kecil yang hampir secara eksklusif menggunakan berbagai desainer, mungkin tidak ada gunanya menggunakan F # untuk "perekat" atau logika. Pada proyek yang lebih besar, ini mungkin tidak terlalu menjadi masalah.

    • Ini bukanlah masalah intrinsik. Tidak seperti jawaban Rex M, saya tidak melihat sesuatu yang intrinsik tentang C # atau F # yang membuat mereka lebih baik melakukan UI dengan banyak bidang yang bisa berubah. Mungkin dia mengacu pada biaya tambahan karena harus menulis "bisa berubah" dan menggunakan <- bukannya =.

    • Juga tergantung perpustakaan / desainer yang digunakan. Kami senang menggunakan ASP.NET MVC dengan F # untuk semua pengontrol, kemudian proyek web C # untuk mendapatkan desainer ASPX. Kami menggabungkan "kode inline" ASPX yang sebenarnya antara C # dan F #, tergantung pada apa yang kami butuhkan di halaman itu. (Jenis IntelliSense versus F #.)

  • Alat lainnya. Mereka mungkin hanya mengharapkan C # saja dan tidak tahu bagaimana menangani proyek F # atau kode yang dikompilasi. Juga, pustaka F # tidak dikirimkan sebagai bagian dari .NET, jadi Anda memiliki sedikit tambahan untuk dikirimkan.

  • Tapi masalah nomor satu? Orang-orang. Jika tidak ada pengembang Anda yang ingin mempelajari F #, atau lebih buruk lagi, mengalami kesulitan yang parah untuk memahami aspek-aspek tertentu, Anda mungkin bersulang. (Meskipun demikian, saya berpendapat Anda tetap bersulang dalam kasus itu.) Oh, dan jika manajemen mengatakan tidak, itu mungkin menjadi masalah.

Saya menulis tentang ini beberapa waktu lalu: Mengapa TIDAK F #?

MichaelGG
sumber
6

Anda meminta perbandingan antara bahasa prosedural dan bahasa fungsional, jadi saya rasa pertanyaan Anda dapat dijawab di sini: Apa perbedaan antara pemrograman prosedural dan pemrograman fungsional?

Adapun mengapa MS menciptakan F # jawabannya sederhana: Membuat bahasa fungsional dengan akses ke pustaka .Net hanya memperluas basis pasar mereka. Dan melihat bagaimana sintaksnya hampir identik dengan OCaml, itu benar-benar tidak membutuhkan banyak usaha di pihak mereka.

Spencer Ruport
sumber
1
Meskipun saya pikir jawaban umum Anda benar bahwa pertanyaan sebenarnya adalah tentang perbandingan paradigma pemrograman dan bukan bahasa, saya merasa jawaban dalam pertanyaan yang Anda maksud agak dangkal.
Jeroen Huinink
Jangan ragu untuk menyarankan pertanyaan lain jika Anda memiliki pertanyaan yang lebih baik. Itu nilai tertinggi yang saya temukan dari pencarian google.
Spencer Ruport
1
Saya pikir dia mencoba bersikap baik tentang Anda yang terdengar seperti keledai karena mengatakan F # tidak memerlukan banyak usaha dari pihak Micrsoft.
Matthew Whited
1 untuk komentar basis pasar. Sederhana dan ada benarnya.
gradbot
1
Saya tidak percaya pada tautan lain itu untuk menjawab pertanyaan saya. C # mendukung banyak konstruksi fungsional di versi yang lebih baru.
gradbot
5

F # bukanlah bahasa pemrograman lain jika Anda membandingkannya dengan C #, C ++, VB. C #, C, VB semuanya adalah bahasa pemrograman imperatif atau prosedural. F # adalah bahasa pemrograman fungsional.

Dua manfaat utama dari bahasa pemrograman fungsional (dibandingkan dengan bahasa imperatif) adalah 1. bahwa bahasa tersebut tidak memiliki efek samping. Ini membuat penalaran matematis tentang properti program Anda jauh lebih mudah. 2. bahwa fungsinya adalah warga negara kelas satu. Anda dapat meneruskan fungsi sebagai parameter ke fungsi lain semudah Anda dapat mengirimkan nilai lainnya.

Baik bahasa pemrograman imperatif dan fungsional memiliki kegunaannya masing-masing. Meskipun saya belum melakukan pekerjaan serius di F #, kami saat ini menerapkan komponen penjadwalan di salah satu produk kami berdasarkan C # dan akan melakukan percobaan dengan mengkodekan penjadwal yang sama di F # juga untuk melihat apakah kebenaran dari implementasi dapat divalidasi lebih mudah daripada dengan C # yang setara.

Jeroen Huinink
sumber
4
-1. F # adalah bahasa multi-paradigma (OO + FP). Hanya bahasa fungsional murni yang tidak memiliki efek samping (seperti Haskell), tetapi F # tidak murni.
Mauricio Scheffer
5

F # pada dasarnya adalah C ++ dari bahasa pemrograman fungsional. Mereka menyimpan hampir semuanya dari Objective Caml, termasuk bagian yang benar-benar bodoh, dan melemparkannya di atas runtime .NET sedemikian rupa sehingga membawa semua hal buruk dari .NET juga.

Misalnya, dengan Objective Caml Anda mendapatkan satu jenis null, opsi <T>. Dengan F # Anda mendapatkan tiga jenis null, opsi <T>, Nullable <T>, dan referensi nulls. Ini berarti jika Anda memiliki opsi, Anda harus memeriksa terlebih dahulu untuk melihat apakah itu "Tidak Ada", lalu Anda perlu memeriksa apakah itu "Beberapa (null)".

F # seperti klon Java lama J #, hanya bahasa bajingan hanya untuk menarik perhatian. Beberapa orang akan menyukainya, beberapa dari mereka bahkan akan menggunakannya, tetapi pada akhirnya itu masih merupakan bahasa berusia 20 tahun yang ditempelkan di CLR.

Jonathan Allen
sumber
2
+1, Ini mungkin kebenaran yang sulit namun saya masih cukup senang bahwa saya dapat menggunakan bahasa fungsional di VS dengan .NET
gradbot
1
Saya setuju bahwa Nullable <T> harus meminta kompiler melakukan beberapa aliasing ajaib untuk kita. Saya tidak yakin bahwa menjadikan "Some null" setara dengan None akan selalu berhasil - beberapa kode interop mungkin bergantung padanya. Tapi referensi null? Bagaimana Anda akan mengatasi lubang besar di .NET? Bungkus setiap jenis referensi dalam sebuah opsi? Dalam praktiknya, ini sepertinya hanya menjadi masalah dengan skenario interop tertentu.
MichaelGG
12
FWIW, saya telah membuat kode secara profesional di F # selama beberapa tahun (lebih lama dari hampir semua orang di dunia) dan saya belum pernah melihat masalah ini atau kode Some nulldalam kode F # mana pun. Dari semua hal yang mungkin dikeluhkan orang, ini harus dicatat dalam daftar ...
JD
1
Membandingkan F # dengan C ++ agak dibuat-buat. Banyak bagian C ++ memiliki semantik yang tidak terdefinisi atau tidak jelas, F # sederhana dan terdefinisi dengan baik. Kualitas runtime .NET tidak dapat ditahan terhadap F #, karena bahasa .NET apa pun akan memiliki masalah yang sama.
Joh
1
Selama lebih dari 2 tahun pemrograman F # profesional, seperti @Jon, saya tidak pernah melihat masalah apa pun yang terkait dengan 'Some null'. Di sisi lain, saya mendapat banyak keuntungan dari fitur kerangka kerja .Net.
Marc Sigrist
5

Salah satu aspek .NET yang paling saya sukai adalah obat generik. Bahkan jika Anda menulis kode prosedural di F #, Anda masih akan mendapatkan keuntungan dari jenis inferensi. Itu membuat penulisan kode generik menjadi mudah.

Di C #, Anda menulis kode konkret secara default, dan Anda harus melakukan beberapa pekerjaan ekstra untuk menulis kode generik.

Di F #, Anda menulis kode generik secara default. Setelah menghabiskan lebih dari satu tahun pemrograman di F # dan C #, saya menemukan bahwa kode perpustakaan yang saya tulis di F # lebih ringkas dan lebih umum daripada kode yang saya tulis di C #, dan karena itu juga lebih dapat digunakan kembali. Saya kehilangan banyak kesempatan untuk menulis kode generik di C #, mungkin karena saya dibutakan oleh anotasi tipe wajib.

Namun ada situasi di mana menggunakan C # lebih disukai, tergantung pada selera dan gaya pemrograman seseorang.

  • C # tidak memaksakan urutan deklarasi di antara tipe, dan tidak sensitif terhadap urutan file dikompilasi.
  • C # memiliki beberapa konversi implisit yang F # tidak mampu karena tipe inferensi.
Joh
sumber