Guest User

Untitled

a guest
Oct 23rd, 2018
102
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.02 KB | None | 0 0
  1. This proposal is strictly about the contracts part of the generics proposal. It only describes a way to specify contracts using existing types, it does not add antyhing to the parameterized types discussion.
  2.  
  3. # Types are contracts
  4.  
  5. This is a parameterized function:
  6.  
  7. ```
  8. func F(type T)(in T) T {
  9. }
  10. ```
  11.  
  12. Structs and interfaces can also be parameterized:
  13.  
  14. ```
  15. type listNode(type T) struct {
  16. payload T
  17. }
  18.  
  19. type ListNode(type T) interface {
  20. GetPayload() T
  21. }
  22.  
  23. ```
  24.  
  25. Note: better syntax could be found for this
  26.  
  27. Here T is a type. This information is not sufficient to compile the
  28. func, struct, and interface because nothing is know about T. To
  29. specify constraints on T, we add contracts.
  30.  
  31. The idea of this proposal is to use existing types as a contract for
  32. T, as opposed to using an abstract contract syntax that describes
  33. operations and constraints on T.
  34.  
  35. ```
  36. contract stringer interface {
  37. String() string
  38. }
  39. ```
  40.  
  41. Here, the contract stringer is essentially an interface supporting
  42. String() function. A contract can also specify a struct:
  43.  
  44. ```
  45. contract linkedListNode struct {
  46. next *linkedListNode
  47. }
  48. ```
  49.  
  50. The above contract specifies that any type T satisfying the linked
  51. list contract must contain a member called 'next' of some type
  52. satisfying linkedListNode. A more restrictive form of this is:
  53.  
  54. ```
  55. contract linkedListNode struct(type T linkedListNode) {
  56. next *T
  57. }
  58. ```
  59.  
  60. This contract defines linkedListNode as any struct T containing a
  61. member 'next' of type T.
  62.  
  63. ## Contracts with multiple types
  64.  
  65. A contract can list multiple types. In that case, the concrete
  66. implementation must satisfy all types of the contract.
  67.  
  68. ```
  69. contract linkedListNode {
  70. T struct {
  71. next *T
  72. }
  73. interface {
  74. GetNext() T
  75. }
  76. }
  77. ```
  78.  
  79. This linkedListNode contract requires that the concrete type
  80. satisfying this contract must have a 'next' field pointing to the same
  81. struct type as well as a GetNext() T function.
  82.  
  83. ## Mutually referential type parameters and parameterized contracts
  84.  
  85. Since contracts are types, this is described in a way that's more
  86. go-like:
  87.  
  88. Using interfaces only:
  89.  
  90. ```
  91. package graph
  92.  
  93. contract Node interface(type E Edge) {
  94. Edges() []E
  95. }
  96.  
  97. contract Edge interface(type N Node) {
  98. Nodes() (N,N)
  99. }
  100.  
  101. type Graph(type N Node, type E Edge) struct {
  102. nodes []N(E)
  103. }
  104. func New(type N Node,type E Edge)(nodes []N) *Graph(N,E) {
  105. }
  106. ```
  107.  
  108. Above, Graph is a parameterized type with Node and Edge types that
  109. must satisfy the given contract. Since Node and Edge are contracts, we
  110. must define structs satisfying those contracts:
  111.  
  112. ```
  113. type MyNode struct {
  114. edges []*MyEdge
  115. }
  116. func (m MyNode) Edges() []MyEdge {return m.edges}
  117.  
  118. type MyEdge struct {
  119. from, to *MyNode
  120. }
  121. func (e MyEdge) Nodes() (*MyEdge,*MyEdge) {return e.from,e.to}
  122.  
  123. func f() {
  124. var g:=graph.New(*MyNode,*MyEdge)(MyNode{...})
  125. }
  126. ```
  127.  
  128. An alternative contract specification is:
  129. ```
  130. package graph
  131.  
  132. contract Node(type E Edge) {
  133. struct {
  134. edges []*E
  135. }
  136. interface {
  137. GetEdges() []*E
  138. }
  139. }
  140.  
  141. contract Edge(type N Node) {
  142. struct {
  143. from,to *N
  144. }
  145. interface {
  146. GetFrom() *N
  147. GetTo() *N
  148. }
  149. }
  150.  
  151. contract Graph(type N Node,type E Edge) {
  152. struct {
  153. nodes []*N
  154. }
  155. }
  156. ```
  157.  
  158. ## Contracts using primitive types and 'like' keyword
  159.  
  160. Contracts can be defined in terms of primitive types:
  161.  
  162. ```
  163. contract unsigned {
  164. like (byte, uint8, uint16, uint32, uint64, uint)
  165. }
  166. ```
  167.  
  168. A type T satisfying the 'unsigned' contract can be any one of the
  169. listed types, or a type derived from any of those types.
  170.  
  171. In general, "like (x,y,...)" within a contract definition implies that
  172. the contrete type satisfying the contract must be one of x, y,... or a
  173. type derived from those.
  174.  
  175. This allows interesting contracts such as:
  176.  
  177. ```
  178. contract numberStringer {
  179. like (byte,uint8, uint16,... <list all numeric types>)
  180. interface {
  181. String() string
  182. }
  183. }
  184. ```
  185.  
  186. The above definition means that a concrete type T must be a type
  187. derived from the listed numeric types, and it must implement the
  188. String() string function.
  189.  
  190. With this style of contract definition, the standard library can
  191. contain a library of common constraints such as integers, floats,
  192. unsigned, signed, etc.
  193.  
  194. One problem this cannot address is == operator. This requires a
  195. built-in contract, something like "supportsEqual". Then we can also
  196. define:
  197.  
  198. ```
  199. contract MapKey {
  200. supportsEqual
  201. }
  202. ```
  203.  
  204. ## Examples from the proposal
  205.  
  206. ### Sort
  207.  
  208. This example defines an ordered contract, and such a contract can also be included in
  209. the library of predefined contracts as:
  210.  
  211. ```
  212. contract Ordered {
  213. like(numeric types, string, ...)
  214. }
  215. ```
  216.  
  217. ### Map keys
  218.  
  219. MapKey would be a predefined contract defined using the "supportsEqual" builtin
  220.  
  221. ### Sets
  222.  
  223. Contract comparable in this example is the same this as supportsEqual builtin.
  224.  
  225. ### Metrics
  226.  
  227. ```
  228. contract Metric1 struct(type T MapKey) {
  229. sync.Mutex
  230. m map[T]int
  231. }
  232.  
  233. func (m *M) Add(type M Metric1(T))(v T) {
  234. m.Lock()
  235. defer m.Unlock()
  236. if m.m==nil {
  237. m.m=make(map[T]int)
  238. }
  239. m[v]++
  240. }
  241. ```
  242.  
  243. Above Metric1 is defined as a contract. Metric1 can also be defined as
  244. a parameterized struct, as done in the official proposal.
  245.  
  246. ### List transform
  247.  
  248. No changes to the official proposal version.
Add Comment
Please, Sign In to add comment