Ada hype baru dengan ekspresi lambda yang telah lama ditunggu di Jawa 8; setiap 3 hari artikel lain muncul dengan mereka tentang betapa kerennya mereka.
Sejauh yang saya mengerti ekspresi lambda tidak lebih dari kelas batin anonim dengan metode tunggal (setidaknya pada level byte-code). Selain itu ia datang dengan fitur bagus lain - inferensi tipe tapi saya percaya ini setara dapat dicapai dengan obat generik pada tingkat tertentu (tentu saja tidak dengan cara yang rapi seperti dengan ekspresi lambda).
Mengetahui hal ini, apakah ekspresi lambda akan membawa sesuatu yang lebih dari sekadar sugaring sintaksis di Jawa? Bisakah saya membuat kelas yang lebih kuat dan fleksibel atau konstruksi berorientasi objek lainnya dengan ekspresi lambda yang tidak mungkin dibangun dengan fitur bahasa saat ini?
sumber
this
menjadi menjadiOuterClass.this
bagian dari proses de-sugaring ekspresi lambda ke kelas anonim.Jawaban:
tl; dr: walaupun sebagian besar berupa gula sintaksis, sintaksis yang lebih baik membuat banyak hal praktis yang digunakan untuk mengakhiri garis kawat gigi dan tanda kurung yang tak terbaca.
Yah, sebenarnya sebaliknya karena lambda jauh lebih tua dari Jawa. Kelas batin anonim dengan metode tunggal adalah Jawa yang paling dekat datang ke lambdas. Ini perkiraan yang "cukup baik" untuk beberapa waktu, tetapi memiliki sintaks yang sangat buruk.
Di permukaan, lambda Jawa 8 tampaknya tidak lebih dari gula sintaksis, tetapi ketika Anda melihat di bawah permukaan, Anda melihat banyak abstraksi yang menarik. Misalnya spec JVM memperlakukan lambda sangat berbeda dari objek "true", dan sementara Anda dapat menanganinya seolah-olah mereka di mana objek, JVM tidak diharuskan untuk mengimplementasikannya seperti itu.
Tetapi sementara semua tipuan teknis itu menarik dan relevan (karena memungkinkan optimasi masa depan di JVM!), Manfaat sebenarnya adalah "hanya" bagian gula sintaksis.
Apa yang lebih mudah dibaca:
atau:
atau (menggunakan pegangan metode alih-alih lambda):
Fakta bahwa Anda akhirnya dapat mengungkapkan dengan cara ringkas yang sebelumnya akan menjadi 5 baris kode (yang 3 sangat membosankan) membawa perubahan nyata dari apa yang praktis (tetapi bukan dari apa yang mungkin, diberikan).
sumber
List
bisa memegang objek apa pun,List<String>
bisa "hanya" memegang string. Generik menambahkan batasan (dan opsi untuk memformalkan pembatasan!), Bukan tambahan daya. Hampir semuanya sejak Java 1.1 adalah gula sintaksis. Dan itu belum tentu hal yang buruk.List<String>
adalah hanyaList
dengan pemain yangString
ditambahkan di sekitar beberapa nilai kembali. Namun demikian mereka sangat berguna dan membuat bahasa lebih nyaman untuk menulis. Lambdas adalah kasus serupa.Untuk Java, ya, itu tidak lebih dari cara yang lebih baik untuk menciptakan kelas batin anonim. Ini karena keputusan mendasar di java bahwa setiap bit kode byte harus hidup dalam kelas tertentu, yang tidak dapat diubah sekarang setelah beberapa dekade kode legasi dipertimbangkan.
Namun, bukan itu yang dimaksud dengan ekspresi lambda. Dalam formalisme di mana mereka adalah konsep asli dan bukan lompatan langsung, lambda adalah blok bangunan fundamental; sintaksis mereka dan sikap orang terhadap mereka sangat berbeda. Contoh fungsi rekursif anonim yang dibuat murni dari lambdas dalam Struktur dan Interpretasi Program Komputer mampu mengubah seluruh konsepsi komputasi Anda. (Namun, saya cukup yakin bahwa cara belajar program hanya untuk esoteris yang pernah menjadi kisah sukses arus utama.)
sumber
Ya, itu hanya gula sintaksis, dalam arti bahwa di mana pun Anda menulis lambda, Anda dapat menulis ulang ekspresi itu sebagai ekspresi kelas batin anonim dengan satu metode, di mana kelas mengimplementasikan antarmuka fungsional yang disimpulkan untuk konteks lambda, dan itu akan sama persis semantik. Dan Anda dapat melakukan ini hanya dengan mengganti ekspresi lambda dengan ekspresi kelas anonim, tanpa mengubah ekspresi atau baris kode lainnya.
sumber
this
perlu dikonversiOuterClass.this
. Itu tidak bertentangan dengan apa yang saya katakan - setiap ekspresi lambda dapat dikonversi menjadi ekspresi kelas anonim yang setara secara semantis tanpa mengubah apa pun di luar ekspresi itu . Saya tidak mengatakan bahwa bagian dalamnya tidak akan berubah.this
di lambda adalah bagian dari gula sintaksis, dan tidak ada perbedaan dalam semantik. Dan tentang perbedaan dalam implementasi, implementasi! = Semantik. Tentang perbedaan identitas objek; identitas objek sangat tangensial dengan fungsi lambdas; tidak ada yang memeriksa identitas objek kelas lambdas / anon karena itu tidak berguna.Joachim Sauer sudah melakukan pekerjaan dengan baik menjawab pertanyaan Anda tetapi hanya mengisyaratkan sesuatu yang saya anggap penting. Karena Lambdas bukan kelas, mereka juga tidak dikompilasi. Semua kelas dalam anonim menghasilkan pembuatan file .class yang pada gilirannya harus dimuat oleh ClassLoader. Jadi menggunakan Lambdas bukan hanya membuat kode Anda lebih indah, tetapi juga mengurangi ukuran kode kompilasi Anda, jejak memori ClassLoader Anda, dan waktu yang diperlukan untuk mentransfer bit dari hard drive Anda.
sumber
Tidak, mereka bukan.
Cara lain untuk mengatakannya adalah lambda adalah cara yang tidak berorientasi objek, namun ringkas, untuk mencapai hal yang sama dengan yang dicapai oleh kelas anonim atau, preferensi saya, kelas batin dengan cara berorientasi objek.
sumber