Skip to content
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

generic generator runtimes #2

Open
joshrtay opened this issue Feb 4, 2016 · 4 comments
Open

generic generator runtimes #2

joshrtay opened this issue Feb 4, 2016 · 4 comments

Comments

@joshrtay
Copy link

joshrtay commented Feb 4, 2016

Just created something really similar called koax. Would love to get your thoughts.

@youknowriad
Copy link
Owner

Hi,

I like some of the ideas in koax :

Using the term middleware instead of 'control' is good, people (from redux and express/koa world) can easily understand its usecase and the fact that is a concept that allow to extend the runtime.

In my implementation, I've used simple functions to define 'middlewares' with some callbacks, but having multiple callbacks can be difficult to get for users (the differences between each callback). Using generators like you did can be a good alternative. While I've not a fixed idea about this yet, maybe we could try this to have the simplest API possible.

I'm not sure but in your implementation, I think there might be some limitations, because of the fact that you traverse middleware in a linear way and dont loop over them in each yield.

say you have a middleware handling a generator that returns a promise, and another one handling promises that returns generators, it's kind of hard to reuse the generator middleware in the promise middleware to get the "leaf" value. (I dont know if this is clear enough).

I also find the "functor" concept a little bit confusing.

I have some questions about handling errors in the KOAX.

@joshrtay
Copy link
Author

joshrtay commented Feb 4, 2016

So i'm not sure I completely understand your question about the middleware implementation. But let me see if I can clarify.

That's essentially correct - the middleware is traversed in a linear fashion, ending the traverse when a middleware returns a value other than next. However, Koax actually does loop over the entire middleware stack with each yield. yield starts a new traverse of the middleware stack with the value provided used as the action in the traverse and the return value of the traverse "yielded". In fact, the following two examples are equivalent:

let app = koax()

app.use(function * (action, next) {
  if (action === 'qux') return yield 'foo'
  else return 'woot'
})
let app = koax()

app.use(function * (action, next) {
  if (action === 'qux') return yield app('foo')
  else return 'woot'
})

It's also important to note that at the top of the middleware stack there is implicit middleware that handles promises, arrays, generators, and functions.

Functors are best not to worry about. Basically it's a way of customizing how data types should be resolved and yielded. You can add a map function to any value that is dispatched to customize how it will be processed. Arrays for example, inherently map over each value in the array, so when an array is yielded every value is dispatched to the middleware stack before being resolved. This leads to the behavior you would expect.

Let me know when you've formulated your questions about errors. I haven't really thought about them too much yet. Shouldn't be too different from the way the co handles them.

@joshrtay
Copy link
Author

joshrtay commented Feb 5, 2016

It might be easies to just look at the code. @koax/compose handles the traversing and @koax/bind adds the middleware layer that handles the promises, arrays, and generators as well as sets up the recursive yields.

@youknowriad
Copy link
Owner

I see, so that answers my question about traversing middlewares. I'm curious to see how these things will evolve and how folks would get to deal with them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants