-
Notifications
You must be signed in to change notification settings - Fork 483
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
Make the case arguments of matching functions in PlutusTx.Bulitins non-strict #5896
Conversation
No, I don't agree with this. It has always been this way, and they just have exactly the caveat that if you want to delay evaluation of one of the cases you need to match on |
We should perhaps write some comment that we should not use (~) in builtins and internals. |
Regardless of the final decision I think that we should provide unit tests that assert effects of strictness annotations either way, analogously to how lazyness/strictness in boolean operator |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great catch. But this is one more argument in favor of Plutus Tx being weird.
120 21253 (129.7%) 8449247912 (84.5%) 4768782 (34.1%) | ||
130 22980 (140.3%) 9152916312 (91.5%) 5164612 (36.9%) | ||
140 24707 (150.8%) 9856584712 (98.6%) 5560442 (39.7%) | ||
150 26434 (161.3%) 10560253112 (105.6%) 5956272 (42.5%) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What??? This is a ridiculous optimization of memory usage.
!unsafeDataAsB : data -> bytestring = unBData | ||
!unsafeDataAsI : data -> integer = unIData | ||
!unsafeDataAsList : data -> list data = unListData | ||
!unsafeDataAsMap : data -> list (pair data data) = unMapData |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why aren't those getting inlined?
let | ||
!ds : list data = unsafeDataAsList d | ||
in | ||
Nothing {integer}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good thing about pattern matching builtins is that they make this not only faster, but also quite shorter.
@@ -385,7 +385,7 @@ encodeUtf8 = BI.encodeUtf8 | |||
|
|||
{-# INLINABLE matchList #-} | |||
matchList :: forall a r . BI.BuiltinList a -> r -> (a -> BI.BuiltinList a -> r) -> r | |||
matchList l nilCase consCase = BI.chooseList l (const nilCase) (\_ -> consCase (BI.head l) (BI.tail l)) () | |||
matchList l ~nilCase ~consCase = BI.chooseList l (const nilCase) (\_ -> consCase (BI.head l) (BI.tail l)) () |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here we explicitly rely on GHC inlining this definition for us. Can we instead make sure to inline it ourselves (even though it's semantics-changing)? Is there a general rule? How many other such cases are we missing?
It sucks that we don't want GHC to touch our code much (because it doesn't understand the semantics), while at the time we want to rely on it in some cases.
I fully agree with you. But I agree with 53.2% -> 42.5% of max MEM even more. |
I think this is just a path to making it totally impossible to reason about Plutus Tx code. I reluctantly agreed with the |
@michaelpj Right, adding |
And to the haddock of every single strict function we expose? Perhaps these are especially likely to trip people up, IDK 🤷 |
I think so - implementing |
I agree with all of that. But:
If we can reliably reason about Plutus Tx code right now, then I'm not so sure we should do what we do here indeed. |
@effectfully What you said is the imo the biggest and most annoying problem with Plutus Tx. And I don't see how we can fix it, outside of introducing lazy evaluation for Plutus Core, so that GHC's transformations become valid from Plutus Tx point of view. That said, I think we can view Plutus Tx as two different subsets of Haskell:
I think we should try and make the second subset as large as possible and encourage people to write Plutus Tx using the second subset. What I did in this PR (adding |
Dunno how this went unnoticed for so long, but obviously the case arguments shouldn't be strict.