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.