Daml choice annotations
preconsuminghas changed. It is no longer an alias for a standard choice, but has the behaviour of a
nonconsumingchoice with an
archive selfas the first sub-action. There is no difference in behaviour, except that the privacy implications are subtly different. Observers see all consequences of a standard choice, whereas they only see the
archivesubaction of a
Introducing pre- and post-consuming choices
Choices in Daml can be ‘consuming’ or ‘non-consuming’ with respect to the contracts on which they are exercised. In short, a consuming choice on a contract leaves the contract inactive, a non-consuming choice does not. By default, a choice is assumed to be consuming. To indicate a non-consuming choice, Daml provides the nonconsuming keyword. Recently, Daml choice annotation syntax has been added to further categorize choices as ‘pre-consuming’ or ‘post-consuming’. This post reviews the consuming concept and explains the meaning of the newly added preconsuming and postconsuming keywords. The example code used here can be found in this Gist.
[Note: The code here uses the new ‘flexible controller’ syntax first introduced in this blog post.]
Normally, exercising a choice on a contract amounts to actions that terminate the contract or replace the contract with one or more new contracts. For this reason, by default, exercising a choice on a contract is assumed to ‘consume’ the contract. For example, suppose a contract represents some kind of offer to purchase goods or services with provision for the provider to withdraw the offer:
It's sometimes the case though that exercising a choice on a contract instance does not imply the instance should be archived. For such a choice, we can indicate that with a nonconsuming annotation. To illustrate, here's a simple model of a leasing agreement between a landlord and tenant. The landlord may like to, say, extend to the tenant the opportunity to ‘refer a friend’ in order to obtain a cash-premium—so we write that into the contract like so:
Introducing pre- and post-consuming choices
Suppose we wish to write a clause into our Lease agreement allowing for its termination. Put yourself in the role of the developer contracted by the realtor to model their business process that mandates that, on termination, not only is the agreement archived but also a ReferAFriendOffer is issued. That would lead us to try to write something like the following.
In fact, the newly introduced preconsuming choice annotation is provided for those that wish to be explicit in their definitions. That is,
What's lacking here is a choice archival scheme with slightly different semantics—one that auto-archives its contract but not before the choice body has been executed. This is provided for by the newly added postconsuming annotation. Now we have the tools to express our intent.
There is one subtlety left to explain regarding privacy rules with respect to post-consuming choices. Like non-consuming choices, contracts created in the choice body are known only to the signatories and controllers of the contracts and not made known to the observers of the contract on which the choice was exercised. That means, in terms of the example, a guarantor will not be privy to the creation of a ReferAFriendOffer raised by exercising Terminate on a lease but, as a stakeholder, will be privy to the archiving of the Lease itself.
A remark for ledger writers
In practice, Daml-LF only has pre-consuming choices. Post-consuming choices are implemented by code generation during the Daml to Daml-LF desugaring process. Don't worry if this remark doesn't mean anything to you as a Daml developer—you can safely ignore it!
In this note, we have revisited the notions of ‘consuming’ and ‘non-consuming’ choices. Consuming choices render their contracts inactive; non-consuming choices have no effect on their contracts. Consuming choices can be further nuanced into ‘pre-consuming’ and ‘post-consuming’ choices. Pre-consuming choices archive their contracts before their bodies are executed, and post-consuming choices archive their contracts after their bodies are executed. Annotations preconsuming, nonconsuming, and postconsuming can be attached to choice definitions to select between the different possibilities. If you don't annotate a choice then it defaults to preconsuming.
Join the community and download the Daml SDK at daml.com
About the author
Shayne Fletcher, B.Sc. - Language Engineer – Daml Language Team, Digital Asset
Shayne joined Digital Asset’s language engineering team in 2018 where he works on the Daml compiler. Shayne has 20+ years experience with C++ and OCaml. He has a deep understanding of programming language theory and a wealth of experience in finance and building language based-products. In a previous role with Bloomberg, Shayne led the team that built the BLAN language for modeling exotic derivative securities. @shayne_fletcher