Detailed explanation:
    
    
    type FooFunc = proc(x: int)
    echo FooFunc is proc(x: int) {.closure.}  # true
    
    proc foo(x: int) = echo "It works OK!!!"
    echo foo is proc(x: int) {.nimcall.}  # true
    # Type of foo proc is different from FooFunc type as FooFunc is closure but 
foo is nimcall.
    echo foo is FooFunc   # false
    echo proc(x: int) is proc(x: int) {.nimcall.} # false
    
    # They are different types but nimcall proc can be assigned to closure proc.
    var
      p: proc(x: int) {.closure.}
      q: proc(x: int) {.nimcall.} = foo
    p = q
    p(1)
    
    type
      SomeGenericObj[T] = object
    
    var
      a, b: SomeGenericObj[proc(x:int){.closure.}]
      x: SomeGenericObj[proc(x: int){.nimcall.}]
    
    a = b
    # Both assignments result in compile error because typeof(a) and typeof(x) 
are different
    #x = a
    #a = x
    
    var
      c: int
      d: int16
    
    # int16 is implicity converted to int
    c = d
    
    var
      i: SomeGenericObj[int]
      j: SomeGenericObj[int16]
    
    # i and j are different types and you cannot assign j to i.
    #i = j
    
    # If you want to assign one generic type value to another generic type 
variable even if generic parameters are different.
    type
      ImplicitlyConvertible[T] = object
    
    proc `<=`[T, U](a: var ImplicitlyConvertible[T]; b: 
ImplicitlyConvertible[U]) =
      when(compiles((var x: T; var y: U; x = y))):
        discard
      else:
        {.error: "Wrong assignment".}
    
    block:
      var
        a, b: ImplicitlyConvertible[proc(x:int){.closure.}]
        x: ImplicitlyConvertible[proc(x: int){.nimcall.}]
      
      a <= b
      a <= x
      # Compile error
      #x <= a
      
      var
        i: ImplicitlyConvertible[int]
        j: ImplicitlyConvertible[int16]
      
      i <= j
      #j <= i
    
    Run

Reply via email to