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 variablegiven 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
key owner: Party
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.
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