Skip to content

Commit 63f14c6

Browse files
committed
Improve "evaluating plinth" example: clarify application and lifting separately.
1 parent d972a38 commit 63f14c6

File tree

2 files changed

+92
-21
lines changed

2 files changed

+92
-21
lines changed

doc/docusaurus/docs/using-plinth/evaluating-plinth.md

+44-10
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,19 @@ Let's consider the following example Plinth program:
2020
start="-- BEGIN Plinth"
2121
end="-- END Plinth" />
2222

23-
In order to evaluate this code, we need to add the `plutus-tx:plutus-tx-testlib`
23+
This code represents a function that expects an `Integer` argument
24+
and returns the `Integer` value.
25+
26+
To compile it, we can use the `compile` function as described earlier in the "[Compiling Plinth code](./compiling-plinth.md)" section:
27+
28+
<LiteralInclude
29+
file="Example/Evaluation/Main.hs"
30+
language="haskell"
31+
title="Plinth code compiled"
32+
start="-- BEGIN CompiledCode"
33+
end="-- END CompiledCode" />
34+
35+
In order to evaluate `compiledCode`, we need to add the `plutus-tx:plutus-tx-testlib`
2436
dependency to our cabal file:
2537
```cabal
2638
build-depends:
@@ -38,9 +50,6 @@ import PlutusTx.Test (
3850
)
3951
```
4052

41-
Our example code represents a function that expects an `Integer` argument
42-
and returns the `Integer` value.
43-
4453
It is possible to evaluate this compiled code without applying it to any arguments,
4554
and evaluation will succeed, returning the value of type `Integer -> Integer`:
4655

@@ -140,17 +149,42 @@ No traces were emitted
140149
This output reveals that the evaluation was successful, and the resultng UPLC
141150
value is an (un-applied) lambda abstraction.
142151

143-
The [Lifting Values into CompiledCode](./lifting.md) section contains and example
144-
of applying the `CompiledCode` to an argument.
152+
To apply the compiled lambda abstraction to an argument we need to have a compiled argument,
153+
and there are several ways of obtaining it from a Haskell value known at compile time:
154+
1. "lift" it into `CompiledCode`. See the [Lifting Values into CompiledCode](./lifting.md) section for more details.
155+
<LiteralInclude
156+
file="Example/Evaluation/Main.hs"
157+
language="haskell"
158+
title="Lift a constant value into CompiledCode"
159+
start="-- BEGIN LiftedArgument"
160+
end="-- END LiftedArgument" />
161+
162+
2. `$(compile [|| ... ||])` it the same way we compiled the function itself.
163+
<LiteralInclude
164+
file="Example/Evaluation/Main.hs"
165+
language="haskell"
166+
title="Compile a constant value into CompiledCode"
167+
start="-- BEGIN CompiledArgument"
168+
end="-- END CompiledArgument" />
169+
170+
Once we have an argument of type `CompiledCode a`, we can apply it to the compiled function
171+
using either the [`applyCode`](https://plutus.cardano.intersectmbo.org/haddock/latest/plutus-tx/PlutusTx-Code.html#v:applyCode) function
172+
173+
<LiteralInclude
174+
file="Example/Evaluation/Main.hs"
175+
language="haskell"
176+
title="Applying compiled function to an argument (type-safe way)"
177+
start="-- BEGIN SafeApplicationResult"
178+
end="-- END SafeApplicationResult" />
145179

146-
Alternatively, we can use the imported `applyLifted` function like this:
180+
or the [`unsafeApplyCode`](https://plutus.cardano.intersectmbo.org/haddock/latest/plutus-tx/PlutusTx-Code.html#v:unsafeApplyCode) function.
147181

148182
<LiteralInclude
149183
file="Example/Evaluation/Main.hs"
150184
language="haskell"
151-
title="How to apply compiled function to a lifted argument"
152-
start="-- BEGIN AppliedResult"
153-
end="-- END AppliedResult" />
185+
title="Applying compiled function to an argument (unsafe way)"
186+
start="-- BEGIN UnsafeApplicationResult"
187+
end="-- END UnsafeApplicationResult" />
154188

155189
Lets print the result of the evaluation:
156190

doc/docusaurus/static/code/Example/Evaluation/Main.hs

+48-11
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,35 @@
33
{-# LANGUAGE NoImplicitPrelude #-}
44
{-# LANGUAGE OverloadedStrings #-}
55
{-# LANGUAGE ScopedTypeVariables #-}
6+
{-# LANGUAGE TemplateHaskell #-}
67
{-# LANGUAGE TypeApplications #-}
78
{-# OPTIONS_GHC -fplugin PlutusTx.Plugin #-}
89
{-# OPTIONS_GHC -fplugin-opt PlutusTx.Plugin:target-version=1.1.0 #-}
910

1011
module Main where
1112

12-
import Data.Proxy (Proxy (..))
13-
import Data.Text.IO qualified as Text
14-
import PlutusTx
15-
import PlutusTx.Plugin (plc)
1613
import PlutusTx.Prelude
17-
import Prelude (IO)
1814

19-
import PlutusTx.Test (EvalResult, applyLifted, evaluateCompiledCode, prettyEvalResult)
15+
import Data.Text.IO qualified as Text
16+
import PlutusTx (CompiledCode, applyCode, compile, liftCodeDef, unsafeApplyCode)
17+
import Prelude (IO, String)
18+
19+
import PlutusTx.Test (EvalResult, evaluateCompiledCode, prettyEvalResult)
2020

2121
-- BEGIN Plinth
22+
2223
plinthCode :: Integer -> Integer
2324
plinthCode x = trace "Evaluating x" x + trace "Evaluating constant" 2
2425

25-
compiledCode :: CompiledCode (Integer -> Integer)
26-
compiledCode = plc (Proxy @"plinth") plinthCode
2726
-- END Plinth
2827

28+
-- BEGIN CompiledCode
29+
30+
compiledCode :: CompiledCode (Integer -> Integer)
31+
compiledCode = $$(compile [||plinthCode||])
32+
33+
-- END CompiledCode
34+
2935
{-
3036
EvalResult
3137
{ evalResult = Right
@@ -45,12 +51,43 @@ EvalResult
4551
}
4652
-}
4753

48-
-- BEGIN AppliedResult
54+
-- BEGIN CompiledArgument
55+
56+
argumentCompiled :: CompiledCode Integer
57+
argumentCompiled = $$(compile [||2||])
58+
59+
-- END CompiledArgument
60+
61+
-- BEGIN LiftedArgument
62+
63+
argumentLifted :: CompiledCode Integer
64+
argumentLifted = liftCodeDef 2
65+
66+
-- END LiftedArgument
67+
68+
-- BEGIN SafeApplicationResult
69+
70+
errorOrResult :: Either String EvalResult
71+
errorOrResult = fmap evaluateCompiledCode appliedSafely
72+
where
73+
appliedSafely :: Either String (CompiledCode Integer)
74+
appliedSafely = compiledCode `applyCode` argumentLifted
75+
76+
-- END SafeApplicationResult
77+
78+
-- BEGIN UnsafeApplicationResult
79+
4980
result :: EvalResult
50-
result = evaluateCompiledCode $ compiledCode `applyLifted` 2
51-
-- END AppliedResult
81+
result = evaluateCompiledCode appliedUnsafely
82+
where
83+
appliedUnsafely :: CompiledCode Integer
84+
appliedUnsafely = compiledCode `unsafeApplyCode` argumentCompiled
85+
86+
-- END UnsafeApplicationResult
5287

5388
-- BEGIN main
89+
5490
main :: IO ()
5591
main = Text.putStrLn $ prettyEvalResult result
92+
5693
-- END main

0 commit comments

Comments
 (0)