On Thu, 18 Oct 2018 at 13:41, Axel Wagner <axel.wagner...@googlemail.com>
wrote:

> On Thu, Oct 18, 2018 at 2:06 PM roger peppe <rogpe...@gmail.com> wrote:
>
>> For generics, that analysis is trivial - there is no need to do any
>> control flow analysis to determine the set of possible generic type
>> parameters to a type or function (with the exception of recursive generic
>> functions, which can be disallowed).
>>
>> For interfaces, the job is much harder. Guru can do it, but only to a
>> limited extent.  And in general it's not possible a) because the number of
>> possible types is not bounded (you can create new types with the reflect
>> package, or by dynamically loading modules) and b) because you'd need to
>> solve the halting problem.
>>
>
> I don't understand what you're trying to say. These two cases are not
> relevant here, because you can't actually do them with the contracts design
> - in fact, at least the reflection one is specifically called out in the
> "Dual implementation" section of the overview. I never claimed the analysis
> for interfaces is *easier*, I claimed that it's *exactly as hard.*
>
> Or, to put it another way: That "limited extend" you mention is exactly
> the extend to which the compiler can do that proof for generics. So doing
> it to that extend provides you with the same performance benefit.
>

> Or, if you prefer: The type-checker and/or heuristic for whether to
> specialize a function for generics provides a blue-print for how to do the
> equivalent analysis for interfaces.
>

It really doesn't, because interface values carry their types with them,
whereas type parameters always stay as type parameters and cannot be
directly stored in a value (unless you convert it to an interface value).

You cannot take the dynamic type of an interface value and turn it into a
type parameter unless you explicitly mention the type... at which point
it's no longer dynamic.

With type-parametric generics, you cannot return a value with a type that
uses a generic type that's not passed in the type parameters. With
interfaces, you can.

With type-parametrics generics, you can expand all possible type parameters
at compile time without needing to do any flow analysis. As an example:
https://play.golang.org/p/68eHo313LZI. It's easy to find out all the
possible types for the generic functions there. Here they are.

        repeat(string)
        repeat(int)
        repeat([]string)
        last([]string)
        index([]string)
        first(int)
        index(int)

The algorithm to do it is quite straightforward:
https://play.golang.org/p/subnLkSSxdI

But in the case where your first paragraph applies - i.e. you can
>>> statically know the full set of types a generic function or type is
>>> instantiated with - the exact same analysis can also provide exactly the
>>> same results for interface-based polymorphism.
>>>
>>
>> It really can't.  The analysis needed for parametric types need not look
>> at anything other than type parameters. The analysis needed for interfaces
>> needs to analyse the code itself. A few examples:
>> https://play.golang.org/p/CEzBpsRIVGQ
>>
>
> AFAICT none of these map to contracts either.
>

Actually they do - interface{} is equivalent to the contract(T){}. But I'm
not sure what you're getting at there.

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to