Di area apa mungkin penggunaan F # lebih tepat daripada C #? [Tutup]

210

Selama beberapa tahun terakhir F # telah berkembang menjadi salah satu bahasa yang didukung penuh Microsoft yang menggunakan banyak ide yang diinkubasi dalam OCaml, ML dan Haskell.

Selama beberapa tahun terakhir C # telah memperluas fitur tujuan umum dengan memperkenalkan fitur bahasa yang lebih dan lebih fungsional: LINQ (daftar pemahaman), Lambdas, Penutupan, Delegasi Anonim dan banyak lagi ...

Mengingat C # mengadopsi fitur-fitur fungsional ini dan taksonomi F # sebagai bahasa fungsional yang tidak murni (ini memungkinkan ANDA untuk mengakses pustaka kerangka kerja atau mengubah status bersama ketika suatu fungsi dipanggil jika Anda mau) ada kesamaan yang kuat antara kedua bahasa meskipun masing-masing memiliki kutub sendiri berlawanan dengan penekanan utama.

Saya tertarik pada model sukses yang menggunakan dua bahasa ini dalam program polyglot produksi Anda dan juga area dalam perangkat lunak produksi (aplikasi web, aplikasi klien, aplikasi server) yang telah Anda tulis dalam F # dalam setahun terakhir ini sehingga Anda sebelumnya akan memiliki ditulis dalam C #.

Peter McG
sumber

Jawaban:

258

Saya telah menulis aplikasi untuk menyeimbangkan jadwal pembangkit listrik nasional untuk portofolio pembangkit listrik ke posisi perdagangan untuk perusahaan energi. Komponen klien dan server berada di C # tetapi mesin perhitungan ditulis dalam F #.

Penggunaan F # untuk mengatasi kompleksitas di jantung aplikasi ini jelas menunjukkan sweet spot untuk bahasa dalam perangkat lunak perusahaan, yaitu analisis algoritmik kompleks dari kumpulan data besar. Pengalaman saya sangat positif. Khususnya:

Unit ukuran Industri tempat saya bekerja penuh dengan unit. Persamaan yang saya terapkan (sering bersifat geometris) berurusan dengan satuan waktu, daya, dan energi. Memiliki sistem tipe memverifikasi kebenaran unit input dan output fungsi adalah penghemat waktu yang sangat besar, baik dalam hal pengujian dan membaca / memahami kode. Ini menghapus seluruh kelas kesalahan yang rentan terhadap sistem sebelumnya.

Pemrograman eksplorasi Bekerja dengan file skrip dan REPL (F # Interactive) memungkinkan saya untuk menjelajahi ruang solusi lebih efektif sebelum melakukan implementasi daripada loop edit / kompilasi / run / tes yang lebih tradisional. Ini adalah cara yang sangat alami bagi seorang programmer untuk membangun pemahaman mereka tentang masalah dan ketegangan desain dalam permainan.

Kode pengujian unit yang ditulis menggunakan fungsi yang tidak memihak dan struktur data yang tidak dapat diubah adalah kegembiraan untuk diuji. Tidak ada interaksi tergantung waktu yang kompleks untuk mengacaukan segalanya atau serangkaian besar dependensi untuk diejek.

Interoperation Saya mendefinisikan antarmuka ke mesin perhitungan di C # dan menerapkan perhitungan dalam F #. Mesin perhitungan kemudian dapat disuntikkan ke modul C # yang perlu menggunakannya tanpa khawatir sama sekali tentang interoperabilitas. Mulus. Programmer C # tidak perlu tahu.

Pengurangan kode Sebagian besar data dimasukkan ke dalam mesin perhitungan dalam bentuk vektor dan matriks. Fungsi pesanan lebih tinggi memakannya untuk sarapan dengan sedikit keributan, kode minimal. Cantik.

Kurangnya bug Pemrograman fungsional bisa terasa aneh. Saya dapat bekerja pada suatu algoritma, berusaha keras untuk mendapatkan kode untuk melewati pemeriksa tipe tetapi setelah pemeriksa tipe puas, itu berfungsi. Hampir biner, baik itu tidak dapat dikompilasi atau benar. Kesalahan tepi kasus yang aneh diminimalkan, rekursi dan fungsi urutan yang lebih tinggi menghapus banyak kode pembukuan yang memperkenalkan kesalahan kasus tepi.

Paralelisme Kemurnian fungsional dari implementasi yang dihasilkan membuatnya siap untuk mengeksploitasi paralelisme yang melekat dalam pemrosesan vektor data. Mungkin di sinilah saya akan pergi berikutnya sekarang. NET 4 keluar.

sepupu simon
sumber
18
+1 untuk menjelaskan mengapa F # sangat cocok untuk mesin rangking angka. +1 (virtual) lainnya untuk menyebutkan satuan ukuran. Bagian dari bahasa itu pantas disebutkan lebih sering.
cfern
5
Jawaban yang bagus, relevan, kontemporer dan menguraikan kesesuaian F # untuk berurusan dengan kompleksitas, saya belajar banyak dari membacanya, terima kasih
Peter McG
Jawaban bagus Simon, dan seperti yang disebutkan Don tadi malam, dikutip dalam slide-slide terbarunya. Saatnya menambahkan tautan "tambahkan ke keranjang"?
Chris Ballard
1
Hai, apakah Anda boleh memberi tahu kami lebih banyak tentang arsitektur aplikasi Anda?
Nikos
76

Selama magang di Microsoft Research, saya bekerja pada beberapa bagian Visual Studio IntelliSense untuk F # (yang itu sendiri ditulis dalam F #). Saya sudah memiliki pengalaman dengan IntelliSense dari proyek C # sebelumnya, jadi saya pikir saya bisa membandingkan keduanya.

  • Visual Studio Extensibility masih berbasis pada COM, jadi Anda harus berurusan dengan objek yang tidak terlalu bagus. Objek NET (dan jelas tidak fungsional), tapi saya tidak merasa ada perbedaan besar antara C # dan F # (berfungsi dengan lancar dari F #)

  • Struktur data yang digunakan untuk mewakili kode program dalam F # sebagian besar adalah serikat terdiskriminasi (yang tidak didukung dalam C # dengan cara yang masuk akal) dan ini membuat perbedaan besar untuk aplikasi semacam ini (di mana Anda perlu memproses struktur pohon, seperti kode program ). Serikat yang diskriminatif dan pencocokan pola memungkinkan Anda untuk menyusun kode dengan lebih baik (pertahankan fungsionalitas terkait di satu tempat daripada menempatkannya di semua tempat dalam metode virtual)

Sebelumnya, saya juga bekerja pada penyedia CodeDOM untuk F # (juga ditulis dalam F #). Saya benar-benar melakukan percobaan pertama di C #, tetapi kemudian mengubah kode menjadi F #.

  • Penyedia CodeDOM perlu melintasi beberapa struktur yang diwakili menggunakan objek .NET, jadi tidak ada banyak ruang untuk menemukan representasi data Anda sendiri (yang merupakan area di mana F # dapat menawarkan manfaat yang bagus).

  • Namun, ada banyak fitur F # kecil yang membuat tugas lebih mudah. Karena Anda perlu membuat string, saya mendefinisikan operator khusus untuk membangun string (menggunakan StringBuilder) dan menerapkan kode menggunakan mereka dan fungsi urutan yang lebih tinggi (misalnya untuk memformat daftar objek yang dipisahkan menggunakan string yang ditentukan, dll.), Yang menghapus banyak pengulangan (dan foreachloop yang membosankan ).

Ini adalah dua contoh yang relatif spesifik, tetapi keduanya terkait dengan bekerja dengan representasi program, atau ekspresi, atau lebih umum, struktur data mirip pohon yang kompleks. Saya pikir di area ini, F # jelas merupakan pilihan yang baik (terlepas dari fitur fungsional di C #).

Tomas Petricek
sumber
6
Sangat menarik, lebih banyak bukti bahwa penggunaan F # dalam Microsoft sudah pasti tinggi, magang yang luar biasa!
Peter McG
43

Kami mengirimkan produk komersial pertama di dunia yang ditulis dalam F # ( F # untuk Visualisasi ) dan yang kedua ( F # untuk Numerik ) serta literatur komersial pertama pada F # ( The F # .NET Journal ) dan menulis serta menerbitkan satu-satunya buku tentang versi saat ini F # ( Visual F # 2010 untuk Komputasi Teknis ).

Kami telah mengirimkan produk-produk serupa yang ditulis dalam C # (mis. Ini ) tetapi kami juga memiliki latar belakang yang kuat dalam penggunaan komersial OCaml. Kami antusias mengadopsi awal F # ketika masih prototipe penelitian kembali pada tahun 2006 karena kami mengakui potensi memiliki bahasa seperti OCaml modern yang layak pada kekuatan .NET platform industri dan, akibatnya, kami mendorong untuk memproduksinya. Hasilnya telah sukses luar biasa dan F # telah jauh melebihi harapan kami yang tinggi.

Bagi kami, F # memiliki banyak keunggulan berbeda dan kami menggunakannya untuk berbagai macam aplikasi. Kami memiliki ratusan ribu baris kode F # dalam produksi. Kami sekarang menggunakan F # untuk semua aplikasi LOB kami: transaksi kartu kredit kami diproses menggunakan kode F #, pemberitahuan produk kami dikirim menggunakan kode F #, langganan kami ditangani dengan menggunakan kode F #, akun kami dilakukan dengan menggunakan kode F # dan seterusnya. Mungkin fitur bahasa utama yang membayar dividen di sini adalah pencocokan pola. Kami bahkan menggunakan F # untuk mewarnai sintaks sorot buku terbaru kami ...

Perpustakaan visualisasi kami adalah penjual besar dan pusat fungsionalitasnya pada F # running interaktif di Visual Studio. Perpustakaan kami menambah ini dengan kemampuan untuk menelurkan visualisasi 2D dan 3D interaktif dengan upaya minimal (misalnya hanyaPlot([Function sin], (-6., 6.))untuk merencanakan gelombang sinus). Secara khusus, semua masalah threading sepenuhnya otomatis sehingga pengguna tidak perlu khawatir tentang utas dan pengiriman UI. Fungsi dan kemalasan kelas satu sangat berharga ketika menulis bagian perpustakaan ini dan tipe data aljabar digunakan secara luas di tempat lain. Kinerja yang dapat diprediksi juga terbukti bernilai di sini ketika pelanggan kami menemukan bug kinerja dalam pengujian hit WPF dan dengan mudah dapat menerapkan kembali kode yang relevan dalam F # untuk peningkatan kinerja 10.000 ×. Karena sifat bebas bentuk GUI produk ini, perancang GUI dan C # tidak akan bermanfaat.

Sebagian besar pekerjaan kami berkisar pada metode numerik, termasuk perpustakaan dan buku komersial kami. F # jauh lebih kuat di daerah ini daripada C # karena ia menawarkan abstraksi tingkat tinggi (misalnya fungsi tingkat tinggi) dengan penalti kinerja minimal. Hasil kami yang paling menarik dalam konteks ini adalah penciptaan implementasi sederhana tetapi umum dari dekomposisi QR dari aljabar linier yang 20 × lebih pendek dari kode Fortran dari implementasi referensi LAPACK, hingga 3 × lebih cepat dari Intel Math yang disetel oleh vendor Pustaka Kernel dan lebih umum karena kode kami dapat menangani matriks jenis apa pun, bahkan matriks simbolik!

Saat ini kami sedang mengembangkan komponen WPF / Silverlight dalam campuran F # (untuk nyali) dan C # (untuk shim), membangun aplikasi WPF untuk bertindak sebagai manual interaktif untuk produk perangkat lunak kami dan saya sedang menulis buku baru, Multicore F #, yang akan menjadi panduan definitif untuk pemrograman paralel memori bersama di .NET.

Jon Harrop
sumber
Apakah Anda Jon Harrop yang sama yang menulis "F # for Scientists"?
Andre Artus
7
Iya. Saya menulis F # untuk Ilmuwan 5 tahun yang lalu.
Jon Harrop
Apakah Anda memiliki referensi beberapa jenis untuk kode dekomposisi QR di F # yang Anda sebutkan dalam paragraf kedua dari belakang Anda? Terima kasih.
Samik R
@SamikR: Tidak, maaf. Itu adalah kode komersial. Itu mudah untuk ditulis.
Jon Harrop
@Jon ada kata di Multicore F #?
profesor bigglesworth
25

Selama 6 bulan terakhir ini, saya telah mengerjakan lapisan emulasi Vim untuk Visual Studio 2010. Ini adalah produk gratis dengan semua sumber yang tersedia secara gratis di github

Proyek ini dibagi menjadi 3 DLL yang mewakili lapisan yang berbeda. Setiap lapisan memiliki dll unit test yang sesuai.

  1. Mesin Vim: F #
  2. Lapisan WPF untuk perhiasan dan integrasi editor: C #
  3. Lapisan Integrasi Visual Studio: C #

Ini adalah proyek besar pertama yang pernah saya lakukan dengan F # dan saya harus mengatakan saya suka bahasa ini. Dalam banyak hal saya menggunakan proyek ini sebagai metode belajar F # (dan kurva belajar ini sangat jelas jika Anda melihat melalui sejarah proyek).

Apa yang saya temukan paling menakjubkan tentang F # adalah betapa ringkasnya sebuah bahasa. Mesin Vim terdiri dari sebagian besar logika namun hanya terdiri dari 30% dari keseluruhan basis kode.

JaredPar
sumber
19
Editor ... bahasa fungsional ... emulasi ... Anda telah menciptakan kembali emacs. Tidaaaaaaaaaaaaaak!
Ben Voigt
2
Kecuali bahwa "Bersertifikat 100% bebas kurung" :)
Pavel Minaev
@Pavel, kecuali untuk tupel tentu saja, dan panggilan metode .net
JaredPar
26
Dua hal yang perlu diperhatikan di sini. Pertama-tama, tuple tidak perlu ()di F # - ,operatorlah yang membuatnya, jadi let x = 1,2tuple yang valid sudah tanpa paren. Kedua, setiap parens pasangan dalam F # dapat diganti dengan pasangan begin.. end(ini diwarisi dari ML) - jadi, misalnya, "foo".IndexOf begin 'a', 1 endadalah panggilan metode .NET yang valid. Jadi, jika Anda ingin bebas dari parens, F # adalah salah satu bahasa yang memungkinkan Anda melakukan hal itu :)
Pavel Minaev
Komentar lucu Pavel! Tidak tahu itu. Saya berpikir bahwa dalam beberapa kasus dengan blok pengelompokan besar, saya mungkin sebenarnya lebih suka begin.. end. JUGA: ATURAN VsVim!
Dan Fitch
13

Banyak pengujian unit untuk komponen F # Visual Studio ditulis dalam F #. Mereka berjalan di luar VS, mengejek berbagai bit Visual Studio. Kemampuan untuk menyimpulkan objek anonim yang mengimplementasikan antarmuka berguna sebagai pengganti kerangka / alat yang mengejek. Saya hanya bisa menulis

let owpe : string list ref = ref []
let vsOutputWindowPane = 
    { new IVsOutputWindowPane with
        member this.Activate () = err(__LINE__)
        member this.Clear () = owpe := []; 0
        member this.FlushToTaskList () = VSConstants.S_OK
        member this.GetName(pbstrPaneName) = err(__LINE__)
        member this.Hide () = err(__LINE__)
        member this.OutputString(pszOutputString) = owpe := pszOutputString :: !owpe ; 0
        member this.OutputStringThreadSafe(pszOutputString) = owpe := pszOutputString :: !owpe ; 0
        member this.OutputTaskItemString(pszOutputString, nPriority, nCategory, pszSubcategory, nBitmap, pszFilename, nLineNum, pszTaskItemText) = err(__LINE__)
        member this.OutputTaskItemStringEx(pszOutputString, nPriority, nCategory, pszSubcategory, nBitmap, pszFilename, nLineNum, pszTaskItemText, pszLookupKwd) = err(__LINE__)
        member this.SetName(pszPaneName) = err(__LINE__)
    }            
DoSomethingThatNeedsA(vsOutputWindowPane)
assert( !owpe = expectedOutputStringList )

ketika saya membutuhkan instance eg IVsOutputWindowPaneuntuk meneruskan ke beberapa komponen lain yang pada akhirnya akan memanggil OutputStringdan Clear, dan kemudian memeriksa string list refobjek di akhir tes untuk melihat apakah output yang diharapkan ditulis.

Brian
sumber
Menarik, lebih banyak bukti bahwa penggunaan F # dalam Microsoft tentu saja tinggi. Saya tidak tahu Anda bisa membuat objek anonim yang mengimplementasikan antarmuka dalam F #
Peter McG
9

Kami menulis bahasa mesin aturan khusus menggunakan implementasi Lex-Yacc di F #

Sunting untuk memasukkan balasan komentar

Tidak ada implementasi lex / yacc di C #. (Sejauh yang kami ketahui, dan F # adalah)

Itu mungkin saja terjadi, tetapi rasa sakit yang tulus untuk membangun parsing diri kita sendiri.

Topik ini menunjukkan beberapa saran lain, seperti perpustakaan eksternal, tetapi arsitek utama kami sangat berpengalaman dalam bahasa fungsional, sehingga pilihan untuk menggunakan F # adalah pilihan.

johnc
sumber
+1 Anda sebelumnya akan menulis ini dalam C # apakah itu tidak cocok atau lebih lambat karena alasan tertentu?
Peter McG
@ Peter McGrattan Setidaknya pada saat penulisan (perangkat lunak), tidak ada implementasi lex / yacc di C #. Itu mungkin saja terjadi, tetapi rasa sakit yang tulus untuk membangun parsing diri kita sendiri. stackoverflow.com/questions/540593/lex-yacc-for-c menunjukkan beberapa saran lain, tetapi arsitek utama kami adalah pakar lama dalam bahasa fungsional, jadi pilihan untuk menggunakan F # adalah no-brainer
johnc
jika Anda pikir tidak ada lex / yacc untuk C # Saya khawatir Anda tidak terlihat cukup keras untuk itu (Ada satu yang lebih tua dari F #) yang mengatakan jika Anda memerlukan lex / yacc F # menurut saya lebih cocok palu untuk kuku itu daripada c #
Rune FS
Saya menggunakan F # dengan fslex / fxyacc sendiri, meskipun tidak dalam proyek "produksi" (belum dirilis) - penyorotan sintaks MSIL dan ekstensi penyelesaian kode untuk VS. Manfaat utama menggunakan F # ada adalah Anda mendapatkan ADT, yang sangat nyaman untuk mewakili pohon parse. Juga, menggunakan ritsleting ( en.wikipedia.org/wiki/Zipper_(data_structure) ) membuatnya mudah untuk melakukan lexing tambahan - dan ritsleting, karena fungsional, lebih mudah untuk dimanipulasi secara ringkas dalam F #.
Pavel Minaev
7

Saat ini saya sedang mengerjakan kompilasi untuk bahasa pemrograman. Kompiler ditulis seluruhnya dalam F #. Compiler (selain dari lex dan parser build dengan lex / yacc) pada dasarnya dibangun sebagai banyak transformasi struktur seperti pohon kompleks.

Seperti yang dicatat oleh orang lain membedakan serikat pekerja dan pencocokan pola membuat bekerja dengan struktur data semacam ini jauh lebih mudah daripada membuang kode dalam metode virtual "di semua tempat"

Saya tidak melakukan pekerjaan F # sebelum saya mulai bekerja pada kompiler (Namun saya memiliki kompiler buld dalam varian OCaml lain yang disebut MoscowML) dan seperti yang dikatakan Jared, terlihat dari kode bagian apa yang saya lakukan pertama kali tetapi secara umum saya menemukan F # mudah untuk belajar masuk ke pola pikir FP lagi setelah coding terutama OO selama satu dekade akan memakan waktu sedikit lebih lama.

bekerja dengan pohon samping saya menemukan kemampuan untuk menulis kode deklaratif manfaat utama FP (F # termasuk) memiliki kode yang menggambarkan algoritma saya mencoba menerapkan berbeda dengan C # menggambarkan bagaimana saya telah menerapkan algortihm adalah keuntungan besar.

Rune FS
sumber
6

Bukan pengalaman pribadi, tetapi Anda dapat mendengarkan episode DNR (saya pikir inilah yang ini ) di mana mereka berbicara dengan Microsoft folk tentang F #. Mereka menulis sebagian besar sistem penilaian Xbox Live, yang jauh dari sepele, menggunakan F #. Sistem diskalakan secara besar-besaran di ratusan mesin dan mereka sangat puas dengannya.

Igor Zevaka
sumber
5

Saya tidak tahu apakah ini sedang dalam produksi, tetapi AI untuk "The Path of Go" ditulis dalam F #:

http://research.microsoft.com/en-us/events/techvista2010/demolist.aspx#ThePathofGo

Path of Go: Game Penelitian Microsoft untuk Xbox 360

Demo ini menampilkan game Xbox 360, yang didasarkan pada game Go, diproduksi sendiri di Microsoft Research Cambridge. Go adalah salah satu game papan paling terkenal di Asia Timur, ini berasal dari China 4000 tahun yang lalu. Di balik kesederhanaan permainan menipu menyembunyikan kerumitan besar. Hanya butuh beberapa menit untuk belajar, tetapi perlu seumur hidup untuk menguasainya. Meskipun komputer telah melampaui kemampuan manusia di Catur, penerapan AI untuk Go yang kompetitif tetap menjadi tantangan penelitian. Permainan ini ditenagai oleh tiga teknologi yang dikembangkan di Microsoft Research Cambridge: AI yang mampu memainkan Go, bahasa F #, dan TrueSkill ™ untuk mencocokkan pemain online. AI diimplementasikan dalam F # dan memenuhi tantangan berjalan secara efisien dalam .net framework pada Xbox 360. Game ini menempatkan Anda di sejumlah adegan 3D yang menakjubkan secara visual. Itu sepenuhnya dikembangkan dalam kode yang dikelola menggunakan lingkungan XNA.

(Orang lain sudah menyebutkan "TrueSkill".)

Brian
sumber
Menarik: F # berjalan pada framework kompak di XBox. Bukankah FSharp.Core.dll bersama dengan FSharp.Core.optdata FSharp.Core.sigdata merujuk pada rakitan non-CF?
Peter McG
1
CTP dikirimkan dengan FSharp.Core terpisah yang dibuat untuk .NETCF. (Ada juga FSharp.Core terpisah untuk Silverlight.)
Brian
Anda berbicara tentang CTP ini?
Jwosty