jwiegley / emacs-async

Simple library for asynchronous processing in Emacs
GNU General Public License v3.0
832 stars 68 forks source link

Some comments about async-let #68

Closed thierryvolpiatto closed 7 years ago

thierryvolpiatto commented 7 years ago

Hi John, just tried async-let, it is very nice, thanks. Some comments though:

(async-let ((x (lambda () "hello"))
            (y (lambda () "world")))
  (message "%s %s" x y))

it would be nice if it could take any value, e.g:

(async-let ((x "hello")
            (y "world"))
  (message "%s %s" x y))

This can be done by wrapping the binding value in a lambda, something like this:


(defmacro async-let (bindings forms)
  "Implements `let', but each binding is established asynchronously.
[...]"
  (declare (indent 1))
  (async--fold-left
   (lambda (acc binding)
     (let ((fun (pcase (cadr binding)
                  ((and (pred functionp) f) f)
                  (f `(lambda () ,f)))))
       `(async-start ,fun
                     (lambda (,(car binding))
                       ,acc))))
     forms (reverse bindings)))

we must write:


(async-let ((x (lambda () "hello"))
            (y (lambda () "world")))
  (progn (+ 1 2)
         (message "%s %s" x y)))

Otherwise it is cool, it even wait the result of the longest binding to compute before sending result without hanging emacs.

(async-let ((x (prog1 (car '("hello")) (sit-for 5)))
            (y (car '("world"))))
  (progn (message "%s %s" x y)))

Thanks.

BTW I have updated elpa.

thierryvolpiatto commented 7 years ago

All issue are more or less fixed in PR #69, I note also that, as a bonus, async-let have the effect of let*, this is working (with #69 changes applied):

(async-let ((x (* 5 2))
            (y (+ x 4))
            (z (+ x y)))
  (message "%s %s = %d" x y z))