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

And undocumented causality loop in layout computation #83

Open
deepfire opened this issue Sep 23, 2024 · 5 comments
Open

And undocumented causality loop in layout computation #83

deepfire opened this issue Sep 23, 2024 · 5 comments

Comments

@deepfire
Copy link

deepfire commented Sep 23, 2024

The following is not a causality loop:

      displayHeight >>= sample . current             

..but this one is:

      tile (fixed 1) $ displayHeight >>= sample . current

I guess this can be somewhat surprising to the user, since the semantics are not exactly explained in the documentation.

@cgibbard
Copy link
Contributor

cgibbard commented Sep 23, 2024

As a general rule, one should usually avoid sample in any widget code (not only here, but in reflex-dom as well), because it's strict in a way which interacts poorly with the way we use recursion to order widgets visually. It can be quite frustrating, because things will often work fine until you go and use your widget inside a larger application and suddenly get a mysterious causality loop at runtime coming from a sample that's a few layers down.

It's kind of an accident of the way they get constructed that the widget monads have MonadSample instances, and it's possible we ought to find a way to simply disable those in ordinary widget code. (The correct and safe place to use sample is typically inside the corresponding push/pull monads.)

@deepfire
Copy link
Author

It can be quite frustrating, because things will often work fine until you go and use your widget inside a larger application and suddenly get a mysterious causality loop at runtime coming from a sample that's a few layers down.

That is exactly my experience -- thank you for the relief of not being alone in the suffering! : -)

@cgibbard
Copy link
Contributor

If you have a Dynamic and want to use its value from the widget code, usually you want to first make sure that the Dynamic is passed down as far as reasonable to the widget that it ought to have an impact on, and then possibly use dyn to switch widgets, if the whole structure of the widget is meant to change based on the value, or, more ideally, you just process it into other Dynamics and such (e.g. using fmap) that plug directly into the primitive widgets, for example, if some text or colours are meant to change based on it.

@deepfire
Copy link
Author

deepfire commented Sep 23, 2024

@cgibbard, by the way, I have hoogled for dyn, yet alas to no avail:

hoogle --count=1000 dyn | grep -w dyn
Language.Haskell.TH.Lib dyn :: Quote m => String -> m Exp
Language.Haskell.TH.Lib.Internal dyn :: Quote m => String -> m Exp

@cgibbard
Copy link
Contributor

Apologies, I was thinking of https://hackage.haskell.org/package/reflex-dom-core-0.8.1.0/docs/Reflex-Dom-Widget-Basic.html#v:dyn

which for some reason is exposed in Reflex as networkView (this whole module is weirdly named, these functions have nothing to do with networks): https://hackage.haskell.org/package/reflex-0.9.3.0/docs/Reflex-Network.html

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

No branches or pull requests

2 participants