1# `cty` types
2
3This page covers in detail all of the primitive types and compound type kinds supported within `cty`. For more general background information, see
4[the `cty` overview](./concepts.md).
5
6## Common Operations and Integration Methods
7
8The following methods apply to all values:
9
10* `Type` returns the type of the value, as a `cty.Type` instance.
11* `Equals` returns a `cty.Bool` that is `cty.True` if the receiver and the
12  given other value are equal. This is an operation method, so its result
13  will be unknown if either argument is unknown.
14* `RawEquals` is similar to `Equals` except that it doesn't implement the
15  usual special behavior for unknowns and dynamic values, and it returns a
16  native Go `bool` as its result. This method is intended for use in tests;
17  `Equals` should be preferred for most uses.
18* `IsKnown` returns `true` if the receiver is a known value, or `false`
19  if it is an unknown value.
20* `IsNull` returns `true` if the receiver is a null value, or `false`
21  otherwise.
22
23All values except capsule-typed values can be serialized with the builtin
24Go package `encoding/gob`. Values can also be used with the `%#v` pattern
25in the `fmt` package to print out a Go-oriented serialization of the
26value.
27
28## Primitive Types
29
30### `cty.Number`
31
32The number type represents arbitrary-precision floating point numbers.
33
34Since numbers are arbitrary-precision, there is no need to worry about
35integer overflow/underflow or loss of precision during arithmetic operations.
36However, eventually a calling application will probably want to convert a
37number to one of the Go numeric types, at which point its range will be
38constrained to fit within that type, generating an error if it does not fit.
39
40The following additional operations are supported on numbers:
41
42* `Absolute` converts a negative value to a positive value of the same
43  magnitude.
44* `Add` computes the sum of two numbers.
45* `Divide` divides the receiver by another number.
46* `GreaterThan` returns `cty.True` if the receiver is greater than the other
47  given number.
48* `GreaterThanOrEqualTo` returns `cty.True` if the receiver is greater than or
49  equal to the other given number.
50* `LessThan` returns `cty.True` if the receiver is less than the other given
51  number.
52* `LessThanOrEqualTo` returns `cty.True` if the receiver is less than or
53  equal to the other given number.
54* `Modulo` computes the remainder from integer division of the receiver by
55  the other given number.
56* `Multiply` computes the product of two numbers.
57* `Negate` inverts the sign of the number.
58* `Subtract` computes the difference between two numbers.
59
60`cty.Number` values can be constructed using several different factory
61functions:
62
63* `NumberVal` creates a number value from a `*big.Float`, from the `math/big` package.
64* `NumberIntVal` creates a number value from a native `int64` value.
65* `NumberUIntVal` creates a number value from a native `uint64` value.
66* `NumberFloatVal` creates a number value from a native `float64` value.
67
68The core API only allows extracting the value from a known number as a
69`*big.Float` using the `AsBigFloat` method. However,
70[the `gocty` package](./gocty.md) provides a more convenient way to convert
71numbers to any native Go number type, with automatic range checking to ensure
72that the value fits into the target type.
73
74The following numbers are provided as package variables for convenience:
75
76* `cty.Zero` is the number zero.
77* `cty.PositiveInfinity` represents positive infinity as a number. All other
78  numbers are less than this value.
79* `cty.NegativeInfinity` represents negative infinity as a number. All other
80  numbers are greater than this value.
81
82### `cty.String`
83
84The string type represents a sequence of unicode codepoints.
85
86There are no additional operations supported for strings.
87
88`cty.String` values can be constructed using the `cty.StringVal` factory
89function. The native Go `string` passed in must be a valid UTF-8 sequence,
90and it will be normalized such that any combining diacritics are converted
91to precomposed forms where available. (Technically-speaking, the mapping
92applied is the NFC normalization as defined in the relevant Unicode
93specifications.)
94
95The `AsString` method can be called on a string value to obtain the native
96Go `string` representation of a known string, after normalization.
97
98### `cty.Bool`
99
100The bool type represents boolean (true or false) values.
101
102The following additional operations are supported on bool values:
103
104* `And` computes the logical AND operation for two boolean values.
105* `Not` returns the boolean opposite of the receiver.
106* `Or` computes the logical OR operation for two boolean values.
107
108Calling applications may either work directly with the predefined `cty.True`
109and `cty.False` variables, or dynamically create a boolean value using
110`cty.BoolVal`.
111
112The `True` method returns a native Go `bool` representing a known boolean
113value. The `False` method returns the opposite of it.
114
115## Collection Type Kinds
116
117`cty` has three different kinds of collection type. All three of them are
118parameterized with a single _element type_ to produce a collection type.
119The difference between the kinds is how the elements are internally organized
120and what operations are used to retrieve them.
121
122### `cty.List` types
123
124List types are ordered sequences of values, accessed using consecutive
125integers starting at zero.
126
127The following operations apply to values of a list type:
128
129* `Index` can be passed an integer number less than the list's length to
130  retrieve one of the list elements.
131* `HasIndex` can be used to determine if a particular call to `Index` would
132  succeed.
133* `Length` returns a number representing the number of elements in the list.
134  The highest integer that can be passed to `Index` is one less than this
135  number.
136
137List types are created by passing an element type to the function `cty.List`.
138List _values_ can be created by passing a type-homogenous `[]cty.Value`
139to `cty.ListVal`, or by passing an element type to `cty.ListValEmpty`.
140
141The following integration methods can be used with known list-typed values:
142
143* `LengthInt` returns the length of the list as a native Go `int`.
144* `ElementIterator` returns an object that can be used to iterate over the
145  list elements.
146* `ForEachElement` runs a given callback function for each element.
147
148### `cty.Map` types
149
150Map types are collection values that are each assigned a unique string key.
151
152The following operations apply to values of a map type:
153
154* `Index` can be passed a string value to retrieve the corresponding
155  element.
156* `HasIndex` can be used to determine if a particular call to `Index` would
157  succeed.
158* `Length` returns a number representing the number of elements in the map.
159
160Map types are created by passing an element type to the function `cty.Map`.
161Map _values_ can be created by passing a type-homogenous `map[string]cty.Value`
162to `cty.MapVal`, or by passing an element type to `cty.MapValEmpty`.
163
164The following integration methods can be used with known map-typed values:
165
166* `LengthInt` returns the number of elements as a native Go `int`.
167* `ElementIterator` returns an object that can be used to iterate over the
168  map elements in lexicographical order by key.
169* `ForEachElement` runs a given callback function for each element in the
170  same order as the `ElementIterator`.
171
172### `cty.Set` types
173
174Set types are collection values that model a mathematical set, where every
175possible value is either in or out of the set. Thus each set element value is
176its own identity in the set, and a given value cannot appear twice in the same
177set.
178
179The following operations apply to values of a set type:
180
181* `HasIndex` can be used to determine whether a particular value is in the
182  receiving set..
183* `Length` returns a number representing the number of elements in the set.
184* `Index` is not particularly useful for sets, but for symmetry with the
185  other collection types it may be passed a value that is in the set and it
186  will then return that same value.
187
188Set types are created by passing an element type to the function `cty.Set`.
189Set _values_ can be created by passing a type-homogenous `[]cty.Value` to
190`cty.SetVal`, though the result is undefined if two values in the slice are
191equal. Alternatively, an empty set can be constructed using `cty.SetValEmpty`.
192
193The following integration methods can be used with known set-typed values:
194
195* `LengthInt` returns the number of elements as a native Go `int`.
196* `ElementIterator` returns an object that can be used to iterate over the
197  set elements in an undefined (but consistent) order.
198* `ForEachElement` runs a given callback function for each element in the
199  same order as the `ElementIterator`.
200
201Set membership is determined by equality, which has an interesting consequence
202for unknown values. Since unknown values are never equal to one another,
203theoretically an infinite number of unknown values can be in a set (constrained
204by available memory) but can never be detected by calls to `HasIndex`.
205
206A set with at least one unknown value in it has an unknown length, because the
207unknown values may or may not match each other (and thus coalesce into a single
208value) once they become known. However, if a set contains a mixture of known
209and unknown values then `HasIndex` will return true for those values because
210they are guaranteed to remain present no matter what final known value each
211of the unknown values takes on.
212
213## Structural Types
214
215`cty` has two different kinds of structural type. They have in common that
216they combine a number of values of arbitrary types together into a single
217value, but differ in how those values are internally organized and in which
218operations are used to retrieve them.
219
220### `cty.Object` types
221
222Object types each have zero or more named attributes that each in turn have
223their own type.
224
225The following operation applies to values of an object type:
226
227* `GetAttr` returns the value of an attribute given its name.
228
229The set of valid attributes for an object type can be inspected using the
230following methods on the type itself:
231
232* `AttributeTypes` returns a `map[string]Type` describing the types of all of
233  the attributes.
234* `AttributeType` returns the type of a single attribute given its name.
235* `HasAttribute` returns `true` if the type has an attribute with the given
236  name.
237
238Object types are constructed by passing a `map[string]Type` to `cty.Object`.
239Object _values_ can be created by passing a `map[string]Value` to
240`cty.ObjectVal`, in which the keys and value types define the object type
241that is implicitly created for that value.
242
243The variable `cty.EmptyObject` contains the object type with no attributes,
244and `cty.EmptyObjectVal` is the only non-null, known value of that type.
245
246There is **currently-experimental** support for creating object types where
247one or more attributes is annotated as being "optional", using the alternative
248constructor `cty.ObjectWithOptionalAttrs`. The behavior of that function or
249of any other function working with its result is subject to change even in
250future minor versions of `cty`. The optional-attribute annotations are
251considered only during type conversion, so for more information refer to
252the guide [Converting between `cty` types](convert.md).
253
254### `cty.Tuple` types
255
256Tuple types each have zero or more elements, each with its own type, arranged
257in a sequence and accessed by integer numbers starting at zero.
258
259A tuple type is therefore somewhat similar to a list type, but rather than
260representing an arbitrary number of values of a single type it represents a
261fixed number of values that may have _different_ types.
262
263The following operations apply to values of a tuple type:
264
265* `Index` can be passed an integer number less than the tuple's length to
266  retrieve one of the tuple elements.
267* `HasIndex` can be used to determine if a particular call to `Index` would
268  succeed.
269* `Length` returns a number representing the number of elements in the tuple.
270  The highest integer that can be passed to `Index` is one less than this
271  number.
272
273Tuple types are created by passing a `[]cty.Type` to the function `cty.Tuple`.
274Tuple _values_ can be created by passing a `[]cty.Value` to `cty.TupleVal`,
275in which the value types define the tuple type that is implicitly created
276for that value.
277
278The variable `cty.EmptyTuple` contains the tuple type with no elements,
279and `cty.EmptyTupleVal` is the only non-null, known value of that type.
280
281The following integration methods can be used with known tuple-typed values:
282
283* `LengthInt` returns the length of the tuple as a native Go `int`.
284* `ElementIterator` returns an object that can be used to iterate over the
285  tuple elements.
286* `ForEachElement` runs a given callback function for each element.
287
288## The Dynamic Pseudo-Type
289
290The dynamic pseudo-type is not a real type but is rather a _placeholder_ for
291a type that isn't known.
292
293One consequence of this being a "pseudo-type" is that there is no known,
294non-null value of this type, but `cty.DynamicVal` is the unknown value of
295this type, and a null value without a known type can be represented by
296`cty.NullVal(cty.DynamicPseudoType)`.
297
298This pseudo-type serves two similar purposes as a placeholder type:
299
300* When `cty.DynamicVal` is used in an operation with another value, the
301  result is either itself `cty.DynamicVal` or it is an unknown value of
302  some suitable type. This allows the dynamic pseudo-type to be used as
303  a placeholder during type checking, optimistically assuming that the
304  eventually-determined type will be compatible and failing at that
305  later point if not.
306* `cty.DynamicPseudoType` can be used with the type `TestConformance` method
307  to declare that any type is permitted in the type being tested for
308  conformance.
309
310`cty` doesn't have _sum types_ (i.e. union types), so `cty.DynamicPseudoType`
311can be used also to represent situations where two or more specific types are
312allowed, under the assumption that more specific type checking will be done
313within the calling application's own logic even though it cannot be expressed
314directly within the `cty` type system.
315
316## Capsule Types
317
318Capsule types are a special kind of type that allows a calling application to
319"smuggle" otherwise-unsupported Go values through the `cty` type system.
320
321Such types and their associated values have no defined meaning in `cty`. The
322interpreter for a language building on `cty` might use capsule types for
323passing language-specific objects between functions provided in that language.
324
325A capsule type is created using the function `cty.Capsule`, which takes a
326"friendly name" for the type along with a `reflect.Type` that defines what
327type of Go value will be encapsulated in values of this type. A capsule-typed
328value can then be created by passing the capsule type and a pointer to a
329native value of the encapsulated type to `cty.CapsuleVal`.
330
331The integration method `EncapsulatedValue` allows the encapsulated data to
332then later be retrieved.
333
334Capsule types compare by reference, so each call to `cty.Capsule` produces
335a distinct type. Capsule _values_ compare by pointer equality, so two
336capsule values are equal if they have the same capsule type and they
337encapsulate a pointer to the same object.
338
339Due to the strange nature of capsule types, they are not totally supported
340by all of the other packages that build on the core `cty` API. They should
341be used with care and the documentation for other packages should be consulted
342for information about caveats and constraints relating to their use.
343
344It's possible for a calling application to write additional logic to make
345capsule types support a subset of operations that are generally expected to
346work for values of any type. For more information, see
347[capsule type operation definitions](./capsule-type-operations.md).
348