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 force and delay to typed plutus core #4187

Closed
phadej opened this issue Nov 4, 2021 · 8 comments
Closed

Add force and delay to typed plutus core #4187

phadej opened this issue Nov 4, 2021 · 8 comments
Labels
enhancement Low priority Doesn't require immediate attention status: triaged

Comments

@phadej
Copy link

phadej commented Nov 4, 2021

Describe the feature you'd like

force and delay are introduced to UPLC to reduce code size, an option would been to use unit abstraction and application.

I don't see a reason why same construct cannot be introduced to typed PLC for the same reason.

For example, there are expressions like (in pseudo-Haskell syntax):

(force ifThenElse)
  ((builtin equalsInteger) ...)
  (\unused -> ...)
  (\unused -> ...)
  ()

instead of

(force (force ifThenElse)
  ((builtin equalsInteger) ...)
  (delay (...))
  (delay (...)))

The difference is small, and I don't expect it (alone) to affect script size or performance, but it feels a right thing to do.

@michaelpj
Copy link
Contributor

This is indeed very easy, and I thought about doing it, indeed I have a patch for it. In the end we decided that it is strictly redundant since you can use trivial type abstractions and instantiations, which erase to delay and force. Given that we've tried very hard to keep the number of terms in PLC to a minimum, I couldn't quite justify it.

@phadej
Copy link
Author

phadej commented Nov 4, 2021

Should the compiler then use trivial type-abstractions and instantiations rather than term-level abstractions? That indeed will have the same effect on UPLC.

@michaelpj
Copy link
Contributor

It does. There's one place where it has to use term abstractions is in the handling of some recursive values.

@michaelpj
Copy link
Contributor

Unless I've missed something.

@phadej
Copy link
Author

phadej commented Nov 4, 2021

I made a plutus-apps test suite dump uniswap.pir:

diff --git a/plutus-use-cases/test/Spec/Uniswap.hs b/plutus-use-cases/test/Spec/Uniswap.hs
index d8c55205b..0bda564a7 100644
--- a/plutus-use-cases/test/Spec/Uniswap.hs
+++ b/plutus-use-cases/test/Spec/Uniswap.hs
@@ -1,11 +1,14 @@
+{-# LANGUAGE DataKinds           #-}
 {-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE TemplateHaskell   #-}
 module Spec.Uniswap(
     tests
     ) where
 
 import           Plutus.Contract.Test
-import qualified Plutus.Contracts.Uniswap.Trace as Uniswap
-import qualified Plutus.Trace.Emulator          as Trace
+import qualified Plutus.Contracts.Uniswap as Uniswap
+import qualified Plutus.Trace.Emulator    as Trace
+import qualified PlutusTx
 
 import           Test.Tasty
 
@@ -17,4 +20,6 @@ tests = testGroup "uniswap" [
                        "setupTokens contract should be still running"
         .&&. assertNoFailedTransactions)
         Uniswap.uniswapTrace
+
+    , goldenPir "test/Spec/uniswap.pir" $$(PlutusTx.compile [|| Uniswap.mkUniswapValidator ||])
     ]

and then there are bindings like:

(termbind
  (strict)
  (vardecl fail (fun (all a (type) a) TxOut))
  (lam
    ds
    (all a (type) a)
    [
      { error TxOut }
      [
        {
          [
            Unit_match
            [
              [
                { (builtin trace) Unit }
                (con string "expected exactly one Uniswap output")
              ]
              Unit
            ]
          ]
          (con unit)
        }
        (con unit ())
      ]
    ]
  )

and

[
  [
    [
      [
        {
          (builtin ifThenElse)
          (fun
            (con unit)
            [
              [ Tuple2 (con bytestring) ]
              (con bytestring)
            ]
          )
        }
        [
          [
            (builtin equalsInteger)
            [
              {
                {
                  (builtin fstPair)
                  (con integer)
                }
                [ (con list) (con data) ]
              }
              tup
            ]
          ]
          (con integer 0)
        ]
      ]
      (lam
        ds
        (con unit)
        [
          [
            {
              { Tuple2 (con bytestring) }
              (con bytestring)
            }
            [
              (builtin unBData)
              [
                {
                  (builtin headList) (con data)
                }
                t
              ]
            ]
          ]
          [
            (builtin unBData)
            [
              { (builtin headList) (con data) }
              [
                {
                  (builtin tailList) (con data)
                }
                t
              ]
            ]
          ]
        ]
      )
    ]
    (lam
      ds
      (con unit)
      [
        {
          error
          [
            [ Tuple2 (con bytestring) ]
            (con bytestring)
          ]
        }
        [
          {
            [
              Unit_match
              [
                [
                  { (builtin trace) Unit }
                  (con string "PT1")
                ]
                Unit
              ]
            ]
            (con unit)
          }
          (con unit ())
        ]
      ]
    )
  ]
  (con unit ())
]

@michaelpj
Copy link
Contributor

Some of these may come from surface Haskell: there are some places in the source where we use unit lambdas instead of type abstractions for simplicity. I'll have a bit more of a look into this later, though.

@effectfully
Copy link
Contributor

This doesn't seem to be a high priority issue, although I agree it would be great to take a deep look at it.

@effectfully effectfully added Low priority Doesn't require immediate attention status: triaged labels Feb 1, 2023
@effectfully
Copy link
Contributor

Closing in favor of #5908.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Low priority Doesn't require immediate attention status: triaged
Projects
None yet
Development

No branches or pull requests

3 participants