@@ -13,10 +13,32 @@ This use of `case` in UPLC was introduced with protocol version 11 and requires
1313:::
1414
1515In UPLC, it is possible to branch on expressions of certain built-in types, like
16- ` Integer ` and ` Bool ` . This can be done with ` case ` syntax, which is also used
17- for [ sums-of-products] ( ./encoding#sums-of-products ) . Using ` case ` on built-in
18- values may improve script performance and size.
19- The built-in types that ` case ` currently supports are:
16+ ` Integer ` and ` Bool ` using ` case ` syntax, which is also used
17+ for [ sums-of-products] ( ./encoding#sums-of-products ) . This may improve script performance
18+ and size, compared to older alternatives that use built-in functions.
19+
20+ This page describes the built-in types that are supported in UPLC and how Plinth
21+ developers can benefit from the improved performance.
22+
23+ ## Usage from Plinth
24+
25+ ::: info
26+
27+ The Plinth compiler option will change from ` datatypes=BuiltinCasing ` to
28+ ` datatypes=SumsOfProducts ` in the future.
29+
30+ :::
31+
32+
33+ Plinth developers can benefit from the performance of ` case ` by enabling the
34+ compiler [ option] ( ./plinth-compiler-options ) ` datatypes=BuiltinCasing ` , and
35+ using standard library functions such as ` caseList ` , ` fstPair ` .
36+ Note that Plinth's ` case ... of ... ` syntax is not generally compiled to UPLC,
37+ as it can be more expressive.
38+
39+ ## Supported types
40+
41+ The UPLC built-in types that ` case ` can be used on are:
2042
2143- ` bool `
2244- ` unit `
@@ -26,42 +48,32 @@ The built-in types that `case` currently supports are:
2648
2749In the future, support for ` data ` is also planned.
2850
29- For each type, the allowed branches and their order differs. See [ Supported
30- Types] ( #supported-types ) for more detail.
31-
32- ## Compiling to ` case ` in Plinth
33-
34- When compiling Plinth code with the [ option] ( ./plinth-compiler-options )
35- ` datatypes=BuiltinCasing ` (which in the future be achieved with
36- ` datatypes=SumsOfProducts ` ), many standard library functions will be compiled
37- into this use of ` case ` , such as ` fstPair ` , ` ifThenElse ` and ` caseList ` . Note
38- that Plinth's ` case ... of ... ` syntax is not generally compiled to UPLC, as
39- it can be more expressive.
40-
41- ## Supported types
42-
4351### Bool
4452
45- Consider the following Plinth code that implements a basic assertion:
53+ The following Plinth code implements a basic assertion:
4654
4755``` haskell
48- assert :: Bool -> ()
56+ assert :: Bool -> BuiltinUnit
4957assert False = error ()
50- assert True = ()
58+ assert True = unitval
5159```
5260
5361With ` datatypes=BuiltinCasing ` , it is compiled to the new casing on builtins:
5462
5563``` uplc
56- \b -> case b error (constr 0 [])
64+ \b -> case b [ error, ()]
5765```
5866
67+ In UPLC, booleans can be used in ` case ` with either one or two branches, where
68+ the first is always the ` False ` branch. When only a single branch is provided,
69+ script execution will fail when the boolean evaluates to True.
70+
5971::: info
6072
6173Compare this to the UPLC that would have been generated otherwise:
6274
6375``` uplc
64- \b -> force (force ifThenElse b (delay (constr 0 [] )) (delay error))
76+ \b -> force (force ifThenElse b (delay ()) (delay error))
6577```
6678
6779This uses the UPLC builtin function ` ifThenElse ` , which requires delaying the branch
@@ -70,11 +82,11 @@ delaying impacts the size and execution cost.
7082:::
7183
7284
73- ### Unit
85+ ### BuiltinUnit
7486
7587The built-in unit type can be used in a trivial way with ` case ` in UPLC, which
7688takes exactly one branch. With ` datatypes=BuiltinCasing ` , Plinth will compile
77- the ` chooseUnit ` built-in into ` case ` . Consider the following trivial Plinth code :
89+ ` chooseUnit ` from ` PlutusTx.Builtins.Internal ` into ` case ` . For example :
7890
7991``` haskell
8092forceUnit :: BuiltinUnit -> Integer
@@ -91,10 +103,9 @@ UPLC's case on built-in unit requires exactly one branch. If the expression
91103being cased on evaluates to the unit value, evaluation will continue with the
92104expression in that branch.
93105
94- ### Pair
106+ ### BuiltinPair
95107
96- To destruct a built-in pair, use ` casePair ` . It compiles into the ` case `
97- construct. For example:
108+ To destruct a built-in pair, use ` casePair ` from ` PlutusTx.Builtins ` . For example:
98109
99110``` haskell
100111addPair :: BuiltinPair Integer Integer -> Integer
@@ -152,11 +163,11 @@ fail. Note that there is no way to provide a "catch-all" case for integers.
152163When not using ` datatypes=BuiltinCasing ` , Plinth's ` caseInteger ` is compiled
153164into a much less efficient implementation that turns the second argument in a
154165list (of which the representation depends on the chosen ` datatypes= ` flag), and
155- does a recursive lookup in that list.
166+ does a recursive lookup in that list. The above Plinth code is compiled to:
156167
157168
158169``` uplc
159- (( \traceError ->
170+ (\traceError ->
160171 (\go i ->
161172 force
162173 (force ifThenElse
@@ -181,12 +192,12 @@ does a recursive lookup in that list.
181192 (delay x)
182193 (delay
183194 ((\x -> s s x) (subtractInteger ds 1) xs)))) ])))
184- (\str -> (\x -> error) (force trace str (constr 0 []))))
195+ (\str -> (\x -> error) (force trace str (constr 0 [])))
185196```
186197:::
187198
188199
189- ### List
200+ ### BuiltinList
190201
191202A ` case ` on built-in lists may be given one or two branches (similar to
192203booleans), where the first one deals with the cons case, and the second one with
0 commit comments