module Structs { 
 
  // STRUCT BASICS 
 
  // a struct is a type with named, typed fields 
  // • structs are nominal types, meaning two structs are not the 
  //   same type even if they have the same field names and types 
  // • structures are immutable by default (see section on mutability) 
  // • structures are stack-allocated/contained by default (see section on references) 
 
  // the following structure has two integer fields, x and y 
  struct Point { 
    x : int; 
    y : int; 
  } 
 
  fn test() { 
    // structs can be constructed using named arguments 
    let p1 = Point(x : 1, y : 2); 
 
    // structs can be constructed using positional arguments 
    let p2 = Point(1, 2);  // x: 1, y: 2 
  } 
 
  // DEFAULT FIELD VALUES 
 
  // fields can have default values which are used  
  // if a value is not specifed when the struct is constructed 
  struct Shape { 
    origin: Point = Point(0, 0); 
    color: string = "#ff00ff"; 
    rotation : double = 0; 
  } 
 
  fn test2() { 
    // construct a Shape with all default values 
    let s1 = Shape(); 
 
    // construct a Shape with default field values except rotation 
    let s2 = Shape(rotation: 45); 
  } 
 
  // INCLUDING FIELDS FROM OTHER STRUCTS 
 
  // structs can include fields from other structs using ..., 
  // but all field names must still be unique.  note that this is 
  // not inheritance - this is equivalent to copy/paste of the fields. 
  struct Line { 
    ...Shape;   // line now has all the fields of Shape 
    length : double; 
  } 
 
  fn test4() { 
    // construct a line, and specify value for origin field defined in Shape 
    let l1 = Line(origin: Point(1, 1), length: 3); 
  } 
 
  // INTERFACE IMPLEMENTATION 
 
  // structs can easily implement an interface with getters 
  // without having to implement the delegation manually 
 
  // define an interface with a get property called name 
  interface NamedObject { 
    name.get() : string; 
  } 
 
  // define a struct with a name field 
  struct Triangle { 
    name : string; 
    p1 : Point; 
    p2 : Point; 
    p3 : Point; 
  } 
 
  // indicate that Triangle struct implements NamedObject interface 
  // with this definition, the compiler will implement the interface 
  impl NamedObject { 
    ...Triangle; 
  } 
 
  fn test5() { 
    // construct a triangle 
    let t1 = Triangle("mytriangle", Point(0, 0), Point(1, 2), Point(3, 4)); 
    let n1 = t1.name;  // access name field 
 
    // get NamedObject interface for triangle 
    let i1 = t1::NamedObject;   // cast to interface type 
    let n2 = i1.name;           // access name field via property getter on interface 
  } 
 
  // USING PROPERTY INTERFACES TO DEFINE FIELDS 
 
  // structs can also use interfaces as a way of defining the fields, 
  // making it easier to keep property accessor interfaces in sync 
  // with their implementations 
 
  // structures can also include interfaces whose members are only properties 
  // this will define a corresponding field for each property, with the same name 
  struct Circle { 
    ...NamedObject;   // adds a name : string; field 
    origin : Point; 
    radius : double; 
  } 
 
  // indicate that Circle struct implements NamedObject interface 
  impl NamedObject { 
    ...Circle; 
  } 
 
  fn test6() { 
    // construct a circle 
    let c1 = Circle("mycircle", Point(0, 0), 1); 
    let n1 = c1.name;   // access name field of circle 
 
    // get NamedObject interface for circle 
    let i1 = c1::NamedObject;   // cast to interface type 
    let n2 = i1.name;  // access name field via property getter on interface 
  } 
 
  // UNIT STRUCTURES 
 
  // a "unit" structure is a structure with no fields 
  // • unit structures are constructed by simply using the name of the structure 
  //   without the usual () 
 
  struct Empty {} 
 
  fn test7() { 
    let x : Empty = Empty; 
 
    if (x == Empty) { 
      // it's empty 
    } 
  } 
 
  // PRIVATE FIELDS 
 
  // To make a field of a structure private, add an leading underscore _ to the name.   
  // Private fields are only accessible from the namespace that defined the struct. 
 
  struct StructWithPrivateField { 
    x : int; 
    y : int; 
    _z : int;   // field _z is only accessible from this namespace 
  }   
}