Adding Increment Quantity Changes to a Contract

I was searching in the Forum and Daml Docs for
information on the following terms:

  • counting assets
  • incrementing
  • incrementing assets
  • counting things

… with no joy.

Use case:

  • A door in a highly-trafficked restaurant
  • A doorway beam sensor
  • A Microcontroller to receive the beam sensor output
  • A functioning Daml contract

Assuming that all the hardware worked correctly, what Daml function, if any, would allow the incrementing of i = i + 1 of incoming values, into a contract?

Perhaps I was searching for the wrong terms, but I did not see any ‘counting’ references in the Docs or on the Forum, other than Functional Programming.


I may have interpreted your question overly broadly, trying to include every relevant topic I can think of, but here goes:

In Daml, as in all purely functional languages, we use the definition of variable given by Bob Harper here. That is, to say that you can replace i with i + 1 is not dissimilar from saying that you can replace 5 with 5 + 1, whereupon 5 ceases to exist any longer.

But the below is allowed.

template Ticker with
    owner: Party
    n: Int
    signatory owner
    key owner: Party
    maintainer key

    controller owner can
      Tick: ContractId Ticker
          create this with n = n + 1

-- ^ `this` is the contract payload, `x with ...` creates a *new*
-- record with the contents of `x` but with fields ... replaced
-- by new values as given
-- The `n`s in `n = n + 1` mean something different.
-- The first means "the field named n in the newly-created record"
-- The second means "the variable n that is in scope"
-- They happen to share a type, but are not "the same" field/variable

What happens if you exercise Tick on a Ticker contract whose payload n happens to be 5? That contract gets archived, and a new contract is created with a new contract ID whose payload n is 6. (This is not inconsistent with our definition of variable as given above.)

Does that mean that if you need to tick 10 times, your only option is to exerciseByKey @Ticker owner Tick 10 times? That would be overkill; it would be better in that case to add an argument to Tick specifying the amount to increment. This is not dissimilar to how you would rather write i + 10 rather than i + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1.

The type signature of the sum function provides a hint as to the functional way of thinking about counting things: as a kind of aggregation, just as COUNT in SQL is considered an aggregation operator. Foldable is considered a core functional construct in most purely-functional standard libraries, including Daml’s, and its essence is the ability to aggregate or enumerate all the values therein.

You can apply this idea of aggregation to the management of contracts, as well. For example, consider a contract representing a party’s ownership of an asset. If the party and asset ID form a key, then all ledger actions must go through that keyed contract, which is a point of contention. Instead, you could imagine that it is not a key, and the contract has a choice that permits netting of two or more contracts representing the same party/asset-ID pair. Then the netting (or “reconciliation” if you like) could be carried out easily, lazily, by a trigger on whatever frequency you like, thus overall reducing contention and increasing concurrent throughput.

Regarding the repeated opening of a door in a restaurant, to take another example, I suspect that it is not only interesting that the door was opened n times, but at what particular times the door was opened, perhaps how long it was kept open for (as an approximation of how many people must have used the door), perhaps whether it was used for entrance or exit, &c &c. In which case the number of door-open events would be just one of an assortment of interesting properties, with little value in having an actual always-up-to-date single Int representing physical count, which would suggest that delayed aggregation (or simply calling sum at the right time on the right List or other foldable) would be the right fit for the use case.

Replacing n with n + 1 in a new contract is just the start. Functions like sum and map give you lots of tools for adding up numbers derived from choice arguments, with which you can make all sorts of interesting replacements for 1 in that “incremental”. The key is that it is more effective to come up with how much you want to increment by first, and then do the + and create (and implied archival, presumably), rather than updating the contract payload over and over within a single choice body.

1 Like

Thank you for that comprehensive and meaningful response. I had already suspected that updating (Or more accurately, Archiving N, Creating N+1) was possible although using sum, map and List would not have occured to me.

Although most of the use cases I have seen for Daml so far, relate to the creation & exchange of Assets, both Digital (No pun intended) and Physical, I had wondered if you could use Daml to input representations of Serial sensor data, and it seems that you could.

Please excuse my clumsy misuse of Functional programing. So much to learn :grinning: