Arc Forumnew | comments | leaders | submitlogin
Follow up to collect..yield in wart
2 points by akkartik 4742 days ago | 5 comments
I wish I could just reply to http://arclanguage.org/item?id=14278. There I said, "you can't say yield.x instead of (yield x)" This is now fixed.

https://github.com/akkartik/wart/commit/1d2b2eeeab98de4f61b0905587e3553ab762490c

https://github.com/akkartik/wart/commit/be0584f3bf8c4c2d3560151bc5d6a3dea2ab7654

yield is no longer lexically scoped (like the acc in accum acc), so collect and yield can now exist in separate functions. I think this may enable a library of different kinds of generators. You could use collect to build filters over generators and so on.

yield still doesn't lazily generate sequences. In the absence of first-class continuations that would require code-walker-based support for coroutines. (http://common-lisp.net/project/cl-cont)



3 points by rocketnia 4742 days ago | link

I'm a little concerned about the dynamic scoping pattern you're using:

  (mac collect body
    `(with (,$acc nil
            ,$old-yield (symbol-function 'yield))
       (= (symbol-function 'yield) [push _ ,$acc])
       (do ,@body)
       (= (symbol-function 'yield) ,$old-yield)
       (rev ,$acc)))
  (def yield(_) 'yield-outside-collect)
I bet Common Lisp's own dynamic scope support would work just as well, and it would probably be friendlier with conditions and restarts. Here's how it might look:

  (defvar *yield* [])
  (def yield(_) (call *yield* _))
  
  (mac collect body
    `(withs (,$acc nil
             *yield* [push _ ,$acc])
       ,@body
       (rev ,$acc)))
---

"yield still doesn't lazily generate sequences. In the absence of first-class continuations that would require code-walker-based support for coroutines."

Have you considered using threads?

-----

1 point by akkartik 4742 days ago | link

Thanks, that works great!

https://github.com/akkartik/wart/commit/5bcaa378483aec8c6e0e...

I sat on the old ugly approach for a few days before realizing it was keeping me from moving forward. How could I forget defvar?? Anyways, I should have just thrown the crappy code over the wall sooner and gotten your feedback.

---

I briefly considered threads for coroutines[1] but recoiled. I may warm to the idea after agonizing over other options ^_^

[1] http://ryepup.unwashedmeme.com/blog/2010/11/21/coroutines-in...

-----

1 point by rocketnia 4742 days ago | link

"Thanks, that works great!"

* jaw drop*

I had no clue whether your replacement of 'let would work with special variables. If it does, awesome. ^_^

By the way, I used [] for the initial value of * yield* just because I didn't know what you wanted to do there. Actually, it would be amusing for 'yield to drop to the debugger by default and coroutine with the user.

---

"I briefly considered threads for coroutines but recoiled. I may warm to the idea after agonizing over other options ^_^"

I just wanted to make sure the idea was out there in the open. I don't actually have an opinion for or against it. ^^;

-----

1 point by akkartik 4742 days ago | link

Yeah, let is implemented just like in arc - it ends up turning into a lambda expression. I believe defvar handles lambda args as well. In sbcl:

  * (setf a 34)                   ; normal var
  * (defun foo() a)
  * (let ((a 35)) (foo))
  34
  * (funcall (lambda(a) (foo)) 35)
  34

  * (defvar a 34)                 ; special var
  * (let ((a 35)) (foo))
  35
  * (funcall (lambda(a) (foo)) 35)
  35
Does that seem reasonable?

Nesting collect works: https://github.com/akkartik/wart/blob/521a299b5ecf4f9acc2dcd... So that means things are good, right? Can you think of any other test cases?

---

"I just wanted to make sure the idea [coroutines using threads] was out there in the open."

Yeah I'm glad it is so people can chime in on the implications.

-----

2 points by akkartik 4742 days ago | link

I just noticed that queues make accum/collect more efficient.

https://github.com/akkartik/wart/commit/521a299b5ecf4f9acc2d...

It's still going to require the entire sequence to be constructed all at once, but things are now marginally better.

-----