Hello,

I have a question concerning generics / function overloading. Say I have a 
(somewhat silly for demonstration purposes) "module A". The main function 
`quotedPair` takes an argument and returns a tuple containing the argument 
itself as well as some sort of "quoted" form of the argument which is generated 
using a `quote` function. I provide an implementation of `quote` for strings 
but I want to give users of my module the possibility to extend `quotedPair`, 
hence `quotedPair` is a generic function.
    
    
    # moda.nim
    
    proc quote*(s: string): string =
      "`" & s & "`"
    
    proc quotedPair*[T](x: T): (T, string) =
      (x, x.quote)
    
    
    Run

But if I try to use module A and extend it with an implementation for integers, 
it does not work:
    
    
    # modb.nim
    import moda
    
    proc quote(s: int): string =
      # reusing the quote implementation for strings here
      quote($s)
    
    # this works
    echo quotedPair("hello")
    
    # this is a compile time error
    echo quotedPair(1)
    
    
    Run

I get a compile time error, although I provide an implementation of `quote` for 
integers.
    
    
    ../moda.nim(8, 10) Error: type mismatch: got <int>
    but expected one of:
    proc quote(s: string): string
      first type mismatch at position: 1
      required type for s: string
      but expression 'x' is of type: int
    
    
    Run

But what I don't understand: As soon as I add _some_ generic version of `quote` 
to module A (that does not even has to match `int`) the code _does_ compile. 
Like so:
    
    
    # moda.nim (modified)
    
    # this doesn't match for `x: int`!
    proc quote*[T](x: seq[T]): string = ""
    
    proc quote*(s: string): string =
        "`" & s & "`"
    
    proc quotedPair*[T](x: T): (T, string) =
        (x, x.quote)
    
    
    Run

What is happening here and is that expected? Also, could I solve my problem 
without the generic (dummy) implementation, maybe somehow 'annotating' the 
`quote` function to be extendable?

By the way, I spotted this technique in Nim mustache. There is a `Context` type 
to which "values" can be added. If the value is not the correct type `Value`, 
it gets cast automatically, see:

<https://github.com/soasme/nim-mustache/blob/master/src/mustachepkg/values.nim#L149>

Nim mustache itself provides some implementations of `castValue`, but they are 
talking explicitly about writing your own implementations for custom types. 
This only seems to work because there are some generic implementations of 
`castValue` that are provided by Nim mustache.

Reply via email to