-
Notifications
You must be signed in to change notification settings - Fork 496
[Experiment] Let/Bind
#7351
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
base: master
Are you sure you want to change the base?
[Experiment] Let/Bind
#7351
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| {-# LANGUAGE DataKinds #-} | ||
| {-# LANGUAGE OverloadedStrings #-} | ||
| {-# LANGUAGE RankNTypes #-} | ||
| {-# LANGUAGE TypeOperators #-} | ||
|
|
||
| module PlutusCore.Builtin.Let where | ||
|
|
||
| import PlutusCore.Builtin.KnownType (Spine) | ||
| import PlutusCore.Core.Type (Type, UniOf) | ||
| import PlutusCore.Name.Unique (TyName) | ||
|
|
||
| import Control.DeepSeq (NFData (..), rwhnf) | ||
| import Data.Default.Class (Default (..)) | ||
| import Data.Text (Text) | ||
| import Data.Vector (Vector) | ||
| import NoThunks.Class | ||
| import Text.PrettyBy (display) | ||
| import Universe | ||
|
|
||
|
|
||
| class LetBuiltin uni where | ||
| -- | Given a constant with its type tag and a vector of branches, choose the appropriate branch | ||
| -- or fail if the constant doesn't correspond to any of the branches (or casing on constants of | ||
| -- this type isn't supported at all). | ||
| letBuiltin | ||
| :: Some (ValueOf uni) | ||
| -> Either Text [Some (ValueOf uni)] | ||
|
|
||
| data LeterBuiltin uni = LeterBuiltin | ||
| { unLeterBuiltin :: !(Some (ValueOf uni) -> Either Text [Some (ValueOf uni)]) | ||
| } | ||
|
|
||
| instance NFData (LeterBuiltin uni) where | ||
| rnf = rwhnf | ||
|
|
||
| deriving via OnlyCheckWhnfNamed "PlutusCore.Builtin.Case.LeterBuiltin" (LeterBuiltin uni) | ||
| instance NoThunks (LeterBuiltin uni) | ||
|
|
||
| instance LetBuiltin uni => Default (LeterBuiltin uni) where | ||
| def = LeterBuiltin letBuiltin | ||
|
|
||
| unavailableLeterBuiltin :: Int -> LeterBuiltin uni | ||
| unavailableLeterBuiltin ver = | ||
| LeterBuiltin $ \_ -> Left $ | ||
| "'let' TODO " <> display ver |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -50,7 +50,7 @@ import PlutusCore.Core.Type (Type (..)) | |
| import PlutusCore.Crypto.BLS12_381.G1 qualified as BLS12_381.G1 | ||
| import PlutusCore.Crypto.BLS12_381.G2 qualified as BLS12_381.G2 | ||
| import PlutusCore.Crypto.BLS12_381.Pairing qualified as BLS12_381.Pairing | ||
| import PlutusCore.Data (Data) | ||
| import PlutusCore.Data (Data (Constr)) | ||
| import PlutusCore.Evaluation.Machine.ExMemoryUsage (IntegerCostedLiterally (..), | ||
| NumBytesCostedAsNumWords (..)) | ||
| import PlutusCore.Pretty.Extra (juxtRenderContext) | ||
|
|
@@ -706,11 +706,28 @@ instance CaseBuiltin DefaultUni where | |
| case x of | ||
| (l, r) -> Right $ headSpine (branches Vector.! 0) [someValueOf tyL l, someValueOf tyR r] | ||
| | otherwise -> Left $ outOfBoundsErr someVal branches | ||
| DefaultUniData -> | ||
| case x of | ||
| Constr ix ds | ||
| | 0 <= ix && ix < toInteger len -> | ||
| Right $ | ||
| headSpine | ||
| (branches Vector.! (fromIntegral ix)) | ||
| (someValueOf DefaultUniData <$> ds) | ||
| | otherwise -> Left $ outOfBoundsErr someVal branches | ||
| _ -> Left "Only 'Constr' constructor can be cased" | ||
| _ -> Left $ display uni <> " isn't supported in 'case'" | ||
| where | ||
| !len = Vector.length branches | ||
| {-# INLINE caseBuiltin #-} | ||
|
|
||
| instance LetBuiltin DefaultUni where | ||
| letBuiltin _someVal@(Some (ValueOf uni x)) = | ||
| case uni of | ||
| DefaultUniList ty -> Right $ someValueOf ty <$> x | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Likewise. |
||
| DefaultUniPair tyL tyR -> Right [someValueOf tyL $ fst x, someValueOf tyR $ snd x] | ||
| _ -> Left $ display uni <> "no" | ||
|
|
||
| {- Note [Stable encoding of tags] | ||
| 'encodeUni' and 'decodeUni' are used for serialisation and deserialisation of types from the | ||
| universe and we need serialised things to be extremely stable, hence the definitions of 'encodeUni' | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -101,6 +101,8 @@ data Term name uni fun ann | |
| | Constr !ann !Word64 ![Term name uni fun ann] | ||
| -- See Note [Supported case-expressions]. | ||
| | Case !ann !(Term name uni fun ann) !(Vector (Term name uni fun ann)) | ||
| | Let !ann ![name] !(Term name uni fun ann) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We discussed this here and it should be at which point you don't need Sorry for the confusion I caused!
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes. Since we talked, I was pulled to do other things, so I haven't got chance to update yet. But looking back now, and also seeing more PIR/PLC internals, I think your version of |
||
| | Bind !ann !(Term name uni fun ann) ![Term name uni fun ann] | ||
| deriving stock (Functor, Generic) | ||
|
|
||
| deriving stock instance (Show name, GShow uni, Everywhere uni Show, Show fun, Show ann, Closed uni) | ||
|
|
@@ -168,6 +170,8 @@ termAnn (Force ann _) = ann | |
| termAnn (Error ann) = ann | ||
| termAnn (Constr ann _ _) = ann | ||
| termAnn (Case ann _ _) = ann | ||
| termAnn (Let ann _ _) = ann | ||
| termAnn (Bind ann _ _) = ann | ||
|
|
||
| bindFunM | ||
| :: Monad m | ||
|
|
@@ -185,6 +189,8 @@ bindFunM f = go where | |
| go (Error ann) = pure $ Error ann | ||
| go (Constr ann i args) = Constr ann i <$> traverse go args | ||
| go (Case ann arg cs) = Case ann <$> go arg <*> traverse go cs | ||
| go (Let ann name body) = Let ann name <$> go body | ||
| go (Bind ann fun arg) = Bind ann <$> go fun <*> traverse go arg | ||
|
|
||
| bindFun | ||
| :: (ann -> fun -> Term name uni fun' ann) | ||
|
|
||
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.
You lost all your money and now live under the bridge, because you performed a linear operation before doing any costing for it.
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.
please, anything but bridge. haven't gone that far yet