question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Proposal: Fixing generic templates over the Ledger API

See original GitHub issue

Current 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) and ContractId FooX are valid over the ledger API.
  • There is no unique mapping from Foo X to FooX 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 and exercise 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 provides exercise. Given that the mapping from Foo X to FooX is not unique, this is no longer possible. The codegen can only decode to ContractId (Foo X) and then the user has to make a choice which template they want to use which could either be done by something like constructor ContractId<FooX>(ContractId<Foo<X>>) or a static method on the FooX class with a signature like exercise(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:closed
  • Created 4 years ago
  • Comments:8 (8 by maintainers)

github_iconTop GitHub Comments

2reactions
cocreaturecommented, Nov 19, 2019

Great, I completely agree with that so sounds like we’re all on the same page now 👍

0reactions
cocreaturecommented, Nov 25, 2019

Closing since we decided to postpone generic templates for now, see #3606

Read more comments on GitHub >

github_iconTop Results From Across the Web

Generic Templates — DAML SDK 2019-11-07 documentation
Generic templates allow you to capture this logic in a single place, instead of having to ... This is how the generic Proposal...
Read more >
Release of Daml SDK v0.13.29 - Digital Asset Blog
Releases can now bundle additional libraries with the SDK in $Daml_SDK/daml-libs . ... Generic template instantiations like template instance IouProposal ...
Read more >
GitHub - input-output-hk/cardano-ledger
This repository contains the formal specifications, executable models, and implementations of the Cardano Ledger. The documents are built in our CI and can...
Read more >
Operational Processes — Canton 0.26.0 documentation
As contracts (1) “belong to” parties and (2) are instances of Daml templates defined in Daml Archives (DARs), importing contracts to Canton also...
Read more >
Fix my Bike Again: Demonstration of Navigator in Daml
There are two views in Navigator: Contracts and Templates. ... After the ledger is updated, we now see the BikeRepairProposal contract gone, ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found