Placement of `do` in choices

I find it very confusing that for choices the placement of the do token is handled differently for controller first vs choice first syntax.

With controller first, you can leave the do block at the end of the statement, like so:

    controller counterparty can
      Sell : ContractId FinancialContract with obligations: Obligations do
        ...

But with choice first, this doesn’t compile:

    choice EnterInto : ContractId MasterAgreement with requestor : Party
      controller requestor do 
        create MasterAgreement with bearer = requestor, counterparty

But moving the do one line down does:

    choice EnterInto : ContractId MasterAgreement with requestor : Party
      controller requestor
        do create MasterAgreement with bearer = requestor, counterparty

Is this intentional? Why this difference?

2 Likes

Yes, this is somewhat unfortunate.

The difference stems from the fact that the older controller-first syntax includes the can keyword, which allows the parser to know when the list of controller-parties is finished – because in general there can be multiple controller parties:

controller counterparty1, counterparty2 can
  Sell : ContractId FinancialContract with obligations: Obligations do
     ...

The layout rules of DAML then insert implicit braces to make the party-list explicit. These braces can be provided explicitly if you like, making the following parse valid:

controller { counterparty1, counterparty2 } can
  Sell : ContractId FinancialContract with obligations: Obligations do
     ...

However, in the newer choice-first syntax, there is no can keyword to mark the end of the controller-parties. So the end of the party list (even a singleton list) must be marked either with a line break (allowing layout to do it’s stuff):

choice EnterInto : ContractId MasterAgreement with requestor : Party
  controller requestor
    do create MasterAgreement with bearer = requestor, counterparty

Or, again, explicit braces may be inserted. Which allows the entire controller declaration on a single line:

choice EnterInto : ContractId MasterAgreement with requestor : Party
  controller { requestor } do create MasterAgreement with bearer = requestor, counterparty

Or, split after the do, if you prefer:

choice EnterInto : ContractId MasterAgreement with requestor : Party
  controller { requestor } do
    create MasterAgreement with bearer = requestor, counterparty
2 Likes

would this also be solved by allowing a can in the choice-first syntax?

1 Like

It’s possible having a keyword at this point would also get you the layout you want, without explicit braces. However there are problems with using can because it has the wrong layout behaviour as a consequence of the old controller-first syntax.

In the old syntax, can is is followed by a list of Choice declarations, in braces, explicit or implicit. In the new syntax, can would be followed by the choice-body expression, which does not have braces.

1 Like

Hi, for that very reason, I put the do on the next line in a choice choice. Also note the double indented with:

choice MyChoiceName: ContractId SomeTemplate
    with
      arg1: Foo
      party: Party 
  controller party 
    do 
      theThings...

Note that this way, the do blocks line up exactly between the two choices syntaxes.