Apakah Clojure memiliki kelanjutan / coroutine / etc?

20

Saya mulai pemrograman dengan Python, dan saya benar-benar bingung dengan konsep seperti coroutine dan closure.

Sekarang saya pikir saya mengenal mereka pada tingkat yang dangkal, tetapi saya tidak pernah merasakan momen "pencerahan" itu, jadi saya memilih untuk belajar Clojure. Saya membeli buku karya Stuart Halloway dan itu bagus, tetapi ketika saya melihat indeks, tidak ada kata-kata seperti coroutine atau lanjutan. Saya mencari di Google, tetapi tidak ada apa-apa di sana.

Jadi, pertanyaan saya adalah:

Apakah Clojure memiliki kelanjutan atau coroutine untuk melakukan tugas-tugas seperti ping-ponging tanpa stack overflow?

Contoh Python (meskipun Python standar tidak mendukung versi fitur lengkap dari coroutine simetris ini):

def ping():
  while 1:
   print "ping"
   function to switching to pong

def pong():
  while 1:
   function to switching to ping
   print "pong"
Pemula
sumber

Jawaban:

20

Clojure tidak memiliki panggilan / cc, tetapi Anda tetap tidak ingin melanjutkan tanpa perbaikan .

Kami membantah call/ccsebagai fitur bahasa inti, sebagai operasi kontrol yang dibedakan untuk mengimplementasikan semua yang lain ke perpustakaan secara bawaan. Primitif call/ccadalah abstraksi yang buruk - dalam berbagai arti 'buruk' seperti ditunjukkan di bawah ini, - dan menangkap kelanjutan dari keseluruhan program tidak praktis berguna. Satu-satunya hadiah untuk kerja keras untuk menangkap seluruh kelanjutan secara efisien adalah lebih banyak kerja keras untuk menyiasati penangkapan seluruh kelanjutan. Baik pengguna dan pelaksana lebih baik dilayani dengan seperangkat primitif kontrol yang dipilih dengan baik dari berbagai tingkat umum dengan interaksi yang dipikirkan dengan baik ...

... Menawarkan call/ccsebagai fitur kontrol inti dalam hal semua fasilitas kontrol lainnya harus diimplementasikan ternyata merupakan ide yang buruk. Kebocoran kinerja, memori, dan sumber daya, kemudahan implementasi, kemudahan penggunaan, kemudahan penalaran, semuanya menentang call/cc. Jika benar-benar ada satu fitur kontrol yang dibedakan untuk diimplementasikan sebagai primitif, dengan yang lain diturunkan ke perpustakaan, itu tidak call/cc.

David Nolen menulis perpustakaan kelanjutan terbatas untuk Clojure. Cobalah!

delimc

Pustaka kelanjutan dibatasi untuk Clojure 1.4.0 (dan 1.3.0). Bagian berdasarkan cl-cont oleh Slava Akhmechet ( http://defmacro.org ) ...

Frank Shearar
sumber
2

Meskipun Clojure tidak memiliki kelanjutan kelas satu atau coroutine bawaan sebagai fitur inti, dimungkinkan untuk mengimplementasikannya sendiri.

Sebagai contoh, core.async adalah pustaka Clojure yang mengimplementasikan model CSP (Concurrent Sequential Processes). Ia menggunakan gomakro untuk mengubah kode di dalam ke mesin negara. Meskipun tidak tepat coroutine per se, itu dapat digunakan untuk menerapkan pola yang sama.

Ada juga pulley.cps , kompiler makro yang saya tulis yang mengubah (via cps/ cps-fnmakro) kode Clojure yang ditulis dalam gaya langsung menjadi gaya kelanjutan-lewat. Sepengetahuan saya, ini adalah program Clojure bertema kelanjutan yang paling lengkap. Ini mendukung pengikatan dinamis, pengecualian, panggilan bolak-balik antara kode asli dan kode yang ditransformasikan (meskipun kelanjutannya tidak dipertahankan di seluruh konteks). Saat ini, hanya kelanjutan yang gagal (yaitu, tradisional call-cc) yang didukung, tetapi saya memiliki rencana untuk mengimplementasikan kelanjutan yang dibatasi di masa depan.

Sementara pulley.cps tidak secara langsung menyediakan coroutine per se, dengan call-ccitu relatif mudah untuk menerapkan Anda sendiri. Bahkan, salah satu contohnya adalah implementasi sederhana dari multitasking koperasi . Ini lebih lanjut dibangun di dalam contoh CSP . Ada juga contoh Ping-Pong , tetapi ini lebih merupakan contoh optimasi panggilan ekor daripada coroutine.

Tentu saja, transformasi semacam ini paling efektif jika diterapkan pada keseluruhan program. Sayangnya, ini tidak dapat dilakukan dengan makro saja, yang dilokalkan. Namun, bahkan transformasi yang dilokalkan pun bisa sangat efektif.

Nathan Davis
sumber
1

Apakah Clojure memiliki kelanjutan atau coroutine untuk melakukan tugas-tugas seperti ping-ponging tanpa stack overflow?

Pertanyaan lama, jadi saya bahkan tidak yakin apakah fitur ini tersedia pada saat itu, tetapi bagi siapa pun yang ingin mengimplementasikan fungsionalitas "ping-pong" apa pun, lihat trampolin !

Saya baru saja menemukannya sebagai jawaban atas pertanyaan saya tentang Gaya Berlanjut Berlanjut yang efisien di Clojure, di sini: /programming/50952443/continuation-passing-style-does-not-seem-to-make-a -difference-in-clojure / 50955276 # 50955276 dan saya pikir itu hanya pekerjaan. Saya sudah mendengarnya beberapa waktu yang lalu, tetapi tidak pernah menyelidiki sepenuhnya. Lebih membodohi saya. Tidak seperti banyak solusi lain yang diusulkan, itu hanya berfungsi .

====== PS. Banyak informasi tutorial online,] di sini ada beberapa yang menurut saya berguna

alex gian
sumber
1
mungkin menghubungkan trampolin untuk menunjuk ke dokumentasi?
esoterik