Saya bertanya-tanya apa perbedaan implementasi teknis antara C # dan Scala dan bagaimana kedua solusi dibandingkan dengan ide-ide dan keprihatinan implementasi yang disuarakan dalam email Peek Past lambda oleh Brian Goetz, dikirim ke milis Project Lambda (JSR 335) ?
Dari email:
Kami menjelajahi jalan "mungkin lambdas hanya menjadi contoh kelas dalam, itu akan sangat sederhana", tetapi akhirnya sampai pada posisi "fungsi adalah arah yang lebih baik untuk masa depan bahasa".
dan selanjutnya:
Pandangan lambdas-adalah-objek tentang konflik dunia dengan masa depan yang memungkinkan ini. Pandangan lambda-fungsi-dunia tidak, dan menjaga fleksibilitas ini adalah salah satu poin yang mendukung tidak membebani lambda bahkan dengan penampilan objek-ness.
Kesimpulan:
Lambdas-are-functions membuka pintu. Lambdas-are-objek menutupnya.
Kami lebih suka melihat pintu-pintu itu dibiarkan terbuka.
Dan beberapa komentar dari seseorang di utas Reddit mengatakan:
Saya sebenarnya mengirim e-mail kepada Neal Gafter tentang ini dan untuk pemahaman saya yang terbatas tentang penjelasannya C # dan desain Java saat ini sangat mirip karena Delegasi sebenarnya objek dan bukan tipe fungsi. Sepertinya dia percaya bahwa Jawa harus belajar dari kerugian lambda C # dan menghindarinya (seperti halnya C # belajar dari kerugian Jawa dan menghindarinya pada awalnya).
Mengapa pendekatan "Lambdas-is-functions" memungkinkan lebih banyak peluang di masa depan daripada "Lambdas-are-objects"? Dapatkah seseorang menjelaskan perbedaan apa yang ada dan bagaimana mereka akan mempengaruhi bagaimana kode akan ditulis?
Melihat hal-hal di Scala "hanya bekerja", saya terus berpikir bahwa saya kehilangan sesuatu tentang pendekatan yang diambil / diusulkan dalam C # / Java (8), mungkin itu terkait dengan kekhawatiran tentang kompatibilitas mundur?
Jawaban:
Saya pikir diskusi tentang objek vs fungsi adalah herring merah. Jika pertanyaannya adalah, "Apakah lambda fungsi atau objek?" jawabannya harus ya .
Itulah inti dari fungsi kelas satu: mereka tidak diperlakukan berbeda dari tipe lainnya. Java sudah berhasil mengabaikan sebagian besar perbedaan antara Objek dan tipe primitif (dan Scala bahkan lebih baik), jadi apakah lambda adalah subkelas Objek atau tipe primitif baru atau sesuatu yang lain tidak terlalu penting untuk bahasa. Yang penting adalah bahwa Anda dapat menempatkan lambda Anda di koleksi, menyebarkannya untuk dipanggil, memanggil mereka, dan melakukan hal lain yang mungkin ingin Anda lakukan dengan objek atau metode.
Scala menyelesaikan ini dengan menggunakan objek wrapper yang memiliki metode yang disebut
apply
yang dapat dipanggil dengan adil()
, membuatnya terlihat seperti pemanggilan metode. Ini bekerja dengan sangat baik; sebagian besar waktu Anda tidak perlu peduli apakah Anda memiliki metode atau memanggil objek fungsi.sumber
Dari apa yang saya mengerti, ini lebih tentang bagaimana lambda dianggap pada tingkat bahasa utama. Seperti yang dikatakan dalam email,
Saya pikir itu meringkas pertanyaan Anda dengan cukup baik. Jika Anda menyatakan bahwa "lambdas adalah objek", maka mereka hanya objek dari kelas tertentu dan Anda terjebak dengan itu. Di sisi lain, jika Anda menyatakan "lambdas adalah fungsi", maka secara semantik Anda memiliki lapangan bermain yang lebih kaya. Java 1.7 mungkin mengkompilasinya ke objek, jadi mereka praktis identik pada saat itu.
Tetapi Java 1.8, atau 1.9, mungkin membawa perubahan pada bahasa (seperti jenis struktur yang direvisi) daripada memungkinkan fungsi untuk digunakan dengan cara yang jauh lebih fleksibel. Jika "lambdas adalah objek", perubahan ini tidak akan kompatibel dan Anda harus memperkenalkan konsep baru altogther, agar tidak merusak kode orang yang ada. Tetapi jika
javac
hanya diam-diam mengubah lambdas menjadi objek di belakang layar, yang barujavac
dapat mengubahnya menjadi apa pun yang diinginkan, selama semantik masih berlaku.sumber
foreach
,map
,filter
untuk koleksi.Kebanyakan, dia hanya tidak ingin melakukan terlalu cepat untuk sesuatu. Saya tidak melihat alasan di luar penghapus yang ia presentasikan, tapi itu memang alasan yang sangat kuat.
Pertimbangkan metode ini dalam Scala's
Regex
:Akan lebih mudah jika mereka hanya ini:
Sayangnya, itu tidak mungkin, karena kedua fungsi tersebut identik di bawah penghapusan. Tapi, baiklah, fungsi ini melakukan hal yang agak berbeda, jadi nama yang berbeda mungkin cukup adil.
Namun, a
Match
adalah sesuatu yang sangat berguna, tetapi sebagian besar waktu Anda ingin yang cocokString
atau daftar subkelompok. Kami ingin memiliki ini:Tidak mungkin, karena penghapusan. Saya memilih contoh khusus ini karena saya terlibat langsung dengannya, tetapi saya telah melihat setidaknya setengah lusin pertanyaan tentang Stack Overflow, di mana orang-orang bertanya mengapa kelebihan muatan itu ilegal, disebabkan oleh masalah persis ini.
Dan, kemudian, pertimbangkan bahwa pencocokan pola Scala dan Java
instanceof
secara efektif tidak berguna karena penghapusan.Saya pikir adil untuk menunda jenis fungsi sampai masalah ini ditangani. Lagi pula, ada banyak bahasa yang memilikinya di JVM, dan tidak seperti Java adalah bahasa yang berkembang dengan cepat.
sumber