]> Cypherpunks repositories - gostls13.git/commitdiff
document reflect.
authorRob Pike <r@golang.org>
Tue, 10 Mar 2009 00:47:15 +0000 (17:47 -0700)
committerRob Pike <r@golang.org>
Tue, 10 Mar 2009 00:47:15 +0000 (17:47 -0700)
R=rsc
DELTA=201  (90 added, 0 deleted, 111 changed)
OCL=25904
CL=25966

src/lib/reflect/all_test.go
src/lib/reflect/tostring.go
src/lib/reflect/type.go
src/lib/reflect/value.go

index f6428fdf3843613e7b809692caded5f2cfd2dee3..7636f09501fe01f6bd1f3ac97c981a75b9f6f5f3 100644 (file)
@@ -43,7 +43,7 @@ func assert(s, t string) {
 
 func typedump(s, t string) {
        typ := reflect.ParseTypeString("", s);
-       assert(reflect.TypeToString(typ, true), t);
+       assert(reflect.typeToString(typ, true), t);
 }
 
 func valuedump(s, t string) {
@@ -84,7 +84,7 @@ func valuedump(s, t string) {
        case reflect.BoolKind:
                v.(reflect.BoolValue).Set(true);
        }
-       assert(reflect.ValueToString(v), t);
+       assert(reflect.valueToString(v), t);
 }
 
 type T struct { a int; b float64; c string; d *int }
@@ -156,43 +156,43 @@ func TestAll(tt *testing.T) {     // TODO(r): wrap up better
 
        {       var tmp = 123;
                value := reflect.NewValue(tmp);
-               assert(reflect.ValueToString(value), "123");
+               assert(reflect.valueToString(value), "123");
        }
        {       var tmp = 123.4;
                value := reflect.NewValue(tmp);
-               assert(reflect.ValueToString(value), "123.4");
+               assert(reflect.valueToString(value), "123.4");
        }
        {       var tmp = "abc";
                value := reflect.NewValue(tmp);
-               assert(reflect.ValueToString(value), "abc");
+               assert(reflect.valueToString(value), "abc");
        }
        {
                var i int = 7;
                var tmp = &T{123, 456.75, "hello", &i};
                value := reflect.NewValue(tmp);
-               assert(reflect.ValueToString(value.(reflect.PtrValue).Sub()), "reflect.T{123, 456.75, hello, *int(@)}");
+               assert(reflect.valueToString(value.(reflect.PtrValue).Sub()), "reflect.T{123, 456.75, hello, *int(@)}");
        }
        {
                type C chan *T; // TODO: should not be necessary
                var tmp = new(C);
                value := reflect.NewValue(tmp);
-               assert(reflect.ValueToString(value), "*reflect.C·all_test(@)");
+               assert(reflect.valueToString(value), "*reflect.C·all_test(@)");
        }
 //     {
 //             type A [10]int;
 //             var tmp A = A{1,2,3,4,5,6,7,8,9,10};
 //             value := reflect.NewValue(&tmp);
-//             assert(reflect.ValueToString(value.(reflect.PtrValue).Sub()), "reflect.A·all_test{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}");
+//             assert(reflect.valueToString(value.(reflect.PtrValue).Sub()), "reflect.A·all_test{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}");
 //             value.(reflect.PtrValue).Sub().(reflect.ArrayValue).Elem(4).(reflect.IntValue).Set(123);
-//             assert(reflect.ValueToString(value.(reflect.PtrValue).Sub()), "reflect.A·all_test{1, 2, 3, 4, 123, 6, 7, 8, 9, 10}");
+//             assert(reflect.valueToString(value.(reflect.PtrValue).Sub()), "reflect.A·all_test{1, 2, 3, 4, 123, 6, 7, 8, 9, 10}");
 //     }
        {
                type AA []int;
                var tmp = AA{1,2,3,4,5,6,7,8,9,10};
                value := reflect.NewValue(&tmp);        // TODO: NewValue(tmp) too
-               assert(reflect.ValueToString(value.(reflect.PtrValue).Sub()), "reflect.AA·all_test{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}");
+               assert(reflect.valueToString(value.(reflect.PtrValue).Sub()), "reflect.AA·all_test{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}");
                value.(reflect.PtrValue).Sub().(reflect.ArrayValue).Elem(4).(reflect.IntValue).Set(123);
-               assert(reflect.ValueToString(value.(reflect.PtrValue).Sub()), "reflect.AA·all_test{1, 2, 3, 4, 123, 6, 7, 8, 9, 10}");
+               assert(reflect.valueToString(value.(reflect.PtrValue).Sub()), "reflect.AA·all_test{1, 2, 3, 4, 123, 6, 7, 8, 9, 10}");
        }
 
        {
index b2ccfdf483288d241ff43db487f33457e5b64ed2..202d0ecbc3d23bbddb28f23c362942a9299700c3 100644 (file)
@@ -3,7 +3,9 @@
 // license that can be found in the LICENSE file.
 
 // Reflection library.
-// Formatting of types and values for debugging.
+// Formatting of reflection types and values for debugging.
+// Not defined as methods so they do not need to be linked into most binaries;
+// the functions are not used by the library itself, only in tests.
 
 package reflect
 
@@ -12,8 +14,8 @@ import (
        "strconv";
 )
 
-func TypeToString(typ Type, expand bool) string
-func ValueToString(val Value) string
+func typeToString(typ Type, expand bool) string
+func valueToString(val Value) string
 
 func doubleQuote(s string) string {
        out := "\"";
@@ -50,7 +52,7 @@ func typeFieldsToString(t hasFields, sep string) string {
                if str1 != "" {
                        str1 += " "
                }
-               str1 += TypeToString(typ, false);
+               str1 += typeToString(typ, false);
                if tag != "" {
                        str1 += " " + doubleQuote(tag);
                }
@@ -62,7 +64,11 @@ func typeFieldsToString(t hasFields, sep string) string {
        return str;
 }
 
-func TypeToString(typ Type, expand bool) string {
+// typeToString returns a textual representation of typ.  The expand
+// flag specifies whether to expand the contents of type names; if false,
+// the name itself is used as the representation.
+// Meant for debugging only; typ.String() serves for most purposes.
+func typeToString(typ Type, expand bool) string {
        var str string;
        if name := typ.Name(); !expand && name != "" {
                return name
@@ -78,7 +84,7 @@ func TypeToString(typ Type, expand bool) string {
                return typ.Name();
        case PtrKind:
                p := typ.(PtrType);
-               return "*" + TypeToString(p.Sub(), false);
+               return "*" + typeToString(p.Sub(), false);
        case ArrayKind:
                a := typ.(ArrayType);
                if a.IsSlice() {
@@ -86,11 +92,11 @@ func TypeToString(typ Type, expand bool) string {
                } else {
                        str = "[" + strconv.Itoa64(int64(a.Len())) +  "]"
                }
-               return str + TypeToString(a.Elem(), false);
+               return str + typeToString(a.Elem(), false);
        case MapKind:
                m := typ.(MapType);
-               str = "map[" + TypeToString(m.Key(), false) + "]";
-               return str + TypeToString(m.Elem(), false);
+               str = "map[" + typeToString(m.Key(), false) + "]";
+               return str + typeToString(m.Elem(), false);
        case ChanKind:
                c := typ.(ChanType);
                switch c.Dir() {
@@ -101,9 +107,9 @@ func TypeToString(typ Type, expand bool) string {
                case BothDir:
                        str = "chan";
                default:
-                       panicln("reflect.TypeToString: unknown chan direction");
+                       panicln("reflect.typeToString: unknown chan direction");
                }
-               return str + TypeToString(c.Elem(), false);
+               return str + typeToString(c.Elem(), false);
        case StructKind:
                return "struct{" + typeFieldsToString(typ.(StructType), ";") + "}";
        case InterfaceKind:
@@ -116,9 +122,9 @@ func TypeToString(typ Type, expand bool) string {
                }
                return str;
        default:
-               panicln("reflect.TypeToString: can't print type ", typ.Kind());
+               panicln("reflect.typeToString: can't print type ", typ.Kind());
        }
-       return "reflect.TypeToString: can't happen";
+       return "reflect.typeToString: can't happen";
 }
 
 // TODO: want an unsigned one too
@@ -126,7 +132,9 @@ func integer(v int64) string {
        return strconv.Itoa64(v);
 }
 
-func ValueToString(val Value) string {
+// valueToString returns a textual representation of the reflection value val.
+// For debugging only.
+func valueToString(val Value) string {
        var str string;
        typ := val.Type();
        switch(val.Kind()) {
@@ -174,41 +182,41 @@ func ValueToString(val Value) string {
                }
        case PtrKind:
                v := val.(PtrValue);
-               return TypeToString(typ, false) + "(" + integer(int64(uintptr(v.Get()))) + ")";
+               return typeToString(typ, false) + "(" + integer(int64(uintptr(v.Get()))) + ")";
        case ArrayKind:
                t := typ.(ArrayType);
                v := val.(ArrayValue);
-               str += TypeToString(t, false);
+               str += typeToString(t, false);
                str += "{";
                for i := 0; i < v.Len(); i++ {
                        if i > 0 {
                                str += ", "
                        }
-                       str += ValueToString(v.Elem(i));
+                       str += valueToString(v.Elem(i));
                }
                str += "}";
                return str;
        case MapKind:
                t := typ.(MapType);
                v := val.(MapValue);
-               str = TypeToString(t, false);
+               str = typeToString(t, false);
                str += "{";
                str += "<can't iterate on maps>";
                str += "}";
                return str;
        case ChanKind:
-               str = TypeToString(typ, false);
+               str = typeToString(typ, false);
                return str;
        case StructKind:
                t := typ.(StructType);
                v := val.(StructValue);
-               str += TypeToString(t, false);
+               str += typeToString(t, false);
                str += "{";
                for i := 0; i < v.Len(); i++ {
                        if i > 0 {
                                str += ", "
                        }
-                       str += ValueToString(v.Field(i));
+                       str += valueToString(v.Field(i));
                }
                str += "}";
                return str;
@@ -217,7 +225,7 @@ func ValueToString(val Value) string {
        case FuncKind:
                return "can't print funcs yet";
        default:
-               panicln("reflect.ValueToString: can't print type ", val.Kind());
+               panicln("reflect.valueToString: can't print type ", val.Kind());
        }
-       return "reflect.ValueToString: can't happen";
+       return "reflect.valueToString: can't happen";
 }
index 96953f3b0f6f828d9abd1bf9d5a2afe07a29d225..fcc33e442d599270463e11d2038ad0723d7c612d 100644 (file)
@@ -5,6 +5,10 @@
 // Reflection library.
 // Types and parsing of type strings.
 
+// This package implements data ``reflection''.  A program can use it to analyze types
+// and values it does not know at compile time, such as the values passed in a call
+// to a function with a ... parameter.  This is achieved by extracting the dynamic
+// contents of an interface value.
 package reflect
 
 import (
@@ -19,6 +23,7 @@ func ExpandType(name string) Type
 
 func typestrings() string      // implemented in C; declared here
 
+// These constants identify what kind of thing a Type represents: an int, struct, etc.
 const (
        MissingKind = iota;
        ArrayKind;
@@ -57,10 +62,18 @@ const (
 var missingString = "$missing$"        // syntactic name for undefined type names
 var dotDotDotString = "..."
 
+// Type is the generic interface to reflection types.  Once its Kind is known,
+// such as BoolKind, the Type can be narrowed to the appropriate, more
+// specific interface, such as BoolType.  Such narrowed types still implement
+// the Type interface.
 type Type interface {
+       // The kind of thing described: ArrayKind, BoolKind, etc.
        Kind()  int;
+       // The name declared for the type ("int", "BoolArray", etc.).
        Name()  string;
+       // For a named type, same as Name(); otherwise a representation of the type such as "[]int".
        String()        string;
+       // The number of bytes needed to store a value; analogous to unsafe.Sizeof().
        Size()  int;
 }
 
@@ -104,7 +117,10 @@ func newBasicType(name string, kind int, size int) Type {
        return &basicType{ commonType{kind, name, name, size} }
 }
 
-// Prebuilt basic types
+// Prebuilt basic Type objects representing the predeclared basic types.
+// Most are self-evident except:
+//     Missing represents types whose representation cannot be discovered; usually an error.
+//     DotDotDot represents the pseudo-type of a ... parameter.
 var (
        Missing = newBasicType(missingString, MissingKind, 1);
        empty interface{};
@@ -149,9 +165,10 @@ func (t *stubType) Get() Type {
 
 // -- Pointer
 
+// PtrType represents a pointer.
 type PtrType interface {
        Type;
-       Sub()   Type
+       Sub()   Type    // The type of the pointed-to item; for "*int", it will be "int".
 }
 
 type ptrTypeStruct struct {
@@ -169,11 +186,12 @@ func (t *ptrTypeStruct) Sub() Type {
 
 // -- Array
 
+// ArrayType represents an array or slice type.
 type ArrayType interface {
        Type;
-       IsSlice()       bool;
-       Len()   int;
-       Elem()  Type;
+       IsSlice()       bool;   // True for slices, false for arrays.
+       Len()   int;    // 0 for slices, the length for array types.
+       Elem()  Type;   // The type of the elements.
 }
 
 type arrayTypeStruct struct {
@@ -184,7 +202,7 @@ type arrayTypeStruct struct {
 }
 
 func newArrayTypeStruct(name, typestring string, open bool, len int, elem *stubType) *arrayTypeStruct {
-       return &arrayTypeStruct{ commonType{ArrayKind, typestring, name, 0}, elem, open, len}
+       return &arrayTypeStruct{ commonType{ArrayKind, typestring, name, 0 }, elem, open, len}
 }
 
 func (t *arrayTypeStruct) Size() int {
@@ -199,7 +217,9 @@ func (t *arrayTypeStruct) IsSlice() bool {
 }
 
 func (t *arrayTypeStruct) Len() int {
-       // what about open array?  TODO
+       if t.isslice {
+               return 0
+       }
        return t.len
 }
 
@@ -209,10 +229,11 @@ func (t *arrayTypeStruct) Elem() Type {
 
 // -- Map
 
+// MapType represents a map type.
 type MapType interface {
        Type;
-       Key()   Type;
-       Elem()  Type;
+       Key()   Type;   // The type of the keys.
+       Elem()  Type;   // The type of the elements/values.
 }
 
 type mapTypeStruct struct {
@@ -235,13 +256,15 @@ func (t *mapTypeStruct) Elem() Type {
 
 // -- Chan
 
+// ChanType represents a chan type.
 type ChanType interface {
        Type;
-       Dir()   int;
-       Elem()  Type;
+       Dir()   int;    // The direction of the channel.
+       Elem()  Type;   // The type of the elements.
 }
 
-const (        // channel direction
+// Channel direction.
+const (
        SendDir = 1 << iota;
        RecvDir;
        BothDir = SendDir | RecvDir;
@@ -267,9 +290,13 @@ func (t *chanTypeStruct) Elem() Type {
 
 // -- Struct
 
+// StructType represents a struct type.
 type StructType interface {
        Type;
-       Field(int)      (name string, typ Type, tag string, offset int);
+       // Field returns, for field i, its name, Type, tag information, and byte offset.
+       // The indices are in declaration order starting at 0.
+       Field(i int)    (name string, typ Type, tag string, offset int);
+       // Len is the number of fields.
        Len()   int;
 }
 
@@ -328,8 +355,12 @@ func (t *structTypeStruct) Len() int {
 
 // -- Interface
 
+// InterfaceType represents an interface type.
+// It behaves much like a StructType, treating the methods as fields.
 type InterfaceType interface {
        Type;
+       // Field returns, for method i, its name, Type, the empty string, and 0.
+       // The indices are in declaration order starting at 0.  TODO: is this true?
        Field(int)      (name string, typ Type, tag string, offset int);
        Len()   int;
 }
@@ -355,10 +386,11 @@ var nilInterface = newInterfaceTypeStruct("nil", "", make([]structField, 0));
 
 // -- Func
 
+// FuncType represents a function type.
 type FuncType interface {
        Type;
-       In()    StructType;
-       Out()   StructType;
+       In()    StructType;     // The parameters in the form of a StructType.
+       Out()   StructType;     // The results in the form of a StructType.
 }
 
 type funcTypeStruct struct {
@@ -466,6 +498,9 @@ func init() {
 }
 
 /*
+       Parsing of type strings.  These strings are how the run-time recovers type
+       information dynamically.
+
        Grammar
 
        stubtype =      - represent as StubType when possible
@@ -850,6 +885,9 @@ func (p *typeParser) Type(name string) *stubType {
        return s;
 }
 
+// ParseTypeString takes a type name and type string (such as "[]int") and
+// returns the Type structure representing a type name specifying the corresponding
+// type.  An empty typestring represents (the type of) a nil interface value.
 func ParseTypeString(name, typestring string) Type {
        if typestring == "" {
                // If the typestring is empty, it represents (the type of) a nil interface value
@@ -909,7 +947,8 @@ func typeNameToTypeString(name string) string {
        return s
 }
 
-// Type is known by name.  Find (and create if necessary) its real type.
+// ExpandType takes the name of a type and returns its Type structure,
+// unpacking the associated type string if necessary.
 func ExpandType(name string) Type {
        lock();
        t, ok := types[name];
index 9056d74d59cbe7221e733d7fb2198b2cbbbe7a47..f4e63407adaf9ec861e27a9511fe6396843411cd 100644 (file)
@@ -12,16 +12,25 @@ import (
        "unsafe";
 )
 
+// Addr is shorthand for unsafe.Pointer and is used to represent the address of Values.
 type Addr unsafe.Pointer
 
 func equalType(a, b Type) bool {
        return a.String() == b.String()
 }
 
+// Value is the generic interface to reflection values.  Once its Kind is known,
+// such as BoolKind, the Value can be narrowed to the appropriate, more
+// specific interface, such as BoolValue.  Such narrowed values still implement
+// the Value interface.
 type Value interface {
+       // The kind of thing described: ArrayKind, BoolKind, etc.
        Kind()  int;
+       // The reflection Type of the value.
        Type()  Type;
+       // The address of the value.
        Addr()  Addr;
+       // The value itself is the dynamic value of an empty interface.
        Interface()     interface {};
 }
 
@@ -65,6 +74,8 @@ type creatorFn func(typ Type, addr Addr) Value
 
 // -- Missing
 
+// MissingValue represents a value whose type is not known. It usually
+// indicates an error.
 type MissingValue interface {
        Value;
 }
@@ -79,10 +90,11 @@ func missingCreator(typ Type, addr Addr) Value {
 
 // -- Int
 
+// IntValue represents an int value.
 type IntValue interface {
        Value;
-       Get()   int;
-       Set(int);
+       Get()   int;    // Get the underlying int.
+       Set(int);       // Set the underlying int.
 }
 
 type intValueStruct struct {
@@ -103,10 +115,11 @@ func (v *intValueStruct) Set(i int) {
 
 // -- Int8
 
+// Int8Value represents an int8 value.
 type Int8Value interface {
        Value;
-       Get()   int8;
-       Set(int8);
+       Get()   int8;   // Get the underlying int8.
+       Set(int8);      // Set the underlying int8.
 }
 
 type int8ValueStruct struct {
@@ -127,10 +140,11 @@ func (v *int8ValueStruct) Set(i int8) {
 
 // -- Int16
 
+// Int16Value represents an int16 value.
 type Int16Value interface {
        Value;
-       Get()   int16;
-       Set(int16);
+       Get()   int16;  // Get the underlying int16.
+       Set(int16);     // Set the underlying int16.
 }
 
 type int16ValueStruct struct {
@@ -151,10 +165,11 @@ func (v *int16ValueStruct) Set(i int16) {
 
 // -- Int32
 
+// Int32Value represents an int32 value.
 type Int32Value interface {
        Value;
-       Get()   int32;
-       Set(int32);
+       Get()   int32;  // Get the underlying int32.
+       Set(int32);     // Set the underlying int32.
 }
 
 type int32ValueStruct struct {
@@ -175,10 +190,11 @@ func (v *int32ValueStruct) Set(i int32) {
 
 // -- Int64
 
+// Int64Value represents an int64 value.
 type Int64Value interface {
        Value;
-       Get()   int64;
-       Set(int64);
+       Get()   int64;  // Get the underlying int64.
+       Set(int64);     // Set the underlying int64.
 }
 
 type int64ValueStruct struct {
@@ -199,10 +215,11 @@ func (v *int64ValueStruct) Set(i int64) {
 
 // -- Uint
 
+// UintValue represents a uint value.
 type UintValue interface {
        Value;
-       Get()   uint;
-       Set(uint);
+       Get()   uint;   // Get the underlying uint.
+       Set(uint);      // Set the underlying uint.
 }
 
 type uintValueStruct struct {
@@ -223,10 +240,11 @@ func (v *uintValueStruct) Set(i uint) {
 
 // -- Uint8
 
+// Uint8Value represents a uint8 value.
 type Uint8Value interface {
        Value;
-       Get()   uint8;
-       Set(uint8);
+       Get()   uint8;  // Get the underlying uint8.
+       Set(uint8);     // Set the underlying uint8.
 }
 
 type uint8ValueStruct struct {
@@ -247,10 +265,11 @@ func (v *uint8ValueStruct) Set(i uint8) {
 
 // -- Uint16
 
+// Uint16Value represents a uint16 value.
 type Uint16Value interface {
        Value;
-       Get()   uint16;
-       Set(uint16);
+       Get()   uint16; // Get the underlying uint16.
+       Set(uint16);    // Set the underlying uint16.
 }
 
 type uint16ValueStruct struct {
@@ -271,10 +290,11 @@ func (v *uint16ValueStruct) Set(i uint16) {
 
 // -- Uint32
 
+// Uint32Value represents a uint32 value.
 type Uint32Value interface {
        Value;
-       Get()   uint32;
-       Set(uint32);
+       Get()   uint32; // Get the underlying uint32.
+       Set(uint32);    // Set the underlying uint32.
 }
 
 type uint32ValueStruct struct {
@@ -295,10 +315,11 @@ func (v *uint32ValueStruct) Set(i uint32) {
 
 // -- Uint64
 
+// Uint64Value represents a uint64 value.
 type Uint64Value interface {
        Value;
-       Get()   uint64;
-       Set(uint64);
+       Get()   uint64; // Get the underlying uint64.
+       Set(uint64);    // Set the underlying uint64.
 }
 
 type uint64ValueStruct struct {
@@ -319,10 +340,11 @@ func (v *uint64ValueStruct) Set(i uint64) {
 
 // -- Uintptr
 
+// UintptrValue represents a uintptr value.
 type UintptrValue interface {
        Value;
-       Get()   uintptr;
-       Set(uintptr);
+       Get()   uintptr;        // Get the underlying uintptr.
+       Set(uintptr);   // Set the underlying uintptr.
 }
 
 type uintptrValueStruct struct {
@@ -343,10 +365,11 @@ func (v *uintptrValueStruct) Set(i uintptr) {
 
 // -- Float
 
+// FloatValue represents a float value.
 type FloatValue interface {
        Value;
-       Get()   float;
-       Set(float);
+       Get()   float;  // Get the underlying float.
+       Set(float);     // Get the underlying float.
 }
 
 type floatValueStruct struct {
@@ -367,10 +390,11 @@ func (v *floatValueStruct) Set(f float) {
 
 // -- Float32
 
+// Float32Value represents a float32 value.
 type Float32Value interface {
        Value;
-       Get()   float32;
-       Set(float32);
+       Get()   float32;        // Get the underlying float32.
+       Set(float32);   // Get the underlying float32.
 }
 
 type float32ValueStruct struct {
@@ -391,10 +415,11 @@ func (v *float32ValueStruct) Set(f float32) {
 
 // -- Float64
 
+// Float64Value represents a float64 value.
 type Float64Value interface {
        Value;
-       Get()   float64;
-       Set(float64);
+       Get()   float64;        // Get the underlying float64.
+       Set(float64);   // Get the underlying float64.
 }
 
 type float64ValueStruct struct {
@@ -415,10 +440,11 @@ func (v *float64ValueStruct) Set(f float64) {
 
 // -- Float80
 
+// Float80Value represents a float80 value.
 type Float80Value interface {
        Value;
-       Get()   float80;
-       Set(float80);
+       Get()   float80;        // Get the underlying float80.
+       Set(float80);   // Get the underlying float80.
 }
 
 type float80ValueStruct struct {
@@ -442,10 +468,11 @@ func (v *Float80ValueStruct) Set(f float80) {
 
 // -- String
 
+// StringValue represents a string value.
 type StringValue interface {
        Value;
-       Get()   string;
-       Set(string);
+       Get()   string; // Get the underlying string value.
+       Set(string);    // Set the underlying string value.
 }
 
 type stringValueStruct struct {
@@ -466,10 +493,11 @@ func (v *stringValueStruct) Set(s string) {
 
 // -- Bool
 
+// BoolValue represents a bool value.
 type BoolValue interface {
        Value;
-       Get()   bool;
-       Set(bool);
+       Get()   bool;   // Get the underlying bool value.
+       Set(bool);      // Set the underlying bool value.
 }
 
 type boolValueStruct struct {
@@ -490,11 +518,12 @@ func (v *boolValueStruct) Set(b bool) {
 
 // -- Pointer
 
+// PtrValue represents a pointer value.
 type PtrValue interface {
        Value;
-       Sub()   Value;
-       Get()   Addr;
-       SetSub(Value);
+       Sub()   Value;  // The Value pointed to.
+       Get()   Addr;   // Get the address stored in the pointer.
+       SetSub(Value);  // Set the the pointed-to Value.
 }
 
 type ptrValueStruct struct {
@@ -526,15 +555,16 @@ func ptrCreator(typ Type, addr Addr) Value {
 // -- Array
 // Slices and arrays are represented by the same interface.
 
+// ArrayValue represents an array or slice value.
 type ArrayValue interface {
        Value;
-       IsSlice()       bool;
-       Len()   int;
-       Cap() int;
-       Elem(i int)     Value;
-       SetLen(len int);
-       Set(src ArrayValue);
-       CopyFrom(src ArrayValue, n int)
+       IsSlice()       bool;   // Is this a slice (true) or array (false)?
+       Len()   int;    // The length of the array/slice.
+       Cap() int;      // The capacity of the array/slice (==Len() for arrays).
+       Elem(i int)     Value;  // The Value of the i'th element.
+       SetLen(len int);        // Set the length; slice only.
+       Set(src ArrayValue);    // Set the underlying Value; slice only for src and dest both.
+       CopyFrom(src ArrayValue, n int) // Copy the elements from src; lengths must match.
 }
 
 func copyArray(dst ArrayValue, src ArrayValue, n int);
@@ -581,7 +611,7 @@ func (v *sliceValueStruct) SetLen(len int) {
 
 func (v *sliceValueStruct) Set(src ArrayValue) {
        if !src.IsSlice() {
-               panic("can't set from fixed array");
+               panic("can't set slice from array");
        }
        s := src.(*sliceValueStruct);
        if !equalType(v.typ, s.typ) {
@@ -619,10 +649,11 @@ func (v *arrayValueStruct) Cap() int {
 }
 
 func (v *arrayValueStruct) SetLen(len int) {
+       panicln("can't set len of array");
 }
 
 func (v *arrayValueStruct) Set(src ArrayValue) {
-       panicln("can't set fixed array");
+       panicln("can't set array");
 }
 
 func (v *arrayValueStruct) Elem(i int) Value {
@@ -659,10 +690,12 @@ func arrayCreator(typ Type, addr Addr) Value {
 
 // -- Map      TODO: finish and test
 
+// MapValue represents a map value.
+// Its implementation is incomplete.
 type MapValue interface {
        Value;
-       Len()   int;
-       Elem(key Value) Value;
+       Len()   int;    // The number of elements; currently always returns 0.
+       Elem(key Value) Value;  // The value indexed by key; unimplemented.
 }
 
 type mapValueStruct struct {
@@ -684,6 +717,8 @@ func (v *mapValueStruct) Elem(key Value) Value {
 
 // -- Chan
 
+// ChanValue represents a chan value.
+// Its implementation is incomplete.
 type ChanValue interface {
        Value;
 }
@@ -698,10 +733,11 @@ func chanCreator(typ Type, addr Addr) Value {
 
 // -- Struct
 
+// StructValue represents a struct value.
 type StructValue interface {
        Value;
-       Len()   int;
-       Field(i int)    Value;
+       Len()   int;    // The number of fields.
+       Field(i int)    Value;  // The Value of field i.
 }
 
 type structValueStruct struct {
@@ -732,9 +768,10 @@ func structCreator(typ Type, addr Addr) Value {
 
 // -- Interface
 
+// InterfaceValue represents an interface value.
 type InterfaceValue interface {
        Value;
-       Get()   interface {};
+       Get()   interface {};   // Get the underlying interface{} value.
 }
 
 type interfaceValueStruct struct {
@@ -751,6 +788,9 @@ func interfaceCreator(typ Type, addr Addr) Value {
 
 // -- Func
 
+
+// FuncValue represents a func value.
+// Its implementation is incomplete.
 type FuncValue interface {
        Value;
 }
@@ -801,6 +841,7 @@ func newValueAddr(typ Type, addr Addr) Value {
        return c(typ, addr);
 }
 
+// NewInitValue creates a new, zero-initialized Value for the specified Type.
 func NewInitValue(typ Type) Value {
        // Some values cannot be made this way.
        switch typ.Kind() {
@@ -819,6 +860,8 @@ func NewInitValue(typ Type) Value {
        return newValueAddr(typ, Addr(&data[0]));
 }
 
+// NewSliceValue creates a new, zero-initialized slice value (ArrayValue) for the specified
+// slice type (ArrayType), length, and capacity.
 func NewSliceValue(typ ArrayType, len, cap int) ArrayValue {
        if !typ.IsSlice() {
                return nil
@@ -869,7 +912,7 @@ func copyArray(dst ArrayValue, src ArrayValue, n int) {
        }
 }
 
-
+// NewValue creates a new Value from the interface{} object provided.
 func NewValue(e interface {}) Value {
        value, typestring, indir := sys.Reflect(e);
        typ, ok := typecache[typestring];