Template Modification Fails on Template Role
Reference: GitHub - digital-asset/boat
Am modifying the Boat example with the goal of initially substituting ‘making a Boat’ to ‘planting a Pine Tree’. Once that all works, I’ll modify the Custody and Transfer roles into something more germane. Currently the only sticking point seems to be in the template ManufacturerRole.
template ManufacturerRole
template ManufacturerRole
with
manufacturer: Party
coastGuard: Party
operator: Party
where
signatory operator
observer coastGuard
controller manufacturer can
nonconsuming Manufacture: ContractId Boat
with
name: Text
do
Exchanging the terms manufacturer, coastGuard, and operator for seedling_planter, forest_compliance, and forest_operator works OK.
Seedling_PlanterRole
template Seedling_PlanterRole
with
seedling_planter: Party
forest_compliance: Party
forest_operator: Party
where
signatory forest_operator
observer forest_compliance
controller seedling_planter can
nonconsuming seedling_planter: ContractId Tree
with
name: Text
do
The error from daml start is:
Range: 94:19-94:35
Source: parser
Severity: DsError
Message: daml/Main.daml:94:20: error:parse error on input ‘seedling_planter’
ERROR: Creation of DAR file failed.
Line 94 being: nonconsuming seedling_planter: ContractId Tree
However with the template below, I cannot get my head around what the seedling_planter equivalent for the non-consuming Manufacture should be.
The error is due to capitalization. Choice names need to be calitalized. I’d think that Plant_Seedling is to seedling_planter what Manufacture is to manufacturer so maybe go for nonconsuming Plant_Seedling : ContractId Tree in line 94.
Choice names are types (records, under the hood) and thus must start with a capital letter. You’re also missing a keyword, which is more likely the immediate issue here: nonconsuming must be followed by choice; as in
EDIT: As @bernhard kindly pointed out in private, I missed the use of the controller can syntax, which does not include the choice keyword.
Thank you @bernhard und @Gary_Verhaegen 
Now have:
- seedling_planter instead of manufacturer (Noun)
- Plant_Seedling instead of Manufacture (Verb)
- Removed two instances on
boatthat were in the Main.daml
- Removed duplicate
-- forest_compliance = forest_owner
Works now with the exception on a single error.
SDK 1.15.0 has been released!
See https://github.com/digital-asset/daml/releases/tag/v1.15.0 for details.
SDK 1.15.0 has been released!
See https://github.com/digital-asset/daml/releases/tag/v1.15.0 for details.
Compiling tree to a DAR.
File: daml/Main.daml
Hidden: no
Range: 50:14-50:27
Source: typecheck
Severity: DsError
Message: daml/Main.daml:50:15: error: Not in scope: ‘newCompliance’
ERROR: Creation of DAR file failed.
daml-helper: Received ExitFailure 1 when running
Shell command: /home/quid/.daml/bin/daml build
Line 50 newCompliance = owner
However I am not using the term Compliance but forest_compliance`
I think that using hyphenated_words presents syntax-related issues, and that perhaps hyphenatedwords might be a better idea.
Can you share the code you’re using now that produces this error?
As for snake_case vs camelCase both are perfectly fine from a syntax pov. In Haskell, the convention is to use camelCase and we borrowed that for Daml so the standard library uses that consistently and I’d generally recommend to not deviate from that but it’s only a convention. Everything will work perfectly fine if you use snake_case for your own identifiers.
I personally prefer snake_case and use it liberally in both Daml and Haskell (at least when I don’t need to share it; if I’m writing a library, I follow community conventions); not only do I find snake_case easier to read, I also quite like the fact that my identifiers are distinguishable at a glance from library identifiers.
Either way, the part the compiler cares about is that value identifiers start with a lowercase and type (and module) identifiers start with an uppercase. After that you can mix and match underscores, letters and numbers in any combination you see fit.
Your error message seems fairly consistent with your explanations, actually. What it seems to say is that, on line 50, you have
newCompliance = owner
and that is invalid because newCompliance does not exist in the current scope. You tell us you’re using forest_compliance as an identifier, so it’s not very surprising that newCompliance does not exist.
If that line is expected to introduce a new identifier, the syntax is incorrect. Depending on context, it must be either (in a do block, if right-hand-side is an action)
newCompliance <- someActionOf owner
or (in a do block, if right-hand-side is a pure value)
let newCompliance = owner
or (outside of a do block`)
let newCompliance = owner
in ...
The line newCompliance = owner could be valid syntax for introducing a new binding, but only in the context of a where clause, and if that were the context you’re in, it wouldn’t be reporting an error.
The other possibilities I can see are:
- You want to do a comparison rather than introduce a new binding; in that case, you want
==instead of=. - You are trying to assign a value to the field of a record, in which case you need to change
newComplianceto instead be the name of the field in that record (perhaps that isforest_compliance?).
As @cocreature mentioned, it would be a lot easier to help you if you provided a bit more context than the single failing line.