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 {
} else if x2, ok2 := a.(second) {
...
} 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 x,ok := a.(t) ; ok {
  GenericFunction(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.



>
> 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/CABZtUk7s07jbDBexwMQO_xeQAajd4CX3RPG1kM-VZgLzF8RC1g%40mail.gmail.com.

Reply via email to