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:
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.
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
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