Ah, my bad, this is a confusing mistake on my end. There should not be any aliceTV in this code snippet.
As a more general answer, Daml code runs “next to” the ledger, but is not directly integrated with the ledger. This means that you have a notion of “asking things from the ledger”, and “getting an answer”. A value of type Action a in Daml represents a question that could be asked of the ledger* and for which the ledger will respond with a value of type a.
*: Action is actually a little bit more general than that, but this hand-wavy explanation serves our purposes for now.
The special syntax var <- expr, where var is a variable name and expr is an expression of type Action a, is what allows a Daml program to “realize” that question, i.e. effectively connect to the ledger and ask for the result of the given Action, saving the response (of type a in this case) as var for further use by the Daml code locally. The <- syntax can only be used within the context of a do block.
Let’s look at the default template (daml new t) for an example:
setup : Script AssetId
setup = script do
alice <- allocatePartyWithHint "Alice" (PartyIdHint "Alice")
bob <- allocatePartyWithHint "Bob" (PartyIdHint "Bob")
aliceTV <- submit alice do
createCmd Asset with
issuer = alice
owner = alice
name = "TV"
bobTV <- submit alice do
exerciseCmd aliceTV Give with newOwner = bob
submit bob do
exerciseCmd bobTV Give with newOwner = alice
First off, notice that setup is of type Script. This is not explicit here, but if you look at the documentation for Script you will see that Script is a type of Action (this is what the line instance Action Script means), so we can use the do and <- notations.
The first line of this script reads:
alice <- allocatePartyWithHint "Alice" (PartyIdHint "Alice")
If you look through the documentation, you will see that the return value of allocatePartyWithHint is Script Party, which means that this line means: “execute the allocatePartyWithHint operation on the ledger, get the answer, and then store that under the name alice`”.
Similarly, submit party cmds is of type Script, which is why we can save aliceTV and bobTV down the line.
So going back to the original question, in
aliceTV <- submitMustFail alice do
aliceTV is defined at this point; it did not exist before. (Each of the four blocks actually defines a “new” aliceTV that has no relationship with the previous one; this is a terrible practice and you should not do that.) All of those blocks really should just be:
submitMustFail alice do ...
Hope that helps.