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.