Text file talks/2014/compiling.slide

     1  Go: Easy to Read, Hard to Compile
     2  Corner cases when compiling Go
     3  
     4  Ian Lance Taylor
     5  Google
     6  iant@golang.org
     7  
     8  * Introduction
     9  
    10  - To really learn a language, write a compiler for it
    11  - Compiler bugs imply language complexity
    12  - Or, compiler bugs imply differences from C/C++
    13  - Sometimes simpler for users is harder for compilers
    14  - Fortunately Go is much simpler to compile than C++ or even C
    15  
    16  This talk is based on Go compiler bugs encountered over the years.
    17  
    18  * Recursive Types
    19  
    20  Names in Go packages are defined in the entire package, so Go types
    21  can refer to themselves recursively.
    22  
    23  .code compiling/rtype1.go /1 START OMIT/,/1 END OMIT/
    24  
    25  This is not permitted in C/C++, except for the special case of a
    26  struct/union/class field which is a pointer/reference.
    27  
    28  All Go compiler code that walks over types has to be careful to avoid
    29  endless loops.
    30  
    31  * Recursive Types
    32  
    33  What good is a recursive pointer type?  It can only be nil or a
    34  pointer to itself.  That's enough for Peano arithmetic.
    35  
    36  .code compiling/rtype1.go /2 START OMIT/,/2 END OMIT/
    37  
    38  * Recursive Types
    39  
    40  Actually, a recursive pointer can have a bit more information: it can
    41  have a finalizer.
    42  
    43  .play compiling/rtype1.go /3 START OMIT/,/3 END OMIT/
    44  
    45  * Recursive Types
    46  
    47  Recursive function types are actually useful: they can implement a
    48  state machine.
    49  
    50  .code compiling/rtype2.go /1 START OMIT/,/1 END OMIT/
    51  
    52  * Recursive types
    53  
    54  .play compiling/rtype2.go /2 START OMIT/,/2 END OMIT/
    55  
    56  * Recursive Types
    57  
    58  Simple rule: all names at package scope are visible in the entire
    59  package.
    60  
    61  Complex consequence: compiler must handle recursive types (also
    62  recursive initializers).
    63  
    64  * Constants
    65  
    66  Go has both typed and untyped constants.  They follow the same rules,
    67  except that a typed constant must be representable in its type.
    68  
    69  This is reasonably clear for integers, less so for floats.
    70  
    71  .play compiling/const1.go /1 START OMIT/,/1 END OMIT/
    72  
    73  * Constants
    74  
    75  Go's floating point variables follow IEEE-754 rules.
    76  
    77  Constants do not.
    78  
    79  .play compiling/const2.go /1 START OMIT/,/1 END OMIT/
    80  
    81  * Constants
    82  
    83  The special unsafe.Sizeof function returns a constant.
    84  
    85  .play compiling/const3.go /1 START OMIT/,/1 END OMIT/
    86  
    87  * Constants
    88  
    89  Simple rule: constants are untyped; they are mathematically exact and
    90  do not require type conversions.
    91  
    92  Complex consequence: exact floating point behavior depends on the
    93  type.
    94  
    95  * Name Lookup
    96  
    97  Name lookup in a Go compiler is simple compared to many languages.
    98  For every name the scope in which to look it up is obvious.  This
    99  makes parsing Go quite simple.
   100  
   101  With one exception.  What is the scope for i?
   102  
   103  .code compiling/name1.go /1 START OMIT/,/1 END OMIT/
   104  
   105  * Name Lookup
   106  
   107  One possibility.
   108  
   109  .play compiling/name1.go /2 START OMIT/,/2 END OMIT/
   110  
   111  * Name Lookup
   112  
   113  Another possibility.
   114  
   115  .play compiling/name2.go /2 START OMIT/,/2 END OMIT/
   116  
   117  * Name Lookup
   118  
   119  Simple rule: in a struct composite literal you can use field names as
   120  keys.
   121  
   122  Complex consequence: if you don't know the type of the composite
   123  literal, the lookup scope of names used as keys is unclear when
   124  parsing.
   125  
   126  * Methods
   127  
   128  Any named type can have methods.  Any struct type can inherit methods
   129  from an embedded field.  It follows that you can sometimes call
   130  methods on a variable even if it has an unnamed type.
   131  
   132  .play compiling/var1.go /1 START OMIT/,/1 END OMIT/
   133  
   134  * Methods
   135  
   136  Simple rules: named types can have methods; structs can have embedded
   137  fields.
   138  
   139  Complex consequence: unnamed types can have methods.
   140  
   141  * Conclusion
   142  
   143  - Go is simpler to compile than most languages
   144  - There are still complexities for the compiler
   145  - Most complexities stem from making Go easier to write
   146  

View as plain text