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

PLT-1539: Use foldr for Foldable #5179

Merged
merged 3 commits into from
Feb 28, 2023
Merged

PLT-1539: Use foldr for Foldable #5179

merged 3 commits into from
Feb 28, 2023

Conversation

zliu41
Copy link
Member

@zliu41 zliu41 commented Feb 27, 2023

Suggested by @effectfully in #5168 (comment)

This doesn't make any and friends short-circuit, but does reduce the cost (sometimes dramatically) across the board, even more so than this suggestion for improving foldMap.

@michaelpj
Copy link
Contributor

Seems good to me. I doubt anyone is defining their own Foldable instances, and if they are it's an easy fix.

any p = getSum #. foldMap (Sum #. p)
any p = foldr f False
where
f a acc = p a || acc
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Try inlining f manually. base has a reason for pulling it out (and marking with INLINE, which you also might try), but we at the moment probably don't and there's a chance it would be sufficient for GHC not to create a thunk for acc.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've tried inlining f and || manually, as well as oneShot, inline and {-# INLINE #-}, but without telling the GHC to run the inliner (sm_inline = False), nothing I've tried managed to make GHC turn

(\a acc -> if p a then True else acc) x (go xs)

into

if p x then True else go xs

We do run GHC's pre-inliner, but apparently that doesn't do it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to propagate the INLINE, then it might work.

Comment on lines +15 to +23
let !acc : Bool = go xs in Bool_match
(ifThenElse
{Bool}
(lessThanEqualsInteger 1 x)
False True) {all dead. Bool}
(/\dead -> acc) (/\dead ->
False)
{all dead. dead})
{all dead. dead}
Copy link
Contributor

@effectfully effectfully Feb 27, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So everything works just fine except GHC makes a thunk for go xs and pulls it out of ifThenElse. And we interpret it as a strict binding.

where
go = \case
[] -> z
x : xs -> f x (go xs)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about oneShot (f x) (go xs) then? I know we probably shouldn't try to do fancy things to get efficient compilation, because it's way too unreliable, but maybe a few general policies here and there would be fine?

@zliu41 zliu41 merged commit 1eb6fca into master Feb 28, 2023
@zliu41 zliu41 deleted the zliu41/foldr branch February 28, 2023 13:54
3 (c
in
letrec !go : List integer -> Bool
= \(ds : List integer) ->
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prettyprinting improvement: always put the binding on the next line so we can indent it just 2 instead of 7 for letrec

{integer} ds {all dead. Bool} (/\dead -> True)
(\(x : integer) (xs : List integer) ->
/\dead ->
let !acc : Bool = go xs in Bool_match
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why didn't we break at the in here?

in
let !eta : List integer
= (let a = List integer in \(c : integer -> a -> a) (n : a) ->
c
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is hilarious but I'm not sure what we could do better

@zliu41
Copy link
Member Author

zliu41 commented Feb 28, 2023

I'll capture these prettyprinter improvements in a ticket.

I also noticed

data (Monoid :: * -> *) a | Monoid_match where
    CConsMonoid : (\a -> a -> a -> a) a -> a -> Monoid a

That seems messed up.

@michaelpj
Copy link
Contributor

I just went ahead and did it: #5184

Not sure what's up with the CConsMonoid thing though!

v0d1ch pushed a commit to v0d1ch/plutus that referenced this pull request Dec 6, 2024
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.

3 participants