sorry, previous is v unclear as it's assuming a solution to question 1 in
clarification on question 2.  amended below...

On Mon, Jun 22, 2020 at 12:40 PM Jon Reiter <jonrei...@gmail.com> wrote:

> On Mon, Jun 22, 2020 at 12:00 PM Ian Lance Taylor <i...@golang.org> wrote:
>
>> On Sat, Jun 20, 2020 at 10:48 PM Jon Reiter <jonrei...@gmail.com> wrote:
>> >
>> > the draft lays out an example function GeneralAbsDifference.  these
>> comments build around that.  i wanted to see how far i could get towards
>> working specialization within this framework.  the baseline assumption is
>> that when specialization is required today the acceptable amount of type
>> switching/assertion goes up a bit.
>> >
>> > so the simplest variation is
>> > func GeneralAbsDifference(a,b interface{}) interface{} {
>> >  ai, aiok := a.(int)
>> >  bi, biok := b.(int)
>> >  if aiok && biok {
>> >    return OrderedAbsDifference(ai, bi)
>> >  }
>> >  // repeat for all types
>> > }
>> >
>> > that works but is, even given the qualifier above, not really
>> acceptable.  you can make it a bit cleaner with reflect but still, it's
>> bad.  changing interface{} to Numeric doesn't work with compile error
>> "interface type for variable cannot contain type constraints".  fair
>> enough, although i'm not convinced no such useful check is possible at
>> compile time.  with that facility available it's debatable whether some of
>> those otherwise-not-so-clean setups are worth it in exchange for only
>> having to write the underlying absdiff() functions once each.
>> >
>> > if we pretend the arguments can be of type Numeric we can try our type
>> logic as:
>> >  ao, aook := a.(OrderedNumeric)
>> >  ...
>> > in hopes of getting a somewhat-cleaner arrangement.  this, with a and b
>> using interface{} so it could otherwise compile, returns the entertaining
>> error message "OrderedNumeric does not satisfy OrderedNumeric."  and it is
>> true that type does not appear in the type list of the interface.  in this
>> case there are two arguments and we'd need to ensure they are of the same
>> acceptable type.  i was expecting this to compile and then to write some
>> logic using reflect and see how badly it turned out.  that's not an option.
>> >
>> > but consider this for a single-argument function.  then there is no
>> uncertainty -- the logic i'd need to write is straightforward and can
>> surely be automatically generated.  i think that is true whenever each type
>> parameter specifies only 1 argument's type.  multiple-argument
>> generic-specialization would then require creating "tuple interfaces" that
>> glue the params together but would be otherwise clean and explicit.  it's
>> certainly better than what you'd need to do today to handle any of this.
>> >
>> > so two specific questions:
>> >  - is there some part-way use of types in interfaces that can be used
>> in non-generic function arg specs?  in this case the return value would
>> require it but in general arguments-only would be useful too.
>>
>> Possibly such a thing could be defined, but it's not in the current
>> design draft.  And I'm not sure it would help.  If I write F(a, b
>> Ordered) then both a and b may be Ordered, but nothing requires that
>> they be the same ordered type.
>>
>
> yeah agree i only see a simple way for 1 argument (maybe i did not express
> that clearly).  you could rewrite multiple arguments using generic lists i
> guess, or explicit Pair, Triplet, etc types.
>
>
>>
>> >  - at least for cases where no ambiguity exists is it possible for a
>> type-containing interface to act like it's on it's own type list?
>>
>> I guess I'm not sure why you need this.  If you have a type list, it
>> seems feasible to type switch on each possible type.  I'm sure I'm
>> missing something.
>>
>
> so the code looks like:
> if x1,ok1 := a.(first) ; ok {
>   Generic1(x1)
>
>> } else if x2, ok2 := a.(second) {
>
      Generic2(x2)

> ...
> } else {
>  // never get here as long as every type is covered
> }
>
> but that "never get here" is only true as long as the if/elses match every
> type in the type list.  you could get halfway with something like:
>
for t := range reflect.TypesOnTheList(a) { // maybe
> reflect.TypesOnTheList(reflect.GenericTypeOf(a))
>
  if t == A || t == B || ... {

>  if x,ok := a.(t) ; ok {
>   GenericFunction(x)
>  }
>
} else if t == C || t== D || ... {
    if x,ok := a.(t) ; ok {

>   GenericFunction2(x)
>  }
>
}

> }
>
> this is a step more than syntactic sugar wrt the spec as it automates some
> maintenance.  with that function in reflect it's just convenience.  the
> reflect version here is similar to your "reflection on type arguments"
> section and could be done that way too.  here i think you can get the
> compiler to reject GenericTypeOf() on a non-generic type and ensure the
> loop always hits it's mark.
>

punting on question 1, you can do this with something like what is proposed
in the reflection on type arguments section, i think quite safely.


>
>
>
>>
>> Ian
>>
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CABZtUk6sbKswtCXYCTxF40Db5yZx5CfPzahxh8rcp3DC7tdDsw%40mail.gmail.com.

Reply via email to