Saya merasa sangat nyaman dengan pemrograman Imperatif. Saya tidak pernah mengalami kesulitan dalam mengekspresikan algoritme apa yang saya ingin komputer lakukan setelah saya menemukan apa yang ingin saya lakukan. Tetapi ketika datang ke bahasa seperti SQL atau saya sering terjebak karena kepala saya terlalu terbiasa dengan pemrograman Imperatif.
Misalnya, Anda memiliki band hubungan (bandName, bandCountry), venue (venueName, venueCountry), drama (bandName, venueName), dan saya ingin menulis kueri yang mengatakan: semua nama venue sedemikian rupa sehingga untuk setiap bandNegara ada band dari negara yang bermain di tempat nama itu.
Contoh: Saya ingin semua nama venue tempat band dari semua negara (bandCountry) bermain. Juga, dengan "hubungan" yang saya maksud adalah tabel SQL.
Dalam benak saya, saya segera pergi "untuk setiap venueName, ganti semua bandCountries dan untuk setiap bandCountry dapatkan daftar band yang berasal darinya. Jika tidak ada yang bermain di venueName, pergi ke venueName berikutnya. Lain, di akhir bandCountries iteration menambahkan venueName ke set nama venue yang baik ".
... tetapi Anda tidak dapat berbicara seperti itu di SQL dan saya benar-benar perlu memikirkan cara merumuskan ini, dengan solusi Imperatif intuitif yang terus-menerus mengganggu di belakang kepala saya. Apakah ada orang lain yang memiliki masalah ini? Bagaimana Anda mengatasi ini? Apakah Anda menemukan pergeseran paradigma? Membuat peta dari konsep Imperatif ke konsep SQL untuk menerjemahkan solusi Imperatif menjadi solusi Deklaratif? Baca buku yang bagus?
PS Saya tidak mencari solusi untuk pertanyaan di atas, saya menyelesaikannya.
sumber
Jawaban:
Ide di balik melakukan hal-hal secara deklaratif adalah bahwa Anda seharusnya menentukan apa , bukan bagaimana .
Bagi saya, sepertinya Anda berada di jalur yang benar. Masalahnya bukan bahwa Anda memikirkan hal-hal dengan cara yang salah. Itu karena Anda terlalu jauh. Mari kita lihat apa yang Anda coba lakukan:
Sejauh ini, ini hebat. Tetapi kemudian Anda melakukan ini:
Intinya, Anda melakukan pekerjaan yang tidak perlu. Anda tahu apa yang Anda inginkan, itulah yang benar-benar Anda butuhkan. Tetapi kemudian Anda melanjutkan dan mencoba mencari cara untuk mendapatkannya.
Jika saya jadi Anda, saya akan mencoba membiasakan diri sebagai berikut:
Mungkin butuh waktu dan usaha dari Anda, tetapi begitu Anda benar-benar grok pemrograman deklaratif, itu menjadi sangat berguna. Bahkan, Anda mungkin menemukan diri Anda menggunakan pemrograman deklaratif di sisa kode Anda.
Jika Anda mencari buku, saya akan merekomendasikan SQL dan Teori Relasional . Ini sangat membantu Anda memahami teori di balik database SQL. Ingatlah untuk mengambil rekomendasi Date dengan sebutir garam. Dia memberikan informasi yang sangat bagus, tetapi dia kadang-kadang bisa sedikit berargumen.
sumber
berpikir dalam hal set, bukan iterator; pernyataan sql mendefinisikan properti set output yang diinginkan (alias tabel / relasi)
hasil dari ini (jika saya memahami maksud Anda dengan benar!) akan menjadi himpunan tempat yang memiliki setidaknya satu band yang bermain di tempat itu. Iterasi atas bandCountry tidak perlu, karena relasi PLAYS sudah memiliki informasi yang Anda cari, Anda hanya perlu menghilangkan duplikat
jadi dalam SQL ini akan menjadi:
EDIT: ok, jadi set sebenarnya yang diinginkan sedikit lebih rumit. Pertanyaan yang diajukan dari database adalah: venue apa yang telah menjadi tuan rumah band dari semua negara?
Jadi, kami mendefinisikan kriteria keanggotaan untuk elemen set yang diinginkan sebagai tujuan, lalu bekerja mundur untuk mengisi set. Sebuah venue adalah anggota dari set output jika memiliki baris PLAYS untuk setidaknya satu band dari setiap negara. Bagaimana kami mendapatkan informasi ini?
Salah satu caranya adalah dengan menghitung negara yang berbeda untuk setiap tempat dan membandingkannya dengan jumlah semua negara. Tapi kami tidak memiliki hubungan NEGARA. Jika kita memikirkan model yang diberikan untuk sesaat, kita melihat bahwa himpunan semua negara bukanlah kriteria yang tepat; itu adalah himpunan semua negara yang memiliki setidaknya satu band. Jadi kita tidak memerlukan tabel negara (meskipun untuk model yang dinormalisasi kita harus memilikinya), dan kita tidak peduli dengan negara tempat, kita bisa menghitung negara-negara yang memiliki band, misalnya (dalam MS-SQL )
Kami dapat menghitung negara band untuk setiap venue
dan kita bisa menyatukan keduanya menggunakan subquery
Sekarang, itu bukan permintaan tercantik yang mungkin (GROUP BY dan HAVING mungkin dianggap solusi yang lebih 'elegan' daripada variabel temp dan subquery) tapi cukup jelas apa yang kita cari sehingga kita akan membiarkannya di situ untuk tujuan OP .
Tujuan OP adalah untuk belajar bagaimana mengubah pola pikir dari imperatif ke deklaratif. Untuk itu, lihat apa yang dilakukan oleh solusi imperatif:
Apa kriteria penentu di atas? Aku rasa ini:
Ini adalah kriteria yang mendiskualifikasi . Proses berpikir imperatif dimulai dengan ember penuh dan membuang hal-hal yang tidak sesuai dengan kriteria. Kami memfilter data.
Itu bagus untuk hal-hal sederhana, tetapi membantu berpikir dalam hal membangun set hasil yang diinginkan; apa kriteria kualifikasi yang sesuai yang akan memungkinkan seseorang untuk mengisi ember sebagai gantinya?
Kualifikasi akhir dapat disederhanakan menggunakan hitungan: bandCountry 'puas' jika setidaknya satu band dari sana bermain di suatu venue; jumlah negara band 'puas' untuk suatu venue harus sama dengan jumlah negara band untuk tempat yang akan dikualifikasi.
Sekarang kita dapat memberi alasan lintas hubungan dengan navigasi:
yang mengarah kembali ke solusi di atas (atau faksimili yang masuk akal)
RINGKASAN
sumber
Salah satu cara untuk mempelajari cara berpikir dan memprogram dalam gaya deklaratif adalah dengan mempelajari bahasa susunan tujuan umum seperti APL atau J. SQL mungkin bukan kendaraan terbaik untuk mempelajari cara memprogram deklaratif. Di APL atau J Anda belajar untuk beroperasi pada seluruh array (vektor, matriks, atau array dengan peringkat lebih tinggi), tanpa pengulangan atau pengulangan yang eksplisit. Ini membuat pemahaman SQL dan aljabar relasional jauh lebih mudah. Sebagai contoh yang sangat sederhana, untuk memilih item dari vektor V yang nilainya lebih besar dari 100, dalam APL kita menulis:
Di sini V> 100 mengevaluasi ke array boolean dengan bentuk yang sama dengan V, dengan 1 menandai nilai yang ingin kita pertahankan. Tidak terjadi pada APLer berpengalaman bahwa ada iterasi yang terjadi, kami hanya menerapkan masker ke vektor V, mengembalikan vektor baru. Ini tentu saja secara konseptual apa SQL di mana klausa atau aljabar relasional membatasi operasi lakukan.
Saya tidak berpikir Anda bisa menguasai pemrograman deklaratif tanpa melakukan banyak hal, dan SQL umumnya terlalu spesifik. Anda perlu menulis banyak kode tujuan umum, belajar bagaimana melakukannya tanpa loop dan jika / kemudian / lain struktur dan semua peralatan yang menghadiri pemrograman gaya imperatif, prosedural dan skalar.
Mungkin ada bahasa fungsional lain yang membantu dengan cara berpikir ini juga, tetapi bahasa array sangat dekat dengan SQL.
sumber
a = a + 1
) semalam. Dibutuhkan waktu untuk mempelajari gaya deklaratif seperti logika, fungsional, dan lain-lain seperti butuh waktu untuk mempelajari pemrograman imperatif.Pertama, Anda harus mempelajari keduanya. Anda mungkin memiliki preferensi, tetapi ketika bekerja di daerah di mana yang lain lebih baik, jangan melawannya. Banyak programmer yang tergoda untuk menggunakan kursor dalam database relasional karena mereka sangat terbiasa untuk melangkah melalui setiap record, tetapi database jauh lebih baik di set. Anda tidak ingin masuk ke dalam pola pikir "Saya tahu bagaimana melakukannya dengan cara ini dan saya memiliki kendali paling besar, bla, bla, bla".
sumber
Anda belajar berpikir secara deklaratif seperti Anda belajar berpikir secara imperatif: dengan berlatih mulai dengan masalah yang lebih sederhana dan terus maju saat Anda "mengerti".
Pengalaman pertama Anda dengan pemrograman imperatif mencakup sejumlah pernyataan kontra-intuitif (dan, pada kenyataannya, sangat konyol) seperti "
a = a + 1
". Anda memusatkan pikiran Anda ke titik yang sekarang Anda mungkin bahkan tidak ingat mundur dari ketidakbenaran jelas dari pernyataan itu. Masalah Anda dengan gaya deklaratif adalah bahwa Anda kembali ke tempat Anda berada saat pertama kali memulai dengan gaya imperatif: a "clueless newb". Lebih buruk lagi, Anda sudah bertahun-tahun berlatih dengan satu gaya yang benar-benar bertentangan dengan gaya baru ini dan memiliki kebiasaan bertahun-tahun untuk dibatalkan - seperti kebiasaan untuk "mengendalikan dengan segala cara".Gaya deklaratif bekerja dengan pendekatan berbeda yang Anda tidak memiliki intuisi untuk saat ini (kecuali jika Anda telah menjaga keterampilan matematika Anda sangat tajam selama bertahun-tahun - yang kebanyakan orang tidak). Anda harus mempelajari kembali cara berpikir dan satu-satunya cara untuk mempelajari kembali itu adalah dengan melakukannya, satu langkah sederhana pada suatu waktu.
Memilih SQL sebagai perampokan pertama Anda ke pemrograman deklaratif mungkin merupakan kesalahan jika Anda benar-benar ingin mempelajari konsep-konsepnya. Tentu kalkulus tuple yang menjadi dasarnya adalah deklaratif, tetapi sayangnya kemurnian kalkulus tuple telah sangat dikompromikan oleh realitas implementasi dan bahasa tersebut, pada dasarnya, telah menjadi sedikit berantakan. Sebagai gantinya, Anda mungkin ingin melihat bahasa lain yang lebih langsung berguna (dalam arti Anda terbiasa) bahasa deklaratif seperti Lisps (esp. Scheme ), Haskell dan ML untuk (kebanyakan) pemrograman fungsional atau, sebagai alternatif, Prolog dan Merkurius untuk (kebanyakan) pemrograman logika.
Mempelajari bahasa-bahasa lain ini akan memberi Anda wawasan yang lebih baik, menurut pendapat saya, tentang bagaimana pemrograman deklaratif bekerja karena beberapa alasan:
Mereka berguna untuk pemrograman "cradle to grave" - karena Anda dapat menulis program lengkap dalam bahasa-bahasa ini dari awal hingga akhir. Mereka berguna berdiri sendiri, tidak seperti SQL yang benar-benar sangat tidak berguna bagi kebanyakan orang sebagai bahasa mandiri.
Mereka masing-masing memberi Anda pandangan yang berbeda pada pemrograman deklaratif yang dapat memberi Anda jalan yang berbeda untuk akhirnya "mendapatkannya".
Mereka juga masing-masing memberi Anda pandangan yang berbeda pada pemikiran tentang pemrograman secara umum. Mereka akan meningkatkan kemampuan Anda untuk beralasan tentang masalah dan pengkodean meskipun Anda tidak pernah menggunakannya secara langsung.
Pelajaran yang Anda pelajari dari mereka akan membantu Anda dengan SQL Anda juga - terutama jika Anda memoles kalkulus tuple di belakang database relasional untuk bentuk murni berpikir tentang data.
Saya terutama merekomendasikan belajar salah satu bahasa fungsional ( Clojure , sebagai salah satu Lisps, mungkin merupakan pilihan yang baik di sini) dan salah satu bahasa logika (saya suka merkuri terbaik, tetapi Prolog memiliki banyak bahan yang lebih berguna untuk belajar) untuk perluasan proses berpikir maksimal.
sumber
Tidak salah untuk berpikir secara imperatif dalam pengaturan deklaratif seperti SQL. Hanya saja, pemikiran imperatif harus terjadi pada tingkat yang sedikit lebih tinggi dari apa yang Anda gambarkan. Setiap kali saya perlu query database yang menggunakan SQL saya selalu berpikir sendiri:
Di atas adalah algoritma imperatif tingkat tinggi dan berfungsi cukup baik bagi saya dalam pengaturan SQL. Saya pikir ini dianggap sebagai pendekatan top-down dan Steven A. Lowe menggambarkan pendekatan bottom-up yang cukup bagus .
sumber
Kunci dari pertanyaan Anda adalah dalam apa yang Anda katakan di paragraf berikutnya hingga terakhir: "Anda tidak dapat berbicara seperti itu di SQL." Mungkin lebih bermanfaat bagi Anda pada tahap ini untuk mendekati SQL sebagai bahasa asing daripada bahasa pemrograman. Jika Anda memikirkannya seperti ini, menulis kueri SQL benar-benar menerjemahkan pernyataan bahasa Inggris tentang apa yang Anda inginkan ke dalam "SQLish". Komputer memahami SQLish dengan sempurna dan akan melakukan apa yang Anda katakan, sehingga Anda tidak perlu khawatir tentang implementasi selama Anda menerjemahkan dengan benar.
Yang mengatakan, apa cara terbaik untuk belajar bahasa asing? Anda jelas harus mempelajari tata bahasa dan kosakata, yang bisa Anda dapatkan dari dokumentasi SQL Anda. Yang paling penting adalah latihan. Anda harus membaca dan menulis SQL sebanyak yang Anda bisa, dan jangan merasa bahwa Anda harus mengetahui sintaks secara menyeluruh terlebih dahulu; Anda dapat, dan harus, mencari hal-hal saat Anda pergi bersama. Anda akan tahu bahwa Anda mendapatkannya ketika Anda merasa lebih mudah untuk menggambarkan data apa yang Anda inginkan dalam SQL daripada dalam bahasa Inggris.
sumber
Butuh waktu lama untuk membungkus kepala saya di sekitar SQL juga. Kami melakukan beberapa teori relasional di universitas dan pada saat itu, yang hanya mempersulit masalah. Pada akhirnya, proses pembelajaran saya adalah banyak trial and error yang diinformasikan oleh berbagai bahan pembelajaran dan contoh yang saya temukan berguna di sepanjang jalan. Pada dasarnya, Anda akan terbiasa pada akhirnya, dan menambahkan cara berpikir baru tentang data dan pertanyaan akan bermanfaat bagi perkembangan mental Anda.
Saya menemukan bahwa saya dapat mempercepat pembelajaran saya dengan secara bertahap membangun kumpulan skrip sederhana yang menunjukkan bagaimana menggunakan setiap fitur bahasa dan bagaimana mencapai hasil tertentu pada tabel yang diketahui (definisi tabel termasuk untuk referensi).
Awal tahun ini saya melakukan beberapa pelatihan formal yang melibatkan proyek migrasi data pada database Oracle yang berantakan, di mana saya harus secara bertahap mengumpulkan fragmen-fragmen dari perpustakaan saya untuk menyaring hasil kueri dengan berbagai cara sampai saya mendapatkan apa yang saya inginkan, kemudian mengubahnya sebagai perlu, dan sebagainya. Beberapa pertanyaan menjadi sangat kompleks dan sulit untuk di-debug. Saya ragu saya bisa membacanya sekarang, tetapi saya harap saya bisa menemukan solusi yang sama lagi dengan menggunakan blok bangunan referensi saya.
Cara lain untuk meningkatkan kesadaran intuitif Anda tentang ruang deklaratif dan fungsional adalah mempelajari teori himpunan dan bahasa pemrograman yang lebih cocok dengan paradigma tertentu. Saat ini saya sedang dalam proses belajar beberapa Haskell, misalnya, untuk mempertahankan dan meningkatkan kemampuan matematika saya.
sumber
Ketika Anda menghadapi masalah Anda biasanya berpikir bagaimana menyelesaikannya. Tetapi jika Anda tahu bagaimana komputer menyelesaikannya untuk Anda! Maka Anda khawatir tentang bagaimana akan dihilangkan.
Saya mencoba mengatakan bagaimana itu terjadi.
Anda mungkin sudah terbiasa dengan program rekursif, dalam program rekursif, Anda mendefinisikan masalahnya daripada mengatakan bagaimana itu diselesaikan. Anda mendefinisikan basis, dan mendefinisikan n berdasarkan pada n-1 . (misalnya
factorial(n) = n * factorial(n-1)
) Tetapi Anda mungkin sudah tahu bagaimana komputer menyelesaikannya. itu mulai dari fungsi dan memanggil fungsi secara rekursif sampai mencapai definisi dasar, kemudian mengevaluasi semua fungsi lain berdasarkan nilai dasar.Itulah yang terjadi dalam pemrograman deklaratif. Anda mendefinisikan semuanya berdasarkan definisi yang ada. Dan komputer tahu cara memperoleh jawaban untuk Anda berdasarkan fungsi dasar.
Dalam SQL Anda mungkin tidak menghubungkan definisi satu sama lain tetapi Anda menghubungkan objek atau informasi satu sama lain, Anda menentukan apa yang Anda inginkan dan pencarian komputer untuk sesuatu (objek, informasi) berdasarkan pada hubungan yang Anda berikan.
sumber