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

Add a data-backed list to ScriptContext #6597

Merged
merged 14 commits into from
Nov 11, 2024
Merged

Conversation

ana-pantilie
Copy link
Contributor

@ana-pantilie ana-pantilie commented Oct 25, 2024

Fixes https://github.com/IntersectMBO/plutus-private/issues/60
Fixes https://github.com/IntersectMBO/plutus-private/issues/61

I'm going to migrate both this and AssocMap to Quickcheck in a separate issue.


Pre-submit checklist:

  • Branch
    • Tests are provided (if possible)
    • Commit sequence broadly makes sense
    • Key commits have useful messages
    • Changelog fragments have been written (if appropriate)
    • Relevant tickets are mentioned in commit messages
    • Formatting, PNG optimization, etc. are updated
  • PR
    • (For external contributions) Corresponding issue exists and is linked in the description
    • Targeting master unless this is a cherry-pick backport
    • Self-reviewed the diff
    • Useful pull request description
    • Reviewer requested

B.caseList'
ys
(\h t -> BI.mkCons h (go t ys))
xs
Copy link
Contributor

Choose a reason for hiding this comment

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

You don't need to pass ys around just to return it untouched in the end, right?


{-# INLINEABLE fromSOP #-}
fromSOP :: (ToData a) => [a] -> List a
fromSOP = List . BI.unsafeDataAsList . B.mkList . fmap toBuiltinData
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not explicit recursion to make it a single-pass traversal?

-- TODO: return [] or List?
{-# INLINEABLE findIndices #-}
findIndices :: (UnsafeFromData a) => (a -> Bool) -> List a -> [Integer]
findIndices pred (List l) = go 0 l
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: not a fan of stealing a Haskell Prelude name (pred).

[]
(\h t ->
let h' = unsafeFromBuiltinData h
indices = go (B.addInteger i 1) t
Copy link
Contributor

Choose a reason for hiding this comment

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

Please use addInteger 1 t. Search for "Yoda conditions" on Slack for why that makes any sense at all.


-- TODO: return [] or List?
{-# INLINEABLE findIndices #-}
findIndices :: (UnsafeFromData a) => (a -> Bool) -> List a -> [Integer]
Copy link
Contributor

Choose a reason for hiding this comment

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

Good question... Probably List. What's even the point of returning the SOP version if it has the same performance?


-- TODO: return [] or List?
{-# INLINEABLE mapMaybe #-}
mapMaybe :: (UnsafeFromData a) => (a -> Maybe b) -> List a -> [b]
Copy link
Contributor

@effectfully effectfully Oct 31, 2024

Choose a reason for hiding this comment

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

The

mapMaybe :: (Data -> Maybe Data) -> List a -> List b

version might be useful.

go =
B.caseList'
id
(\_ t -> B.addInteger 1 . go t)
Copy link
Contributor

Choose a reason for hiding this comment

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

I wouldn't be surprised if that actually performs worse than the eta-expanded version.

({cpu: 4224100
| mem: 26500})
Copy link
Contributor

Choose a reason for hiding this comment

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

Impressive.

2285
Copy link
Contributor

Choose a reason for hiding this comment

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

Impressive too.

num <- forAll $ Gen.integral rangeElem
let list = semanticsToList listS
dataList = semanticsToDataList listS
expected = mapS (+ num) listS
Copy link
Contributor

Choose a reason for hiding this comment

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

With QuickCheck you can generate actual functions. hedgehog is probably also capable of that.

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.

I think Data-backed map's toList and fromList should now use Data-backed list.


-- TODO: return [] or List?
{-# INLINEABLE filter #-}
filter :: (UnsafeFromData a) => (a -> Bool) -> List a -> [a]
Copy link
Member

Choose a reason for hiding this comment

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

Converting elements to/from Data is supposed to be extremely cheap, since the a in List a is supposed to be Data-encoded, otherwise it makes little sense to use List a.

I think filter should return List a. Not against adding a filter' that returns SOP. But then, the [a] -> List a version can also be useful. Adding all of these seems excessive.

append (List l) (List l') = List (go l l')
where
go xs ys =
B.caseList'
Copy link
Member

Choose a reason for hiding this comment

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

This will all need to be updated since caseList' isn't usable yet. @effectfully a reminder to back out the change.

Copy link
Contributor

Choose a reason for hiding this comment

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

@effectfully a reminder to back out the change.

Yes, sorry, I remember about it, I just can't stop discussing and reviewing things.

Copy link
Contributor

Choose a reason for hiding this comment

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

This code won't need to be updated though, I'll just make caseList' and others chooseList-based.

fromSOPProgram = $$(compile [|| Data.List.fromSOP ||])

toSOPSpec :: Property
toSOPSpec = property $ do
Copy link
Member

Choose a reason for hiding this comment

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

Seems a lot of repetition in those xyzSpecs that can be factored out.

@ana-pantilie ana-pantilie enabled auto-merge (squash) November 11, 2024 15:50
@ana-pantilie ana-pantilie merged commit b526c79 into master Nov 11, 2024
8 checks passed
@ana-pantilie ana-pantilie deleted the ana/data-backed-list branch November 11, 2024 16:54
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