I think your example is not relevant, as it clearly intend to change the input type, the goal is to preserve it, while still working with its value.
interface{} value type destroys the input type information, so you might have the opposite value type, a type that preserves. A type that let you write, *func, please, return the type i got*. I did not mention templating, code generate / whatever/ like in https://en.wikipedia.org/wiki/Generic_programming I read something related in "*Generic programming* is a style of computer programming <https://en.wikipedia.org/wiki/Computer_programming> in which algorithms <https://en.wikipedia.org/wiki/Algorithm> are written in terms of types <https://en.wikipedia.org/wiki/Data_type> *to-be-specified-later* that are then *instantiated* when needed for specific types provided as parameters <https://en.wikipedia.org/wiki/Parameter_%28computer_programming%29>." ...*to-be-specified-later... *runtime leaks in the static type system, mostly a question of pov. - <t> behaves like interface{} value type, because it does still say absolutely nothing. Not because it lacks of identity, but because it represents too many possible type. - <t:Interface> is a shorthand to avoid a, probably, very repetitive type assert in order to use a <t>, much like an interface{}, but better, because its shorter - <t> can be use only in func/method parameter (*excluded *receiver) ? I have not been able to find it meaningful elsewhere. - if you don t need to return the input type, you don t need <t> - ultimately, []interface{} == []<t>, they both are list of stuff we have no idea what its about, but <t> has no sense if it is not scoped to a function call stack. - ultimately, []<t:Stringer> does not make sense. - when you receive a func (x <t>) <t> {}, it does actually says nothing to you, the declarer of the func, not because it lacks of identity, but because it represents too many possible types. If you d want to do something of it, you need to type assert it, to narrow it to something meaningful. - when you receive a constrained <t:Interface>, you can work on value of type Interface, and you can return whatever, including the input parameter type - when you call a func with a constrained type, you can actually statically verify that the input value satisfies the constraint. - when you call a <t>, anything is as good as nil (i guess) On Wednesday, July 19, 2017 at 11:47:40 PM UTC+2, Eric Johnson wrote: > > While I lean towards the view that Go should add support for type > generics, I'm not sure your example actually provides sufficient detail to > be an argument for them. > > On Monday, July 17, 2017 at 2:07:46 AM UTC-7, mhh...@gmail.com wrote: >> >> in func do(i interface{}) interface{} (return i), do says nothing because >> "interface{} says nothing", >> >> from the caller pov, it looses information at the return call, >> >> var x = "o" >> do(x) // <- return lost the track it was a string >> >> if you delegate that func to another func, >> it can t says anything else rather than nothing unless it introduces type >> assertion. >> func to(do func(interface{})interface{}) func (interface{}) interface{} { >> return func (i interface{}) interface{} {return do(i)} } >> >> if the observation become "interface{} destroys information", >> does it make sense to consider a "value type of any type that carries out >> its input type" ? >> func do(any <t>) <t> {return any} >> do("thing") <- this is explicitly string >> >> Acting the same way as interface, except that little thing about >> destroying/preserving an information. >> >> It can be delegated to func that works on anything, still returns >> concrete types. >> func to(do func(*<t>*)<t>) func (<t>) *<t>* { return func (i <t>) <t> >> {return do(i)} } >> >> to(do)("whatever") // got a string, right ? >> >> One step forward, >> what if <t> might be able to say "any type with a constraint on that >> interface", >> func do(any <t:Stringer>) <t> {return any} >> do(WhateverStringerCapable{}) <- much like using a regular parameter of >> type Stringer/interface{}, but now the return call reflects the invoke call >> , so its more complete than interface{}/Stringer. >> > > If the "do" method takes and returns a Stringer, then why not just declare > it that way? To make this a more interesting discussion, you have to get > into the details of what the "do" function actually needs to do? Why can't > it just use standard interfaces? > > As I see it, one of the generics problems comes from using the built-in > slices and maps. As it current stands, if I create a method: > > func concat(foo []Stringer) String { > result = "" > for _, s := range foo { > result = result + s.String() + "; > } > return result > } > > but suppose I have two structs, Foo, and Bar, and both *Foo, and *Bar > implement Stringer. > > I cannot do this: > func myFunc(f []*Foo, b []*Bar) string { > return concat(f) + concat(b) > } > > This seems like a more concrete scenario than the one you identified. > > Eric. > > >> >> no? >> >> Or maybe there is a reason in destroying that information ? >> > -- 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.