Informative error messages could help a lot to Daml learners.
Unfortunately, the current error messages don’t reference the Daml template surface syntax, which is syntactic sugar over some underlying code, but the underlying code itself, which can be confusing for beginners.
Let me show you an example. I start with the Asset
template of the skeleton project template, mess up the Give
choice return type declaration, and examine if the error message is understandable for beginners. (Spoiler: it’s not.)
The first statement in the error message is:
Couldn't match type ‘ContractId Asset’ with ‘Text’
Expected type: Update Text
Actual type: Update (ContractId Asset)
One element of the error message, namely that in the code marked with red we have a type mismatch, is clear. Also, if we know where to look, we can conclude that somewhere else in the code we have to substitute Text
with ‘ContractId Asset’, for which we have a type synonyme, AssetId
.
What about the detailed explanation?
Advanced learners of Daml know, that a choice is actually a function with a return value of Update a
. This must be so, because the effect of a choice is a ledger update, which cannot be expressed by a pure function. The a
part of the Update a
expression describes the type of the value returned in the case of a successful ledger update, which may or may not succeed. The description of the Update a
data type from the docs is the following:
The
Update a
type represents anAction
to update or query the ledger, before returning a value of typea
. Examples includecreate
andfetch
.
The template surface syntax omits the Update
part of the actual Update a
return type declaration, as explained at one section of the docs, in the chapter 4 Transforming data using choices:
In my experience the fact, that the simple choice return type is actually a shortcut, is not well known for beginners. On one hand, it is convenient that we don’t have to repeat the boilerplate Update
part of the return type declaration. On the other hand, as every shortcut which is not know to be a shortcut, is confusing, and can make the false impression that we deal with a pure function here.
And the error message in this form doesn’t help to understand the real meaning of the choice return type declaration.
The second part of the error message is even more confusing to beginners:
In a stmt of a 'do' block: create setField @"owner" newOwner this
In the expression: do create setField @"owner" newOwner this
In the expression:
let _ = arg in do create setField @"owner" newOwner this
In order to understand this, you have to know that the with owner = newOwner
part of the surface syntax is sugar over setField @"owner" newOwner
, which uses the setField
function from the DA.Record module of the standard library.
And finally, I have to admit that I don’t understand the let _ = arg in
part of the error message, just conclude that it must be the underlying code for the this
keyword.