// Package luar provides custom type reflection to gopher-lua.
//
// Notice
//
// This package is currently in development, and its behavior may change. This
// message will be removed once the package is considered stable.
//
// Basic types
//
// Go bool, number, and string types are converted to the equivalent basic
// Lua type.
//
// Example:
//  New(L, "Hello World") -> lua.LString("Hello World")
//  New(L, uint(834))     -> lua.LNumber(uint(834))
//
// Channel types
//
// Channel types have the following methods defined:
//  receive():    Receives data from the channel. Returns nil plus false if the
//                channel is closed.
//  send(data):   Sends data to the channel.
//  close():      Closes the channel.
//
// Taking the length (#) of a channel returns how many unread items are in its
// buffer.
//
// Example:
//  ch := make(chan string)
//  L.SetGlobal("ch", New(L, ch))
//  ---
//  ch:receive()      -- equivalent to v, ok := ch
//  ch:send("hello")  -- equivalent to ch <- "hello"
//  ch:close()        -- equivalent to close(ch)
//
// Function types
//
// Function types can be called from Lua. Its arguments and returned values
// will be automatically converted from and to Lua types, respectively (see
// exception below). However, a function that uses luar.LState can bypass the
// automatic argument and return value conversion (see luar.LState
// documentation for example).
//
// Example:
//  fn := func(name string, age uint) string {
//    return fmt.Sprintf("Hello %s, age %d", name, age)
//  }
//  L.SetGlobal("fn", New(L, fn))
//  ---
//  print(fn("Tim", 5)) -- prints "Hello Tim, age 5"
//
// A special conversion case happens when function returns a lua.LValue slice.
// In that case, luar will automatically unpack the slice.
//
// Example:
//  fn := func() []lua.LValue {
//    return []lua.LValue{lua.LString("Hello"), lua.LNumber(2.5)}
//  }
//  L.SetGlobal("fn", New(L, fn))
//  ---
//  x, y = fn()
//  print(x) -- prints "Hello"
//  print(y) -- prints "2.5"
//
// Map types
//
// Map types can be accessed and modified like a normal Lua table a meta table.
// Its length can also be queried using the # operator.
//
// Rather than using pairs to create an map iterator, calling the value (e.g.
// map_variable()) will return an iterator for the map.
//
// Example:
//  places := map[string]string{
//    "NA": "North America",
//    "EU": "European Union",
//  }
//  L.SetGlobal("places", New(L, places))
//  ---
//  print(#places)       -- prints "2"
//  print(places.NA)     -- prints "North America"
//  print(places["EU"])  -- prints "European Union"
//  for k, v in places() do
//    print(k .. ": " .. v)
//  end
//
// Slice types
//
// Like map types, slices be accessed, be modified, and have their length
// queried. Additionally, the following methods are defined for slices:
//  append(items...):   Appends the items to the slice. Returns a slice with
//                      the items appended.
//  capacity():         Returns the slice capacity.
//
// For consistency with other Lua code, slices use one-based indexing.
//
// Example:
//  letters := []string{"a", "e", "i"}
//  L.SetGlobal("letters", New(L, letters))
//  ---
//  letters = letters:append("o", "u")
//
// Struct types
//
// Struct types can have their fields accessed and modified and their methods
// called. First letters of field/method names are automatically converted to
// uppercase.
//
// Example:
//  type Person {
//    Name string
//  }
//  func (p Person) SayHello() {
//    fmt.Printf("Hello, %s\n", p.Name)
//  }
//
//  tim := Person{"Tim"}
//  L.SetGlobal("tim", New(L, tim))
//  ---
//  tim:SayHello() -- same as tim:sayHello()
//
// Pointer types
//
// Pointers to structs operate the same way structs do. Pointers can also be
// dereferenced using the unary minus (-) operator.
//
// Example:
//  str := "hello"
//  L.SetGlobal("strptr", New(L, &str))
//  ---
//  print(-strptr) -- prints "hello"
//
// The pointed to value can changed using the pow (^) operator.
//
// Example:
//  str := "hello"
//  L.SetGlobal("strptr", New(L, &str))
//  ---
//  print(str^"world") -- prints "world", and str's value is now "world"
//
// Type types
//
// Type constructors can be created using NewType. When called, it returns a
// new variable which is of the same type that was passed to NewType. Its
// behavior is dependent on the kind of value passed, as described below:
//
//  Kind      Constructor arguments          Return value
//  -----------------------------------------------------
//  Channel   Buffer size (opt)              Channel
//  Map       None                           Map
//  Slice     Length (opt), Capacity (opt)   Slice
//  Default   None                           Pointer to the newly allocated value
//
// Example:
//  type Person struct {
//    Name string
//  }
//  L.SetGlobal("Person", NewType(L, Person{}))
//  ---
//  p = Person()
//  p.Name = "John"
//  print("Hello, " .. p.Name)  // prints "Hello, John"
package luar
