src/bookofnim/helloworld/modules/userDefinedTypes

Source   Edit  

user defined types

TLDR

  • objects, tuples and enums are used to define custom types
    • object variants are in traitsAdts.nim
  • if a ref/ptr points to nothing, its value is nil
  • enum and object types may only be defined within a type statement
  • tuples vs objects
    • tuples
      • structurally equivalent: order and type of fields must match
      • all fields are public
      • can be destructured/unpacked; use _ to ignore elements
      • lexical ordering of fields are maintained
      • field access by name/index (const int)
      • can be anonymous and dont require a type statement
    • objects
      • provide inheritance & hidden fields
      • nominally equivalent: type name must match
      • provide inheritance
      • field access by name

links

TODOs

  • add a testfile
  • import in bookofnim.nim
  • update readme

base types

  • used to construct custom types

objects

  • ref/ptr objects can use of to distinguish between types
  • traced by the garbage collector, no need to free them when allocated
  • each object type has a constructor
  • when instantiated unspecified fields receive the field types default value
  • only private fields require exported get/setters

tuples

  • fixed-length; maintain lexical order of fields
  • similar to objects sans inheritance, + unpacking + more dynamic + fields always public
  • instantiation must match order of fields in signature (field name not required)

enum

  • A variable of an enum can only be assigned one of the enum's specified values
  • enum values are usually a set of ordered symbols, internally mapped to an integer (0-based)
  • $ convert enum index value to its name
  • ord convert enum name to its index value
  • its idiomatic nim to have ordinal enums (0, 1, 2, 3, etc)
    • and not assign disjoint values (1, 5, -10)

inheritance

  • introduce many-to-one relationships: many instances point to the same heap
  • reference equality check
  • base types should ref RootObj/a type that does
    • else they are implictly final
    • RootRef is a reference to RootObj (root of nims object hierachy, like javascripts object)
  • objects can be self-referencing
  • use the operator when logging the object (see strutils)
  • when both ref & non-ref exist for the same type, end each type name with Obj/Ref

ref

  • generic traced pointer type mem is gc'ed on heap
  • generally you should always use ref objects with inheritance
  • non-ref objects truncate subclass fields on = assignment
  • since objs are value types, composition is as efficient as inheritance
  • dont have to label ref objects as var in proc signatures to mutate them

ptr

  • generic untraced pointer type
  • untraced references (are unsafe), pointing to manually managed memory locations
  • required when accessing hardware/low-level ops

ref/pter procs

  • . and always def-ref, i.e. return the value and not the ref
  • . access tuple/object
  • new(T) object of type T and return a traced ref, when T is a ref the result type will be T, else ref T
  • newT object of type T and return a trace reference to it in a
  • newT same as before, but this time finalizer is called a is gc'ed
  • of i.e. instanceof creates a single layer of inheritance between types
  • as
  • in notin is isnot
  • isNil(x) sometimes more efficient than == nil for pter types

dynamic dispatch

  • generally only required with ref/ptr objects
  • use method whenever an object has an inherited subtype only known at runtime

multi-methods

  • occurs when multiple overloaded procs exist with different signatures
  • however they are still ambiguous because of inheritance
  • you have to use --multimethods:on when compiling

recursive types

  • objects, tuples and ref objects that recursively depend on each other
  • must be declared within a single type section

Types

AmericaOfJobs = enum
  nineToFives, fiveToNines, twentyFourSeven
Source   Edit  
BlinkLights = enum
  off, on, slowBlink, mediumBlink, fastBlink
Source   Edit  
Computer = object
  
Source   Edit  
Direction = enum
  north, east, south, west
Source   Edit  
DistroObj = object
  
Source   Edit  
DistroRef = ref DistroObj
Source   Edit  
ExplicitEnum = enum
  AA = (0, "letter AA"), BB = (1, "letter BB")
Source   Edit  
Expression = ref object of RootObj
abstract base class for an expression Source   Edit  
IWoop = ref object of WhoWoop
Source   Edit  
LevelSetting = array[north .. west, BlinkLights]
Source   Edit  
Literal = ref object of Expression
  
Source   Edit  
NirvStack = tuple[fe: seq[string], be: seq[string]]
Source   Edit  
Node = ref object
  
Source   Edit  
OrRefObject = ref object
  
Source   Edit  
PeopleOfAmerica {.pure.} = enum
  coders = "think i am", teachers = "pretend to be", farmers = "prefer to be",
  scientists = "trying to be"
Source   Edit  
PlusExpr = ref object of Expression
  
Source   Edit  
SomeObj = object
  pub*: string
Source   Edit  
Someone = object
  
Source   Edit  
SomeoneRef = ref Someone
Source   Edit  
StackNirv = tuple[fe: seq[string], be: seq[string]]
Source   Edit  
Sym = object
  
Source   Edit  
Thing = ref object of RootObj
Source   Edit  
Unit = ref object of Thing
  
Source   Edit  
Vector = object
  
Source   Edit  
WhoWoop = ref object of RootObj
  
Source   Edit  
YouWoop = ref object of WhoWoop
Source   Edit  

Vars

aaaa: Unit
Source   Edit  
bbbb: Unit
Source   Edit  
bizDevOps: tuple[biz: string, dev: string, ops: string] = ("intermediate",
    "senior", "beginner")
Source   Edit  
hardCoreStack: NirvStack = (@["ts"], @["ts, bash"])
Source   Edit  
level: LevelSetting
Source   Edit  
myobj = SomeObj(pub: "pub field")
Source   Edit  
newCoreStack: StackNirv = (fe: @["ts", "nim"], be: @["ts", "nim", "bash"])
Source   Edit  
sherlockwoops: seq[WhoWoop] = @[]
Source   Edit  
sj = (iz: "super", wha: 133, t: 't')
Source   Edit  

Lets

aaa = [(10, 'a'), (20, 'b'), (30, 'c')]
Source   Edit  
bizRating = tmpTuple_1409286529[0]
Source   Edit  
devRating = tmpTuple_1409286529[1]
Source   Edit  
first = tmpTuple_1409286533[0]
Source   Edit  
js = ("super", 133, 't')
Source   Edit  
opsRating = tmpTuple_1409286529[2]
Source   Edit  
people: ref Someone = new(Someone)
Source   Edit  
people2 = SomeoneRef(name: "npc", bday: "before noah", age: 1)
Source   Edit  
third = tmpTuple_1409286533[2]
Source   Edit  
tmpTuple_1409286529 = bizDevOps
Source   Edit  
tmpTuple_1409286533 = bizDevOps
Source   Edit  

Procs

proc `[]`(v: Vector; i: int): float {....raises: [], tags: [], forbids: [].}
Source   Edit  
proc `[]=`(v: var Vector; i: int; value: float) {....raises: [], tags: [],
    forbids: [].}
Source   Edit  
proc did_i_woop(self: WhoWoop): string {....raises: [], tags: [], forbids: [].}
Source   Edit  
proc dIdIwoop(self: IWoop): string {....raises: [], tags: [], forbids: [].}
Source   Edit  
proc didiwoop(self: YouWoop): string {....raises: [], tags: [], forbids: [].}
Source   Edit  
proc newLit(x: int): Literal {....raises: [], tags: [], forbids: [].}
Source   Edit  
proc newPlus(a, b: Expression): PlusExpr {....raises: [], tags: [], forbids: [].}
Source   Edit  
proc prv(x: SomeObj): string {.inline, ...raises: [], tags: [], forbids: [].}
Source   Edit  
proc prv=(x: var SomeObj; v: string) {.inline, ...raises: [], tags: [], forbids: [].}
Source   Edit  

Methods

method baseMethod(self: SomeoneRef): bool {.base, ...raises: [CatchableError],
    tags: [], forbids: [].}
Source   Edit  
method collide(a, b: Thing) {.inline, ...raises: [], tags: [], forbids: [].}
Source   Edit  
method collide(a: Thing; b: Unit) {.inline, ...raises: [], tags: [], forbids: [].}
Source   Edit  
method collide(a: Unit; b: Thing) {.inline, ...raises: [], tags: [], forbids: [].}
Source   Edit  
method eval(e: Expression): int {.base, ...raises: [], tags: [], forbids: [].}
Source   Edit  
method eval(e: Literal): int {....raises: [], tags: [], forbids: [].}
Source   Edit  
method eval(e: PlusExpr): int {....raises: [Exception], tags: [RootEffect],
                                forbids: [].}
Source   Edit