Halo semuanya!
Baru-baru ini, C ++ Siberia 2019 berikutnya diadakan di Novosibirsk. Konferensi ini memiliki suasana yang nyaman dan banyak laporan bagus. Saya mengambil kesempatan ini untuk berbicara dengan dua pembicara kami, yang akan segera Anda temui di Moskow.
Ivan Chukic adalah salah satu pengembang KDE, seorang guru dan peneliti desain bahasa pemrograman di University of Belgrade.
Alexander Granin ( graninas ) adalah seorang pembicara dan pengembang terkenal yang berspesialisasi dalam FP, penyelenggara komunitas FP Novosibirsk, LambdaNsk.

Sergey: Halo semuanya, mari berkenalan. Alexander adalah pembicara utama pada C ++ Siberia ini, dan Ivan adalah pembicara utama tahun lalu. Mari kita bicara tentang pemrograman fungsional. Sejauh yang saya ingat, FP dalam C ++ adalah tema dari keynote Anda sebelumnya, Ivan ...
Ivan: Tidak sepenuhnya, tetapi sebagian - ya.
Sergey: Dan topik laporan Alexander adalah tentang pemrograman fungsional. Karena itu, saya menyiapkan beberapa pertanyaan, dan yang pertama - bagaimana Anda menentukan AF?
Alexander: Saya tidak berpikir bahwa ada satu definisi AF yang "benar", tetapi berbicara tentang saya secara pribadi, AF adalah sesuatu dengan komposisi fungsional dan fungsi kelas satu.
Ivan: Saya setuju, tetapi saya akan menambahkan lebih banyak fungsi dengan urutan lebih tinggi - fungsi yang dapat menggunakan fungsi lain sebagai argumen dan sebagai hasilnya kembali.
Sergey : Tautan ke fungsi dalam C - apakah itu dipertimbangkan?
Ivan: Tidak, C bukan bahasa pemrograman fungsional :-)
Sergey: Katakan mengapa?
Ivan: Karena Anda tidak dapat membuat fungsi baru dari kombinasi pointer fungsi, Anda hanya bisa menunjuk ke yang sudah ada. Tentu saja, jika beberapa hack assembler tidak digunakan.
Sergey: Luar biasa, sekarang saya punya jawaban resmi! Orang-orang terus-menerus bertanya pertanyaan ini mengapa C bukan bahasa pemrograman fungsional, karena ada fungsi lengkap di sana. Dan inilah mengapa C ++ adalah bahasa fungsional, lebih bisa dimengerti ...
Alexander: Saya tidak akan mengatakan bahwa C ++ adalah bahasa pemrograman yang benar-benar fungsional, ia mendukung banyak paradigma yang dituangkan ke dalam satu bahasa.
Sergey: Maksud saya - C ++ mendukung paradigma fungsional, tentu saja. Ngomong-ngomong, mengapa? Apakah dia mendukungnya karena Anda dapat memanipulasi fungsi tingkat tinggi?
Ivan: Ya, menurut saya dia selalu seperti itu, karena bahkan di C ++ 98, fungsi tingkat tinggi sudah ada, bahkan di STL. Ini bukan bahasa fungsional yang paling nyaman - ada bahasa yang mengimplementasikan FP dan lebih baik. Tetapi untuk kebutuhan saya selalu cukup fungsional.
Sergey: Tapi dari tempat ini lebih terinci. Kebutuhan apa yang Anda miliki?
Ivan: Ini rumit. Ayo, ceritakan sebuah kisah. Ketika saya di universitas, kami melewati LISP, dan semua orang membenci LISP ini karena jelek. Tapi yang saya pahami darinya adalah bagaimana mensimulasikan konstruksi C secara langsung dalam kode LISP. Dan kemudian suatu hari versi baru Jawa keluar, yang dirilis untuk hal-hal seperti foreach
, dan saya pikir: wow, Anda memerlukan kompiler baru, versi bahasa baru dan semua yang baru hanya untuk mengimplementasikan sesuatu yang saya lakukan di universitas pada LISP , yang umumnya bahkan tidak mendukung loop. Pada saat itu, saya menyadari bahwa FP adalah hal yang cukup bagus untuk membangun abstraksi tingkat tinggi, dan itulah mengapa saya menggunakan fungsional C ++ pada tahun 2019.
Sergey: Sebenarnya, Anda menggunakan FP untuk desain tingkat tinggi.
Ivan: Tepat sekali.
Alexander: Saat ini saya tidak bekerja di C ++, tapi saya tidak akan menolak untuk menggunakannya untuk memanipulasi data, ini jauh lebih menyenangkan daripada dalam pendekatan imperatif. Bahkan jika dibandingkan dengan OOP, berbeda dengan itu, hanya transformasi yang dapat diterima di sini, dan ini nyaman.
Sergey: Ya, Anda bisa menggunakan FP tidak hanya dengan C ++, bukan? OK, lalu pertanyaan berikutnya: bagian C ++ apa yang Anda gunakan? Jika hanya masalah desain yang penting, Anda hanya dapat memilih bagian yang cocok dengan FP, yang benar-benar Anda gunakan.
Ivan: Ini pasti akan menjadi fungsi lambda. Dan bahkan yang lebih penting - templat, karena memungkinkan Anda untuk melewati fungsi lain sebagai argumen dan yang lainnya, dan lambda hanyalah sintaks yang bagus untuk menulis objek fungsional.
Sergey: Ya, kami sudah menyadari bahwa Anda benar-benar menyukai lambdas :-)
Ivan: Bukannya mereka benar - benar menyukainya, tapi ini jelas merupakan hal terbaik yang kami miliki di C ++ 98, lebih nyaman untuk bekerja dengan mereka.
Alexander: Ya, saya juga suka lambdas - fitur ini sangat universal sehingga Anda hanya bisa menulisnya saja. Ini adalah sesuatu seperti kombinator universal yang memungkinkan Anda membangun logika apa pun - mungkin tidak seindah dalam bahasa lain, tetapi tidak kalah bermanfaat.
Sergey: Ivan, Anda mencatat di sini bahwa ada standar sebelum C ++ 11, misalnya, C ++ 03, yang sangat umum, dan sudah ada fitur fungsional di sana. Dan ada lebih banyak fitur fungsional dalam standar baru ... Apakah mungkin untuk mengatakan bahwa C ++ bergerak menuju FP? Akankah gerakan ini berlanjut atau berhenti? Lalu apa yang akan terjadi?
Ivan: Ada laporan bagus oleh Simon Peython Jones tentang bahasa pemrograman secara umum, dan di sana ia menggambar grafik yang menunjukkan banyak bahasa aman dan bahasa yang digunakan. Haskell memulai ceritanya sebagai bahasa yang benar-benar aman yang dengannya tidak ada yang bisa dilakukan - karena tidak ada I / O, dan tidak ada sama sekali. SPJ mengkategorikan bahasa C dan bahasa rakitan sebagai bahasa yang sangat berguna, tetapi pada saat yang sama sangat tidak aman. Sejak itu, Haskell telah mulai bergerak ke arah keamanan yang lebih besar. Di sisi lain, fitur-fitur yang muncul di C ++ - mereka muncul terutama untuk meningkatkan keamanan sehingga Anda dapat menulis program yang benar lebih sederhana. Kebetulan sebagian besar dari hal-hal ini berasal dari bahasa pemrograman fungsional.
Sergey: Mengapa menurut Anda begitu? Karena sifat AF?
Ivan: Ya, mungkin secara alami ... tapi saya tidak tahu pasti.
Alexander: Saya pikir AF sangat memikat semua orang hanya karena kami lelah berjuang dengan templat, mengatur ulang byte, dengan semacam ampas tingkat rendah - kami ingin sesuatu yang layak untuk menerapkan kecerdasan kami sendiri.
Sergey: Ya , bagi Anda ini semacam latihan intelektual?
Alexander: Ya, seperti itu.
Sergey: Saya mengerti. Betapa jauh lebih menarik bagi pengembang untuk memikirkan abstraksi tingkat tinggi daripada menerapkan fitur standar yang bodoh - ini tidak menyenangkan. Maka ini adalah pertanyaan C: apakah Anda memiliki pengalaman dengan aplikasi praktis FP di C ++? Ada proyek produksi?
Ivan: Tentu saja. Salah satu proyek terbesar di dunia, KDE, memiliki beberapa bagian di dalamnya yang secara intensif menggunakan gaya fungsional. Tentu saja, ini adalah campuran, jadi untuk berbicara, lebih berorientasi objek tradisional C ++ dengan serangkaian konsep fungsional. Saya tidak akan pernah menjadi seorang purist atau sesuatu seperti itu. Saya selalu mencoba menggabungkan yang terbaik dari dunia yang berbeda.
Sergey: Bagaimana dengan Haskell atau Scala? Bagaimanapun, mereka banyak digunakan dalam produksi. Bagaimana Anda menyukai gagasan bahwa Haskell sekarang dianggap sebagai standar bahasa fungsional? Ini terutama dicatat oleh para puritan.
Ivan: Ya, saya setuju bahwa Haskell hari ini adalah sinonim untuk FP. Bahkan, setiap fitur dari Haskell dianggap oleh orang sebagai sesuatu yang terkait dengan FP. Ini belum tentu benar, tetapi saya pikir Haskell telah benar-benar menjadi bahasa pemrograman fungsional akademik yang paling populer. Saya tahu bahwa beberapa bank di London dan Eropa Utara menggunakan Haskell secara ekstensif, tetapi Scala masih jauh lebih populer saat ini.
Alexander: Saya setuju bahwa Scala lebih populer, tetapi Haskell tampaknya menjadi bahasa yang lebih fungsional, sebagian besar fiturnya diimplementasikan lebih benar. Artinya, ketika Anda memiliki kari yang mudah dilakukan, ketika ada cara mudah untuk membuat komposisi, pemrograman menjadi mudah dan sederhana, itu seperti berjalan melalui hutan dan menikmati pemandangan.
Ivan: Tapi terkadang ada beruang di hutan. Jika Anda berada di Rusia.
Sergey: Apakah menurut Anda C ++ terutama terinspirasi oleh Haskell? Apakah itu sepadan?
Ivan: Apakah Anda memberi petunjuk kepada anggota komite tertentu? :-) Seseorang mengisyaratkan bahwa konsep muncul sebagai hasil dari memahami kelas kelas, tetapi Bjorn menghentikan rumor ini dan bahkan menulis beberapa dokumen tentang bagaimana konsep berbeda dari kelas kelas. Dari sudut pandang saya, mereka berbeda dalam segala hal, tetapi melayani satu tujuan. Hanya pendekatan yang berbeda.
Sergey: Apakah masa depan / janji dengan cara apa pun terkait dengan FI? Bartosh tampaknya berpendapat bahwa ini adalah monad yang diimplementasikan dengan buruk.
Ivan: Ya, mereka diimplementasikan sebagai monad, mentransmisikan sekuel, tapi saya tidak yakin apa yang paling penting dalam masalah ini.
Sergey: Apakah kita perlu meningkatkan dukungan monad di C ++?
Alexander: Tentu saja, ini adalah fitur paling penting yang dapat mengubah C ++ menjadi bahasa yang sangat baik.
Ivan: Ngomong-ngomong, karena kita ada di konferensi, izinkan saya mengajukan pertanyaan juga, Sergey. Anda mengatakan bahwa konferensi adalah pekerjaan yang menyenangkan. Bagikan apa yang begitu menarik tentang hal itu, dan maukah Anda menasihati saya atau Kamerad Granin untuk secara mandiri menyelenggarakan konferensi di bagian lain dunia?
Sergey: Organisasi konferensi benar-benar keren, Anda bertemu banyak orang yang menarik, tetapi ini hanyalah puncak gunung es. Dan di sana - banyak pekerjaan, semua persiapan aula ini, makanan untuk para peserta, belum lagi mencari pembicara. C ++ Rusia masih bukan konferensi paling terkenal di dunia, dan para pembicara harus menjelaskan bahwa kita adalah konferensi baru, bahwa hal-hal menarik sedang terjadi di sini. Anda perlu meyakinkan pembicara, terutama pembicara bintang terkenal yang tidak terlalu tertarik terbang ke Rusia hanya untuk melihat negara baru. Pekerjaan organisasi itu sulit, terutama jika Anda bekerja di pekerjaan utama. Tapi semuanya terbayar dengan berkomunikasi dengan orang-orang hebat ini. Meskipun demikian, saya sekarang telah mencapai titik bahwa saya lebih suka menghadiri konferensi orang lain daripada saya akan melakukan konferensi saya sendiri.
Ivan: Yaitu, Anda menyarankan untuk menghadiri konferensi, daripada melakukannya.
Sergey: Ya, jika Anda dapat menghindari penyelenggaraan konferensi, Anda harus mengambil kesempatan. Saat berorganisasi, beban besar akan jatuh pada Anda, ini adalah pekerjaan 8 jam lagi. Secara pribadi, saya mulai bekerja tambahan 8 jam sehari sekitar 3 bulan sebelum konferensi. Ini menyenangkan untuk dilakukan ... tapi saya harap keluarga saya juga menyenangkan. Terima kasih sudah bertanya!
Dan sekarang, kembali ke topik. Kami berbicara tentang pemrograman fungsional, dan Anda hampir meyakinkan saya, dalam arti bahwa laporan Anda meyakinkan saya. Ada kecurigaan bahwa pendekatan fungsional dalam C ++ akan membantu saya dengan multithreading ketika saya perlu menyinkronkan hal-hal yang berbeda. Apakah ini akan sangat membantu?
Ivan: Tentu saja.
Alexander: Terlepas dari kenyataan bahwa saya memiliki pengalaman terbatas dengan multithreading fungsional khususnya dalam C ++, saya harus mengatakan bahwa ketika Anda memiliki dunia fungsi murni, jauh lebih mudah untuk membicarakannya di lingkungan multithreaded. Jika Anda menulis logika, misalnya, kompetitif, Anda tidak perlu berpikir tentang menyinkronkan semua hal ini, tentang mutex, tentang bagian penting, tentang apa pun. Semua ini hilang begitu saja, karena Anda menganggap kode tersebut sebagai kode berurutan biasa, dan semua multithreading dan sinkronisasi tersembunyi di suatu tempat di dalamnya. Ada banyak pendekatan untuk pemrograman multithreaded, dan fungsional. Saya tidak yakin bahwa ini benar-benar terjadi dalam semua pendekatan, tetapi misalnya, memori transaksional perangkat lunak adalah pendekatan yang bagus untuk mengurangi kompleksitas dalam aplikasi kompetitif. Sayangnya, ini adalah masalah memilih kompromi yang tepat.
Ivan: Ketika kompiler melakukan semua pekerjaan untuk Anda, Anda harus membayarnya dengan efisiensi.
Alexander: Ya, ada berbagai masalah. Pertama, Anda perlu memahami semua hal ini seperti STM, dan kemudian meneruskan pengetahuan rahasia ini kepada kolega Anda. Dan kemudian ada kesalahan dalam implementasi tertentu dan tempat-tempat yang dapat bekerja lebih baik saat menggunakan kontrol utas manual. Tetapi Anda dapat menulis lebih cepat dan lebih mudah daripada dengan kontrol manual seperti itu. Akan lebih lambat untuk dieksekusi, tetapi kode akan lebih sedikit kesalahan. Omong-omong, Ivan, apa pendapat Anda tentang seberapa baik masalah ini dibahas dengan baik di konferensi?
Ivan: Topik ini sedang booming. Dalam beberapa tahun terakhir, semua konferensi utama - CPPConf, C ++ Rusia, Rapat C ++, dll. - Menerima laporan baik secara langsung di FP, atau pada struktur data aljabar, atau sesuatu seperti itu. Kadang-kadang pembicara bahkan tidak curiga bahwa dalam laporan mereka, mereka berbicara tentang beberapa konsep dari FP. Di C ++, banyak hal datang dari berbagai tempat ... Orang biasanya tidak menulis hanya dalam satu bahasa. Bayangkan Ivan Ivanov mengerjakan proyek yang ditulis dalam bahasa Erlang dan C ++. Kemudian Tatyana Petrovna tiba, dan dia sudah bekerja untuk Haskell dengan fungsi bersih dan semua itu, mereka mengambil mekanisme favorit mereka dan memindahkannya ke C ++, dan sebagai hasilnya, sejumlah besar orang dari berbagai komunitas membawa lebih banyak barang ke C ++. Semua ini terjadi di depan mata kita. Paling tidak, ini terjadi di komunitas pengembang C ++, tetapi untuk perusahaan C ++, saya tidak begitu yakin. Namun, banyak orang di komunitas C ++ sekarang bekerja pada konsep fungsional.
Alexander: Saya benar mengerti bahwa banyak pengembang C ++ teratas mempelajari Haskell hanya untuk memahami apa yang terjadi dengan C ++?
Ivan: Saya tidak yakin mereka mengajar Haskell karena alasan ini. Saya pikir pengembang C ++ sangat egois. Mereka belajar C ++ dengan baik hanya karena itu rumit. Dan jika Anda ingin mempelajari sesuatu yang benar-benar baru, jalur Anda jelas tidak terletak di Jawa, yang dibuat khusus untuk menjadi sederhana. Anda perlu melihat di bidang bahasa yang tidak biasa dan aneh, yang paling aneh, dan Haskell secara otomatis akan menjadi jawaban yang paling populer. Seseorang melihatnya, mengerti: oh, ini adalah sesuatu yang lebih kompleks daripada C ++, Anda perlu belajar. Ketika saya mempelajari Haskell, itu sama dengan saya, dan saya punya teman-teman yang mengikuti alur pemikiran yang persis sama.
Alexander: Ketika Eric Nibler ada bersama kami di Siberia dan menunjukkan perpustakaannya untuk jangkauan, ia sering ditanya apa sumber inspirasi. Dia menjawab bahwa itu adalah Haskell. Mungkin semua fitur berturut-turut tidak boleh diambil darinya, tetapi beberapa jelas dibutuhkan di komunitas.
Ivan: Ini sedikit evolusi. Bahan genetik. Dan Haskell juga dapat ditingkatkan dengan mengambil sesuatu dari C ++. Sebagian besar bahasa mengalami evolusi seperti itu. Java mencoba untuk mengadaptasi LINQ dari C # ke dirinya sendiri, dan pencipta LINQ dari C # menarik inspirasi dari Haskell, dll. Ternyata jaringan kusut yang indah dari pengaruh timbal balik antara berbagai bahasa.
Alexander: Namun, apakah C ++ masih bahasa tingkat rendah?
Ivan: Kebanyakan orang berpikir begitu.
Sergey: "level rendah" seperti apa yang kamu bicarakan?
Ivan: Dikompilasi ke kode tingkat rendah. Tetapi ia bekerja dengan abstraksi tingkat tinggi. Inti dan tujuannya adalah bahwa abstraksi semacam itu tidak mengarah pada overhead yang tidak perlu dalam hal kinerja. C ++ harus menghasilkan kode dari abstraksi yang tidak lebih buruk dari tulisan tangan. Setidaknya secara teoritis.
Alexander: Apa yang terjadi jika seseorang melanggar aturan ini? Misalnya, Ranges.
Ivan: Kinerja kompilasi menderita - ya. Semua fitur baru, terutama fitur yang disediakan di perpustakaan, menambah waktu kompilasi. Tetapi tidak ada alasan mengapa rentang harus lambat. Jika rentang melambat, maka satu-satunya hal yang dapat Anda salahkan di sini adalah kompiler yang tidak dioptimalkan untuk kasus khusus ini.
Sergey: Ranges sendiri tidak mengerem, tetapi Ranges dalam mode debug - ini adalah inti dari seluruh diskusi. Dalam mode rilis, mereka bekerja dengan baik.
Ivan: Ini normal.
Sergey: Tidak semua orang setuju dengan ini :-)
Ivan: Ya, saya tahu dalam praktiknya. Di satu perusahaan, di perpustakaan yang paling sering digunakan ... Saya tidak akan mengatakan jenis perusahaan dan perpustakaan itu ... ada algoritma yang secara asimptot secara signifikan lebih lambat dalam mode debug. Dan siapa yang sekarang akan mengeluh bahwa rentang melakukan hal yang sama?
Sergey: Dalam artikel yang sedang kita bahas, intinya bukan di sendiri, mereka hanya contoh bagi seorang penulis yang marah karena situasi ini menjadi tren, dan produktivitas yang rendah dalam mode debug. Di area subjeknya, mesin game, ini tidak bisa diterima.
Alexander: Orang-orang ini sama sekali tidak menyukai STL, karena kerjanya lebih lambat dari yang mereka butuhkan. Rentang hanya memperluas perpustakaan ke arah yang sama, dan bagi mereka sepertinya fitur lain yang tidak berguna yang tidak dapat mereka gunakan.
Sergey: Pembenci akan membenci.
Ivan: Tepat sekali. Misalnya, semua orang menggunakan penyortiran. Bayangkan saja tidak ada lagi penyortiran di perpustakaan standar. Bagaimana Anda mengimplementasikannya?
Sergey: Saya biasanya mengajukan pertanyaan seperti itu dalam sebuah wawancara :-) Ini adalah pertanyaan yang sangat umum.
Ivan: Ya, pertanyaan yang sering muncul adalah bagaimana menerapkan penyortiran. Dan kemudian Anda berbicara tentang beberapa versi dasar penyortiran cepat, yang sebenarnya tidak digunakan sama sekali di mana pun di dunia, karena itu bisa sangat lambat dalam kasus-kasus tertentu. Pustaka standar tidak mengizinkannya untuk digunakan, karena membutuhkan N log yang dijamin N, dan pengurutan yang cepat tidak bisa. Sebagian besar bisa, tetapi standar di tempat ini sangat ketat, dan tidak berarti akumulasi N log N, itu harus murni N log N, dan bagaimana Anda mengimplementasikan algoritma seperti itu? Anda perlu melakukan penelitian, menemukan banyak optimasi berbeda untuk penyortiran cepat, dan menggabungkannya menjadi satu algoritma yang terdiri dari setidaknya tiga algoritma yang berbeda, seperti yang dilakukan di libstdc ++. Ini adalah arti dari perpustakaan standar - Anda tidak perlu tahu semua hal ini untuk diprogram. Tidak perlu mencari tahu bagaimana mengimplementasikan semuanya dengan cara yang paling efisien, orang lain sudah mengurus ini untuk Anda. Karenanya, saya tidak suka pendekatan ini ketika orang berkata: "STL sangat rumit, jangan gunakan dan tulis semuanya dari awal secara manual."
Sergey: Kami mendekati akhir wawancara, jadi pertanyaan terakhir: bagaimana Anda suka di Rusia?
Alexander: Semakin dingin.
Sergey: Bahkan untukmu? Anda orang lokal!
Ivan: Tapi bagi saya itu jauh lebih hangat dari yang diharapkan.
Sergey: Sekarang sudah -16, dan kami sudah bilang -40.
Ivan: Ya, Anda berjanji! Saya khusus disiapkan untuk minus empat puluh. Dan kemudian saya melihat termometer, dan di sana semuanya lebih hangat dan lebih hangat.
Sergey: Nah, sekarang kita hanya akan bertemu di C ++ Russia 2019, itu akan di Moskow, dan akan ada suhu plus. Terima kasih untuk wawancaranya dan sampai jumpa lagi!
Menit periklanan. Pada 19-20 April, sebuah konferensi Rusia C ++ akan diadakan, di mana Ivan akan membuat presentasi “Desain C ++ yang hanya bergerak” , dan Alexander akan berbicara tentang pengurai monadik. Selain itu, Ivan akan mengadakan satu dari tiga pelatihan besar - “Pemrograman fungsional terapan dalam C ++” . Sebulan tersisa sebelum konferensi dan program terus disempurnakan. Di situs web resmi Anda dapat melihat laporan mana yang sudah masuk ke program dan membeli tiket . Harap dicatat bahwa ada berbagai jenis tiket, dan memilih tiket yang tepat dapat menghemat banyak.