Model Mental atau Metafora Dunia Nyata untuk Pemrograman Fungsional


16

Adakah yang punya model mental atau metafora yang bagus untuk pemrograman fungsional yang merujuk sesuatu di dunia nyata?

Pemrograman Berorientasi Objek secara intuitif masuk akal bagi saya. Ada hal-hal yang memiliki properti dan kadang-kadang mereka juga dapat melakukan hal-hal atau melakukan perhitungan pada properti mereka (metode). (Mis: Mobil, Bentuk, Kucing).

Saya menanggung pemrograman fungsional tidak ada niat buruk sama sekali dan saya tidak tertarik dalam perdebatan tentang kebaikan keduanya. Saya hanya perlu metafora atau model mental untuk bekerja seperti yang saya miliki dengan pemrograman Berorientasi Objek.

Apa saja model mental yang baik atau metafora dunia nyata untuk pemrograman dalam paradigma fungsional? Ada sesuatu tentang fungsi-fungsi yang terdiri dari fungsi-fungsi pemrosesan fungsi yang membuat seseorang tanpa tempat yang kuat untuk berdiri dan berpikir.


Apa makna konkret dari "pemrograman fungsional" yang Anda maksudkan, "tidak ada efek samping / deklaratif" atau "komposisi fungsi / fungsi kelas satu"? Atau keduanya?
acelent

Pertanyaan menarik. Dengan pengetahuan kecil saya saat ini, dan sedikit pengalaman pemrograman dalam, "pemrograman fungsional," saya tidak bisa menjawab pertanyaan itu. Jika saya harus menebak, saya akan mengatakan keduanya.
Guido Anselmi

13
Model "dunia nyata" sering diberikan sebagai motivasi untuk pemrograman berorientasi objek. Saya pikir ini adalah pendekatan yang pada akhirnya harus Anda lewati, karena objek dalam OOP tidak harus selalu sesuai dengan objek dunia nyata, dan bahkan ketika mereka melakukannya, korespondensi sering tidak lengkap; misalnya, hubungan "is-a" tidak selalu sama. Di sisi lain, begitu Anda mengatakan bahwa Anda menginginkan model atau metafora untuk bahasa pemrograman yang didasarkan pada sesuatu di "dunia nyata", saya pikir Anda pada dasarnya membatasi diri pada bentuk OOP yang terbatas ini.
David K

Model mental yang sangat bagus, jika Anda memiliki pengalaman menggunakan sistem unix-like (atau PowerShell di Windows modern) adalah shell one-liners. Mereka tidak persis sama karena pipa shell secara teknis pemrograman berbasis aliran bukannya fungsional tetapi mereka memiliki "rasa" yang sama sebagai seorang programmer.
slebetman

1
Juga, Anda akan menemukan ketika Anda belajar bahasa fungsional, dalam pemrograman fungsional berorientasi objek diperlakukan sebagai alat, seperti ekspresi reguler misalnya. Sesuatu yang dapat Anda gunakan jika Anda suka tetapi Anda tidak harus melakukannya. Dalam beberapa bahasa seperti lisp dan tcl dan sebagainya, OO bukan fitur bawaan untuk bahasa tersebut tetapi perpustakaan yang dapat Anda gunakan (atau Anda bahkan dapat menulis OO sendiri jika Anda merasa berani). Jadi masalah yang secara alami memiliki solusi OO dapat diselesaikan dengan menggunakan OO dalam sebagian besar bahasa fungsional. Orang hanya tidak memperlakukan OO sebagai agama.
slebetman

Jawaban:


32

Pemrograman fungsional adalah semua tentang menempelkan fungsi yang lebih kecil bersama untuk mencapai hasil Anda. Model mental yang layak (bagi saya, setidaknya) adalah jalur perakitan. Setiap fungsi yang dikomposisikan adalah satu langkah lagi dalam proses perakitan. Pertimbangkan fungsi ini di sini:

smallest  = head . sort

Di Haskell, fungsi ini akan mengembalikan elemen terkecil dalam daftar. Baris perakitan pertama mengurutkan input, lalu mengembalikan elemen pertama (dengan asumsi itu diurutkan paling sedikit ke terbesar.) Jika kita hanya ingin mendapatkan nilai genap terkecil, maka kita dapat mengubah jalur perakitan agar terlihat seperti berikut:

smallestEven = head . sort . filter even

Hanya satu langkah lagi di ban berjalan.

Singkatnya, fungsi hanya menggambarkan langkah-langkah yang diambil untuk mengubah input mentah (bagian-bagian) menjadi barang yang diproses (output.)


2
Dalam bahasa fungsional murni tanpa variabel global, maka satu jalur perakitan tidak dapat memengaruhi yang lain (kecuali jika memberi makan input jalur lainnya.) Secara teoritis setiap jalur perakitan yang tidak bergantung satu sama lain dapat dijalankan secara paralel, tetapi saya tidak yakin jika ada kompiler melakukan ini.
bstamour

3
@GuidoAnselmi Salah satu cara untuk memikirkannya adalah bahwa jalur perakitan dalam pemrograman fungsional membangun output baru sambil membiarkan input tetap utuh, sedangkan jalur perakitan dalam OOP tradisional mengubah input.
Doval

2
Metafora ini hanya masuk akal dalam arti "fungsi kelas / komposisi fungsi" yang berarti "pemrograman fungsi", bukan dalam "tanpa efek samping / deklaratif". Selain itu, pemrograman berorientasi objek tidak selalu memiliki efek samping, sehingga Anda dapat menerapkan jalur perakitan yang merusak atau konstruktif dengan OOP atau makna FP ini. OOP lebih tentang enkapsulasi, penyampaian pesan, dan polimorfisme daripada tentang efek samping, tergantung pada bagaimana Anda memodelkan sesuatu. Misalnya apakah Anda memerlukan identitas referensi dari awal hingga akhir?
acelent

3
@ Bstamour: Lebih tepatnya, orang harus menulis (f . g) (x)artinya f(g(x))atau f . gsarana \x -> f (g (x)).
Giorgio

3
@MarjanVenema Hal-hal yang mengalir dalam contoh itu hanya karena begitulah .didefinisikan; ini bukan cara Haskell bekerja secara umum . Anda bisa juga mendefinisikan operator pipa maju F # |>di Haskell dan menulis smallest x = (sort x) |> headdan data akan mengalir dengan benar. Kupikir aku akan menunjukkannya.
Doval

18

Adakah yang punya model mental yang bagus untuk pemrograman fungsional?

Matematika. Pemrograman fungsional terinspirasi oleh dan dimodelkan pada matematika. Fungsi matematika tidak memiliki status, tidak memiliki efek samping, dll, dan begitu pula dengan FP. Jika Anda berpikir tentang FP dalam hal fungsi matematika daripada menggunakan gaya OO "bagaimana saya melakukan ini untuk itu" pendekatan, Anda akan berada dalam kondisi yang baik. Jika Anda mencoba membawa kepekaan OO ke FP, Anda akan berenang melawan arus.


1
Terima kasih. Namun, saya memerlukan metafora dari dunia nyata (mis. Bukan dari komputer atau matematika).
Guido Anselmi

3
@GuidoAnselmi: Fungsi adalah kotak hitam. Anda meletakkan sesuatu di satu sisi dan kemudian sesuatu yang baru muncul di sisi lain. Jika Anda memasukkan barang yang sama, Anda selalu mengeluarkan barang yang sama. Anda dapat mengambil banyak kotak kecil ini dan menggabungkannya dalam pesanan berbeda untuk membangun pabrik yang mungkin mengambil logam mentah dan menghasilkan mobil. Di dalam proses dipecah menjadi banyak bagian, tetapi dari luar itu hanya fungsi lain.
Daenyth

16

Bagaimana dengan buku flip ?

Dalam buku flip, setiap halaman mewakili dunia sebagaimana adanya pada saat tertentu. Dalam program kami, dunia direpresentasikan sebagai beberapa struktur data majemuk (mis. Kami memiliki pisang yang ada di tangan gorila yang ada di pohon yang ada di hutan). Setiap halaman berikutnya memajukan cerita dengan sedikit memodifikasi representasi sebelumnya. Dalam FP, struktur data persisten dirancang untuk menggunakan kembali struktur sebelumnya secara efisien sehingga perubahan hanya menyediakan delta dan bukan rendisi yang sepenuhnya baru.

Apa yang mungkin tidak jelas adalah bahwa sebuah halaman di buku flip kami juga akan mewakili hal yang tidak berwujud. Misalnya, jika gorila menjatuhkan pisang, kita mungkin mulai menerapkan efek gravitasi pada kelaikan dan akselerasi menuju lantai hutan. Untuk mengakomodasi ini, kami akan melampirkan atribut seperti kecepatan dan lintasan ke pisang kami.

Dalam program kami akan ada fungsi yang menerima halaman buku flip (alias negara dunia) sebagai argumen dan menghasilkan halaman baru . Dengan cara ini, kisah kita diceritakan tanpa pernah benar-benar mengubah keadaan objek yang ada. Kami hanya mengganti setiap halaman dengan yang lebih baru menggunakan apa yang secara efektif merupakan perhitungan.


3

Hubungan.

Teman: Diberi dua orang, hubungan pertemanan mengikuti hukum umum ini

  1. Memiliki niat baik satu sama lain
  2. Berpikir satu sama lain adalah teman mereka (jadi hukum harus dipenuhi oleh kedua anggota dalam hubungan ini)
  3. Nikmati menghabiskan waktu satu sama lain

Monoid: Diberikan beberapa item dan fungsi yang mengambil 2 item dan mengembalikan 1, hubungan monoid mengikuti hukum umum ini

  1. Ada salah satu item (hanya satu, yang disebut identitas) yang dilewatkan ke fungsi dengan item lain akan memastikan fungsi selalu mengembalikan item lainnya (0 + 1 = 1, sehingga 0 adalah identitas ketika item adalah angka dan fungsi adalah tambahan)
  2. Fungsi tidak dapat beroperasi atau mengembalikan item yang tidak ada dalam set yang memiliki hubungan monoid
  3. Fungsi ini asosiatif dan dapat digunakan dengan item dalam urutan yang agak independen, ini berarti a * (b * c) = (a * b) * c yang mengatakan Anda dapat mengalikan dengan hasil b * c atau c dengan hasil a * b dan hasilnya akan sama mana yang Anda lakukan pertama kali.

Pemrograman fungsional adalah semua tentang generalisasi, teman adalah hubungan yang sangat umum yang dapat dilihat dalam banyak skenario, tetapi dalam semua berbagai format umumnya mengikuti undang-undang di atas.

Menyadari undang-undang yang mengatur hubungan antara berbagai hal, Anda dapat membuat implementasi umum yang bekerja pada segala format hal yang memiliki jenis hubungan tersebut. Dalam pemrograman fungsional Anda mencoba mengidentifikasi hubungan antara hal-hal sehingga mereka dapat diklasifikasikan dan diperlakukan secara umum.

Anda ingin metafora dari dunia nyata? Lihatlah bagaimana berbagai hal terkait dan cobalah untuk mengidentifikasi hukum umum (seperti yang berlaku untuk beberapa skenario di mana hal-hal selain hukum mungkin berbeda). Ada hubungan antara petugas registrasi dan pembelanja di toko, ia memiliki beberapa hukum umum, perangkat lunak telah dikembangkan untuk memfasilitasi tujuan orang-orang dalam hubungan umum di jalan sistem POS. Demikian pula ketika Anda mulai melihat undang-undang umum ini menentukan bagaimana hal-hal terkait, Anda dapat mulai mengandalkan undang-undang hubungan tersebut dalam menulis perangkat lunak Anda dan bukan pada hal-hal khusus dari contoh hubungan.


2

Semuanya adalah nilai, dan Anda menerapkan fungsi ke nilai (yang mungkin fungsi) untuk menghasilkan nilai baru, lebih disukai tanpa menghasilkan efek samping.


Terima kasih. Sayangnya, itu lebih mirip deskripsi daripada model mental atau metafora. Saya membutuhkan metafora dari dunia nyata (bukan dari komputer).
Guido Anselmi

1
Seperti yang ditunjukkan Caleb , model pemrograman fungsional matematika, bukan dunia nyata. Ini dapat memodelkan dunia nyata melalui lensa matematika, tetapi Anda kemungkinan tidak akan menemukan metafora yang memuaskan Anda, karena FP menolak konsep hal-hal dengan identitas gigih dan keadaan yang bisa berubah. Jika Anda suka, saya bisa menunjukkan bagaimana OOP membuat peta menjadi FP, tetapi itu tetap bukan jawaban yang Anda inginkan.
Doval

Tetapi matematika didasarkan pada dunia nyata. 1 matahari, 9 planet. 2 apel ditambah 2 apel menghasilkan empat apel.
Guido Anselmi

Dan dalam pemrograman fungsional, Anda juga dapat memiliki jenis untuk matahari, planet, dan apel, kemudian membuat satu nilai berjenis matahari, 9 nilai jenis planet, dan menentukan tambahan untuk jenis apel.
Doval

3
@ GuidoAnselmi Anda memilikinya sepenuhnya mundur, orang menganalisis dunia nyata dengan matematika, tidak memiliki dasar di dunia nyata. Matematika digunakan untuk menganalisis dan mendefinisikan hubungan antara semua hal, nyata dan tidak. 9 planet adalah Anda menerapkan konstruk matematika (himpunan bilangan alami) ke konstruk dunia nyata (planet) dengan fungsi analisis matematika (hitung). Dunia nyata tidak memiliki 9 planet, ia memiliki apa yang dimilikinya, matematika hanya berbicara tentang representasi simbolik dari hal-hal di mana simbol memiliki hubungan antara satu sama lain.
Jimmy Hoffa

1

Hal utama yang harus disadari tentang pemrograman fungsional adalah bahwa semuanya adalah nilai - bahkan kode itu sendiri adalah 'nilai'.

Contoh terbaik dari lingkungan pemrograman fungsional yang sederhana adalah alat bisnis favorit semua orang - spreadsheet. Setiap sel dalam spreadsheet adalah data, atau hasil dari suatu fungsi. Terlebih lagi, fungsi ini tidak dapat mematikan dan memodifikasi sel lain.

Ketika salah satu bergerak ke bahasa fungsional, bukannya jaringan Cartesian dari A1dan B42, fungsi memiliki nama. Hanya itu yang sebenarnya.

Ada aspek-aspek lain yang bisa ditambahkan seseorang di luar ini ... tapi itu pemrograman fungsional pada intinya. Orang tidak perlu khawatir tentang struktur daftar atau pengelompokan hal-hal. Pemrograman fungsional adalah tentang meneruskan nilai ke dalam suatu fungsi dan mendapatkan nilai kembali tanpa mucking di tempat lain dalam memori.

Itu dia. Pemrograman fungsional adalah spreadsheet dengan nama daripada kisi.


0

Anda dapat menganggap pemrograman fungsional sebagai perilaku . Program adalah deskripsi perilaku yang Anda inginkan dari komputer. Fungsi adalah unit dasar perilaku, dan komposisi fungsi adalah salah satu cara untuk membangun perilaku yang lebih besar dari yang lebih kecil.

Dalam OOP, objek kode dimaksudkan sebagai keadaan objek dalam domain masalah; itu berubah seiring waktu untuk mencerminkan perubahan pada objek domain itu. Dalam FP, nilai mewakili keadaan objek domain; tidak pernah berubah, Anda cukup membuat nilai yang berbeda untuk mewakili negara yang berbeda.

Saya menemukan model fungsional sedikit lebih jujur ​​tentang apa yang sebenarnya dilakukan komputer — mewakili. Lagi pula, saya tidak bisa begitu saja menyulap new Tesla()kehabisan udara. :)


-5

Kalimat lebih fungsional daripada berorientasi objek, dengan asumsi Anda memecahnya lebih atau kurang seperti berikut ini ...

The brown cow is in the meadow across the deep river.

Jadi kita perlu menemukan frasa kepala dan sisanya:

The cow (brown)
the meadow (across)
the river (deep)

Dalam satu pergi:

sentence: The cow ((the meadow (the river (deep)) (across)) brown)

Pohon Parse:

|                     sentence
|                      /         
|                  The cow
|                 /       \
|            the meadow   brown
|            /         \
|      the river      across
|              \
|              deep

Parsimony menginfeksi pemikiran fungsional;

Angkat topi ke Gottlieb Frege 1890-an, Alan Turing (entschiedungsprobleme) 1930-an, Noam Chomsky (1960-an).


4
Ini adalah penjelasan yang membingungkan, dan saya akrab dengan FP untuk memulai.
Daenyth

Sepertinya meniru bentuk Lisp tanpa memahami artinya
Izkata
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.