Halo kolega.
Belum lama ini, kami mencetak
buku oleh Odersky, Spoon dan Wenners tentang Scala 2.12. Toh, untuk Scala 3 masih jauh.
Penulis artikel hari ini adalah Adam Worski, salah satu pendiri SoftwareMill dan pengembang Scala yang berpengalaman. Dia mendapat ringkasan menarik tentang kekuatan bahasa Scala modern, yang kami bawa ke perhatian Anda.
Setelah
kuliah paripurna oleh Martin Odersky tentang ScalaDays, di mana ia menguraikan rencana untuk Scala 3 dan
kuliah paripurna oleh John de Goes di konferensi ScalapeΓ±o tentang masa depan
Scala , diskusi yang hidup berlanjut di
komunitas Scala . Terlepas dari diskusi presentasi pleno ini, banyak diskusi dilakukan di twitter, di komunitas Slack, serta di reddit (lihat, misalnya,
1 ,
2 ).
Itu pertanyaannya!Semua ini sangat menarik dan informatif bagi para spesialis yang sudah bekerja di ekosistem Scala. Namun, sebagian besar kontroversi terkait dengan berbagai kelemahan Scala sebagai bahasa yang dapat dipahami secara intuitif atau aktual. Momen-momen ini dapat menakuti orang-orang "dari luar", membuat mereka bertanya: "Mengapa saya harus menggunakan Scala?", "Bagaimana jika ini jalan buntu?", "Akankah Scala 3 mengulangi kesuksesan Python 3?" dll. Seperti dalam kebanyakan diskusi, titik terlemah dan paling emosional menarik perhatian, dan perdebatan ini tidak terkecuali.
Jadi mari
kita mundur : mengapa Anda bahkan membutuhkan Scala? Apa alasan teknis dan bisnis untuk bekerja dengan bahasa ini?
Area Subjek ProyekUntuk mulai dengan, bahasa Scala sangat baik untuk bidang subjek tertentu (tetapi tidak untuk semua orang!). Aset terpenting Scala adalah
fleksibilitasnya dalam mendefinisikan abstraksi . Yang Anda inginkan - sejumlah "batu bata" sederhana untuk ini; terkadang mendefinisikan abstraksi tidak lebih sulit daripada menggunakan kelas, metode, dan ekspresi lambda. Terkadang Anda harus menggunakan parameter implisit atau metode ekstensi; dalam kasus yang jarang terjadi, tetap hanya menggunakan perintah makro. Namun,
ada opsi .
Dengan demikian, Scala sangat cocok untuk Anda jika Anda perlu
menavigasi area subjek yang kompleks . Sebagai contoh, kita dapat berbicara tentang pemrograman terdistribusi atau kompetitif. Concurrency sangat sulit, dan Scala memiliki sejumlah perpustakaan yang menyederhanakan tugas ini dengan membangun abstraksi. Ada dua pendekatan utama untuk ini: aktor, diimplementasikan dengan
Akka , dan dalam semangat FP, disajikan oleh
Monix /
kucing-efek dan
Scalaz /
ZIO (jika Anda ingin membaca lebih lanjut tentang membandingkan alat-alat ini - saya menulis
serangkaian artikel tentang topik ini) )
Namun, tentu saja, kita dapat berbicara tentang bidang studi lain. Kemampuan Scala juga memungkinkan kami membawa pemodelan aplikasi bisnis yang khas ke tingkat selanjutnya. Tetapi dalam kasus ini kita berbicara tentang kompleksitas urutan yang berbeda. Dalam hal sistem terdistribusi, kita dihadapkan dengan kompleksitas teknis. Ketika memprogram logika bisnis dalam aplikasi, kita sudah bicara tentang kerumitan area subjek. Misalnya, buku Debasish Ghosh "
Pemodelan domain fungsional dan reaktif " menjelaskan cara menggabungkan DDD dengan pemrograman fungsional dan reaktif.
Kesulitan bahasaCatatan: ketika berbicara tentang Scala, semua orang suka menekankan luasnya kemungkinan bahasa ini, menekankan bahwa justru karena keserbagunaan seperti itu, bahasa ini sangat kompleks. Ini tidak sepenuhnya benar.
Seperti disebutkan di atas, Scala memiliki sejumlah konstruksi dasar dari mana abstraksi dapat dibangun. Namun, semuanya dapat
digabungkan satu sama lain, karena bahasa tersebut memperoleh fleksibilitas tersebut. Sebagian besar proyek inovatif yang Anda temui datang ke kombinasi satu atau lain dari jenis pesanan yang lebih tinggi, parameter implisit dan subtipe.
Jadi, dengan sejumlah fitur dasar yang relatif kecil (ukuran tata bahasa Scala lebih sederhana daripada Kotlin, Java, atau Swift!) - yang, pada gilirannya, memfasilitasi pembelajaran - pilihan kombinasi jauh lebih banyak.
Apakah pilihannya terlalu luas? Saya kira tidak. Programmer, sebagai profesional yang kompeten dan bertanggung jawab, lebih dari mampu memilih opsi terbaik untuk memecahkan masalah tertentu. Untuk informasi lebih lanjut, lihat artikel β
Simple Scala Stack β.
Java hanya lebih baikAda banyak pembicaraan sekarang bahwa
Kotlin telah menggantikan Scala sebagai "seperti Jawa, hanya lebih baik." Tetapi saya percaya bahwa
Scala, dan bukan Kotlin , yang masih layak mendapatkan gelar seperti itu. Ada dua alasan utama untuk ini:
Pertama,
kekekalan dalam Scala adalah yang terpenting . Ini karena sifat Scala: menulis kode di atasnya adalah nyaman terutama dengan bantuan data yang tidak dapat diubah. Data tersebut termasuk, khususnya:
val
(sebagai unit kelas pertama), kelas
case
, fungsi tingkat tinggi, dll. Tetapi intinya adalah bagaimana perpustakaan bahasa Scala standar dirancang dan ditulis; semua struktur data yang digunakan secara default tidak dapat diubah. Berkat kekekalan, sejumlah hal disederhanakan, terutama di dunia kita yang memiliki kompetisi tinggi, di mana bahasa-bahasa itu menang, di mana ketidakmampuan lebih disukai.
Kedua, Scala mendukung
konstruktor tipe, tipe urutan lebih tinggi, dan tipe kelas (dinyatakan secara implisit), yang sangat menyederhanakan pekerjaan dengan jenis pembungkus / wadah, misalnya,
Promise
,
Future
atau
Task
. Pembungkus seperti itu berlaku ketika pemrograman dalam gaya asinkron atau reaktif, dan keberadaan konstruksi bahasa yang menyederhanakan kerja, katakanlah, dengan basis kode di mana
Future
digunakan secara aktif adalah argumen lain yang mendukung Scala.
Apa tipe kelasnya? Peran mereka kira-kira sama dengan pola desain di Jawa, namun, mereka lebih fleksibel dan mudah digunakan segera setelah Anda memahami maknanya dengan tegas. Ada beberapa panduan bagus tentang ini, seperti
1 ,
2 .
Bagaimana dengan konstruktor tipe? Ini adalah jenis seperti
Future
atau
Option
, berfungsi sebagai "wadah" atau "pembungkus" untuk jenis lainnya. Jadi, Anda dapat memiliki
Option[String]
atau
Future[Int]
. Jenis pesanan yang lebih tinggi memungkinkan Anda untuk menulis kode yang abstrak setiap bungkus. Lihat misalnya.
1 ,
2Tiba-tiba Anda bertanya-tanya, mengapa bahkan menggunakan
Future
/
Task
? Intinya bukan hanya sebagian besar perhitungan "reaktif" berkinerja tinggi dengan penundaan minimal dilakukan menggunakan I / O asinkron, yang hanya diminta oleh desain semacam itu. Alasan lain diberikan dalam
diskusi ini
tentang reddit dan dalam artikel saya β
Mengapa repot-repot dengan pembungkus? "
Bekerja di lingkungan yang sebagian besar tidak berubah, serta kemampuan untuk menangani konstruksi seperti
Future
,
Promise
atau
Task
(dan abstraksikan!) Secara radikal mengubah kode Anda. Sekilas, ini mungkin tidak jelas: jika Anda memiliki pengalaman Java atau Ruby di belakang Anda, maka Anda tidak akan dapat segera mewujudkan aspek-aspek Scala ini. Tetapi, bahkan dari sudut pandang pendidikan, sangat berguna untuk memahami bagaimana pendekatan "fungsional" bekerja dan, yang lebih penting, mengapa itu bisa berubah menjadi
alternatif yang sangat berharga .
Secara alami, baik Scala dan Kotlin memiliki sejumlah keunggulan umum di atas Jawa, misalnya:
- Sintaks yang lebih kompak
- Kode stereotip kurang
- Sistem tipe yang lebih kaya
- Kurangnya ballast bahasa
Pada saat yang sama, kedua bahasa menyediakan akses ke ekosistem perpustakaan dan kerangka kerja JVM.
Semakin kaya sistem tipe (dalam Scala lebih kaya daripada di Kotlin, dan di Kotlin lebih kaya daripada di Jawa), semakin banyak pekerjaan verifikasi yang dilakukan oleh kompiler, dan bukan oleh orang. Untuk inilah komputer diciptakan: untuk melakukan tugas berulang yang membosankan dan rutin. Memeriksa penerapan tipe jelas hanya salah satu dari tugas-tugas ini.
Pada saat yang sama, sistem tipe kaya berguna tidak hanya ketika
menulis kode , tetapi juga, pada tingkat yang jauh lebih besar, ketika
membaca kode . Ketika mudah bagi Anda untuk menavigasi basis kode, memahami apa yang dilakukannya, dan, apalagi, itu tidak menakutkan (atau tidak begitu menakutkan) untuk melakukan
refactoring , ini mengkarakterisasi bahasa dengan sangat positif baik dari sudut pandang teknis maupun sudut pandang yang diterapkan.
FP vs OOPPertanyaan lain yang sering diajukan dalam diskusi tersebut adalah apakah bahasa Scala harus terus mematuhi sintesis OOP dan FP, atau haruskah itu berkembang di sepanjang jalur yang murni fungsional. Saya adalah
pendukung sintesis , terutama karena FP dan OOP, menurut pendapat saya, bukan pendekatan alternatif, tetapi saling melengkapi.
FP
pemrograman menggunakan fungsi , meskipun tidak ada, tetapi transparan referensial (lihat
jawaban ini
untuk reddit di utas sebelumnya, di mana transparansi referensial dijelaskan dengan sempurna). Dalam OOP, komunikasi dengan objek diatur menggunakan "pesan" atau, dalam terminologi kami, panggilan ke metode virtual. Tidak ada satu alasan pun mengapa kedua pendekatan ini tidak dapat hidup berdampingan, dan Scala telah menunjukkan ini!
Dalam sebuah
tweet tentang keutamaan Scala, John de Goes menyebutkan beberapa fitur OOP yang berguna untuk pendekatan fungsional murni, khususnya,
modul kelas satu (diperoleh dengan membuat objek),
sintaksis titik (metode memanggil dalam objek), dan
instance kelas / jenis sebagai konstruksi kelas satu . Semua ini adalah elemen kombinasi sukses dari dua paradigma. Mungkin ada lagi yang hanya sekitar sudut?
Proyek "sintesis" belum selesai, pasti ada bidang untuk diskusi di sini. Salah satu aspek yang tidak lengkap adalah sintaks yang diusulkan untuk metode ekstensi, yang seharusnya menggantikan konversi implisit yang jauh lebih membingungkan. Lain adalah mengoptimalkan sintaks dari kelas tipe;
Saran yang dibuat beberapa waktu lalu jelas kasar dan tidak mencakup beberapa penggunaan monad yang paling umum di Scala. Beberapa saran lebih baik, yang lain membutuhkan perbaikan, tetapi bagus bahwa mereka diterima dan diskusi sedang berlangsung; terima kasih kepada mereka, bahasanya hidup dan, pada akhirnya, solusi terbaik adalah tetap di dalamnya.
Scala 3Scala 3 akan dirilis dalam dua tahun. Sejumlah kemungkinan menarik akan muncul di dalamnya, khususnya, jenis buram, parameter sifat, pendekatan metaprogramming baru, jenis gabungan & & persimpangan, jenis fungsi implisit - ini hanya beberapa contoh. Tentu saja, ada kekhawatiran (yang beralasan) tentang migrasi.
Sudah diketahui bahwa alat khusus akan diperkenalkan untuk
migrasi kode otomatis dari Scala 2 ke Scala 3 menggunakan
scalafix . Karena Scala adalah bahasa yang diketik secara statis, tugas seperti itu dapat diselesaikan dalam skala besar dan jauh lebih sederhana daripada, misalnya, dalam Python. Tapi, tentu saja, tidak ada keajaiban di sini: bahkan jika alat ini memberikan 99% cakupan kode yang benar, 1% dari kasus yang paling bermasalah masih akan tetap ada. Karena Anda tidak dapat mengandalkan sihir, migrasi fragmen-fragmen ini perlu dilakukan secara manual.
Ini adalah biaya untuk bekerja dengan bahasa yang berkembang aktif: Anda mendapatkan peluang terbaru, tetapi beberapa dari mereka sebenarnya tidak begitu baik dan perlu ditingkatkan. Meski begitu, perubahan yang diusulkan tidak revolusioner. Bahasa Scala 3 sangat mirip dengan Scala 2, tidak ada perubahan paradigma besar yang diharapkan.
Sangat menggembirakan bahwa tim Scala serius tentang migrasi. Sementara migrasi sebelumnya antara versi Scala yang lebih lama (mis. Dari 2.8 menjadi 2.9) cukup memberatkan, migrasi baru-baru ini berjalan jauh lebih baik. Ada tiga pihak utama yang terlibat: EPFL,
ScalaCenter dan
Lightbend semuanya (sering bersama-sama) bekerja untuk memfasilitasi migrasi. Misalnya, ada alat
MIMA yang kompatibel biner, dan banyak perpustakaan baru terus-menerus dibuat di komunitas untuk memastikan pekerjaan yang nyaman dengan versi Scala baru.
Akhirnya, alat TASTY yang belum selesai (yang, karenanya, belum dapat dievaluasi) harus memastikan penggunaan file biner dari Scala 2 ke Scala 3.
Jadi mengapa menggunakan Scala?Jadi, apa alasan untuk berhenti di Scala, jika Anda menganggap bahasa ini dari sudut pandang bisnis? Semua keuntungan teknis di atas bermanfaat langsung untuk bisnis. Ketika Anda memiliki bahasa di mana Anda dapat menulis kode kompleks dengan bug lebih sedikit, maka Anda diberikan penundaan minimal dalam hal dan pengguna puas. Jika Anda mulai menulis aplikasi kompetitif yang praktis dan tidak tergelincir untuk Scala, yang disediakan alat khusus di Scala, ini akan menjadi manfaat serius bagi perusahaan Anda.
Selain itu, jangan lupa tentang
Spark , platform terdepan untuk
analisis data terdistribusi . Scala digunakan tidak hanya untuk mengimplementasikan Spark seperti itu, tetapi juga untuk menentukan perhitungan sendiri. Berikut ini adalah abstraksi berorientasi ilmu data lainnya yang menyembunyikan model komputasi yang kompleks.
RingkasanTentu saja, ada masalah di Scala, tetapi di mana mereka tidak? Alasan untuk optimisme adalah bahwa banyak orang yang menggunakan Scala setiap hari aktif bekerja untuk
meningkatkan alat , perpustakaan, dan bahasa itu sendiri. Saya dapat berasumsi bahwa mereka terus bekerja dengan Scala justru karena, dengan semua kekurangan yang tersedia, tidak ada satu bahasa yang sangat cocok untuk bidang subjek mereka.
Scala memungkinkan Anda untuk mengembangkan gaya pemrograman Anda sendiri, tidak peduli apa bahasa Anda dulu: Java, Ruby, atau coba saja diri Anda dalam pemrograman. Tidak ada pendekatan unik untuk memenangkan Scala; baik pendekatan Akka yang lebih
penting , atau pendekatan yang lebih
fungsional dari Kucing dan Scalaz.
Di sinilah masalahnya dapat dilihat: ada sebagian kecil di komunitas Scala yang mematuhi pendekatan OOP / AF "reaktif", "sintetis", dan AF murni. Namun, sebenarnya ini adalah keuntungan yang sangat besar. Karena keragaman tersebut, diskusi diadakan, banyak pendapat yang berbeda diungkapkan dari sudut pandang yang berbeda. Pada hal ini, pada gilirannya, Anda dapat dengan sempurna belajar bagaimana menyelesaikan masalah yang tidak standar dan memperkaya alat Anda sendiri.
Apa pun jalur yang Anda pilih di Scala, Anda akan didukung oleh komunitas kolega yang mengesankan yang terlibat dalam pengembangan perpustakaan dan kerangka kerja; orang-orang ini selalu siap membantu dan mendiskusikan ide-ide yang muncul.