Apa perbedaan antara coroutine dan lanjutan dan generator?
generator
continuations
coroutine
Mehdi Asgari
sumber
sumber
Jawaban:
Saya akan mulai dengan generator, karena mereka adalah kasus paling sederhana. Seperti @zvolkov sebutkan, mereka adalah fungsi / objek yang dapat berulang kali dipanggil tanpa kembali, tetapi ketika dipanggil akan mengembalikan (menghasilkan) nilai dan kemudian menunda eksekusi mereka. Ketika mereka dipanggil lagi, mereka akan mulai dari tempat mereka menunda eksekusi dan melakukan hal mereka lagi.
Generator pada dasarnya adalah coroutine yang dipotong (asimetris). Perbedaan antara coroutine dan generator adalah coroutine dapat menerima argumen setelah awalnya disebut, sedangkan generator tidak bisa.
Agak sulit untuk memberikan contoh sepele tentang di mana Anda akan menggunakan coroutine, tetapi inilah upaya terbaik saya. Ambil ini (dibuat) kode Python sebagai contoh.
Contoh di mana coroutine digunakan adalah lexers dan parser. Tanpa coroutine dalam bahasa atau ditiru bagaimanapun, kode lexing dan parsing perlu dicampur bersama meskipun mereka benar-benar dua masalah yang terpisah. Tetapi menggunakan coroutine, Anda dapat memisahkan kode lexing dan parsing.
(Saya akan membahas perbedaan antara coroutine simetris dan asimetrik. Cukup dengan mengatakan bahwa mereka setara, Anda dapat mengkonversi dari satu ke yang lain, dan coroutine asimetris - yang merupakan generator yang paling mirip - adalah lebih mudah untuk dipahami. Saya menjelaskan bagaimana seseorang dapat menerapkan coroutine asimetris dengan Python.)
Kelanjutan sebenarnya adalah binatang yang sangat sederhana. Semua itu adalah fungsi yang mewakili titik lain dalam program yang, jika Anda menyebutnya, akan menyebabkan eksekusi secara otomatis beralih ke titik yang diwakili fungsi tersebut. Anda menggunakan versi yang sangat terbatas setiap hari tanpa menyadarinya. Pengecualian, misalnya, dapat dianggap sebagai semacam kelanjutan dari dalam ke luar. Saya akan memberi Anda contoh pseudocode berbasis Python dari kelanjutan.
Katakanlah Python memiliki fungsi yang disebut
callcc()
, dan fungsi ini mengambil dua argumen, yang pertama adalah fungsi, dan yang kedua adalah daftar argumen untuk memanggilnya. Satu-satunya batasan pada fungsi itu adalah bahwa argumen terakhir yang diambil adalah fungsi (yang akan menjadi kelanjutan kami saat ini).Apa yang akan terjadi adalah yang
callcc()
pada gilirannya akan memanggilfoo()
dengan kelanjutan saat ini (cc
), yaitu, referensi ke titik dalam program di manacallcc()
dipanggil. Ketikafoo()
memanggil kelanjutan saat ini, itu pada dasarnya sama dengan mengatakancallcc()
untuk kembali dengan nilai yang Anda panggil kelanjutan saat ini, dan ketika melakukan itu, itu memutar kembali tumpukan ke tempat kelanjutan saat ini dibuat, yaitu, ketika Anda meneleponcallcc()
.Hasil dari semua ini adalah bahwa varian Python hipotetis kita akan dicetak
'42'
.Saya harap itu membantu, dan saya yakin penjelasan saya dapat ditingkatkan sedikit!
sumber
Coroutine adalah salah satu dari beberapa prosedur yang bergantian melakukan pekerjaan mereka dan kemudian berhenti untuk memberikan kontrol kepada coroutine lain dalam kelompok.
Lanjutan adalah "penunjuk ke fungsi" yang Anda lewati untuk beberapa prosedur, yang akan dieksekusi ("dilanjutkan dengan") ketika prosedur itu dilakukan.
Generator (dalam. NET) adalah konstruksi bahasa yang dapat memuntahkan nilai, "menjeda" pelaksanaan metode dan kemudian melanjutkan dari titik yang sama ketika ditanya untuk nilai berikutnya.
sumber
Dalam versi Python yang lebih baru, Anda dapat mengirim nilai ke Generator dengan
generator.send()
, yang membuat Generator python secara efektif coroutine.Perbedaan utama antara Generator python, dan generator lainnya, katakanlah greenlet, adalah bahwa dengan python, Anda
yield value
hanya dapat kembali ke pemanggil. Sementara di greenlet,target.switch(value)
dapat membawa Anda ke target coroutine tertentu dan menghasilkan nilai di manatarget
akan terus berjalan.sumber
yield
panggilan harus dalam fungsi yang sama, yang disebut "Generator". Anda tidak dapatyield
dari sub-fungsi, itulah sebabnya Python disebut semi-coroutine , sedangkan Lua memiliki coroutine asimetris . (Ada proposal untuk memperbanyak hasil panen, tetapi saya pikir itu hanya membuat lumpur air.)