Apa yang memicu popularitas fungsi lambda dalam bahasa pemrograman arus utama modern?


112

Dalam beberapa tahun terakhir fungsi anonim (fungsi lambda AKA) telah menjadi konstruksi bahasa yang sangat populer dan hampir setiap bahasa pemrograman utama / utama telah memperkenalkannya atau direncanakan untuk memperkenalkannya dalam revisi standar yang akan datang.

Namun, fungsi anonim adalah konsep yang sangat tua dan sangat terkenal dalam Matematika dan Ilmu Komputer (ditemukan oleh ahli matematika Alonzo Church sekitar tahun 1936, dan digunakan oleh bahasa pemrograman Lisp sejak 1958, lihat misalnya di sini ).

Jadi mengapa tidak bahasa pemrograman arus utama saat ini (banyak yang berasal 15 hingga 20 tahun yang lalu) mendukung fungsi lambda dari awal dan hanya memperkenalkannya nanti?

Dan apa yang memicu adopsi besar-besaran fungsi anonim dalam beberapa tahun terakhir? Apakah ada peristiwa khusus, persyaratan baru atau teknik pemrograman yang memulai fenomena ini?

CATATAN PENTING

Fokus pertanyaan ini adalah pengenalan fungsi anonim dalam bahasa modern, arus utama (dan karenanya, mungkin dengan beberapa pengecualian, tidak berfungsi). Juga, perhatikan bahwa fungsi anonim (blok) hadir di Smalltalk, yang bukan bahasa fungsional, dan bahwa fungsi yang dinamai normal telah hadir bahkan dalam bahasa prosedural seperti C dan Pascal untuk waktu yang lama.

Tolong jangan terlalu menggeneralisasi jawaban Anda dengan berbicara tentang "adopsi paradigma fungsional dan manfaatnya", karena ini bukan topik pertanyaan.


7
15-20 tahun yang lalu orang-orang mengajukan pertanyaan yang sama tentang OO ... itu bukan konsep baru tetapi memiliki ledakan popularitas.
MattDavey

7
@MattDavey Kebanyakan pasti tidak setuju, tapi kemudian saya harus mengingatkan mereka bahwa "kebanyakan pengembang Smalltalk" tidak terlalu banyak; P
yannis

30
Saya pikir pertanyaan yang lebih menarik adalah apa yang memicu kematian mereka ! Bagaimanapun, ada suatu masa, ketika sebagian besar bahasa modern memang memiliki lambda, maka bahasa seperti Jawa dan C ++ menjadi populer. (Walaupun saya tidak akan menyebut Jawa sebagai bahasa "modern". Konsep paling modern di Jawa adalah Generics, yang berawal dari akhir tahun 60an / awal 70an. Bahkan kombinasi fitur yang disediakan Java, keamanan pointer, keamanan memori, tipe keamanan, GC, OO yang diketik secara statis, Generik semuanya ada di Eiffel pada tahun 1985 ... dan jauh lebih baik, IMHO.)
Jörg W Mittag

31
Bahkan sebelum Java 1.0 keluar, saat itu masih dalam tahap desain awal, hampir semua orang menunjukkan bahwa Java membutuhkan lambda. Beberapa desainer yang bekerja di Jawa termasuk Guy Steele (pendukung Lisp, co-designer Scheme, co-penulis Common Lisp, desainer Benteng), James Gosling (menulis interpreter Emacs Lisp pertama untuk PC), Gilad Bracha (Smalltalk pendukung, co-desainer Animorphic Smalltalk, desainer Newspeak), Phil Wadler (co-desainer Haskell), Martin Odersky (desainer Scala). Bagaimana Jawa berakhir tanpa lambdas benar-benar di luar jangkauan saya.
Jörg W Mittag

8
"Sedikit kecil" sering kali berarti 50% fungsi, 50% noise.
kevin cline

Jawaban:


86

Tentu saja ada kecenderungan yang nyata terhadap pemrograman fungsional, atau setidaknya beberapa aspek tertentu. Beberapa bahasa populer yang pada beberapa titik mengadopsi fungsi anonim adalah C ++ ( C ++ 11 ), PHP ( PHP 5.3.0 ), C # ( C # v2.0 ), Delphi (sejak 2009), Objective C ( blok ) sementara Java 8 akan membawa dukungan untuk lambdas ke bahasa . Dan ada bahasa populer yang umumnya tidak dianggap fungsional tetapi mendukung fungsi anonim sejak awal, atau setidaknya sejak awal, contoh yang bersinar adalah JavaScript.

Seperti halnya semua tren, mencoba mencari satu peristiwa yang memicu mereka mungkin hanya buang-buang waktu, biasanya merupakan kombinasi faktor, yang sebagian besar tidak dapat dikuantifikasi. Lisp Praktis Umum , yang diterbitkan pada tahun 2005, mungkin telah memainkan peran penting dalam membawa perhatian baru kepada Lisp sebagai bahasa praktis , karena untuk beberapa waktu Lisp sebagian besar adalah bahasa yang akan Anda temui dalam lingkungan akademik, atau ceruk pasar yang sangat spesifik. Popularitas JavaScript mungkin juga memainkan peran penting dalam membawa perhatian baru ke fungsi anonim, seperti yang dijelaskan oleh munificent dalam jawabannya .

Selain adopsi konsep-konsep fungsional dari bahasa multi-guna, ada juga perubahan nyata ke bahasa fungsional (atau sebagian besar fungsional). Bahasa-bahasa seperti Erlang (1986), Haskell (1990), OCaml (1996), Scala (2003), F # (2005), Clojure (2007), dan bahkan bahasa-bahasa khusus domain seperti R (1993) tampaknya telah memperoleh pengikut yang kuat dengan kuat setelah mereka diperkenalkan. Tren umum telah membawa perhatian baru pada bahasa fungsional yang lebih tua, seperti Scheme (1975), dan jelas Common Lisp.

Saya pikir satu-satunya peristiwa yang lebih penting adalah adopsi pemrograman fungsional di industri. Saya sama sekali tidak tahu mengapa itu tidak terjadi, tetapi bagi saya tampaknya pada suatu titik selama pemrograman fungsional awal dan pertengahan tahun 90-an mulai menemukan tempatnya di industri, mulai (mungkin) dengan proliferasi Erlang di telekomunikasi dan adopsi Haskell dalam dirgantara dan desain perangkat keras .

Joel Spolsky telah menulis posting blog yang sangat menarik, The Perils of JavaSchools , di mana ia menentang tren (saat itu) universitas untuk lebih menyukai Jawa daripada yang lain, mungkin lebih sulit untuk belajar bahasa. Meskipun posting blog tidak ada hubungannya dengan pemrograman fungsional, ia mengidentifikasi masalah utama:

Di situlah letak perdebatan. Bertahun-tahun diombang-ambing oleh undergrad CS yang malas seperti saya, dikombinasikan dengan keluhan dari industri tentang betapa sedikit lulusan CS yang lulus dari universitas-universitas Amerika, telah mengambil korban, dan dalam dekade terakhir sejumlah besar sekolah yang seharusnya sempurna telah mencapai 100% Jawa. Sangat keren, para perekrut yang menggunakan "grep" untuk mengevaluasi resume sepertinya menyukainya, dan, yang paling penting, tidak ada yang cukup sulit tentang Java untuk benar-benar menyingkirkan para programmer tanpa bagian otak yang melakukan pointer atau rekursi, sehingga tingkat drop-out lebih rendah, dan departemen ilmu komputer memiliki lebih banyak siswa, dan anggaran yang lebih besar, dan semuanya baik-baik saja.

Aku masih ingat betapa aku membenci Lisp, ketika aku pertama kali bertemu dengannya selama masa kuliahku. Ini jelas nyonya yang kasar, dan itu bukan bahasa di mana Anda bisa segera produktif (well, setidaknya saya tidak bisa). Dibandingkan dengan Lisp, Haskell (misalnya) jauh lebih ramah, Anda dapat menjadi produktif tanpa banyak usaha dan tanpa merasa seperti orang idiot, dan itu mungkin juga menjadi faktor penting dalam pergeseran menuju pemrograman fungsional.

Secara keseluruhan, ini adalah hal yang baik. Beberapa bahasa multi-tujuan mengadopsi konsep paradigma yang mungkin tampak misterius bagi sebagian besar pengguna mereka sebelumnya, dan kesenjangan antara paradigma utama semakin menyempit.

Pertanyaan-pertanyaan Terkait:

Bacaan lebih lanjut:


Terima kasih atas jawabannya (dan banyak ide menarik). +1 Namun, saya berpendapat bahwa memperkenalkan (hanya) lambdas ke dalam bahasa pemrograman adalah langkah yang sangat kecil menuju FP, dan bahkan mungkin membingungkan banyak orang (apa yang dilakukan lambda sendirian di dalam bahasa imperatif?). Setelah mempelajari beberapa Haskell, Scala, dan SML, saya tidak punya perasaan saya bisa melakukan FP nyata dengan bahasa imperatif yang hanya mendukung lambdas (bagaimana dengan currying, dan pencocokan pola, immutability?).
Giorgio


2
@YannisRizos: Perl memiliki fungsi anonim sejak rilis pertama 5 (1994), tetapi mereka tidak sepenuhnya "benar" sampai 5.004 (1997).
Blrfl

1
@penartur Itulah yang saya pikirkan juga, tetapi seorang editor yang ramah mengoreksi saya dengan menunjuk saya di sini: msdn.microsoft.com/en-us/library/0yw3tz5k%28v=vs.80%29.aspx
yannis

Saya pikir mungkin "acara" utama yang membawa popularitas bahasa fungsional adalah web. Lebih khusus lagi, pergeseran dari program desktop ke sisi server. Ini memberikan kebebasan pengembang untuk memilih bahasa pemrograman apa pun. Paul Graham dan Lisp di tahun 90-an adalah contoh penting.
Gilad Naor

32

Saya pikir ini menarik betapa popularitas pemrograman fungsional telah paralel dengan pertumbuhan dan proliferasi Javascript. Javascript memiliki banyak fitur radikal di sepanjang spektrum pemrograman fungsional yang pada saat penciptaannya (1995) tidak begitu populer di antara bahasa pemrograman mainstream (C ++ / Java). Itu tiba-tiba disuntikkan ke arus utama sebagai satu-satunya bahasa pemrograman web sisi klien. Tiba-tiba banyak programmer hanya perlu tahu Javascript dan karena itu Anda harus tahu sesuatu tentang fitur bahasa pemrograman fungsional.

Saya bertanya-tanya bagaimana bahasa / fitur fungsional populer akan jika bukan karena munculnya tiba-tiba Javascript.


5
Javascript jelas merupakan bahasa yang penting, tetapi saya tidak yakin apakah pengenalan Javascript dapat menjelaskan popularitas pemrograman fungsional sendiri: banyak bahasa pemrograman fungsional lainnya telah muncul selama beberapa tahun terakhir, seperti yang digambarkan oleh Yannis dalam jawabannya. .
Giorgio

8
@Iorgio - mungkin ada banyak bahasa pemrograman fungsional lainnya, tetapi (relatif) tidak ada yang menggunakannya. Penggunaan JS dan meningkatnya pandangan bahwa cara C ++ / Java membuat functors benar-benar menyakitkan dan menjengkelkan adalah kekuatan pendorong utama, bahkan jika semakin banyak bahasa akademis menegaskan bagaimana mereka harus diimplementasikan.
Telastyn

1
Popularitas bahasa dinamis secara umum diisyaratkan sebagai salah satu penjelasan untuk popularitas Haskell: book.realworldhaskell.org/read/…
yannis

Selain itu, fokus pertanyaannya bukan pada popularitas FP secara umum, tetapi tentang keterlambatan pengenalan fungsi anonim dalam tujuan umum, bahasa yang tidak berfungsi. Sekalipun publik besar (kebanyakan programmer) tidak mengenal mereka, perancang bahasa mengenal mereka dengan sangat baik. Pasti ada alasan untuk meninggalkan mereka di awal. Mungkin mereka dianggap tidak intuitif untuk pengembang awal 90-ikatan.
Giorgio

@giorgio - Mereka jauh lebih sulit untuk diimplementasikan dibandingkan dengan functors gaya Java. Kombinasikan itu dengan kurangnya pengetahuan / adopsi dan itu adalah pilihan desain yang cukup jelas.
Telastyn

27

Penangan event JavaScript dan DOM berarti bahwa jutaan programmer harus belajar setidaknya sedikit tentang fungsi-fungsi kelas satu untuk melakukan interaktivitas apa pun di web.

Dari sana, ini adalah langkah yang relatif singkat untuk fungsi anonim . Karena JavaScript tidak menutup this, itu juga sangat mendorong Anda untuk belajar tentang penutupan juga. Dan kemudian Anda emas: Anda memahami fungsi kelas satu anonim yang menutup lingkup leksikal.

Setelah Anda merasa nyaman dengan itu, Anda menginginkannya dalam setiap bahasa yang Anda gunakan.


7
+1 ini bukan hanya tentang fungsi anonim. Penutupan adalah konsep yang jauh lebih luas dari sekedar mendefinisikan fungsi sementara inline.
phkahler

@phkahler: Anda benar dan, dalam hal ini, Java sudah memiliki penutup (dan bahkan lebih kuat dari apa yang Anda dapatkan dengan fungsi literal) tetapi tidak memiliki notasi ringkas untuk kasus umum kelas anonim satu metode.
Giorgio

17

Ini jelas bukan satu - satunya faktor, tetapi saya akan menunjukkan popularitas Ruby. Tidak mengatakan ini lebih penting daripada salah satu dari enam jawaban yang ada di papan tulis, tetapi saya pikir banyak hal terjadi sekaligus dan itu berguna untuk menyebutkan semuanya.

Ruby bukan bahasa fungsional dan lambdas, prods, dan bloknya terasa kikuk ketika Anda menggunakan sesuatu seperti ML, tetapi faktanya, Ruby mempopulerkan gagasan pemetaan dan pengurangan hingga generasi programmer muda yang meninggalkan Jawa dan PHP untuk hipper padang rumput. Lambdas dalam beberapa bahasa tampaknya bergerak defensif lebih dari apa pun ("Tetap di sini! Kita juga punya itu !!)

Tetapi sintaks blok dan cara mengintegrasikannya dengan .each, .map, .reduce, dan sebagainya memunculkan ide fungsi anonim bahkan jika itu benar-benar sebuah konstruksi sintaksis yang berperilaku seperti coroutine. Dan konversi yang mudah ke proc via & membuatnya menjadi obat gerbang untuk pemrograman fungsional.

Saya berpendapat bahwa programmer Ruby on Rails yang menulis JavaScript sudah dihidupkan untuk melakukan sesuatu dengan gaya fungsional yang ringan. Berpasangan dengan programmer blogging, penemuan Reddit, hacker News, dan Stack Overflow sekitar waktu yang sama, dan ide-ide menyebar lebih cepat melalui Internet daripada yang mereka lakukan di zaman Newsgroup.

TL; DR: Ruby, Rails, JavaScript, blogging, dan Reddit / Hacker News / Stack Overflow mendorong ide-ide fungsional ke pasar massal, jadi semua orang menginginkannya dalam bahasa yang ada untuk mencegah pembelotan lebih lanjut.


2
+1 Untuk jawaban yang bagus dan (jika saya bisa, karena saya hanya punya satu upvote) +1 untuk menunjukkan bahwa "Lambdas dalam beberapa bahasa tampaknya bergerak defensif lebih dari apa pun (" Tetap di sini! Kita juga punya itu !!) ". Saya pikir ini adalah faktor juga. Untuk beberapa bahasa lambdas adalah fitur yang bagus untuk dimiliki, meskipun ia menambahkan sedikit daya ekspresif pada bahasa secara keseluruhan, itu memberikan bahasa tersebut popularitas (sebuah sejumlah programmer tampaknya berpikir bahwa dukungan untuk fungsi anonim setara dengan pemrograman fungsional yang sepenuhnya mendukung)
Giorgio

2
Saya benar-benar berpikir ini adalah alasan mengapa sebagian besar bahasa telah mengimplementasikan sintaksis blok dalam beberapa tahun terakhir. Tetapi satu-satunya cara untuk memastikan adalah dengan bertanya kepada pengembang bahasa apa motif mereka. Kami hanya dapat berspekulasi imo.
SpoBo

bagi saya, Ruby adalah bahasa yang pertama kali membuat balok batu dan sangat menarik, jadi +1. Haskell mungkin memiliki efek juga.
rogerdpack

13

Seperti yang ditunjukkan Yannis , ada sejumlah faktor yang memengaruhi adopsi fungsi tingkat tinggi dalam bahasa yang sebelumnya tidak ada. Salah satu hal penting yang hanya disentuhnya sedikit adalah proliferasi prosesor multi-core dan, dengan itu, keinginan untuk pemrosesan yang lebih paralel dan bersamaan.

Peta / filter / pengurangan gaya pemrograman fungsional sangat ramah terhadap paralelisasi, yang memungkinkan programmer untuk dengan mudah menggunakan banyak core, tanpa menulis kode threading eksplisit.

Sebagai Giorgio mencatat, ada lebih banyak pemrograman fungsional dari sekedar fungsi tingkat tinggi. Fungsi, ditambah peta / filter / mengurangi pola pemrograman, dan imutabilitas adalah inti dari pemrograman fungsional. Bersama-sama hal-hal ini menjadi alat yang kuat untuk pemrograman paralel dan bersamaan. Untungnya, banyak bahasa sudah mendukung beberapa gagasan tentang kekekalan, dan, bahkan jika tidak, pemrogram dapat memperlakukan hal-hal sebagai kekal memungkinkan perpustakaan dan kompiler untuk membuat dan mengelola operasi asinkron atau paralel.

Menambahkan fungsi tingkat tinggi ke bahasa adalah langkah penting untuk menyederhanakan pemrograman bersamaan.

Memperbarui

Saya akan menambahkan beberapa contoh yang lebih rinci untuk mengatasi masalah yang dicatat Loki.

Pertimbangkan kode C # berikut yang melintasi koleksi widget, membuat daftar harga widget baru.

List<float> widgetPrices;
    float salesTax = RetrieveLocalSalesTax();
foreach( Widget w in widgets ) {
    widgetPrices.Add( CalculateWidgetPrice( w, salesTax ) );
}

Untuk koleksi besar widget, atau metode CalculateWidgetPrice (Widget) yang intensif secara komputasi, loop ini tidak akan memanfaatkan core yang tersedia dengan baik. Untuk melakukan perhitungan harga pada inti yang berbeda akan membutuhkan programmer untuk secara eksplisit membuat dan mengelola utas, melewati pekerjaan di sekitar, dan mengumpulkan hasilnya bersama-sama.

Pertimbangkan solusi setelah fungsi tingkat tinggi ditambahkan ke C #:

var widgetPrices = widgets.Select( w=> CalculateWidgetPrice( w, salesTax ) );

Foreach loop telah dipindahkan ke metode Select, menyembunyikan detail implementasinya. Yang tersisa bagi programmer adalah memberi tahu Pilih fungsi apa yang akan diterapkan pada setiap elemen. Ini akan memungkinkan implementasi Select untuk menjalankan perhitungan dalam parellel, menangani semua masalah sinkronisasi dan manajemen thread tanpa keterlibatan programmer.

Tapi, tentu saja, Select tidak melakukan itu secara paralel. Di situlah immutabilitas masuk. Implementasi Select tidak tahu bahwa fungsi yang disediakan (CalculateWidgets di atas) tidak memiliki efek samping. Fungsi ini dapat mengubah status program di luar tampilan Select dan sinkronisasi, merusak segalanya. Misalnya, dalam hal ini nilai salesTax dapat diubah karena kesalahan. Bahasa fungsional murni memberikan kekekalan, sehingga fungsi Select (peta) dapat mengetahui dengan pasti bahwa tidak ada keadaan yang berubah.

C # mengatasinya dengan menyediakan PLINQ sebagai alternatif untuk Linq. Itu akan terlihat seperti:

var widgetPrices = widgets.AsParallel().Select(w => CalculateWidgetPrice( w, salesTax) );

Yang memanfaatkan sepenuhnya semua inti dari sistem Anda tanpa manajemen eksplisit dari inti tersebut.


Saya menunjukkan keinginan untuk pemrosesan yang lebih paralel dan bersamaan, itu dibahas dalam artikel "A history of Erlang" ACM yang saya tautkan pada paragraf keempat. Tapi itu poin yang sangat bagus, dan saya mungkin harus sedikit lebih berkembang. +1 karena sekarang saya tidak perlu; P
yannis

Anda benar, saya tidak melihat dengan cukup hati-hati. Saya mengedit komentar saya.
Ben

Oh, kamu tidak benar-benar harus melakukan itu, aku tidak mengeluh;)
yannis

4
Tak satu pun dari apa yang Anda jelaskan di atas membutuhkan lambda. Fungsionalitas yang sama dicapai dengan mudah dengan fungsi bernama. Di sini Anda hanya mendokumentasikan causedan perceived affecttanpa menjelaskan correlation. Baris terakhir IMO adalah pertanyaannya; tetapi Anda tidak menjawabnya. Mengapa ini menyederhanakan pemrograman bersamaan.
Martin York

@ Ben: Berhati-hatilah karena contoh Anda menyangkut fungsi tingkat tinggi yang tidak membutuhkan fungsi anonim untuk digunakan. Jawaban Anda berisi ide-ide menarik (untuk pertanyaan lain) tetapi keluar dari topik sekarang.
Giorgio

9

Saya setuju dengan banyak jawaban di sini, tetapi yang menarik adalah bahwa ketika saya belajar tentang lambda dan menerimanya, itu bukan karena alasan apa pun yang disebutkan orang lain.

Dalam banyak kasus, fungsi lambda hanya meningkatkan keterbacaan kode Anda. Sebelum lambdas ketika Anda memanggil metode yang menerima pointer fungsi (atau fungsi, atau mendelegasikan), Anda harus mendefinisikan tubuh fungsi itu di tempat lain, jadi ketika Anda memiliki konstruksi "foreach", pembaca Anda harus melompat ke yang berbeda bagian dari kode untuk melihat apa sebenarnya yang Anda rencanakan untuk dilakukan dengan setiap elemen.

Jika tubuh fungsi yang memproses elemen hanya beberapa baris, saya akan menggunakan fungsi anonim karena sekarang ketika Anda membaca kode, fungsi tetap tidak berubah, tetapi pembaca tidak harus melompat-lompat, seluruh implementasi adalah tepat di depannya.

Banyak teknik pemrograman paralel dan paralelisasi dapat dicapai tanpa fungsi anonim; hanya menyatakan yang biasa dan memberikan referensi untuk itu kapan pun Anda perlu. Tetapi dengan lambdas kemudahan menulis kode dan kemudahan membaca kode sangat meningkat.


1
Penjelasan yang sangat bagus (+1). Pemrogram yang lalai telah mengetahui semua ini sejak 1958. ;-)
Giorgio

4
@ Giorgio: Tentu saja, tetapi programmer lisp juga harus membeli keyboard khusus dengan kunci kurung buka / tutup yang diperkuat :)
DXM

@DXM: bukan keyboard, mereka mendapatkan perangkat input tambahan yang seperti pedal piano untuk membuka dan menutup tanda kurung ;-)
vartec

@DXM, vartec: Sudah melakukan beberapa Skema belakangan ini dan saya menemukan kurung OK. Beberapa kode C ++ bisa jauh lebih samar (dan saya punya lebih banyak pengalaman dengan C ++ daripada dengan Skema). :-)
Giorgio

9

Setelah terlibat dalam sejarah baru-baru ini di sini, saya percaya bahwa salah satu faktor adalah penambahan obat generik ke Java dan .NET. Itu secara alami mengarah ke Func < , > dan abstraksi komputasi yang sangat diketik lainnya (Tugas < >, Async < > dll.)

Di dunia .NET kami menambahkan fitur-fitur ini tepat untuk mendukung FP. Itu memicu serangkaian pekerjaan bahasa yang berhubungan dengan pemrograman fungsional, terutama C # 3.0, LINQ, Rx dan F #. Kemajuan itu mempengaruhi ekosistem lain juga dan masih berlanjut hingga hari ini dalam C #, F # dan TypeScript.

Membantu Haskell bekerja di MSR juga, tentu saja :)

Tentu saja ada banyak pengaruh lain juga (JS tentu saja) dan langkah-langkah ini pada gilirannya dipengaruhi oleh banyak hal lainnya - tetapi menambahkan obat generik ke bahasa-bahasa ini membantu mematahkan ortodoksi OO yang kaku pada akhir 90-an di sebagian besar dunia perangkat lunak dan membantu membuka pintu untuk FP.

Don Syme

ps F # adalah tahun 2003, bukan 2005 - meskipun kami akan mengatakan itu tidak mencapai 1,0 sampai 2005. Kami juga melakukan prototipe Haskell.NET pada 2001-02.


Selamat datang! Saya menggunakan 2005 untuk F #, karena itu tahun yang dilaporkan dalam artikel Wikipedia F # sebagai tahun rilis stabil pertama. Apakah Anda ingin saya mengubahnya ke tahun 2003?
yannis


4

Dari apa yang saya lihat sebagian besar jawaban berkonsentrasi pada menjelaskan mengapa pemrograman fungsional secara umum membuatnya kembali dan membuatnya menjadi arus utama. Namun saya merasa ini tidak benar-benar menjawab pertanyaan tentang fungsi anonim pada khususnya, dan mengapa mereka tiba-tiba menjadi sangat populer.

Yang benar-benar mendapatkan popularitas, adalah penutupan . Karena dalam kebanyakan kasus, penutupan adalah fungsi yang dibuang variabel yang dilewati, jelas masuk akal untuk menggunakan sintaks fungsi anonim untuk ini. Dan sebenarnya dalam beberapa bahasa itu satu-satunya cara untuk membuat penutupan.

Mengapa penutupan mendapatkan popularitas? Karena mereka berguna dalam pemrograman event-driven, saat membuat fungsi panggilan balik . Saat ini cara menulis kode klien JavaScript (sebenarnya ini adalah cara menulis kode GUI). Saat ini juga cara penulisan kode back-end yang sangat efisien serta kode sistem, karena kode yang ditulis dalam paradigma yang digerakkan oleh event biasanya asinkron dan non-pemblokiran . Untuk back-end ini menjadi populer sebagai solusi untuk masalah C10K .


Terima kasih telah menekankan bahwa pertanyaan ini bukan tentang pemrograman fungsional (+1) karena (1) gagasan blok kode yang diedarkan sebagai argumen juga digunakan dalam bahasa non-fungsional seperti Smalltalk, dan (2) keadaan mutasi ditangkap dari konteks leksikal penutupan (mungkin dalam banyak implementasi lambda) jelas tidak berfungsi . Dan ya, setelah ditutup, langkah menuju penutupan anonim itu singkat. Hal yang menarik adalah bahwa penutupan juga telah lama dikenal, dan pemrograman berbasis acara telah digunakan (sejauh yang saya tahu) sejak tahun delapan puluhan.
Giorgio

Tapi mungkin itu hanya dalam beberapa tahun terakhir menjadi jelas bahwa penutupan dapat digunakan lebih sering daripada yang diperkirakan sebelumnya.
Giorgio

@Iorgio: ya, sebagian besar konsep yang saat ini digunakan sudah ada sejak lama, sangat lama. Namun mereka belum digunakan seperti itu, mereka digunakan sekarang.
vartec

1

Saya pikir alasannya adalah meningkatnya prevalensi pemrograman konkuren dan terdistribusi, di mana inti pemrograman berorientasi objek (merangkum keadaan berubah dengan objek) tidak lagi berlaku. Dalam kasus sistem terdistribusi, karena ada adalah tidak ada negara bersama (dan perangkat lunak abstraksi dari konsep yang bocor) dan dalam kasus sistem bersamaan, karena benar sinkronisasi akses ke negara bersama telah terbukti rumit dan rawan kesalahan. Artinya, salah satu manfaat utama pemrograman berorientasi objek tidak lagi berlaku untuk banyak program, membuat paradigma berorientasi objek jauh lebih bermanfaat daripada dulu.

Sebaliknya, paradigma fungsional tidak menggunakan keadaan bisa berubah. Oleh karena itu, setiap pengalaman yang kami peroleh dengan paradigma dan pola fungsional lebih cepat ditransfer ke perhitungan bersamaan dan didistribusikan. Dan alih-alih menemukan kembali roda, industri sekarang meminjam pola dan fitur bahasa tersebut untuk memenuhi kebutuhannya.


4
Fungsi anonim dalam beberapa bahasa arus utama (misalnya C ++ 11) memang memungkinkan keadaan bisa berubah (mereka bahkan dapat menangkap variabel dari lingkungan yang mendefinisikan dan mengubahnya selama eksekusi mereka). Jadi saya berpikir bahwa berbicara tentang paradigma fungsional secara umum dan tentang kekekalan pada khususnya sedikit keluar dari ruang lingkup pertanyaan yang diajukan.
Giorgio

Setelah baru saja membaca beberapa fitur catatan untuk Java 8, salah satu tujuan utama lambda proyek adalah untuk mendukung konkurensi. Dan ITU segera membawa kita ke clusterbability mutabilitas bahwa semua javabeans indah ini akan mengalami Setelah Java mendapatkan lambdas (dengan asumsi itu benar-benar terjadi pada rilis final versi 8), mereka kemudian perlu mengatasi masalah immutable-by-default, entah bagaimana (itu menghancurkan bahasa, berpikir dalam Lisp - efek samping fungsi bebas - sebagai gantinya dari dalam COBOL - memukul pada DATA DIVISI / COPYBOOK)
Roboprog

Kata baik. Perpindahan dari keadaan yang bisa berubah membuat konkurensi lebih mudah dan teknologi seperti cascalog dan spark dengan mudah mendistribusikan pemrograman fungsional di sekelompok komputer. Lihat glennengstrand.info/analytics/distributed/functional/… untuk detail lebih lanjut tentang bagaimana dan mengapa.
Glenn

1

Jika dapat menambahkan € 0,02 saya, meskipun saya akan setuju dengan pentingnya JavaScript memperkenalkan konsep, saya pikir lebih dari pemrograman bersamaan saya akan menyalahkan mode pemrograman asinkron saat ini. Ketika melakukan panggilan async (diperlukan dengan halaman web), fungsi anonim sederhana sangat berguna, sehingga setiap programmer web (yaitu, setiap programmer) harus terbiasa dengan konsep tersebut.


1

Contoh lain yang sangat tua dari sesuatu yang mirip dengan fungsi anonim / lambdas adalah panggilan-dengan-nama di Algol 60. Namun perlu dicatat bahwa panggilan-dengan-nama lebih dekat dengan melewati makro sebagai parameter daripada melewati fungsi sebenarnya, dan itu lebih rapuh / sulit untuk mengerti sebagai hasilnya.


0

Di sini nenek moyang yang terbaik dari pengetahuan saya.

  • 2005: Javascript baru-baru ini membawa pemrograman tingkat tinggi dengan lambdas kembali ke arus utama. Di perpustakaan tertentu seperti underscore.js dan jquery . Salah satu perpustakaan pertama adalah prototype.js yang mendahului jquery sekitar tahun. Prototipe didasarkan pada modul Enumerable dari Ruby, yang mengarahkan kita ke ...
  • 1996: Modul Rubumer Enumerable dengan jelas mengambil inspirasi dari kerangka koleksi Smalltalk. Seperti yang telah disebutkan oleh Matz dalam banyak wawancara, yang mengarahkan kita ke ...
  • 1980: Smalltalk menggunakan banyak pemrograman tingkat tinggi dan menyediakan koleksi API yang banyak menggunakan pemrograman tingkat tinggi (misalnya, kelas Iterable GNU Smalltalk ). Dalam kode Smalltalk idiomatik Anda tidak akan menemukan apa pun untuk loop tetapi hanya enumerasi tingkat tinggi. Sayangnya ketika Java ketika kerangka koleksi Smalltalk diangkut ke Jawa pada tahun 1998, enumerasi tingkat tinggi ditinggalkan. Begitulah pemrograman tingkat tinggi dihapus dari arus utama selama sepuluh tahun mendatang! Smalltalk memiliki banyak keturunan, tetapi yang relevan dengan pertanyaan OP adalah LISP, yang mengarahkan kita ke ...
  • 1958: LISP, jelas, memiliki pemrograman tingkat tinggi pada intinya.

Salah, tentu saja, adalah nenek moyang seluruh ML. ML, SML, OCaml, Haskell, F #. Itu harus dihitung untuk sesuatu ..
Muhammad Alkarouri

-1

Fungsi anonim bagus karena memberi nama hal-hal itu sulit, dan jika Anda hanya menggunakan fungsi di satu tempat, itu tidak memerlukan nama.

Fungsi Lambda baru saja menjadi arus utama karena sampai saat ini, sebagian besar bahasa tidak mendukung penutupan.

Saya akan menyarankan bahwa Javascript telah mendorong arus utama ini. Ini adalah bahasa universal yang tidak memiliki cara untuk mengekspresikan paralelisme, dan fungsi anonim memudahkan penggunaan model panggilan balik. Selain itu bahasa populer seperti Ruby dan Haskell telah berkontribusi.


1
"Fungsi Lambda baru-baru ini menjadi arus utama karena sampai saat ini, sebagian besar bahasa tidak mendukung penutupan.": Alasan ini terdengar agak melingkar bagi saya: menjadi arus utama berarti sebagian besar bahasa mendukungnya. Orang bisa langsung bertanya, "Apa yang memicu popularitas penutupan dalam bahasa pemrograman modern."
Giorgio

Saya tahu bahwa Python tidak memiliki implementasi lambdas terbaik. Tetapi dalam hal popularitas, itu mungkin berkontribusi lebih dari Haskell.
Muhammad Alkarouri
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.