Documentation ¶
Overview ¶
Package types provides a framework for our mcl language values and types.
Index ¶
- Constants
- Variables
- func Into(v Value, rv reflect.Value) error
- func IsComparableKind(kind Kind) bool
- func Iter(typ *Type, fn func(*Type) error) error
- func TypeStructTagToFieldName(st reflect.Type) (map[string]string, error)
- type Base
- type BoolValue
- type Elem
- type FloatValue
- type FuncValue
- func (obj *FuncValue) Call(ctx context.Context, args []Value) (Value, error)
- func (obj *FuncValue) Cmp(val Value) error
- func (obj *FuncValue) Copy() Value
- func (obj *FuncValue) Less(v Value) bool
- func (obj *FuncValue) String() string
- func (obj *FuncValue) Type() *Type
- func (obj *FuncValue) Value() interface{}
- type IntValue
- type Kind
- type ListValue
- func (obj *ListValue) Add(v Value) error
- func (obj *ListValue) Cmp(val Value) error
- func (obj *ListValue) Contains(v Value) (index int, exists bool)
- func (obj *ListValue) Copy() Value
- func (obj *ListValue) Less(v Value) bool
- func (obj *ListValue) List() []Value
- func (obj *ListValue) Lookup(index int) (value Value, exists bool)
- func (obj *ListValue) String() string
- func (obj *ListValue) Type() *Type
- func (obj *ListValue) Value() interface{}
- type MapValue
- func (obj *MapValue) Add(k, v Value) error
- func (obj *MapValue) Cmp(val Value) error
- func (obj *MapValue) Copy() Value
- func (obj *MapValue) Less(v Value) bool
- func (obj *MapValue) Lookup(key Value) (value Value, exists bool)
- func (obj *MapValue) Map() map[Value]Value
- func (obj *MapValue) String() string
- func (obj *MapValue) Type() *Type
- func (obj *MapValue) Value() interface{}
- type StrValue
- type StructValue
- func (obj *StructValue) Cmp(val Value) error
- func (obj *StructValue) Copy() Value
- func (obj *StructValue) Less(v Value) bool
- func (obj *StructValue) Lookup(k string) (value Value, exists bool)
- func (obj *StructValue) Set(k string, v Value) error
- func (obj *StructValue) String() string
- func (obj *StructValue) Struct() map[string]Value
- func (obj *StructValue) Type() *Type
- func (obj *StructValue) Value() interface{}
- type Type
- func (obj *Type) Cmp(typ *Type) error
- func (obj *Type) ComplexCmp(typ *Type) (string, error)
- func (obj *Type) Copy() *Type
- func (obj *Type) HasUni() bool
- func (obj *Type) HasVariant() bool
- func (obj *Type) New() Value
- func (obj *Type) Reflect() reflect.Type
- func (obj *Type) String() string
- func (obj *Type) Underlying() *Type
- type TypeOfOption
- func AllowInterfaceTypeOpt(allowInterfaceType bool) TypeOfOption
- func SkipBadStructFieldsOpt(skipBadStructFields bool) TypeOfOption
- func SkipPrivateFieldsOpt(skipPrivateFields bool) TypeOfOption
- func StrictStructTagOpt(strictStructTag bool) TypeOfOption
- func StructTagOpt(structTag string) TypeOfOption
- type UnifiedState
- type Value
- type ValueSlice
- type VariantValue
- func (obj *VariantValue) Bool() bool
- func (obj *VariantValue) Cmp(val Value) error
- func (obj *VariantValue) Copy() Value
- func (obj *VariantValue) Float() float64
- func (obj *VariantValue) Func() interface{}
- func (obj *VariantValue) Int() int64
- func (obj *VariantValue) Less(v Value) bool
- func (obj *VariantValue) List() []Value
- func (obj *VariantValue) Map() map[Value]Value
- func (obj *VariantValue) Str() string
- func (obj *VariantValue) String() string
- func (obj *VariantValue) Struct() map[string]Value
- func (obj *VariantValue) Type() *Type
- func (obj *VariantValue) Value() interface{}
Constants ¶
const ( // StructTag is the key we use in struct field names for key mapping. StructTag = "lang" // MaxInt8 is 127. It's max uint8: ^uint8(0), then we >> 1 for max int8. MaxInt8 = int((^uint8(0)) >> 1) )
Variables ¶
var ( TypeBool = NewType("bool") TypeStr = NewType("str") TypeInt = NewType("int") TypeFloat = NewType("float") TypeListStr = NewType("[]str") TypeVariant = NewType("variant") )
Basic types defined here as a convenience for use with Type.Cmp(X).
var ( // ErrNilValue is returned when ValueOf() attempts to represent a nil // pointer as an mcl value. This is not supported in mcl. ErrNilValue = errors.New("cannot represent a nil golang value in mcl") // ErrInvalidValue is returned when ValueOf() is called on an invalid or // zero reflect.Value. ErrInvalidValue = errors.New("cannot represent invalid reflect.Value") )
Functions ¶
func Into ¶
Into mutates the given reflect.Value with the data represented by the Value.
Container types like map/list (and to a certain extent structs) will be cleared before adding the contained data such that the existing data doesn't affect the outcome, and the output reflect.Value directly maps to the input Value.
In almost every case, it is likely that the reflect.Value will be modified, instantiating nil pointers and even potentially partially filling data before returning an error. It should be assumed that if this returns an error, the reflect.Value passed in has been trashed and should be discarded before reuse.
func IsComparableKind ¶
IsComparableKind returns true if you pass it a comparable kind. These have a Cmp method on the Value interface that won't panic. Notably KindFunc and any other special kinds are not present in this list.
func Iter ¶
Iter applies a function to each type in the top-level type. It stops if that function errors, and returns that error to the top-level caller. It panics if it encounters an invalid or partial type struct. This version starts at the top and works its way deeper.
func TypeStructTagToFieldName ¶
TypeStructTagToFieldName returns a mapping from recommended alias to actual field name. It returns an error if it finds a collision. It uses the `lang` tags. It must be passed a reflect.Type representation of a struct or it will error. TODO: This is a copy of engineUtil.StructTagToFieldName taking a reflect.Type
Types ¶
type Base ¶
type Base struct{}
Base implements the missing methods that all types need.
func (*Base) Bool ¶
Bool represents the value of this type as a bool if it is one. If this is not a bool, then this panics.
func (*Base) Float ¶
Float represents the value of this type as a float if it is one. If this is not a float, then this panics.
func (*Base) Func ¶
func (obj *Base) Func() interface{}
Func represents the value of this type as a function if it is one. If this is not a function, then this panics.
func (*Base) Int ¶
Int represents the value of this type as an integer if it is one. If this is not an integer, then this panics.
func (*Base) List ¶
List represents the value of this type as a list if it is one. If this is not a list, then this panics.
func (*Base) Map ¶
Map represents the value of this type as a dictionary if it is one. If this is not a map, then this panics.
type BoolValue ¶
BoolValue represents a boolean value.
func (*BoolValue) Bool ¶
Bool represents the value of this type as a bool if it is one. If this is not a bool, then this panics.
func (*BoolValue) Less ¶
Less compares to value and returns true if we're smaller. This panics if the two types aren't the same.
type Elem ¶
Elem is the type used for the unification variable in the Uni field of Type. We create this alias here to avoid needing to write *disjoint.Elem[*Type] all over. This is a golang type alias. These should be created with NewElem.
type FloatValue ¶
FloatValue represents an integer value.
func (*FloatValue) Cmp ¶
func (obj *FloatValue) Cmp(val Value) error
Cmp returns an error if this value isn't the same as the arg passed in.
func (*FloatValue) Float ¶
func (obj *FloatValue) Float() float64
Float represents the value of this type as a float if it is one. If this is not a float, then this panics.
func (*FloatValue) Less ¶
func (obj *FloatValue) Less(v Value) bool
Less compares to value and returns true if we're smaller. This panics if the two types aren't the same.
func (*FloatValue) String ¶
func (obj *FloatValue) String() string
String returns a visual representation of this value.
func (*FloatValue) Type ¶
func (obj *FloatValue) Type() *Type
Type returns the type data structure that represents this type.
func (*FloatValue) Value ¶
func (obj *FloatValue) Value() interface{}
Value returns the raw value of this type.
type FuncValue ¶
type FuncValue struct { Base V func(context.Context, []Value) (Value, error) T *Type // contains ordered field types, arg names are a bonus part }
FuncValue represents a function which takes a list of Value arguments and returns a Value. It can also return an error which could represent that something went horribly wrong. (Think, an internal panic.)
This is not general enough to represent all functions in the language (see the full.FuncValue), but it is a useful common case.
FuncValue is not a Value, but it is a useful building block for implementing Func nodes.
func NewFunc ¶
NewFunc creates a useless function which will get overwritten by something more useful later.
func (*FuncValue) Call ¶
Call runs the function value and returns its result. It returns an error if something goes wrong during execution, and panic's if you call this with inappropriate input types, or if it returns an inappropriate output type.
func (*FuncValue) Cmp ¶
Cmp returns an error if this value isn't the same as the arg passed in. In this situation, they can't be compared so we panic.
func (*FuncValue) Less ¶
Less compares to value and returns true if we're smaller. This panics if the two types aren't the same. In this situation, they can't be compared so we panic.
type IntValue ¶
IntValue represents an integer value.
func (*IntValue) Int ¶
Int represents the value of this type as an integer if it is one. If this is not an integer, then this panics.
func (*IntValue) Less ¶
Less compares to value and returns true if we're smaller. This panics if the two types aren't the same.
type Kind ¶
type Kind int // this used to be called Type
The Kind represents the base type of each value.
type ListValue ¶
ListValue represents a list value.
func (*ListValue) Contains ¶
Contains searches for a value in the list. On success it returns the index.
func (*ListValue) Less ¶
Less compares to value and returns true if we're smaller. This panics if the two types aren't the same.
func (*ListValue) List ¶
List represents the value of this type as a list if it is one. If this is not a list, then this panics.
type MapValue ¶
type MapValue struct { Base // the types of all keys and values are represented inside of T V map[Value]Value T *Type }
MapValue represents a dictionary value.
func (*MapValue) Less ¶
Less compares to value and returns true if we're smaller. This panics if the two types aren't the same.
func (*MapValue) Map ¶
Map represents the value of this type as a dictionary if it is one. If this is not a map, then this panics.
type StrValue ¶
StrValue represents a string value.
func (*StrValue) Less ¶
Less compares to value and returns true if we're smaller. This panics if the two types aren't the same.
func (*StrValue) Str ¶
Str represents the value of this type as a string if it is one. If this is not a string, then this panics.
type StructValue ¶
type StructValue struct { Base V map[string]Value // each field can have a different type T *Type // contains ordered field types }
StructValue represents a struct value. The keys are ordered. TODO: if all functions require arg names to call, we don't need to order!
func NewStruct ¶
func NewStruct(t *Type) *StructValue
NewStruct creates a new struct with the specified field types.
func (*StructValue) Cmp ¶
func (obj *StructValue) Cmp(val Value) error
Cmp returns an error if this value isn't the same as the arg passed in.
func (*StructValue) Less ¶
func (obj *StructValue) Less(v Value) bool
Less compares to value and returns true if we're smaller. This panics if the two types aren't the same.
func (*StructValue) Lookup ¶
func (obj *StructValue) Lookup(k string) (value Value, exists bool)
Lookup searches the struct for a key. On success it also returns the Value.
func (*StructValue) Set ¶
func (obj *StructValue) Set(k string, v Value) error
Set sets a field to this value. It errors if the types do not match.
func (*StructValue) String ¶
func (obj *StructValue) String() string
String returns a visual representation of this value.
func (*StructValue) Struct ¶
func (obj *StructValue) Struct() map[string]Value
Struct represents the value of this type as a struct if it is one. If this is not a struct, then this panics.
func (*StructValue) Type ¶
func (obj *StructValue) Type() *Type
Type returns the type data structure that represents this type.
func (*StructValue) Value ¶
func (obj *StructValue) Value() interface{}
Value returns the raw value of this type.
type Type ¶
type Type struct { Kind Kind Val *Type // if Kind == List, use Val only Key *Type // if Kind == Map, use Val and Key Map map[string]*Type // if Kind == Struct, use Map and Ord (for order) Ord []string Out *Type // if Kind == Func, use Map and Ord for Input, Out for Output Var *Type // if Kind == Variant, use Var only // unification variable (question mark, eg ?1, ?2) Uni *Elem // if Kind == Unification (optional) use Uni only }
Type is the datastructure representing any type. It can be recursive for container types like lists, maps, and structs. TODO: should we create a `Type` interface?
func ConfigurableTypeOf ¶
func ConfigurableTypeOf(t reflect.Type, opts ...TypeOfOption) (*Type, error)
ConfigurableTypeOf is a configurable version of the TypeOf function to avoid repeating code for the different variants of it that we want.
func ResTypeOf ¶
ResTypeOf is almost identical to TypeOf, except it behaves slightly differently so that it can return what is needed for resources.
func TypeOf ¶
TypeOf takes a reflect.Type and returns an equivalent *Type. It removes any pointers since our language does not support pointers. It returns nil if it cannot represent the type in our type system. Common examples of things it cannot express include reflect.Invalid, reflect.Interface, Reflect.Complex128 and more. It is not reversible because some information may be either added or lost. For example, reflect.Array and reflect.Slice are both converted to a Type of KindList, and KindFunc names the arguments of a func sequentially. The lossy inverse of this is Reflect.
func (*Type) ComplexCmp ¶
ComplexCmp tells us if the input type is compatible with the concrete one. It can match against types containing variants, or against partial types. If the two types are equivalent, it will return nil. If the input type is identical, and concrete, the return status will be the empty string. If this match finds a possibility against a partial type, the status will be set to the "partial" string, and if it is compatible with the variant type it will be "variant"... Comparing to a partial can only match "impossible" (error) or possible (nil). This now also supports comparing a partial type to a variant type as well... TODO: Should we support KindUnification somehow?
func (*Type) HasVariant ¶
HasVariant tells us if the type contains any mention of the Variant type.
func (*Type) New ¶
New creates a new Value of this type. It will represent the "zero" value. It panics if you give it a malformed type.
func (*Type) Reflect ¶
Reflect returns a representative type satisfying the golang Type Interface. The lossy inverse of this is TypeOf.
func (*Type) Underlying ¶
Underlying returns the underlying type of the type in question. For variants, this unpacks them recursively, for everything else this returns itself.
type TypeOfOption ¶
type TypeOfOption func(*typeOfOptions)
TypeOfOption is a type that can be used to configure the ConfigurableTypeOf function.
func AllowInterfaceTypeOpt ¶
func AllowInterfaceTypeOpt(allowInterfaceType bool) TypeOfOption
AllowInterfaceTypeOpt specifies whether we should allow matching on an interface kind. This is used by ResTypeOf.
func SkipBadStructFieldsOpt ¶
func SkipBadStructFieldsOpt(skipBadStructFields bool) TypeOfOption
SkipBadStructFieldsOpt specifies whether we should skip over struct fields that errored when we tried to find their type. This is used by ResTypeOf.
func SkipPrivateFieldsOpt ¶
func SkipPrivateFieldsOpt(skipPrivateFields bool) TypeOfOption
SkipPrivateFieldsOpt specifies whether we should skip over struct fields that are private or unexported. This is used by ResTypeOf.
func StrictStructTagOpt ¶
func StrictStructTagOpt(strictStructTag bool) TypeOfOption
StrictStructTagOpt specifies whether we require that a struct tag be present to be able to use the field. If false, then the field is skipped if it is missing a struct tag.
func StructTagOpt ¶
func StructTagOpt(structTag string) TypeOfOption
StructTagOpt specifies whether we should skip over struct fields that errored when we tried to find their type. This is used by ResTypeOf.
type UnifiedState ¶
type UnifiedState struct {
// contains filtered or unexported fields
}
UnifiedState stores a mapping of unification variable to unique id. This is most often used for printing consistent unification variables in your logs. It must be built with NewUnifiedState before it can be used or it will panic.
func NewUnifiedState ¶
func NewUnifiedState() *UnifiedState
NewUnifiedState builds a new unified state store.
func (*UnifiedState) String ¶
func (obj *UnifiedState) String(typ *Type) string
String returns a representation of the input type using the specified state.
type Value ¶
type Value interface { fmt.Stringer // String() string (for display purposes) Type() *Type Less(Value) bool // to find the smaller of the two values (for sort) Cmp(Value) error // error if the two values aren't the same Copy() Value // returns a copy of this value Value() interface{} Bool() bool Str() string Int() int64 Float() float64 List() []Value Map() map[Value]Value // keys must all have same type, same for values Struct() map[string]Value Func() interface{} // func(interfaces.Txn, []interfaces.Func) (interfaces.Func, error) }
Value represents an interface to get values out of each type. It is similar to the reflection interfaces used in the golang standard library.
func ListStrToValue ¶
ListStrToValue is a simple helper function to convert from a list of strings in golang to the equivalent in our type system.
func ValueOf ¶
ValueOf takes a reflect.Value and returns an equivalent Value. Remember that the mcl type system currently can't represent certain values that *are* possible in golang. This is intentional. For example, mcl can't represent a *string (pointer to a string) where as this is quite common in golang. This is because mcl has no `nil/null` values. It is designed this way to avoid the well-known expensive "null-pointer-exception" style bugs. A version two of the language might consider an "Optional" type. In the meantime, you can still represent an "undefined" value, but only so far as when it's passed to a resource field. This is done with our "elvis" operator. When using this function, if you pass in something with a nil value, then expect a panic or an error if you're lucky.
func ValueOfGolang ¶
ValueOfGolang is a helper that takes a golang value, and produces the mcl equivalent internal representation. This is very useful for writing tests. A reminder that if you pass in a nil value, or something containing a nil value, then you won't get what you want. See our documentation for ValueOf.
type ValueSlice ¶
type ValueSlice []Value
ValueSlice is a linear list of values. It is used for sorting purposes.
func (ValueSlice) Len ¶
func (vs ValueSlice) Len() int
func (ValueSlice) Less ¶
func (vs ValueSlice) Less(i, j int) bool
func (ValueSlice) Swap ¶
func (vs ValueSlice) Swap(i, j int)
type VariantValue ¶
type VariantValue struct { Base V Value // formerly I experimented with using interface{} instead T *Type }
VariantValue represents a variant value.
func NewVariant ¶
func NewVariant(t *Type) *VariantValue
NewVariant creates a new variant value. TODO: I haven't thought about this thoroughly yet.
func (*VariantValue) Bool ¶
func (obj *VariantValue) Bool() bool
Bool represents the value of this type as a bool if it is one. If this is not a bool, then this panics.
func (*VariantValue) Cmp ¶
func (obj *VariantValue) Cmp(val Value) error
Cmp returns an error if this value isn't the same as the arg passed in.
func (*VariantValue) Copy ¶
func (obj *VariantValue) Copy() Value
Copy returns a copy of this value.
func (*VariantValue) Float ¶
func (obj *VariantValue) Float() float64
Float represents the value of this type as a float if it is one. If this is not a float, then this panics.
func (*VariantValue) Func ¶
func (obj *VariantValue) Func() interface{}
Func represents the value of this type as a function if it is one. If this is not a function, then this panics.
func (*VariantValue) Int ¶
func (obj *VariantValue) Int() int64
Int represents the value of this type as an integer if it is one. If this is not an integer, then this panics.
func (*VariantValue) Less ¶
func (obj *VariantValue) Less(v Value) bool
Less compares to value and returns true if we're smaller. This panics if the two types aren't the same. For variants, the two sub types must be the same.
func (*VariantValue) List ¶
func (obj *VariantValue) List() []Value
List represents the value of this type as a list if it is one. If this is not a list, then this panics.
func (*VariantValue) Map ¶
func (obj *VariantValue) Map() map[Value]Value
Map represents the value of this type as a dictionary if it is one. If this is not a map, then this panics.
func (*VariantValue) Str ¶
func (obj *VariantValue) Str() string
Str represents the value of this type as a string if it is one. If this is not a string, then this panics.
func (*VariantValue) String ¶
func (obj *VariantValue) String() string
String returns a visual representation of this value.
func (*VariantValue) Struct ¶
func (obj *VariantValue) Struct() map[string]Value
Struct represents the value of this type as a struct if it is one. If this is not a struct, then this panics.
func (*VariantValue) Type ¶
func (obj *VariantValue) Type() *Type
Type returns the type data structure that represents this type.
func (*VariantValue) Value ¶
func (obj *VariantValue) Value() interface{}
Value returns the raw value of this type.