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

Live dangerously with never #41

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open

Live dangerously with never #41

wants to merge 1 commit into from

Conversation

treeowl
Copy link

@treeowl treeowl commented Aug 27, 2017

Implement never by tying a recursive knot and then using
unsafeCoerce. This gets rid of all its Effects. It's also
a bit scary.

Implement `never` by tying a recursive knot and then using
`unsafeCoerce`. This gets rid of all its `Effect`s. It's also
a bit scary.
@treeowl
Copy link
Author

treeowl commented Aug 27, 2017

A more definitely safe way to reduce, but not eliminate, the monadic junk in never:

never =  fix $ Step . pure . Step . pure . Step . pure . Step . pure . ... . Effect . return

I'm just a bit worried about building a long chain of pointers to follow, and also about what a CPU's branch predictor will think about this sort of stop-start thing. It might be worth benchmarking.

@treeowl
Copy link
Author

treeowl commented Aug 27, 2017

BTW, I'm not at all sure this is actually a good thing to do. never likely isn't a performance-critical function, and this implementation is utterly wild and unsupported. I mostly wanted to see if it was even possible. But if you want it, here it is.

@ocharles
Copy link

I can't say I'm particularly in support of this. Seems like clever for clever's sake. If it could at least be verified with a benchmark, I'd be more inclined.

@treeowl
Copy link
Author

treeowl commented Sep 7, 2017

@ocharles I think you're right. But it would be worth thinking about whether the Step constructor should really be lazy anyway. I'm always a bit uncomfortable about strict polymorphic fields. Stream ((->) a) forces the values of functions, which perversely distinguishes _|_ from const _|_ and plays unpredictably with GHC's eta expansion. Now that type (the type of stream sinks) doesn't really seem too important in this package, but I still think it's worth considering. It would always be possible to offer strict operations even with a lazy constructor, although getting it right requires some care and there might be (small?) performance regressions.

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

Successfully merging this pull request may close these issues.

2 participants