Skip to content

Add makeIsDataAsList for generating IsData instances that uses List internally #7121

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

Merged
merged 4 commits into from
Jun 2, 2025

Conversation

SeungheonOh
Copy link
Collaborator

@SeungheonOh SeungheonOh commented May 28, 2025

closes #7115

PlutusTx.IsData.TH in general is rather a mess; there's a ton of unnecessary "helpers" and obfuscation. It would be nice to redo parts of it from scratch since now I introduced a bit of code duplication on top. But perhaps in a separate refactoring PR.

I'll add some more test cases tomorrow

@@ -158,6 +164,7 @@ tests =
, goldenUEval "mono" [plc (Proxy @"mono") (isDataRoundtrip (Mono2 2))]
, goldenUEval "poly" [plc (Proxy @"poly") (isDataRoundtrip (Poly1 (1 :: Integer) (2 :: Integer)))]
, goldenUEval "record" [plc (Proxy @"record") (isDataRoundtrip (MyMonoRecord 1 2))]
, goldenUEval "recordAsList" [plc (Proxy @"record") (isDataRoundtrip (MyMonoRecordAsList 1 2))]
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Need something better than this since goldenUEval doesn't check if given value actually is True value.

Copy link
Contributor

Choose a reason for hiding this comment

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

Let me play a "Devil's advocate":
Now, as the golden file containing a representation of True is in place, you have your check -
If only it starts producing False - you'd get a golden test failure.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Still bad 😅

Copy link
Member

Choose a reason for hiding this comment

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

Is your concern that constr 0 [] could represent something else other than True? True, but highly unlikely.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It should be okay for now, but we've seen representation of Bool changing(with introduction of SOP) and also more importantly, there's no reason to have this as golden at all! Golden from these cases are just purely unnecessary noises

I'll make some changes

@SeungheonOh SeungheonOh requested a review from Unisay May 28, 2025 18:11
@SeungheonOh SeungheonOh added the No Changelog Required Add this to skip the Changelog Check label May 28, 2025
Comment on lines 50 to 52
-- Do not change this to raw integer pattern matching.
-- GHC will inline `equalsEq` and do integer equality by matching
-- them structurally, which the plugin does not know how to handle.
Copy link
Contributor

Choose a reason for hiding this comment

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

Valuable insight 👍🏼

instance P.Eq MyMonoRecordAsList where
{-# INLINEABLE (==) #-}
(MyMonoRecordAsList x1 y1) == (MyMonoRecordAsList x2 y2) = x1 P.== x2 && y1 P.== y2
IsData.makeIsDataAsList ''MyMonoRecordAsList
Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder if its possible to capture resulting syntax in a golden file 🤔

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes, do we want that?

Copy link
Contributor

Choose a reason for hiding this comment

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

@zliu41 wdyt?

Copy link
Member

Choose a reason for hiding this comment

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

Yes - because otherwise there's no evidence that makeIsDataAsList actually uses the List constructor. The existing tests would succeed if it was using Constr.

@zliu41 zliu41 removed the No Changelog Required Add this to skip the Changelog Check label Jun 1, 2025
Copy link
Member

@zliu41 zliu41 left a comment

Choose a reason for hiding this comment

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

This needs a changelog - it's a user-facing change. Also needs a golden test showing that it uses the List constructor. Otherwise looks good.

@@ -158,6 +164,7 @@ tests =
, goldenUEval "mono" [plc (Proxy @"mono") (isDataRoundtrip (Mono2 2))]
, goldenUEval "poly" [plc (Proxy @"poly") (isDataRoundtrip (Poly1 (1 :: Integer) (2 :: Integer)))]
, goldenUEval "record" [plc (Proxy @"record") (isDataRoundtrip (MyMonoRecord 1 2))]
, goldenUEval "recordAsList" [plc (Proxy @"record") (isDataRoundtrip (MyMonoRecordAsList 1 2))]
Copy link
Member

Choose a reason for hiding this comment

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

Is your concern that constr 0 [] could represent something else other than True? True, but highly unlikely.

instance P.Eq MyMonoRecordAsList where
{-# INLINEABLE (==) #-}
(MyMonoRecordAsList x1 y1) == (MyMonoRecordAsList x2 y2) = x1 P.== x2 && y1 P.== y2
IsData.makeIsDataAsList ''MyMonoRecordAsList
Copy link
Member

Choose a reason for hiding this comment

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

Yes - because otherwise there's no evidence that makeIsDataAsList actually uses the List constructor. The existing tests would succeed if it was using Constr.

compiledCodeToHask foo bar baz :: Either String (CompiledCode ())
```
-}
compiledCodeToHask
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@Unisay I made this cute little helper. You might be interested; no need for spamming unsafeApplyCode.

Copy link
Contributor

Choose a reason for hiding this comment

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

I like ergonomics of it but not sure about semantics: does it translate to the Apply constructor in UPLC?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

this is just fancy applyCode and unsafeApplyCode, so it will behave identically to these, which iirc will create Apply node on UPLC.

Perhaps name can be made less confusing. My reasoning for compiledCodeToHask was that it lifts functions in UPLC(CompiledCode (a->b->c)) into functions in Hask(CompiledCode a -> CompiledCode b -> CompiledCode c).

Copy link
Contributor

Choose a reason for hiding this comment

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

If it has the same semantics (we're not substituting UPLC application with Haskell application) then I support it!

Copy link
Member

@zliu41 zliu41 left a comment

Choose a reason for hiding this comment

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

@SeungheonOh Sorry for the confusion but I didn't mean showing the TH splices in the golden files. You can make a pir.golden compiled from converting a small data type to Data, which would show that it uses the List constructor, and that's much simpler than the TH splices.

@SeungheonOh
Copy link
Collaborator Author

@zliu41 Okay, I'll add pir goldens too. But, I think TH splice goldens are still be very helpful as a quick reference point to see how codegen currently behaves. It would be especially useful when we need to make changes later on and my memories on how generated code looks like got faded away.

@zliu41 zliu41 merged commit 8626d8f into master Jun 2, 2025
6 of 7 checks passed
@zliu41 zliu41 deleted the sho/7115 branch June 2, 2025 20:20
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.

IsData helper for list-encoded product types
3 participants