it's because (well, one of the reasons, rather) we didn't find a great API to 
create a new type and add methods to it:

- one needs a new typename
- one needs a set of methods that have the receiver type as first argument.

you're a bit in a chicken-and-egg situation because it would be great to be 
able to create a type with *all* its methods known at the time of the type 
creation, so a type couldn't "gain" new methods (and thus implement new 
interfaces) during the course of the execution of a program.

having a kind of "start-new-type", "add new methods", "seal-type" API is error 
prone.

alternatively, one could use a "type builder" type:

type TypeBuilder struct { .. }

func NewTypeBuilder(name string, kind reflect.Kind) *TypeBuilder { ... }

// still the issue of how to address the receiver (ptr? value?)
// and its type within the 'fct' reflect.Value possibly created
// via a reflect.MakeFunc.

func (bldr *TypeBuilder) AddMethod(name string, fct reflect.Value) { ... }

// Build seals the type and returns the finalized named type.
func (bldr *TypeBuilder) Build() reflect.Type { ... }

but at the time, this kind of API was departing a bit from what we had in 
reflect.

-s
‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐
On Tuesday, December 29th, 2020 at 6:21 PM, 'Axel Wagner' via golang-nuts 
<[email protected]> wrote:

> On Tue, Dec 29, 2020 at 6:01 PM Arnaud Delobelle <[email protected]> wrote:
>
>> On Tuesday, 29 December 2020 at 16:25:41 UTC [email protected] wrote:
>>
>>> On Tue, Dec 29, 2020 at 4:37 PM Arnaud Delobelle <[email protected]> wrote:
>>>
>>>> Question 1: I *think* that the compiler has all the information necessary 
>>>> to implement type assertion to the Cont interface as I have, i.e. it knows 
>>>> only 3 types implement that interface, so could it not do the optimisation 
>>>> on my behalf?
>>>
>>>>
>>>
>>>> Question 2: Or is it possible that other Go values can be made at runtime 
>>>> that would implement this interface but not be one of the three known 
>>>> types that implement it?
>>>
>>> Yes, re 2. `reflect` can create new types at runtime. AFAIK the 
>>> implementation for interface-type-assertions is basically to look it up in 
>>> a global hashmap, which is pre-seeded with compile-time known types and 
>>> then gets filled on each (successful) inteface-type-assertion with the 
>>> correct method tables. But, I'm handwaving.
>>
>> Ok, I have just looked at the docs for the reflect package, but I can't see 
>> a way to create a type that implements anything but the empty interface. Is 
>> that correct? In that case, wouldn't it mean that it is known at compile 
>> time what types implement a given (non-empty) interface?
>>
>> Edit: I see that reflect.StructOf allows creation of struct types out of 
>> StructField specifications, which have an Anonymous boolean field. I imagine 
>> that the created struct will inherit the methods of embedded types, so it 
>> may implement non empty interfaces. I'm interested in valid use-cases for 
>> this, as it seems to be the thing that prevents this optimisation from being 
>> possible.
>
> Yes, indeed: https://play.golang.org/p/JCcgMvg8f_z
> Personally, I'm rather disappointed that reflect doesn't allow better ways to 
> create types with methods at runtime. I think encoding packages could take 
> advantage of that by consuming an IDL and creating behaviorally complete 
> types.
>
> FWIW, promoted methods haven't always been created by reflect, but even then, 
> the compiler didn't do this analysis. AIUI, it was considered prohibitively 
> expensive to analyze all possible interface/type combinations. TinyGo does 
> it, but a) it has different use-cases (in particular, not prioritizing 
> compile time as much) and b) AIUI doesn't fully support reflect, so doesn't 
> have to worry about runtime type-creation.
>
> But I'm not an expert, so don't trust my judgement of how feasible this 
> optimization would be.
>
>>> Under these assumptions, it might be *possible* to first check against the 
>>> statically known types and only fall back on the map if none of that 
>>> matches. But it doesn't seem 100% clear to me that that's always faster.
>>>
>>> I think concrete type-assertions will always be faster than interface 
>>> type-assertions though - for a concrete type-assertions, it's really just 
>>> comparing the two type-pointers and copying the value (which, in your case, 
>>> is a pointer itself), whereas for an interface type-assertion, the actual 
>>> method table must be assembled or looked up.
>>
>> Yes, that's what I was imagining, and why I decided to try coercion to 
>> concrete type instead!
>>
>> --
>> Arnaud
>>
>> --
>> 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 [email protected].
>> To view this discussion on the web visit 
>> [https://groups.google.com/d/msgid/golang-nuts/e6a8cd0f-bf8c-46ee-9435-48394a120cb5n%40googlegroups.com](https://groups.google.com/d/msgid/golang-nuts/e6a8cd0f-bf8c-46ee-9435-48394a120cb5n%40googlegroups.com?utm_medium=email&utm_source=footer).
>
> --
> 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 [email protected].
> To view this discussion on the web visit 
> [https://groups.google.com/d/msgid/golang-nuts/CAEkBMfEumXWu%3DictPOTKmw575WRN-NTrFza2hsHuaBQLZ%3DtwxQ%40mail.gmail.com](https://groups.google.com/d/msgid/golang-nuts/CAEkBMfEumXWu%3DictPOTKmw575WRN-NTrFza2hsHuaBQLZ%3DtwxQ%40mail.gmail.com?utm_medium=email&utm_source=footer).

-- 
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 [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/R7LfGOEsXsrAQDh3u_mPmf6gMvRlM6t15Rj5QZF5Sl51Bx_QvWQH3FVkJcANZA4UUEEsK6ni-Vu7OrJmSs-31b8B3iM_2q4w_hFN3-IICvY%3D%40sbinet.org.

Reply via email to