purescript-concur / purescript-concur-react

Concur UI Framework for Purescript
https://purescript-concur.github.io/purescript-concur-react
MIT License
271 stars 17 forks source link

Effects with view #2

Closed anttih closed 6 years ago

anttih commented 6 years ago

It seems that you cannot currently do widget <|> interval 10 where widget renders a view and waits for DOM events and interval is a side effect that blocks some amount of time and then returns a value. I see that in your haskell implementation a side effect is tagged with a view as well enabling this kind of behavior. I think this behavior is crucial for implementing something like your Mario example. Should we tackle this somehow or have I missed something?

Ps. I replaced Eff usage with IO (Aff without the row of effects) in my fork so interval was easy to implement.

Update: interval is Milliseconds -> IO (Widget HTML Unit) so the example is really something like

do
  tick <- liftIO (interval 10)`
  widget <|> tick
ajnsit commented 6 years ago

Yeah, the current implementation doesn't really support asynchronous effects. I'll put in some quick changes to support them so that the interval example can work.

anttih commented 6 years ago

Just to make sure I got my point across: even with IO I wasn't able to make this work. What happens is that widget there won't render anything because WidgetEff doesn't render any view.

ajnsit commented 6 years ago

Right. What it currently implements is only blocking Effects, which block the entire UI. To do anything else, I would need to fork the effect, which didn't make sense until I implemented proper async effects.

ajnsit commented 6 years ago

I implemented this here - https://github.com/ajnsit/purescript-concur/commit/7fb255abf44936a72bbdd21d36280ec63fe4011f. There is one pending bug (I wasn't able to figure out how to fork computations with Aff), but it works otherwise.

anttih commented 6 years ago

Nice!

You can fork with forkAff.

anttih commented 6 years ago

The Free datatype is not used there.

Edit: in your code I mean.

ajnsit commented 6 years ago

I'm effectively using a simplistic Free monad, even though I didn't use the Free datatype from purescript-free, because we didn't need the sequential bind optimisation which was complicating the implementation.

Also, I discovered a bug in the implementation, thanks to the statefulness of react. When I have a couple of hours, I'll probably just throw out the current async implementation and implement something more correct, that does not depend on react's state. At that time I would probably also fall back on using purescript-free.

ajnsit commented 6 years ago

Keeping this issue open until a correct async implementation is in place.

anttih commented 6 years ago

I been working on making my halogen-vdom implementation async as well. Just got it somewhat working last night. I followed your approach you had in the haskell version. I may as well share it just to at least get some feedback.

https://gist.github.com/anttih/411e992335dfc3517ba243c8e8667661

I'm hoping we can share the core types at some point.

ajnsit commented 6 years ago

Update: I have started working on this in this PR - https://github.com/ajnsit/purescript-concur/pull/4

ajnsit commented 6 years ago

Okay, asynchronous effects seem to be working properly now. You can check the examples - https://ajnsit.github.io/purescript-concur/.

ajnsit commented 6 years ago

BTW I will soon break out the common code (in https://github.com/ajnsit/purescript-concur/blob/master/src/Concur/Core.purs) into its own package (purescript-concur-core). Hopefully it should be fully reusable for the halogen-vdom implementation. Let me know if it isn't.

anttih commented 6 years ago

This is great! I've been eyeing on your implementation and I think it should work with the vdom stuff. Hopefully I'll get to try this out in a few days.