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

[Builtins] Add the 'dropList' builtin #6468

Draft
wants to merge 8 commits into
base: master
Choose a base branch
from
34 changes: 34 additions & 0 deletions plutus-core/plutus-core/src/PlutusCore/Default/Builtins.hs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
-- editorconfig-checker-disable-file
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
Expand Down Expand Up @@ -46,6 +48,10 @@ import Data.Text.Encoding (decodeUtf8', encodeUtf8)
import Flat hiding (from, to)
import Flat.Decoder (Get, dBEBits8)
import Flat.Encoder as Flat (Encoding, NumBits, eBits)
#if MIN_VERSION_base(4,15,0)
import GHC.Num.Integer (Integer (..))
#endif
import GHC.Types (Int (..))
import NoThunks.Class (NoThunks)
import Prettyprinter (viaShow)

Expand Down Expand Up @@ -104,6 +110,7 @@ data DefaultFun
| HeadList
| TailList
| NullList
| DropList
-- Data
-- See Note [Pattern matching on built-in types].
-- It is convenient to have a "choosing" function for a data type that has more than two
Expand Down Expand Up @@ -1557,6 +1564,30 @@ instance uni ~ DefaultUni => ToBuiltinMeaning uni DefaultFun where
nullListDenotation
(runCostingFunOneArgument . paramNullList)

toBuiltinMeaning _semvar DropList =
let dropListDenotation :: Integer -> SomeConstant uni [a] -> BuiltinResult (Opaque val [a])
dropListDenotation i (SomeConstant (Some (ValueOf uniListA xs))) = do
-- See Note [Operational vs structural errors within builtins].
case uniListA of
DefaultUniList _ ->
#if MIN_VERSION_base(4,15,0)
fromValueOf uniListA <$> case i of
IS i# -> pure $ drop (I# i#) xs
IP _ -> case drop maxBound xs of
[] -> pure []
_ ->
throwing _StructuralUnliftingError
"Panic: unreachable clause executed"
IN _ -> pure xs
#else
throwing _StructuralUnliftingError "'dropList' is not supported on GHC-8.10"
#endif
_ -> throwing _StructuralUnliftingError "Expected a list but got something else"
{-# INLINE dropListDenotation #-}
in makeBuiltinMeaning
dropListDenotation
(runCostingFunTwoArguments . unimplementedCostingFun)

-- Data
toBuiltinMeaning _semvar ChooseData =
let chooseDataDenotation :: Data -> a -> a -> a -> a -> a -> a
Expand Down Expand Up @@ -2187,6 +2218,8 @@ instance Flat DefaultFun where
CaseList -> 88
CaseData -> 89

DropList -> 90

decode = go =<< decodeBuiltin
where go 0 = pure AddInteger
go 1 = pure SubtractInteger
Expand Down Expand Up @@ -2278,6 +2311,7 @@ instance Flat DefaultFun where
go 87 = pure ExpModInteger
go 88 = pure CaseList
go 89 = pure CaseData
go 90 = pure DropList
go t = fail $ "Failed to decode builtin tag, got: " ++ show t

size _ n = n + builtinTagWidth
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
all a. integer -> list a -> list a
Original file line number Diff line number Diff line change
Expand Up @@ -146,3 +146,4 @@ isCommutative = \case
CountSetBits -> False
FindFirstSetBit -> False
ExpModInteger -> False
DropList -> False
3 changes: 2 additions & 1 deletion plutus-ledger-api/src/PlutusLedgerApi/Common/Versions.hs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,8 @@ builtinsIntroducedIn = Map.fromList [
]),
((PlutusV3, futurePV), Set.fromList [
ExpModInteger,
CaseList, CaseData
CaseList, CaseData,
DropList
])
]

Expand Down
2 changes: 2 additions & 0 deletions plutus-tx-plugin/src/PlutusTx/Compiler/Builtins.hs
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ builtinNames = [
, 'Builtins.mkNilData
, 'Builtins.mkNilPairData
, 'Builtins.mkCons
, 'Builtins.drop

, ''Builtins.BuiltinData
, 'Builtins.chooseData
Expand Down Expand Up @@ -413,6 +414,7 @@ defineBuiltinTerms = do
PLC.MkNilData -> defineBuiltinInl 'Builtins.mkNilData
PLC.MkNilPairData -> defineBuiltinInl 'Builtins.mkNilPairData
PLC.MkCons -> defineBuiltinInl 'Builtins.mkCons
PLC.DropList -> defineBuiltinInl 'Builtins.drop

-- Data
PLC.ChooseData -> defineBuiltinInl 'Builtins.chooseData
Expand Down
1 change: 1 addition & 0 deletions plutus-tx/src/PlutusTx/Builtins.hs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ module PlutusTx.Builtins (
, headMaybe
, BI.head
, BI.tail
, BI.drop
Copy link
Contributor

Choose a reason for hiding this comment

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

Should this also go in PlutusTx.Prelude? I seem to remember that the contents of that file are kind of random though.

, uncons
, unsafeUncons
-- * Tracing
Expand Down
5 changes: 5 additions & 0 deletions plutus-tx/src/PlutusTx/Builtins/Internal.hs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import Data.Data (Data)
import Data.Foldable qualified as Foldable
import Data.Hashable (Hashable (..))
import Data.Kind (Type)
import Data.List qualified as Haskell
import Data.Text as Text (Text, empty)
import Data.Text.Encoding as Text (decodeUtf8, encodeUtf8)
import GHC.Generics (Generic)
Expand Down Expand Up @@ -408,6 +409,10 @@ chooseList :: BuiltinList a -> b -> b -> b
chooseList (BuiltinList []) b1 _ = b1
chooseList (BuiltinList (_:_)) _ b2 = b2

{-# OPAQUE drop #-}
drop :: Integer -> BuiltinList a -> BuiltinList a
Copy link
Contributor

@kwxm kwxm Oct 30, 2024

Choose a reason for hiding this comment

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

Why not dropList? So that it just replaces the Haskell version with minimal effort from the user?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

For consistency, we also have head (and not headList) and tail (and not tailList) in this file.

drop i (BuiltinList xs) = BuiltinList (Haskell.genericDrop i xs)

{-# OPAQUE caseList' #-}
caseList' :: forall a r . r -> (a -> BuiltinList a -> r) -> BuiltinList a -> r
caseList' nilCase _ (BuiltinList []) = nilCase
Expand Down