Saya baru saja mulai melihat implementasi kembali koleksi perpustakaan Scala yang akan segera hadir dalam rilis 2.8 . Mereka yang akrab dengan perpustakaan dari 2.7 akan memperhatikan bahwa perpustakaan, dari perspektif penggunaan, telah sedikit berubah. Sebagai contoh...
> List("Paris", "London").map(_.length)
res0: List[Int] List(5, 6)
... akan berfungsi di kedua versi. Perpustakaan ini benar-benar bisa digunakan : sebenarnya itu fantastis. Namun, mereka yang sebelumnya tidak terbiasa dengan Scala dan mencari-cari bahasa sekarang harus memahami tanda tangan metode seperti:
def map[B, That](f: A => B)(implicit bf: CanBuildFrom[Repr, B, That]): That
Untuk fungsi sederhana seperti ini, ini adalah tanda tangan yang menakutkan dan saya merasa kesulitan untuk memahami. Bukannya saya pikir Scala mungkin akan menjadi Jawa berikutnya (atau / C / C ++ / C #) - Saya tidak percaya penciptanya membidiknya di pasar itu - tapi saya pikir Scala mungkin layak untuk Scala menjadi Ruby atau Python berikutnya (yaitu untuk mendapatkan basis pengguna komersial yang signifikan)
- Apakah ini akan menunda orang datang ke Scala?
- Apakah ini akan memberi Scala nama buruk di dunia komersial sebagai mainan akademis yang hanya bisa dipahami oleh mahasiswa PhD yang berdedikasi? Apakah CTO dan pimpinan perangkat lunak akan takut?
- Apakah perpustakaan mendesain ulang ide yang masuk akal?
- Jika Anda menggunakan Scala secara komersial, apakah Anda khawatir tentang ini? Apakah Anda berencana untuk mengadopsi 2.8 segera atau menunggu untuk melihat apa yang terjadi?
Steve Yegge pernah menyerang Scala (keliru menurut saya) untuk apa yang dia lihat sebagai sistem tipe yang terlalu rumit. Saya khawatir bahwa seseorang akan memiliki hari lapangan menyebarkan FUD dengan API ini (mirip dengan bagaimana Josh Bloch menakuti JCP karena menambahkan penutupan ke Jawa).
Catatan - saya harus jelas bahwa, sementara saya percaya bahwa Joshua Bloch berpengaruh dalam penolakan terhadap proposal penutupan BGGA, saya tidak menganggap ini selain kepercayaannya yang dipegang dengan jujur bahwa proposal tersebut mewakili kesalahan.
Terlepas dari apa pun yang terus dikatakan istri dan rekan kerja saya, saya tidak berpikir saya idiot: Saya memiliki gelar matematika yang baik dari Universitas Oxford , dan saya telah pemrograman secara komersial selama hampir 12 tahun dan di Scala selama sekitar setahun (juga secara komersial).
Perhatikan judul subjek yang meradang ini adalah kutipan yang dibuat tentang manifesto partai politik Inggris pada awal 1980-an . Pertanyaan ini subyektif tetapi ini adalah pertanyaan asli, saya telah membuatnya menjadi CW dan saya ingin beberapa pendapat tentang masalah ini.
sumber
Jawaban:
Saya harap itu bukan "catatan bunuh diri", tapi saya bisa mengerti maksud Anda. Anda menemukan apa yang pada saat yang sama merupakan kekuatan dan masalah Scala: ekstensibilitasnya . Ini memungkinkan kami menerapkan sebagian besar fungsi utama di perpustakaan. Dalam beberapa bahasa lain, urutan dengan sesuatu seperti
map
ataucollect
akan dibangun, dan tidak ada yang harus melihat semua simpai yang harus dilewati oleh kompiler untuk membuatnya bekerja dengan lancar. Di Scala, semuanya ada di perpustakaan, dan karenanya di tempat terbuka.Bahkan fungsionalitas
map
yang didukung oleh jenisnya yang rumit cukup canggih. Pertimbangkan ini:Lihat bagaimana Anda selalu mendapatkan jenis yang terbaik? Jika Anda memetakan
Int
s keInt
s Anda mendapatkan lagiBitSet
, tetapi jika Anda memetakanInt
s keString
, Anda mendapatkan jenderalSet
. Tipe statis dan representasi runtime dari hasil peta bergantung pada tipe hasil fungsi yang diteruskan ke sana. Dan ini berfungsi bahkan jika set kosong, jadi fungsinya tidak pernah diterapkan! Sejauh yang saya tahu tidak ada kerangka kerja pengumpulan lain dengan fungsi yang setara. Namun dari perspektif pengguna, ini adalah bagaimana hal-hal seharusnya berfungsi.Masalah yang kita miliki adalah bahwa semua teknologi pintar yang membuat ini terjadi bocor ke jenis tanda tangan yang menjadi besar dan menakutkan. Tapi mungkin pengguna tidak boleh ditampilkan secara default tanda tangan tipe lengkap
map
? Bagaimana jika dia mendongakmap
diBitSet
dia mendapat:Docs tidak akan berbohong dalam kasus itu, karena dari perspektif pengguna memang peta memiliki tipe
(Int => Int) => BitSet
. Tetapimap
juga memiliki tipe yang lebih umum yang dapat diperiksa dengan mengklik tautan lain.Kami belum mengimplementasikan fungsi seperti ini di alat kami. Tetapi saya percaya kita perlu melakukan ini, untuk menghindari menakut-nakuti orang dan untuk memberikan informasi yang lebih bermanfaat. Dengan alat seperti itu, semoga kerangka kerja pintar dan perpustakaan tidak akan menjadi catatan bunuh diri.
sumber
Saya tidak memiliki gelar PhD, atau gelar apa pun selain dalam CS atau matematika atau memang bidang lainnya. Saya tidak punya pengalaman sebelumnya dengan Scala atau bahasa serupa lainnya. Saya tidak punya pengalaman dengan sistem tipe yang bahkan sebanding. Bahkan, satu-satunya bahasa yang saya miliki lebih dari sekedar pengetahuan dangkal yang bahkan memiliki sistem tipe adalah Pascal, tidak dikenal dengan sistem tipenya yang canggih. (Meskipun memang memiliki berbagai jenis, yang AFAIK cukup banyak tidak memiliki bahasa lain, tetapi itu tidak benar-benar relevan di sini.) Tiga bahasa lain yang saya tahu adalah BASIC, Smalltalk dan Ruby, tidak ada yang bahkan memiliki sistem tipe.
Namun, saya sama sekali tidak kesulitan memahami tanda tangan dari
map
fungsi yang Anda posting. Bagi saya, sepertinya hampir mirip dengan tanda tangan yangmap
ada di setiap bahasa lain yang pernah saya lihat. Perbedaannya adalah bahwa versi ini lebih umum. Itu lebih mirip C ++ STL daripada, katakanlah, Haskell. Secara khusus, ini abstrak dari jenis pengumpulan beton dengan hanya mengharuskan argumen ituIterableLike
, dan juga abstrak dari jenis pengembalian beton dengan hanya membutuhkan fungsi konversi implisit yang dapat membangun sesuatu dari kumpulan nilai-nilai hasil. Ya, itu cukup rumit, tetapi itu hanya ekspresi dari paradigma umum pemrograman generik: jangan menganggap apa pun yang sebenarnya tidak harus Anda lakukan.Dalam hal ini,
map
sebenarnya tidak perlu koleksi menjadi daftar, atau dipesan atau disortir atau semacamnya. Satu-satunya hal yang menjadimap
perhatian adalah bahwa ia bisa mendapatkan akses ke semua elemen koleksi, satu demi satu, tetapi tanpa urutan tertentu. Dan tidak perlu tahu apa koleksi yang dihasilkan, hanya perlu tahu cara membangunnya. Jadi, itulah yang dibutuhkan tanda tangan tipenya.Jadi, bukannya
yang merupakan tipe tanda tangan tradisional untuk
map
, itu digeneralisasi untuk tidak memerlukan konkretList
melainkan hanyaIterableLike
struktur datayang kemudian digeneralisasikan lebih lanjut dengan hanya mensyaratkan adanya fungsi yang dapat mengubah hasilnya menjadi struktur data apa pun yang diinginkan pengguna:
Saya akui bahwa sintaksnya sedikit clunkier, tetapi semantiknya sama. Pada dasarnya, ini dimulai dari
yang merupakan tanda tangan tradisional untuk
map
. (Perhatikan bagaimana karena sifat berorientasi objek Scala, parameter daftar input menghilang, karena sekarang parameter penerima implisit yang dimiliki setiap metode dalam sistem OO satu-pengiriman). Kemudian ia digeneralisasikan dari betonList
ke yang lebih umumIterableLike
Sekarang, ini menggantikan
IterableLike
kumpulan hasil dengan fungsi yang menghasilkan , yah, benar-benar apa saja.Yang saya benar-benar percaya tidak terlalu sulit untuk dipahami. Sebenarnya hanya ada beberapa alat intelektual yang Anda butuhkan:
map
itu. Jika Anda hanya memberikan tipe tanda tangan tanpa nama metode, saya akui, akan jauh lebih sulit untuk mengetahui apa yang sedang terjadi. Tetapi karena Anda sudah tahu apamap
yang seharusnya dilakukan, dan Anda tahu apa yang seharusnya menjadi tanda tangan, Anda dapat dengan cepat memindai tanda tangan dan fokus pada anomali, seperti "mengapa inimap
mengambil dua fungsi sebagai argumen, bukan satu?"Tidak satu pun dari ketiganya yang dapat menyebabkan sakit kepala serius bagi profesional atau bahkan programmer.
map
telah menjadi fungsi standar di hampir setiap bahasa yang dirancang dalam 50 tahun terakhir, fakta bahwa bahasa yang berbeda memiliki sintaks yang berbeda harus jelas bagi siapa saja yang telah merancang situs web dengan HTML dan CSS dan Anda tidak dapat berlangganan ke pemrograman yang bahkan jauh mailinglist terkait tanpa fanboy C ++ yang mengganggu dari gereja St. Stepanov menjelaskan manfaat pemrograman generik.Ya, Scala itu kompleks. Ya, Scala memiliki salah satu sistem tipe paling canggih yang dikenal manusia, menyaingi dan bahkan melampaui bahasa seperti Haskell, Miranda, Clean atau Cyclone. Tetapi jika kompleksitas adalah argumen yang menentang keberhasilan suatu bahasa pemrograman, C ++ akan sudah lama mati dan kita semua akan menulis Skema. Ada banyak alasan mengapa Scala kemungkinan besar tidak akan berhasil, tetapi fakta bahwa programmer tidak dapat repot-repot menyalakan otak mereka sebelum duduk di depan keyboard mungkin tidak akan menjadi yang utama.
sumber
That
disimpulkan dan dihubungkan dengan tipe yangB
menjadi satu pertanyaan yang muncul di benak. Di mana implikasinya berasal dari menjadi yang lain. Bahkan tanpa pengamatan terperinci ini, saya masih merasa secara pribadi bahwa ini adalah tanda tangan yang kompleks. Tetapi ternyata ada orang-orang seperti Anda di luar sana yang tidak terganggu oleh ini sama sekali!Hal yang sama di C ++ :
sumber
func
harus menjadi parameter templat, dan Anda harus menggunakanresult_of
danis_callable
untuk mendapatkan jenis lainnya dan membatasi kelebihan beban diatur dengan tepat :-)Yah, saya bisa mengerti rasa sakit Anda, tetapi, terus terang, orang-orang seperti Anda dan saya - atau hampir semua pengguna Stack Overflow biasa - bukan aturannya.
Yang saya maksud dengan itu adalah bahwa ... kebanyakan programmer tidak akan peduli dengan tanda tangan jenis itu, karena mereka tidak akan pernah melihatnya ! Mereka tidak membaca dokumentasi.
Selama mereka melihat beberapa contoh bagaimana kode bekerja, dan kode tidak gagal mereka dalam menghasilkan hasil yang mereka harapkan , mereka tidak akan pernah melihat dokumentasi. Ketika itu gagal, mereka akan melihat dokumentasi dan berharap untuk melihat contoh penggunaan di atas.
Dengan mengingat hal-hal ini, saya berpikir bahwa:
Siapa pun (seperti pada kebanyakan orang) yang pernah menemukan tanda tangan jenis itu akan mengejek Scala tanpa akhir jika mereka lebih dulu menolaknya, dan akan menganggapnya sebagai simbol kekuatan Scala jika mereka menyukai Scala.
Jika dokumentasi tidak ditingkatkan untuk memberikan contoh penggunaan dan menjelaskan dengan jelas apa metode untuk dan bagaimana menggunakannya, itu dapat mengurangi adopsi Scala sedikit.
Dalam jangka panjang, itu tidak masalah. Scala dapat melakukan hal-hal seperti itu akan membuat perpustakaan yang ditulis untuk Scala jauh lebih kuat dan lebih aman untuk digunakan. Perpustakaan dan kerangka kerja ini akan menarik programmer tertarik pada alat yang kuat.
Programmer yang menyukai kesederhanaan dan keterusterangan akan terus menggunakan PHP, atau bahasa serupa.
Sayangnya, programmer Java banyak ke alat-alat listrik, jadi, dalam menjawab itu, saya baru saja merevisi harapan saya untuk adopsi Scala mainstream. Saya tidak ragu sama sekali bahwa Scala akan menjadi bahasa utama. Bukan C-mainstream, tapi mungkin Perl-mainstream atau PHP-mainstream.
Berbicara tentang Java, apakah Anda pernah mengganti loader kelas? Pernahkah Anda melihat apa yang terlibat? Java bisa menakutkan, jika Anda melihat kerangka tempat penulis lakukan. Hanya saja kebanyakan orang tidak. Hal yang sama berlaku untuk Scala, IMHO, tetapi pengadopsi awal memiliki kecenderungan untuk melihat di bawah setiap batu yang mereka temui, untuk melihat apakah ada sesuatu yang bersembunyi di sana.
sumber
As long as they saw some example of how the code works, and the code doesn't fail them in producing the result they expect, they won't ever look at the documentation. When that fails, they'll look at the documentation and expect to see usage examples at the top.
Sedih tapi benar.Ya, tetapi itu juga akan mencegah orang untuk ditunda. Saya menganggap kurangnya koleksi yang menggunakan jenis yang lebih tinggi sebagai kelemahan utama sejak Scala mendapatkan dukungan untuk jenis yang lebih tinggi. Itu membuat API API lebih rumit, tetapi itu benar-benar membuat penggunaan lebih alami.
Beberapa mungkin akan melakukannya. Saya tidak berpikir Scala dapat diakses oleh banyak pengembang "profesional", sebagian karena kompleksitas Scala dan sebagian karena keengganan banyak pengembang untuk belajar. CTO yang mempekerjakan pengembang semacam itu akan merasa takut.
Benar. Itu membuat koleksi cocok jauh lebih baik dengan sisa bahasa dan sistem tipe, bahkan jika masih memiliki beberapa tepi kasar.
Saya tidak menggunakannya secara komersial. Saya mungkin akan menunggu sampai setidaknya beberapa putaran ke seri 2.8.x bahkan sebelum mencoba untuk memperkenalkannya sehingga bug dapat dihilangkan. Saya juga akan menunggu untuk melihat seberapa sukses EPFL dalam meningkatkan pengembangannya dan proses rilis. Apa yang saya lihat terlihat penuh harapan, tetapi saya bekerja untuk perusahaan yang konservatif.
Salah satu topik yang lebih umum dari "apakah Scala terlalu rumit untuk pengembang utama?" ...
Sebagian besar pengembang, arus utama atau lainnya, mempertahankan atau memperluas sistem yang ada. Ini berarti bahwa sebagian besar dari apa yang mereka gunakan ditentukan oleh keputusan yang dibuat sejak lama. Masih banyak orang yang menulis COBOL.
Pengembang utama Tomorrow akan bekerja memelihara dan memperluas aplikasi yang sedang dibangun hari ini. Banyak dari aplikasi ini tidak dibangun oleh pengembang utama. Pengembang utama Tomorrow akan menggunakan bahasa yang digunakan oleh pengembang aplikasi baru paling sukses saat ini.
sumber
Salah satu cara komunitas Scala dapat membantu meringankan rasa takut programmer yang baru mengenal Scala adalah dengan fokus pada praktik dan mengajar dengan contoh - banyak contoh yang dimulai dari yang kecil dan tumbuh secara bertahap lebih besar. Berikut adalah beberapa situs yang mengambil pendekatan ini:
Setelah menghabiskan beberapa waktu di situs-situs ini, orang dengan cepat menyadari bahwa Scala dan perpustakaannya, meskipun mungkin sulit untuk dirancang dan diimplementasikan, tidak begitu sulit untuk digunakan, terutama dalam kasus-kasus umum.
sumber
Saya memiliki gelar sarjana dari universitas AS "pasar massal" yang murah, jadi saya akan mengatakan bahwa saya berada di tengah skala kecerdasan pengguna (atau setidaknya pendidikan) :) Saya telah mencoba-coba Scala hanya untuk beberapa bulan dan telah bekerja pada dua atau tiga aplikasi non-sepele.
Apalagi sekarang IntelliJ telah merilis IDE bagus mereka dengan apa yang saat ini merupakan plugin Scala terbaik IMHO, pengembangan Scala relatif tidak menyakitkan:
Saya menemukan saya dapat menggunakan Scala sebagai "Java tanpa titik koma," yaitu saya menulis kode yang mirip dengan apa yang akan saya lakukan di Jawa, dan mendapat sedikit manfaat dari keringkasan sintaksis seperti yang diperoleh dengan inferensi tipe. Penanganan pengecualian, ketika saya melakukannya, lebih nyaman. Definisi kelas jauh lebih sedikit verbose tanpa pengambil / penyetel boilerplate.
Sesekali saya berhasil menulis satu baris untuk mencapai yang setara dengan beberapa baris Java. Jika berlaku, rangkaian metode fungsional seperti peta, lipat, kumpulkan, saring dll. Menyenangkan untuk disusun dan elegan untuk dilihat.
Jarang sekali saya mendapatkan manfaat dari fitur Scala yang lebih bertenaga: Penutupan dan fungsi parsial (atau kari), pencocokan pola ... itu agak aneh.
Sebagai seorang pemula, saya terus berjuang dengan sintaksis singkat dan idiomatik. Panggilan metode tanpa parameter tidak perlu tanda kurung kecuali di mana mereka melakukannya; case dalam pernyataan pertandingan memerlukan panah gemuk (
=>
), tetapi ada juga tempat di mana Anda membutuhkan panah tipis (->
). Banyak metode memiliki nama pendek tapi agak samar seperti/:
atau\:
- Saya bisa menyelesaikan pekerjaan saya jika saya membalik halaman manual yang cukup, tetapi beberapa kode saya akhirnya tampak seperti Perl atau derau baris. Ironisnya, salah satu bit steno sintaksis yang paling populer hilang dalam tindakan: Saya terus digigit oleh fakta yangInt
tidak mendefinisikan++
metode.Ini hanya pendapat saya: Saya merasa seperti Scala memiliki kekuatan C ++ dikombinasikan dengan kompleksitas dan keterbacaan C ++. Kompleksitas sintaksis bahasa juga membuat dokumentasi API sulit dibaca.
Scala dipikirkan dengan sangat baik dan cemerlang dalam banyak hal. Saya menduga banyak akademisi akan senang memprogram di dalamnya. Namun, ini juga penuh dengan kepintaran dan gotcha, ia memiliki kurva belajar yang jauh lebih tinggi daripada Jawa dan lebih sulit dibaca. Jika saya memindai forum dan melihat berapa banyak pengembang yang masih berjuang dengan poin Java yang lebih baik, saya tidak dapat membayangkan Scala pernah menjadi bahasa utama . Tidak ada perusahaan yang dapat membenarkan pengiriman pengembangnya pada kursus Scala 3 minggu ketika sebelumnya mereka hanya membutuhkan kursus Java 1 minggu.
sumber
Saya pikir masalah utama dengan metode itu adalah bahwa
(implicit bf : CanBuildFrom[Repr, B, That])
berjalan tanpa penjelasan. Meskipun saya tahu argumen implisit apa tidak ada yang menunjukkan bagaimana ini mempengaruhi panggilan. Mengejar skaladoc hanya membuat saya lebih bingung (beberapa kelas terkaitCanBuildFrom
bahkan memiliki dokumentasi).Saya pikir sederhana "harus ada objek implisit dalam ruang lingkup untuk
bf
yang menyediakan pembangun untuk objek bertipeB
ke tipe kembaliThat
" akan sedikit membantu, tapi itu semacam konsep memabukkan ketika semua yang Anda benar-benar ingin lakukan adalah petaA
untukB
ini Sebenarnya, saya tidak yakin itu benar, karena saya tidak tahu apa arti tipe tersebutRepr
, dan dokumentasiTraversable
untuknya tentu tidak memberikan petunjuk sama sekali.Jadi, saya memiliki dua pilihan, tidak satu pun yang menyenangkan:
Saya mendapatkan bahwa Scala pada dasarnya mengekspos nyali tentang bagaimana hal-hal ini bekerja dan yang pada akhirnya ini menyediakan cara untuk melakukan apa yang digambarkan oleh oxbow_lakes. Tapi itu gangguan dalam tanda tangan.
sumber
Repr
adalah representasi traversable, yaitu.List
atauSet
atauMap
. Saya pikir, sebagai kerangka kerja, jika Anda akan mulai melihat tanda tangan metode (daripada hanya menggunakan metode dengan menyalin contoh), Anda harus memahami desain umum terlebih dahulu. IMHO Scaladoc harus penuh dengan penggunaan contohRepr
artinya? Saya akan mengharapkan penjelasan di skaladoc, tetapi itu benar-benar tidak jelas bagi saya. Saya pikir ini adalah pola umum dalam skaladoc (lihatActor.react
danActor.receive
- saya diberitahu, dan telah melihat, bahwa mereka melakukan hal-hal yang sama sekali berbeda, namun skaladoc mereka identik).Saya seorang pemula Scala dan jujur saya tidak melihat masalah dengan tanda tangan jenis itu. Parameter adalah fungsi untuk memetakan dan parameter implisit pembangun untuk mengembalikan koleksi yang benar. Jelas dan mudah dibaca.
Semuanya cukup elegan, sebenarnya. Parameter tipe builder membiarkan kompiler memilih tipe return yang benar sementara mekanisme parameter implisit menyembunyikan parameter tambahan ini dari pengguna kelas. Saya mencoba ini:
Itu polimorfisme dilakukan dengan benar.
Sekarang, memang, ini bukan paradigma umum dan akan menakuti banyak orang. Tapi, itu juga akan menarik banyak orang yang menghargai ekspresif dan keanggunannya.
sumber
Sayangnya tanda tangan untuk peta yang Anda berikan tidak benar untuk peta dan memang ada kritik yang sah.
Kritik pertama adalah bahwa dengan menumbangkan tanda tangan untuk peta, kita memiliki sesuatu yang lebih umum. Adalah kesalahan umum untuk meyakini bahwa ini adalah kebajikan secara default. Bukan itu. Fungsi peta didefinisikan dengan sangat baik sebagai functor kovarian Fx -> (x -> y) -> Fy dengan kepatuhan pada dua hukum komposisi dan identitas. Apa pun yang dikaitkan dengan "peta" adalah parodi.
Tanda tangan yang diberikan adalah sesuatu yang lain, tetapi itu bukan peta. Apa yang saya duga sedang dicoba adalah versi khusus dan sedikit diubah dari tanda tangan "melintasi" dari kertas, The Essence of the Iterator Pattern. Ini tanda tangannya:
Saya akan mengubahnya menjadi Scala:
Tentu saja itu gagal - itu tidak cukup umum! Juga, ini sedikit berbeda (perhatikan bahwa Anda bisa mendapatkan peta dengan menjalankan lintasan melalui fungsi Identity). Namun, saya menduga bahwa jika penulis perpustakaan lebih menyadari generalisasi perpustakaan yang didokumentasikan dengan baik (Pemrograman Aplikatif dengan Efek mendahului yang disebutkan sebelumnya), maka kami tidak akan melihat kesalahan ini.
Kedua, fungsi peta adalah kasus khusus di Scala karena penggunaannya untuk pemahaman. Sayangnya ini berarti bahwa perancang perpustakaan yang lebih siap tidak dapat mengabaikan kesalahan ini tanpa juga mengorbankan gula sintaksis pemahaman. Dengan kata lain, jika perancang perpustakaan Scala menghancurkan metode, maka ini mudah diabaikan, tapi tolong jangan memetakan!
Saya harap seseorang berbicara tentang hal itu, karena seperti itu, akan menjadi lebih sulit untuk menyelesaikan kesalahan yang bersikeras dibuat oleh Scala, tampaknya karena alasan yang saya punya keberatan kuat. Artinya, solusi untuk "keberatan yang tidak bertanggung jawab dari programmer rata-rata (yaitu terlalu keras!)" Bukan "menenangkan mereka untuk membuatnya lebih mudah bagi mereka" tetapi sebaliknya, memberikan petunjuk dan bantuan untuk menjadi programmer yang lebih baik. Sasaran Myself dan Scala berselisih tentang masalah ini, tetapi kembali ke poin Anda.
Anda mungkin mengemukakan pendapat Anda, memprediksi respons khusus dari "programmer rata-rata". Yaitu, orang yang akan mengklaim "tapi itu terlalu rumit!" atau semacamnya. Ini adalah Yegges atau Bloch yang Anda rujuk. Respons saya terhadap orang-orang dari gerakan anti-intelektualisme / pragmatisme ini cukup keras dan saya sudah mengantisipasi rentetan tanggapan, jadi saya akan menghilangkannya.
Saya benar-benar berharap perpustakaan Scala meningkat, atau setidaknya, kesalahan dapat terselip dengan aman di sudut. Java adalah bahasa di mana "berusaha melakukan sesuatu yang bermanfaat" sangat mahal, sehingga sering tidak sepadan karena banyaknya kesalahan tidak bisa dihindari. Saya mohon Scala untuk tidak turun jalan yang sama.
sumber
Saya sangat setuju dengan pertanyaan dan jawaban Martin :). Bahkan di Jawa, membaca javadoc dengan obat generik jauh lebih sulit daripada seharusnya karena kebisingan tambahan. Ini diperparah dalam Scala di mana parameter implisit digunakan seperti dalam kode contoh pertanyaan (sementara yang implisit melakukan hal-hal pengumpulan-morphing yang sangat berguna).
Saya tidak berpikir itu masalah dengan bahasa itu sendiri - saya pikir ini lebih merupakan masalah perkakas. Dan sementara saya setuju dengan apa yang dikatakan Jörg W Mittag, saya pikir melihat scaladoc (atau dokumentasi jenis di IDE Anda) - itu harus membutuhkan daya otak sesedikit mungkin untuk memahami apa metode itu, apa yang diperlukan dan dikembalikan. Seharusnya tidak perlu meretas sedikit aljabar di atas kertas untuk mendapatkannya :)
Pasti IDE membutuhkan cara yang bagus untuk menunjukkan semua metode untuk variabel / ekspresi / jenis apa pun (yang seperti contoh Martin dapat memiliki semua generik yang diuraikan sehingga bagus dan mudah untuk grok). Saya suka ide Martin untuk menyembunyikan implisit secara default juga.
Untuk mengambil contoh di scaladoc ...
Ketika melihat ini di scaladoc saya ingin blok generik [B, Itu] disembunyikan secara default serta parameter implisit (mungkin mereka menunjukkan jika Anda membawa ikon kecil dengan mouse) - sebagai barang tambahan untuk grok membacanya yang biasanya tidak relevan. mis. bayangkan jika ini tampak seperti ...
bagus dan jelas dan jelas apa fungsinya. Anda mungkin bertanya-tanya apa 'Itu', jika Anda mengarahkan mouse atau mengkliknya itu dapat memperluas teks [B, Itu] yang menyoroti 'Itu' misalnya.
Mungkin ikon kecil dapat digunakan untuk deklarasi [] dan (implisit ...) blok sehingga jelas ada sedikit bit dari pernyataan itu runtuh? Sulit untuk menggunakan token untuk itu, tapi saya akan menggunakan a. untuk sekarang...
Jadi secara default 'noise' dari sistem tipe disembunyikan dari 80% utama dari apa yang perlu dilihat orang - nama metode, tipe parameternya dan tipe kembalinya dengan cara ringkas sederhana yang bagus - dengan sedikit tautan yang dapat diperluas ke detail jika Anda benar-benar peduli.
Kebanyakan orang membaca scaladoc untuk mengetahui metode apa yang dapat mereka panggil pada tipe dan parameter apa yang dapat mereka lewati. Kami agak membebani pengguna dengan terlalu banyak detail, bagaimana IMHO.
Ini contoh lain ...
Sekarang jika kita menyembunyikan deklarasi generik, lebih mudah dibaca
Kemudian jika orang-orang mengarahkan kursor, katakanlah, A1 kita dapat menunjukkan deklarasi A1 menjadi A1 <: A. Tipe kovarian dan contravarian dalam generik menambahkan banyak noise juga yang dapat diterjemahkan dalam cara yang jauh lebih mudah untuk grok ke pengguna, saya pikir.
sumber
Saya tidak tahu bagaimana cara menjelaskannya kepada Anda, tetapi saya memiliki gelar PhD dari Cambridge, dan saya menggunakan 2,8 saja.
Lebih serius, saya hampir tidak menghabiskan waktu dengan 2.7 (itu tidak akan inter-op dengan perpustakaan Java yang saya gunakan) dan mulai menggunakan Scala lebih dari sebulan yang lalu. Saya memiliki pengalaman dengan Haskell (tidak banyak), tetapi hanya mengabaikan hal-hal yang Anda khawatirkan dan mencari metode yang sesuai dengan pengalaman saya dengan Java (yang saya gunakan untuk mencari nafkah).
Jadi: Saya adalah "pengguna baru" dan saya tidak menunda - fakta bahwa ia berfungsi seperti Java memberi saya cukup kepercayaan diri untuk mengabaikan bit yang tidak saya mengerti.
(Namun, alasan saya melihat Scala adalah sebagian untuk melihat apakah akan mendorongnya di tempat kerja, dan saya belum akan melakukannya. Membuat dokumentasi tidak terlalu mengintimidasi tentu akan membantu, tetapi yang mengejutkan saya adalah seberapa banyak masih berubah dan dikembangkan (untuk bersikap adil, yang paling mengejutkan saya adalah betapa mengagumkannya hal itu, tetapi perubahan itu nyaris terjadi). Jadi saya kira apa yang saya katakan adalah bahwa saya lebih suka sumber daya terbatas dimasukkan ke dalam memasukkannya ke dalam keadaan akhir - saya tidak berpikir mereka berharap untuk menjadi sepopuler ini secepat ini.)
sumber
Sama sekali tidak kenal Scala, namun beberapa minggu yang lalu saya tidak bisa membaca Clojure. Sekarang saya bisa membaca sebagian besar, tetapi belum bisa menulis apa pun di luar contoh paling sederhana . Saya kira Scala tidak berbeda. Anda memerlukan buku atau kursus yang bagus tergantung pada cara Anda belajar. Hanya membaca deklarasi peta di atas, saya mungkin 1/3 dari itu.
Saya percaya masalah yang lebih besar bukanlah sintaksis dari bahasa-bahasa ini, tetapi mengadopsi dan menginternalisasi paradigma yang membuatnya dapat digunakan dalam kode produksi sehari-hari. Bagi saya, Java bukan lompatan besar dari C ++, yang bukan lompatan besar dari C, yang sama sekali bukan lompatan dari Pascal, atau Basic, dll. Tetapi pengkodean dalam bahasa fungsional seperti Clojure adalah lompatan besar (untuk saya sih). Saya kira dalam Scala Anda dapat kode dalam gaya Java atau gaya Scala. Tetapi di Clojure Anda akan membuat kekacauan yang cukup untuk menjaga kebiasaan imperatif Anda dari Jawa.
sumber
Scala memiliki banyak fitur gila (terutama yang menyangkut parameter implisit) yang terlihat sangat rumit dan akademis, tetapi dirancang untuk membuat berbagai hal mudah digunakan. Yang paling berguna mendapatkan gula sintaksis (seperti
[A <% B]
yang berarti bahwa objek tipe A memiliki konversi implisit ke objek tipe B) dan penjelasan yang terdokumentasi dengan baik tentang apa yang mereka lakukan. Tetapi sebagian besar waktu, sebagai klien dari perpustakaan ini Anda dapat mengabaikan parameter implisit dan percaya mereka untuk melakukan hal yang benar.sumber
Saya tidak berpikir itu adalah faktor utama yang akan mempengaruhi seberapa populernya Scala nantinya, karena Scala memiliki banyak kekuatan dan sintaksisnya tidak asing bagi programmer Java / C ++ / PHP seperti Haskell, OCaml, SML, Lisps, dll ..
Tapi saya pikir popularitas Scala akan lebih rendah daripada di mana Java hari ini, karena saya juga berpikir bahasa mainstream berikutnya harus lebih disederhanakan, dan satu-satunya cara saya melihat untuk sampai ke sana adalah ketidakberubahan murni, yaitu deklaratif seperti HTML, tetapi Turing lengkap . Namun, saya bias karena saya mengembangkan bahasa seperti itu, tetapi saya hanya melakukannya setelah mengesampingkan studi beberapa bulan bahwa Scala tidak cukup untuk apa yang saya butuhkan.
Saya tidak berpikir reputasi Scala akan menderita dari kompleks Haskell. Tetapi saya pikir beberapa orang akan menunda mempelajarinya, karena bagi kebanyakan programmer, saya belum melihat use case yang memaksa mereka untuk menggunakan Scala, dan mereka akan menunda belajar tentang hal itu. Mungkin sisi server yang sangat skalabel adalah use case yang paling menarik.
Dan, untuk pasar umum, pertama belajar Scala bukanlah "angin segar", di mana seseorang menulis program dengan segera, seperti pertama menggunakan HTML atau Python. Scala cenderung tumbuh pada Anda, setelah seseorang mempelajari semua detail yang ia temukan sejak awal. Namun, mungkin jika saya telah membaca Pemrograman di Scala sejak awal, pengalaman dan pendapat saya tentang kurva pembelajaran akan berbeda.
Pastinya.
Saya menggunakan Scala sebagai platform awal bahasa baru saya. Saya mungkin tidak akan membuat kode di perpustakaan koleksi Scala jika saya menggunakan Scala secara komersial sebaliknya. Saya akan membuat perpustakaan berdasarkan teori kategori saya sendiri, karena ketika saya melihat, saya menemukan tanda tangan tipe Scalaz bahkan lebih verbose dan lebih berat daripada perpustakaan koleksi Scala. Sebagian dari masalah itu mungkin adalah cara Scala mengimplementasikan kelas tipe, dan itu adalah alasan kecil saya membuat bahasa saya sendiri.
Saya memutuskan untuk menulis jawaban ini, karena saya ingin memaksakan diri untuk meneliti dan membandingkan desain kelas koleksi Scala dengan yang saya lakukan untuk bahasa saya. Mungkin juga berbagi proses pemikiran saya.
Koleksi 2,8 Scala menggunakan abstraksi pembangun adalah prinsip desain suara. Saya ingin menjelajahi dua pengorbanan desain di bawah ini.
KODE MENULIS-HANYA: Setelah menulis bagian ini, saya membaca komentar Carl Smotricz yang setuju dengan apa yang saya harapkan sebagai tradeoff. Komentar James Strachan dan davetron5000 sependapat bahwa makna That (bahkan bukan That [B]) dan mekanisme implisitnya tidak mudah dipahami secara intuitif. Lihat saya menggunakan monoid dalam edisi # 2 di bawah ini, yang saya pikir jauh lebih eksplisit. Komentar Derek Mahar adalah tentang menulis Scala, tetapi bagaimana dengan membaca Scala dari orang lain yang tidak "dalam kasus umum".
Satu kritik yang saya baca tentang Scala, adalah lebih mudah menulisnya, daripada membaca kode yang ditulis orang lain. Dan saya menemukan ini sesekali benar karena berbagai alasan (misalnya banyak cara untuk menulis fungsi, penutupan otomatis, Unit untuk DSL, dll), tetapi saya ragu apakah ini merupakan faktor utama. Di sini penggunaan parameter fungsi implisit memiliki plus dan minus. Di sisi positifnya, ini mengurangi verbositas dan mengotomatiskan pemilihan objek pembangun. Di Odersky contohkonversi dari BitSet, yaitu Set [Int], ke Set [String] tersirat. Pembaca kode yang tidak dikenal mungkin tidak siap untuk mengetahui apa jenis koleksi, kecuali mereka dapat beralasan dengan baik tentang semua calon potensial pembuat implisit tak terlihat yang mungkin ada dalam lingkup paket saat ini. Tentu saja, programmer yang berpengalaman dan penulis kode akan tahu bahwa BitSet terbatas pada Int, sehingga peta ke String harus dikonversi ke jenis koleksi yang berbeda. Tetapi jenis koleksi yang mana? Itu tidak ditentukan secara eksplisit.
DESAIN KOLEKSI AD-HOC: Setelah menulis bagian ini, saya membaca komentar Tony Morris dan menyadari bahwa saya membuat poin yang hampir sama. Mungkin eksposisi saya yang lebih verbose akan membuat poin lebih jelas.
Dalam "Fighting Bit Rot with Types" Odersky & Moors, dua use case disajikan. Mereka adalah pembatasan BitSet ke elemen Int, dan Peta untuk memasangkan elemen tuple, dan disediakan sebagai alasan bahwa fungsi pemetaan elemen umum, A => B, harus dapat membangun jenis pengumpulan tujuan alternatif. Namun, afaik ini cacat dari perspektif teori kategori. Agar konsisten dalam teori kategori dan dengan demikian menghindari kasus sudut, tipe koleksi ini adalah functors, di mana setiap morfisme, A => B, harus memetakan antara objek dalam kategori functor yang sama, Daftar [A] => Daftar [B], BitSet [A] => BitSet [B]. Sebagai contoh, Opsi adalah functor yang dapat dilihat sebagai kumpulan set dari satu Some (objek) dan None. Tidak ada peta umum dari Opsi Tidak Ada, atau Daftar Nihil, ke fungsi lain yang tidak
Ada pilihan desain pengorbanan yang dibuat di sini. Dalam desain untuk koleksi perpustakaan bahasa baru saya, saya memilih untuk menjadikan semuanya sebagai functor, yang berarti jika saya mengimplementasikan BitSet, ia perlu mendukung semua jenis elemen, dengan menggunakan representasi internal bidang non-bit saat disajikan dengan non-bit parameter tipe integer, dan fungsionalitas itu sudah di Set yang diwarisi dari dalam Scala. Dan Peta dalam desain saya hanya perlu memetakan nilainya, dan dapat menyediakan metode non-functor terpisah untuk memetakan tupel pasangan (kunci, nilai). Salah satu keuntungannya adalah bahwa setiap functor biasanya juga merupakan aplikasi dan mungkin juga monad. Dengan demikian semua fungsi antara tipe elemen, mis. A => B => C => D => ..., secara otomatis terangkat ke fungsi antara tipe-tipe aplikatif terangkat, mis. Daftar [A] => Daftar [B] => Daftar [ C] => Daftar [D] => .... Untuk memetakan dari functor ke kelas koleksi lain, saya menawarkan overload peta yang mengambil monoid, misalnya Nihil, Tidak ada, 0, "", Array (), dll. Jadi fungsi abstraksi pembangun adalah metode append dari monoid dan diberikan secara eksplisit sebagai parameter input yang diperlukan, sehingga tanpa konversi implisit yang tidak terlihat. (Tangent: parameter input ini juga memungkinkan penambahan ke monoids non-kosong, yang desain peta Scala tidak bisa lakukan.) Konversi semacam itu adalah peta dan lipatan dalam pass iterasi yang sama. Saya juga memberikan traversable, dalam arti kategori, "Pemrograman aplikatif dengan efek" McBride & Patterson, yang juga memungkinkan map + fold dalam satu iterasi lulus dari setiap traversable ke aplikatif mana pun, di mana sebagian besar setiap kelas koleksi keduanya.
Jadi afaics koleksi Scala adalah "ad-hoc" dalam arti bahwa itu tidak didasarkan pada teori kategori, dan teori kategori adalah esensi semantik denotasional tingkat tinggi. Meskipun pembangun implisit Scala pada awalnya penampilan "lebih umum" dari model functor + pembangun monoid + traversable -> aplikatif, mereka afaik tidak terbukti konsisten dengan kategori apa pun, dan dengan demikian kita tidak tahu aturan apa yang mereka ikuti dalam akal paling umum dan apa kasus sudut akan diberikan mereka mungkin tidak mematuhi model kategori apa pun. Tidak benar bahwa menambahkan lebih banyak variabel membuat sesuatu lebih umum, dan ini adalah salah satu manfaat besar dari teori kategori adalah memberikan aturan yang digunakan untuk mempertahankan generalitas sambil mengangkat ke semantik tingkat yang lebih tinggi. Koleksi adalah kategori.
Saya membaca di suatu tempat, saya pikir itu adalah Odersky, sebagai pembenaran lain untuk desain perpustakaan, adalah bahwa pemrograman dengan gaya fungsional murni memiliki biaya rekursi dan kecepatan terbatas di mana rekursi ekor tidak digunakan. Saya belum menemukan kesulitan untuk menggunakan rekursi ekor dalam setiap kasus yang saya temui sejauh ini.
Selain itu saya membawa dalam pikiran saya ide yang tidak lengkap bahwa beberapa tradeoff Scala adalah karena mencoba menjadi bahasa yang bisa berubah dan tidak berubah, tidak seperti misalnya Haskell atau bahasa yang saya kembangkan. Ini sesuai dengan komentar Tony Morris tentang pemahaman. Dalam bahasa saya, tidak ada loop dan tidak ada konstruksi yang bisa berubah. Bahasa saya akan berada di atas Scala (untuk saat ini) dan berutang banyak padanya, dan ini tidak akan mungkin jika Scala tidak memiliki sistem tipe umum dan kemampuan berubah-ubah. Itu mungkin tidak benar, karena saya pikir Odersky & Moors ("Fighting Bit Rot with Types") salah untuk menyatakan bahwa Scala adalah satu-satunya bahasa OOP dengan jenis yang lebih tinggi, karena saya memverifikasi (saya sendiri dan melalui Bob Harper) Standar itu ML memilikinya. Juga muncul sistem tipe SML yang mungkin setara (sejak 1980-an), yang mungkin tidak mudah dihargai karena sintaksisnya tidak begitu mirip dengan Java (dan C ++ / PHP) seperti Scala. Bagaimanapun, ini bukan kritik terhadap Scala, melainkan upaya untuk menyajikan analisis kompromi yang tidak lengkap, yang saya harap erat dengan pertanyaan itu. Scala dan SML tidak menderita dari ketidakmampuan Haskell untuk melakukannyaberlian multiple inheritance , yang sangat penting dan saya mengerti adalah mengapa begitu banyak fungsi dalam Haskell Prelude diulang untuk jenis yang berbeda.
sumber
Tampaknya perlu untuk menyatakan gelar yang di sini: BA dalam Ilmu Politik dan B.ed dalam Ilmu Komputer.
Ke titik:
Scala sulit, karena paradigma pemrograman yang mendasarinya sulit. Pemrograman fungsional membuat takut banyak orang. Dimungkinkan untuk membangun penutupan dalam PHP tetapi orang jarang melakukannya. Jadi tidak, bukan tanda tangan ini tetapi sisanya akan membuat orang menjauh, jika mereka tidak memiliki pendidikan khusus untuk membuat mereka menghargai kekuatan paradigma yang mendasarinya.
Jika pendidikan ini tersedia, semua orang bisa melakukannya. Tahun lalu saya membangun komputer catur dengan sekelompok anak sekolah di SCALA! Mereka memiliki masalah tetapi pada akhirnya mereka baik-baik saja.
Saya tidak akan khawatir.
sumber
Saya memiliki gelar matematika dari Oxford juga! Butuh beberapa saat untuk 'mendapatkan' barang koleksi baru. Tapi sekarang saya sangat menyukainya. Sebenarnya, mengetik 'peta' adalah salah satu hal besar pertama yang mengganggu saya di 2.7 (mungkin karena hal pertama yang saya lakukan adalah subkelas salah satu kelas koleksi).
Membaca makalah Martin tentang 2,8 koleksi baru benar-benar membantu menjelaskan penggunaan implisit, tapi ya dokumentasi itu sendiri perlu melakukan pekerjaan yang lebih baik untuk menjelaskan peran berbagai jenis implisit dalam tanda tangan metode API inti.
Perhatian utama saya adalah lebih dari ini: kapan 2.8 akan dirilis? Kapan laporan bug akan berhenti datang untuk itu? sudahkah tim scala digigit lebih dari yang bisa mereka kunyah dengan 2,8 / mencoba mengubah terlalu banyak sekaligus?
Saya benar-benar ingin melihat 2,8 stabil untuk rilis sebagai prioritas sebelum menambahkan hal lain yang baru sama sekali, dan bertanya-tanya (sambil menonton dari sela-sela) apakah beberapa perbaikan dapat dilakukan dengan cara peta jalan pengembangan untuk kompiler scala dikelola.
sumber
Bagaimana dengan pesan kesalahan dalam situs yang digunakan?
Dan bagaimana ketika datang kasus penggunaan yang perlu mengintegrasikan jenis yang ada dengan yang kustom yang cocok dengan DSL. Kita harus dididik dengan baik tentang masalah-masalah asosiasi, diutamakan, konversi implisit, parameter implisit, jenis yang lebih tinggi, dan mungkin jenis eksistensial.
Sangat baik untuk mengetahui bahwa sebagian besar itu sederhana tetapi belum tentu cukup. Setidaknya harus ada satu orang yang mengetahui hal ini jika perpustakaan luas akan dirancang.
sumber