I tried 4 different ways, 2 fails, 2 works.

Using a proc as a generic (failure): 
    
    
    type
      BinaryTree[V; compare: proc(a, b: V): bool] = object
        value: V
    
    proc insert[V; compare](tree: BinaryTree[V, compare], value: V): bool =
      # Error: attempting to call routine: 'compare'
      # found 'insert.compare [declared in 
/home/beta/Programming/Nim/Arraymancer/build/bintree.nim(5, 16)]' of kind 'type'
      compare(value, tree.value)
    
    var a = BinaryTree[int, proc(a, b: int): bool = a < b](value: 10)
    
    echo insert(a, 20)
    
    
    Run

Using a proc as a static (failure): 
    
    
    type
      BinaryTree[V; compare: static proc(a, b: V): bool] = object
        # Error: cannot generate VM code for proc (a, b: V): bool
        value: V
    
    proc insert[V; compare](tree: BinaryTree[V, compare], value: V): bool =
      compare(value, tree.value)
    
    var a = BinaryTree[int, proc(a, b: int): bool = a < b](value: 10)
    
    echo insert(a, 20)
    
    
    Run

Using a compile-time switch (success): 
    
    
    type
      CmpKind = enum
        GreaterThan
        LowerThan
      
      BinaryTree[V; cmp: static CmpKind] = object
        value: V
    
    proc insert[V; cmp](tree: BinaryTree[V, cmp], value: V): bool =
      when cmp == GreaterThan:
        value > tree.value
      elif cmp == LowerThan:
        value < tree.value
    
    var a = BinaryTree[int, LowerThan](value: 10)
    
    echo insert(a, 20)
    
    
    Run

Using a compile-time dispatch table (success): 
    
    
    import macros
    
    type
      CmpKind = enum
        GreaterThan
        LowerThan
      
      BinaryTree[V; cmp: static CmpKind] = object
        value: V
    
    let funcTable {.compileTime.} = [
        GreaterThan: ident">",
        LowerThan: ident"<"
      ]
    
    macro dispatch(a: typed, cmp: static CmpKind, b: typed): untyped =
      result = newCall(funcTable[cmp], a, b)
    
    proc insert[V; cmp](tree: BinaryTree[V, cmp], value: V): bool =
      dispatch(value, cmp, tree.value)
    
    var a = BinaryTree[int, LowerThan](value: 10)
    
    echo insert(a, 20)
    
    
    Run

Reply via email to