Proposal: Fixing generic templates over the Ledger API
See original GitHub issueCurrent Status
If you define a generic template in DAML, we currently create a record with the corresponding type parameters and the name of the generic templates. Once you create an instance of that generic template, we will create a new record in DAML-LF with the type parameters specialized to the ones in the instance and with the name of the instance. In DAML-LF those two records are unrelated and only the monomorphized record is a template. In DAML, the monomorphized record does not exist. We only create a type synoynym for the specialized version of the generic record.
The functions for interacting with the generic template take care of monomorphizing things as necessary, e.g., create
in DAML generates a DAM-LF function that takes the generic record, converts it to the monomorphic record and then calls the DAML-LF create primitive. Similarly for exercise
and other methods.
However, this falls apart once you interact with a generic template via the Ledger API. E.g., if you a choice returning a value of type type FooA = Foo A
in DAML, the DAML-LF return type will be Foo A
. However, that type is not a template, so if you try to pass the result of the choice to a create
it will complain about a mismatch (if you omit the record id, you get lucky but imho that is more of an accident). It is even worse, if you have a choice accepting a ContractId FooA
in DAML. The DAML-LF choice accepts a ContractId (Foo A)
which passes the LF typechecker. However, if you try to exercise this choice, the engine will throw an error complaining that Foo A
can’t possibly be a template since it has a type parameter so a contract id of that type doesn’t make sense.
Effectively, this makes generic templates pretty much unusable over the Ledger API so we need to do something.
Proposed Changes
DAML-LF
- We separate the name of a template in its from the underlying record type. The underlying record type is allowed to have type parameters but all of them must be fixed.
- Defining a template creates a synonym of the name of the template in DAML-LF for the specialized record type. Note that the synonym can be in a different package and module than the record type.
- When specifying the template id in the Ledger API you must use the name given in the template definition, not the record identifier.
- As a record during typechecking, validation in the engine, … the name given in the template is interchangeable with the record type. This includes the record id on a create.
- Both
ContractId (Foo X)
andContractId FooX
are valid over the ledger API. - There is no unique mapping from
Foo X
toFooX
in general as there can be two templates for the same record type specialization in different modules and/or different packages. - The primitives in DAML-LF, most notably
create
andexercise
will continue to require a template id instead of the record it.
Open Questions
- Should we also lift restrictions for non-generic templates, i.e., record types without type parameters? In particular, do we keep the restriction that template name and constructor type constructor are identical and must be defined in the same module? Personally, I think we should to keep things as simple as possible and not complicate non-generic templates.
- How do we handle this in codegens? Currently, codegens automatically decode to the high-level
ContractId
type which providesexercise
. Given that the mapping fromFoo X
toFooX
is not unique, this is no longer possible. The codegen can only decode toContractId (Foo X)
and then the user has to make a choice which template they want to use which could either be done by something likeconstructor ContractId<FooX>(ContractId<Foo<X>>)
or a static method on theFooX
class with a signature likeexercise(ContractId<Foo<X>>, …)
.
Affected Components
- LF conversion in
damlc
. - LF typechecker in Haskell and Scala.
- Engine validation logic.
- Codegens.
cc @gerolf-da @remyhaemmerle-da @hurryabit @bame-da @tweber-da
Issue Analytics
- State:
- Created 4 years ago
- Comments:8 (8 by maintainers)
Top GitHub Comments
Great, I completely agree with that so sounds like we’re all on the same page now 👍
Closing since we decided to postpone generic templates for now, see #3606