# Generics / Templates in Solidity ***Notes from the Solidity language design discussion call on Wed, 2nd of Sept, 5 PM CEST*** **Invite**: https://groups.google.com/g/solidity-users/c/OSeyrReiE6M **Issue**: https://github.com/ethereum/solidity/issues/869 **Example**: https://gist.github.com/chriseth/d8bf126817fa236c0406c130433a0a7e **Attendees**: Alex B, Solidity Chris R, Solidity Daniel, Solidity Francisco G, OpenZeppelin Franzi H, Solidity Goncalo S, ConsenSys Diligence Harry A, Truffle Josselin F, Trail of Bits Mirko S, Nick D, Truffle Nicolás V, Balancer Richard M, Gnosis Safe ### Conclusion/ Summary - Templates/generics *seem* to be potentially useful, but the exact use cases and the degree to which they would be used is still a bit in the dark - Main questions with regards to implementation: How would it work with data location and (how) would we implement constraints? ## Notes - Discussion around the template example: https://gist.github.com/chriseth/d8bf126817fa236c0406c130433a0a7e - Angle brackets? Some parsing concerns but [something about using `:` separator in certain contexts] ### General pros/cons for templates: - Too large code bases since templates don't exist yet - Pre-processor before compiler as alternative for templates? - Value of the type system, therefore templates/generics preferred? - Feedback from a team with big code base "for us templates and generics would reduce a lot of duplicated code and make our codebase more consistent." ### How could implementation look like? - Do we want to have constraints/restrictions on generic type variables? - Quality of error messages quite bad when type checking is done after expansion. Restrictions would improve this - How do we formulate constraints given that there are no internal interfaces - Explore shipping templates without constraints first? - Or going first with one hard-coded constraint? - Is it useful to do templates for boolean types? - How to deal with data locations? - Need a way to write different implementations depending on the data location; but shouldn't mean that data location can't be part of the template - Let's find use cases for templates --> write templates for the use cases, as a start - Assessment needed? How big is the need for templates actually? - Goal for templates / generics: not really to reduce lines of code but rather have "trusted" reusable modules - Gas savings via specialization for subset of types? Are there use cases that would benefit from that? - How will it be compiled? Will there be a separate piece of bytecode for every instanciation? - Using function pointers? - Would DEXes need templates/generics? - VPN protocol was using binary trie for payments: https://github.com/OrchidTechnologies/orchid/blob/master/dir-ethereum/directory.sol - Use a macro system outside of the compiler? - https://github.com/lamarkaz/psol ### Other languages Go's journey: - https://blog.golang.org/generics-next-step - The actual proposal: https://go.googlesource.com/proposal/+/refs/heads/master/design/go2draft-contracts.md ### What are use cases for templates? 1) Containers OpenZeppelin - EnumerableMaps: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/885b76f66f8660bed46930011d606c1a98921c94/contracts/utils/EnumerableMap.sol - EnumerableSets: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/885b76f66f8660bed46930011d606c1a98921c94/contracts/utils/EnumerableSet.sol - Merkle Trees: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/885b76f66f8660bed46930011d606c1a98921c94/contracts/cryptography/MerkleProof.sol 2) Similar, but slightly different, structs - https://github.com/atpar/ap-monorepo/blob/dev/packages/actus-solidity/contracts/Core/ACTUSTypes.sol - https://github.com/atpar/ap-monorepo/blob/dev/packages/ap-contracts/contracts/Core/Base/AssetActor/BaseActor.sol - https://github.com/atpar/ap-monorepo/blob/dev/packages/ap-contracts/contracts/Core/Base/AssetRegistry/Terms/TermsRegistry.sol 3) "Operators" - https://github.com/trufflesuite/truffle/blob/develop/packages/core/lib/testing/Assert.sol (wrapper) and see directory for concrete types: https://github.com/trufflesuite/truffle/tree/develop/packages/core/lib/testing 4) Eternal storage @gnidan could perhaps repeat his explanation I missed :wink: Eternal storage defines getters/setters separately for each supported type. e.g., see https://github.com/ethereum/EIPs/issues/930, e.g. `setAddress`, `setBoolean`, etc. This works fine for primitives because they are relatively finite, but structs are out of the question for Eternal storage. 5) Algorithms - ERC20Snapshot uses a binary search. Generics not necessary but would make code more natural. https://github.com/OpenZeppelin/openzeppelin-contracts/blob/885b76f66f8660bed46930011d606c1a98921c94/contracts/token/ERC20/ERC20Snapshot.sol