-
Notifications
You must be signed in to change notification settings - Fork 50
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
return within dolist did not return #241
Comments
|
Could be solved by using
However, this would lead to inefficiency, and therefore is not recommended.
Alternatively, we could check if
However, this wouldn't work for cases like |
In 2.eus$ (pprint (macroexpand '(dolist (i '(1 2 3)) (return t))))
(let
((i nil) (#:dolist60 '(1 2 3)))
nil
(while #:dolist60 (setq i (pop #:dolist60)) (return t))
nil) In * (pprint (macroexpand '(dolist (i '(1 2 3)) (if (eq i 2) (return t)))))
(BLOCK NIL
(LET ((#:N-LIST466 '(1 2 3)))
(TAGBODY
#:START467
(UNLESS (ENDP #:N-LIST466)
(LET ((I (TRULY-THE (MEMBER 3 2 1) (CAR #:N-LIST466))))
(SETQ #:N-LIST466 (CDR #:N-LIST466))
(TAGBODY
(IF (EQ I 2)
(RETURN T))))
(GO #:START467)))) The original problem is that looping block is not returned as the return value of how about if we implement like below?: (block nil
(let
((i nil) (#:dolist60 '(1 2 3)))
nil
(TAGBODY
#:START467
(UNLESS (ENDP #:dolist60)
(setq i (pop #:dolist60))
(IF (EQ I 2)
(RETURN T))))
(GO #:START467)))) |
I wrote a simple script for comparison: #!/usr/bin/env roseus
;; dolist-test.l
;; Author: furushchev <[email protected]>
(defun iota (n)
(let ((l (make-sequence cons n)))
(dotimes (i n)
(setf (elt l i) i))
l))
(pprint (macroexpand '(dolist (i (iota 10000)))))
(bench (dolist (i (iota 10000))))
(dolist (i (iota 5)) (print i))
(defmacro dolist (vars &rest forms)
(let ((lists (gensym "DOLIST"))
(loop-tag (gensym "DOLIST"))
(maybe-decl (car forms)))
(if (and (consp maybe-decl) (eq (car maybe-decl) 'declare))
(setq forms (cdr forms))
(setq maybe-decl nil))
`(block nil
(let ((,(car vars) nil)
(,lists ,(cadr vars)))
,maybe-decl
(tagbody ,loop-tag
(unless (endp ,lists)
(setq ,(car vars) (pop ,lists))
,@forms
(go ,loop-tag)))
,(caddr vars)
))))
(pprint (macroexpand '(dolist (i (iota 10000)))))
(bench (dolist (i (iota 10000))))
(dolist (i (iota 5)) (print i)) ((i nil) (#:dolist353 (iota 10000)))
nil
(while #:dolist353 (setq i (pop #:dolist353)))
nil)
;; time -> 0.165225[s]
0
1
2
3
4
(block
nil
(let
((i nil) (#:dolist10367 (iota 10000)))
nil
(tagbody
#:dolist10368
(unless
(endp #:dolist10367)
(setq i (pop #:dolist10367))
(go #:dolist10368)))))
;; time -> 0.14457[s]
0
1
2
3
4 It can be even more efficient 🥇 |
Summarized on gist.
Hmm, |
Testing With the new
Currently:
Changes involve:
Fails in new implementation are caused by problems with |
…do-external-symbols (euslisp#241)" This reverts commit b9f3b4b.
…do-external-symbols (euslisp#241)" This reverts commit b9f3b4b.
…do-external-symbols (euslisp#241)" This reverts commit b9f3b4b.
…do-external-symbols (euslisp#241)" This reverts commit b9f3b4b.
from @Affonso-Gui
The text was updated successfully, but these errors were encountered: