If-Then-Else statements inside forA loop in DAML

There are ways to deal with this, but I think forA should not be used at all in this situation.

The way that some languages think of variables is dynamically assigned. That is, your create ContractA line depends on the preceding let syntax having updated this sort of invisible map whose keys are variable names and whose values are the values of those variables. Suppose that the loop never encountered cases that match the if conditions, and therefore never assigned a, b, c, or d? Such languages just hope for the best and (ideally, but probably don’t) prepare for the worst.

Daml treats variables as statically bound, though. If you are permitted to use a variable a of type T, every reference to that variable will absolutely succeed by yielding a value of type T. You cannot write code that hopefully binds some variables; either the code is guaranteed to bind the variable, or is guaranteed to not bind the variable.

There are ways to arrange things in your code such that a, b, c, d values (not the variables) “get out” of the forA. But this is needlessly complex for your specific use case, with all sorts of extra failure cases and states to handle. Instead, here is how I would arrange things, and it can all be done in the single do block established for your None case:

  1. Use partyFromText "PartyC", invoking fromSomeNote on that to get a Party-typed value for "PartyC". Bind it to local variable partyC.
  2. (Optionally) assert that elem partyC otherParties. Since the apparent intention of your code is to abort transaction if any of the parties you need aren’t present in otherParties, doing this will preserve that intention, but maybe you didn’t really mean that.
  3. Use fetchByKey just as you currently do to get the dvContract.
  4. Bind your abc, def fields from that contract to a and b, using let just as you do now.
  5. Repeat steps 1-4 for every other party for which you need to fetch a contract and extract values to local variables.
  6. At the end of the do, your create ContractA will have every variable you need in scope, and guaranteed to be present if you have gotten this far.

To call out specifically which things are not used at all in this approach:

  1. there is no forA
  2. there is no if (though we do use elem and assert, if that is your intention)
  3. there is no nested do
1 Like