-
Notifications
You must be signed in to change notification settings - Fork 71
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
Implement foldMap1 for arrays in JavaScript to fuse mapping and folding #202
Implement foldMap1 for arrays in JavaScript to fuse mapping and folding #202
Conversation
I think we should try to avoid introducing more JS code here, for two reasons:
|
AFAICT, there is incentive for improving
Is one function going to make that much of a difference? |
Right, that’s exactly my point; if we just do this in JS then there won’t be much of an incentive to work on STFn (or some other kind of mechanism that alleviates the same issue). It’s not obvious to me that the current implementation is a problem in practice. Yes, even one function is a pain, because it means backend maintainers have to write and test new code in the FFI modules in the backend language that they have to maintain alongside each library. Of course it won’t just be one function if we get into the habit of dropping down to JS whenever there’s a potential performance boost to be gained, too. |
I don't think it would be difficult to write tail-recursively with unsafeIndex, and I feel like you'd get essentially the same thing? |
AFAICT, there is incentive to work on |
I think it’s our job to try to reduce downstream breakage as much as is reasonably possible in the first place, rather than just doing it anyway and waiting for complaints in order to decide whether or not to keep doing it. I don’t think this performance improvement is enough to justify the breakage. Although I think @natefaubion is right that a tail-recursive implementation based on unsafeIndex ought to work, and that gets us the best of both worlds. |
I agree with that. Also, I don't think I was considering your other point with as much weight as I should have: "...it won’t just be one function if we get into the habit of dropping down to JS whenever there’s a potential performance boost to be gained, too." Since we'll be working on ES builds in v0.15.0, could |
I tried implementing this locally. Unfortunately, it doesn't work due to cyclical module dependencies:
|
We could break the cyclical dependency by moving |
Should Array.NonEmpty not have it's own unsafeIndex? |
I don't think we want to move Array.unsafeIndex since there are optimization rules around it in the compiler. We can add Array.NonEmpty.unsafeIndex, but this would be another FFI addition. It's arguable that this function should exist for feature parity with Array, however. If FFI additions are a hard pass, then I think the status quo is the only thing that works for now. |
Would we add that in v0.15.0 when the next round of breaking changes occur? |
Would we add what, specifically? |
I don't think FFI additions should be a hard pass, they just need to be able to justify themselves. I think adding an FFI |
Add |
I think we could add |
Would this break the inliner rules in the compiler? |
Unless the compiler already implements inliner rules for |
Oh, I forgot that NonEmpty already provides an unsafeIndex. In that case I think my vote is to leave things as they are for now. In the longer term I think we should try to stop this kind of awkward situation from happening by a) having some kind of runtime with a defined interface so that alternate backends know what they have to support (and full-featured enough that it can remove most/all of the FFI in core) and b) finding a way of not having the compiler need to know about any downstream code. But these are both fairly big projects. |
Based on the feedback here, I say we close this PR and leave things as is. |
Let’s close this. |
The default implementations of foldMap1 have to map over the array before folding it, but we can avoid to traverse the array twice with a foreign implementation.