Join ACCESS EU, the first-of-its-kind digital assets security and DLT summit
JUNE 7TH, 2024 @ EURONEXT AMSTERDAM ⟶
Halborn Logo

// Blog

Web3

Workflow Composition with Daml Applications


profile

Rob Behnke

April 18th, 2023


The Daml / Canton platform operates at the intersection of business, law and IT, and the overarching theme which connects these domains is composition or, to put it in a more verbose way: atomic transaction composition. 

This might not be obvious at first sight though because experts of these domains use different terminologies. In this article, we will show you how composition is present in these domains and hopefully will be able to convince you that the Daml ledger model faithfully captures - and the Daml/Canton platform faithfully implements - this kind of composition.

Composition in business

In business, two eminent forms of composition are a) bundling of products and services at a macro level, and b) multi-step transactions at a micro level.

Here’s an example of how macro level bundling should work and what problems arise when bundling is not supported by a proper transactions system: a couple of years ago, Tesla remotely disabled Autopilot on a used Model S after it was sold. The reason for disabling the feature was that the dealer who sold the car to the owner didn’t pay for it to Tesla, although the owner paid for the feature to the dealer. 

The right way to handle similar situations would be to make sure that the activation of the feature happens in an atomic way, together with the owner paying for it to the dealer and the dealer passing the fee on to the service provider. 

At the end of the day, bundled products and services should be presented to the end user as an integrated deal where the user either pays and gets the whole package or doesn’t pay and gets nothing; and subcontractors in the background cannot be left without being paid for their contributions in the case of a sale. 

The lack of such kind of atomic workflow composition is sometimes called siloed operation, and can result in the need of costly and lengthy after-the-fact reconciliation.

The other, micro level kind of business composition is when a transaction consists of several steps which are expected to happen in an “all or nothing” manner. The classic example for this is a bank transfer. Transferring money from the account of Alice to the account of Bob actually comprises two steps, debiting the account of Alice and crediting the account of Bob (plus deducting the transaction fee for the bank if applicable according to the account contracts of the stakeholders). We don’t have to go very far away from this simple transfer until it gets very complex under the hood: e.g. transfers involving currency conversion or delivery vs payment deals are common use cases.

Composition in law

The glue for business relationships is law. Every business relationship is a legal relationship, so the above mentioned cases of business composition are, at the same time, cases of legal composition. 

And there is more: already the establishment of a legal relationship is a composition, namely the composition of offer and acceptance. The execution of a simple two-party contract is a transaction with two legs: if either party fails to authorize it, the contract is “null and void”.

In more general terms: in law, somebody’s right is somebody else’s obligation, and rights can be conditional on the fulfillment of some obligations. Every legal relationship (like a transport contract or an exotic derivative) is the bundle or composition of such rights and obligations.

Composition in mathematics and functional programming

Perhaps you thought that the math you learnt at school doesn’t have anything to do with the use cases of business and legal composition mentioned above. But it does.

One fundamental concept in mathematics is composition, sometimes in the form of decomposition and recomposition. A simple example for composition is the multiplication of natural numbers, with the fundamental trait of being associative, meaning that we can group the numbers multiplied in any way without affecting the result. (2 3) 4 = 6 4 = 2 (3 4) = 2 12 = 24, so we can write simply 2 3 4. (If you think multiplication is not interesting enough to be mentioned, consider the reverse direction, decomposition, which results in the concept of prime numbers and a whole bunch of exciting theoretical questions.)

Another, more involved kind of composition is the composition of functions: if e.g. f(x) = x +1, g(x) = x^2 and h(x) = (x + 1)^2 then the function h is the composition of f and g. This kind of composition is also associative: if we have more than two functions, we can compute their composition by grouping neighboring members of the array in any way as long as their order remains the same.

It turns out that the concept of associative composition is so ubiquitous and fundamental in mathematics that a separate discipline called category theory was founded in the middle of the 20th century to study structures emerging from building blocks composable in an associative way.

What does all this have to do with Daml? Hold on, we are getting there!

In computer science and programming, decomposition and recomposition is a fundamental strategy for solving problems – and possibly proving the correctness of the solution. There is a tough challenge though: it seems that it’s very difficult to describe and typecheck the composition of actions which can fail, like retrieving data from a website. 

It turns out that one concept developed in category theory, the monad, is very suitable to describe types expressing actions which can fail, and the results of such actions. One branch of computer science, called functional programming, makes extensive use of a type system accounting for uncertain actions and their composition. The type system is used by the compiler to reject code violating the composition rules of uncertain actions, preventing a lot of bugs and unintended behavior during the runtime of the program.

(If you are not familiar with the concept of monad, you can check out this video and the blog posts of Bartosz Milewski.)

Looking back to our starting point for a moment, we noticed that actions in business and law can also fail, yet still need to be composed. If you draw the conclusion that the rigorous handling of composition should make functional programming especially suitable to handle the composition of actions in business and law, you are right. The pioneers of such applications were the authors of the paper Composing Contracts: An Adventure in Financial Engineering, among them Simon Peyton Jones, the creator of Haskell.

And indeed, Daml was inspired by this paper, as you can learn from the Daml Forum comment of a member of the team which created it.

Composition in the Daml / Canton platform

The words “compose” and “composition” appear 25 times in the Canton white paper, which explains the goals and high level operational principles of the Daml / Canton platform. This statistic already signals the importance of the concept. Now, we’ll explain in simple terms how the pieces of the puzzle fit together.

The goal of the Daml / Canton platform is to record business/legal transactions, where failure of actions is frequent and expected (like e.g. the lack of funds for a transfer). 

Failure of an action must not halt the operation of the ledger and also must not result in the partial recording of the transaction. If any action of a transaction fails, the whole transaction must be rejected without anything changing on the ledger. Sometimes it’s also needed that the result of a successful action (e.g. the contract id of a created contract) can be used as input to another action within the same transaction.

The composition of actions can be expressed in the Daml smart contract language. The correctness of the Daml programs is checked by the compiler which rejects any program which violates the composition rules. The operational model of Canton makes sure that the transactions correctly expressed in Daml and also having all preconditions fulfilled on the ledger are recorded correctly.

Daml is a functional language, derived from Haskell. On top of the general syntax and basic type classes also present in Haskell, Daml has special features suited to its special purpose. 

The Daml typeclass expressing a ledger update which can fail, is the Update typeclass. Update is a kind of Action (which is the equivalent of monad in Haskell and other functional languages). 

The composition of actions is expressed in the choice body of Daml contracts, using usually do notation also present in Haskell as a syntactic sugar over monadic syntax. The do notation is preferred in Daml because it makes the code more readable to business audiences.


Final Thoughts

In this blog post, you’ve learned about the importance of the concept of composition for the application domain and the operation of the Daml / Canton platform. In subsequent blog posts, we will go into more technical details of the platform. Stay tuned for more!