Apa perbedaan masa depan dan janji Clojure?


86

Baik masa depan maupun janji memblokir sampai mereka menghitung nilainya, jadi apa perbedaan di antara keduanya?


8
Saya tidak yakin mengapa -1 pada pertanyaan, atau apakah pertanyaan yang Anda tidak tahu jawabannya sebelum menanyakan hal-hal buruk?
HANYA PENDAPAT SAYA yang benar

Saya tidak -1 salah satu jawaban ?? Bagaimana kita bisa tahu siapa yang memberikan -1 pada pertanyaan atau jawaban?
yazz.com

Anda dan saya tidak bisa, Zubair. Saya hanya ingin tahu siapa yang memberi -1 pada pertanyaan Anda karena itu pertanyaan yang sangat masuk akal untuk ditanyakan dan pasti sesuai topik untuk SO.
HANYA PENDAPAT SAYA yang benar

Jawaban:


54

Menjawab dalam istilah Clojure, berikut adalah beberapa contoh dari screencast Sean Devlin :

(def a-promise (promise))
(deliver a-promise :fred)

(def f (future (some-sexp)))
(deref f)

Perhatikan bahwa di promise Anda secara eksplisit mengirimkan nilai yang Anda pilih dalam komputasi nanti ( :freddalam kasus ini). Di sisi lain, masa depan sedang dikonsumsi di tempat yang sama dengan tempat ia diciptakan. Ini some-exprmungkin diluncurkan di belakang layar dan dihitung bersama-sama (pada akhirnya), tetapi jika tetap tidak dievaluasi pada saat itu diakses, blok utas sampai tersedia.


diedit untuk menambahkan

Untuk membantu membedakan lebih jauh antara janji dan masa depan, perhatikan hal berikut:

janji

  1. Anda membuat promise. Objek promise tersebut sekarang dapat diteruskan ke utas mana pun.
  2. Anda melanjutkan dengan perhitungan. Ini bisa menjadi kalkulasi yang sangat rumit yang melibatkan efek samping, mengunduh data, input pengguna, akses database, janji lain - apa pun yang Anda suka. Kode tersebut akan terlihat sangat mirip dengan kode jalur utama Anda di program apa pun.
  3. Setelah selesai, Anda bisa delivermendapatkan hasilnya ke objek promise tersebut.
  4. Item apa pun yang mencoba derefmemenuhi janji Anda sebelum Anda selesai menghitung akan diblokir sampai Anda selesai. Setelah Anda selesai dan Anda telah delivermenepati janjinya, janji tersebut tidak akan menghalangi lagi.

masa depan

  1. Anda menciptakan masa depan Anda. Bagian dari masa depan Anda adalah ekspresi perhitungan.
  2. Masa depan mungkin atau mungkin tidak dijalankan secara bersamaan. Itu bisa diberi utas, mungkin dari kolam. Itu hanya bisa menunggu dan tidak melakukan apa-apa. Dari sudut pandang Anda , Anda tidak bisa membedakannya .
  3. Pada titik tertentu Anda (atau utas lainnya) derefadalah masa depan. Jika kalkulasi sudah selesai, Anda mendapatkan hasilnya. Jika belum selesai, Anda memblokir hingga selesai. (Agaknya jika belum dimulai, derefartinya ia mulai dieksekusi, tetapi ini juga tidak dijamin.)

Meskipun Anda bisa membuat ekspresi di masa mendatang serumit kode yang mengikuti pembuatan sebuah promise, itu meragukan yang diinginkan. Ini berarti bahwa masa depan benar-benar lebih cocok untuk penghitungan cepat dan latar belakang sementara promise benar-benar lebih cocok untuk jalur eksekusi yang besar dan rumit. Juga, janji tampaknya, dalam hal perhitungan yang tersedia, sedikit lebih fleksibel dan berorientasi pada pembuat janji yang melakukan pekerjaan dan benang lain yang menuai panen. Futures lebih berorientasi pada memulai utas secara otomatis (tanpa overhead yang jelek dan rawan kesalahan) dan melanjutkan dengan hal-hal lain sampai Anda - utas yang berasal - membutuhkan hasil.


Tetapi Anda dapat memiliki blok kaluslasi apa pun sampai janji ATAU masa depan selesai. yaitu: (@a + @b) akan bekerja dengan cara yang sama dengan masa depan dan janji
yazz.com

2
Sebuah janji memungkinkan lebih banyak fleksibilitas menurut saya. Saya membuat janji. Saya menyampaikan janji itu ke utas lain. Saya kemudian dapat melakukan banyak kalkulasi rumit termasuk menunggu I / O, mengunduh data dari Internet, menunggu input pengguna, dll. Setelah semua selesai, saya memenuhi janji dengan nilai yang dihasilkan. Masa depan mencakup satu ekspresi S. Kurasa, itu bisa menjadi ekspresi-S yang sangat, sangat rumit, tapi akan sedikit ... kaku di sana. Selain itu masa depan melakukan tugasnya secara otomatis di utas (atau kumpulan). Melakukan hal yang sama dengan janji berarti lebih banyak pekerjaan.
HANYA PENDAPAT SAYA yang benar

FWIW karena satu ekspresi-s bisa menjadi panggilan ke jalur kode arbitrer, ini belum tentu tentang berapa banyak kode yang bisa Anda masukkan ke dalam ekspresi. Jadi, alih-alih mengatakan janji itu "lebih fleksibel", saya akan mengatakan tujuannya hanya berbeda. Jika tidak, mengapa harus keduanya?
Geoff

2
Sekadar catatan, tubuh futurepanggilan bisa menyertakan N sexprs.
vemv

Penjelasan ini harus menjadi bagian dari Clojure Doc
Piyush Katariya

25

Baik Future dan Promise adalah mekanisme untuk mengkomunikasikan hasil komputasi asinkron dari Produser ke Konsumen.

Dalam kasus Future , komputasi ditentukan pada saat pembuatan Future dan eksekusi asinkron dimulai "ASAP". Ia juga "tahu" cara menelurkan komputasi asinkron.

Dalam kasus Promise the computation , waktu mulai dan [kemungkinan] pemanggilan asynchronous dipisahkan dari mekanisme pengiriman. Jika hasil komputasi tersedia, Produser harus memanggil deliversecara eksplisit, yang juga berarti Produser mengontrol kapan hasil tersedia.

Untuk Promises Clojure membuat kesalahan desain dengan menggunakan objek yang sama (hasil promisepanggilan) untuk menghasilkan ( deliver) dan mengkonsumsi ( deref) hasil komputasi . Ini adalah dua kemampuan yang sangat berbeda dan harus diperlakukan seperti itu.


@oskarkv Misalkan Anda telah membuat janji dan memberikannya kepada 3 klien. Tidak ada yang menghalangi salah satu klien untuk menyelesaikannya dengan hasil palsu dan menandakannya ke dua klien lain. Ditambah lagi, Anda tidak akan dapat memenuhi janji ini lagi. Sebaliknya, jika Anda memiliki pasangan promise + resolver, berjanji kepada klien Anda dan menyimpan resolver untuk diri Anda sendiri, skenario ini menjadi tidak mungkin. Untuk info lebih lanjut, istilah pencarian yang disarankan adalah "kontrol akses berbasis kemampuan" dan "keamanan berbasis kemampuan".
Dimagog

1
Saya tidak yakin apakah menggabungkan keamanan ke jenis referensi sederhana seperti itu (lihat implnya) sebagaimana mestinya promise. Konsumen 'jahat' jarang; tidak ada yang menghentikan Anda untuk membangun abstraksi Anda sendiri di atas janji.
vemv

8
Ini bukan tentang keamanan, kebetulan pemrograman berbasis kemampuan sering dijelaskan dalam kaitannya dengan keamanan. Di sini semuanya tentang kebenaran kode. Istilah yang sering digunakan adalah "benar menurut konstruksi" dan pertanyaannya adalah "dapatkah Anda membuat program yang salah"? Bukan sengaja, tapi karena kecelakaan. Dengan satu objek Promise Anda bisa, sedangkan dengan dua objek terpisah Anda tidak bisa.
Dimagog

Tidak ada yang menghentikan Anda untuk membalas janji yang tidak dapat dipenuhi, jika itu yang Anda inginkan: (defn undeliverable-promise [] (let [p (promise)] (reify clojure.lang.IDeref (deref [_] (deref p)) clojure.lang.IBlockingDeref (deref [_ ms val] (deref p ms val)) clojure.lang.IPending (isRealized [_] (.isRealized p)) clojure.lang.IFn (invoke [_ _] nil))))
tapichu

Menunjukkan perbedaan bagaimana mekanisme komputasi dipisahkan membuat posting ini menjadi penjelasan yang sangat ringkas. Terima kasih!
synthomat

3

Sudah ada jawaban yang sangat bagus jadi hanya tambahkan ringkasan "cara menggunakan":

Kedua

Membuat janji atau masa depan mengembalikan referensi dengan segera. Referensi ini memblokir di @ / deref hingga hasil komputasi disediakan oleh thread lain.

Masa depan

Saat menciptakan masa depan, Anda memberikan pekerjaan sinkron yang harus diselesaikan. Ini dieksekusi di utas dari kumpulan tak terbatas khusus.

Janji

Anda tidak memberikan argumen saat membuat janji. Referensi harus diteruskan ke utas 'pengguna' lain yang akan delivermenjadi hasilnya.


1

Dalam Clojure, promise, future, dan delayadalah janji-seperti objek. Mereka semua mewakili perhitungan yang dapat ditunggu klien dengan menggunakan deref(atau @). Klien menggunakan kembali hasilnya, sehingga komputasi tidak dijalankan beberapa kali.

Mereka berbeda dalam cara penghitungan dilakukan:

  • futureakan memulai komputasi di thread pekerja yang berbeda. derefakan memblokir sampai hasilnya siap.

  • delay akan melakukan komputasi dengan malas, saat klien pertama menggunakan deref , atau force.

  • promisemenawarkan fleksibilitas paling besar, karena hasilnya dikirimkan dengan cara kustom apa pun dengan menggunakan deliver. Anda menggunakannya saat tidak ada futureatau delaycocok dengan kasus penggunaan Anda.


-4

Pertama, a Promiseadalah a Future. Saya rasa Anda ingin mengetahui perbedaan antara a Promisedan aFutureTask .

SEBUAH Future mewakili nilai yang saat ini tidak diketahui tetapi akan diketahui di masa mendatang.

SEBUAH FutureTask mewakili hasil komputasi yang akan terjadi di masa depan (mungkin di beberapa kumpulan thread). Ketika Anda mencoba mengakses hasilnya, jika komputasi belum terjadi, ia memblokir. Jika tidak, hasilnya segera dikembalikan. Tidak ada pihak lain yang terlibat dalam penghitungan hasil karena penghitungannya ditentukan sebelumnya oleh Anda.

A Promisemerupakan hasil yang akan diberikan oleh pihak yang berjanji kepada pihak yang dijanjikan di masa mendatang. Dalam hal ini Anda adalah yang dijanjikan dan pihak yang berjanji adalah orang yang memberi Anda Promiseobjek tersebut. Mirip dengan FutureTask, jika Anda mencoba mengakses hasil sebelum Promiseterpenuhi, itu akan diblokir sampai pemberi janji memenuhi Promise. Setelah Promiseterpenuhi, Anda mendapatkan nilai yang sama selalu dan segera. Tidak seperti FutureTask, ada pihak lain yang terlibat di sini, yang membuat Promise. Bahwa pihak lain bertanggung jawab untuk melakukan penghitungan dan pemenuhan Promise.

Dalam artian, a FutureTaskadalah PromiseAnda yang dibuat untuk diri sendiri.


Apakah Anda Yakin Sebuah Janji adalah Masa Depan? saya tidak dapat menemukan bahwa itu mengimplementasikan antarmuka. github.com/richhickey/clojure/blob/…
Mikael Sundberg

maaf saya salah tekan enter. Pertanyaan saya diubah
Mikael Sundberg

Jawaban saya dalam pengertian umum, bukan khusus Clojure.
Abhinav Sarkar

9
Menjawab pertanyaan tentang Clojure dengan kode Java sepertinya agak aneh.
HANYA PENDAPAT SAYA yang benar
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.