How to define the following variable types

Hi,

How should we define the following variables types in DAML (will be used as fields in a data record)?

  • Not Required (but not optional)
  • Required (in case a certain condition is met e.g: if Terminated)

Thanks

I’m sorry but you’ll need to be a bit more verbose here. Can you expand on what you mean, perhaps providing an example? As it stands that reads as “optional but not optional” to me, which is a bit confusing.

I can think of three ways to do this:

  1. A single template with a bunch of Optional and Bool fields and ensure clauses.
  2. A single template with a field of some union type.
  3. Multiple templates.

I think 1 is self-explanatory. 2 would schematically look like:

data State
 = State1 with ...
 | State2 with ...
 | State3 with ...

template TemplateName
 with
  state: State
  sig: Party
 where
  ...

where each separate state has exactly the fields it needs to be valid. That way your set of fields is “correct by construction” and you never need any optional field within the StateX constructors.

The downside of both 1 and 2 is that you’ll need to check in your choices which state you’re in. That’s going to be arguably a bit easier in 2 than in 1, but either way most choices will be essentially a switch statement on the state of the contract. And that may be a sign that you need to pull out an OO trick and represent your state machine a bit more explicitly.

Approach 3 is basically the same as 2 except the “union” is defined at the template level:

template ContractInState1
  with
    ...
  where
    ...

template ContractInState2
  ...

Which of the three approaches is better for a given use-case is going to depend on the details of said use-case. Specifically, if most of the choices are the same across all states, perhaps approach 1 is better. If many choices are different, but they only depend on a small subset of the template fields, maybe approach 2 is best, pulling out only that small subset into the separate union type. If most choices depend on which state you’re in, approach 3 would be better.

You may also need to take into consideration how those contracts will look through the API and how those choices affect your client code.

The easiest way to determine whether you need to switch from a variant (data X = S1 ... | S2 ... | ...) or optionals to a workflow defined in separate templates is to ask yourself,

“are there choices that make sense in some states but not in others?”

If so, you should almost certainly use separate templates. If every choice make sense for every StateN, then a variant is probably a good way to do it.