Maybe a loaded question but what is the goal of this thread? Is it to establish whether or not generics impact readability? In that case it should get a lot more civil and charitable on both sides.
Anyway, my take on that: The examples mentioned, in a very real way, are not really suitable to discuss that question. Any readability impact comes not so much from simple declarations, but from a) how frequent type-parameterized objects are going to be and b) how often we can omit the type-parameteres. The issues are things like parameterized type-parameters (today this example <https://twitter.com/MuseumOfTypes/status/428302745330651136> flew through my twitter stream, to illustrate the point) and extra layers of abstraction (like using a Map<Iterable<rune>, Numeric> instead of a map[string]int). Basically, we have three opposing forces: 1) How powerful the generics implementation is, that is what are the things that can be parameterized, 2) How powerful type-inference is for them, that is in which specific circumstances types can be omitted (this is the vital "readability" part) and 3) How simple the description of them is, that is how easy is it to understand failed type-checks to the programmer and how much space would they take up in the spec and/or implementation. Currently, Go *mostly* has 1 near zero (it is a little positive due to the existence of map, [], chan… and append/copy/…), in preference of 2 and 3. Most people agree, that 1 should get a little more love though. It's easy to come up with syntax or semantics that make 1 large, but the issue is, that while we want to increase 1, we don't just want to neglect 2 and 3. Most languages with powerful generics will also include a lot of machinery for 2, that is a complicated type-inference mechanism. Because it's so complicated, they will mostly omit 3, that is they will not specify how exactly it works and leave that up to the implementation, giving them the flexibility to tune the intelligence over time. Most of them (*cough* C++ <https://codegolf.stackexchange.com/questions/1956/generate-the-longest-error-message-in-c> *cough*) also completely fail to provide meaningful error messages for even reasonably simple failures. Now, it's easy to just write down *some* generic (or not generic) code to illustrate some level of readability. But to actually see the effects, a lot more and realistic code is needed and we *need* to talk about 2 and 3. An incredibly good example for how to discuss these is Ian's Proposal for type parameters <https://github.com/golang/proposal/blob/master/design/15292/2013-12-type-params.md>. It gives a detailed description of the power, the type-inference mechanism and the complexity of implementation. AIUI, it failed because of 3. Not every message or opinion about this, of course, needs this level of detail. But just ignoring the complexity is oversimplifying and doesn't do your position a lot of favor. A better way to talk about readability would be, to take a real piece of code that you'd like to write generically (or predict that people would write), take one or two of the existing (declined) proposals and write your code down assuming it where implemented. The advantage is, that the proposals usually are detailed enough to meaningfully talk about the tradeoffs involved and to be sure that "the compiler can infer that" isn't just hand-waved. But Hot-Takes don't really help anyone. On Fri, Aug 25, 2017 at 10:11 AM, Egon <egonel...@gmail.com> wrote: > package tree > > type Node<$Entry> struct { > Value $Entry > Left *Node<$Entry> > Right *Node<$Entry> > } > > func (node *Node) Insert(value node.$Entry) { > var side **Node<node.$Entry> > if node.Value.Less(value) { > side = &node.Right > } else { > side = &node.Left > } > > if *side == nil { > *side = &Node<node.$Entry>{Value: value} > } else { > (*side).Insert(value) > } > } > > -- > > package tree<Entry> > > type Entry generic { > Less(Entry) bool > } > > type Node struct { > Value Entry > Left *Node > Right *Node > } > > func (node *Node) Insert(value Entry) { > var side *Node > if node.Value.Less(value) { > side = &node.Right > } else { > side = &node.Left > } > > if *side == nil { > *side = &Node{Value: value} > } else { > (*side).Insert(value) > } > } > > > On Thursday, 24 August 2017 20:08:16 UTC+3, mhh...@gmail.com wrote: >> >> Why would you put generics on a method ? >> >> The syntax you demonstrate is horrible, indeed. >> >> what if generics are type related >> >> type notFinal struct { >> p1 <T1> >> p2 <T2> >> } >> >> func (n notFinal) whatever(in <T1>) string { >> return fmt.Sprintf(in) // anything to interface{}, works. >> } >> >> type Final notFinal<int, string> >> >> Final.whatever(1) // "1" >> >> //notFinal not instantiable, not type assertable >> >> >> >> Or func related >> >> type notFinal func(in <T1>) string >> >> func Final notFinal<int> >> >> Final(1) // "1" >> >> >> That said, ultimately, the more the syntax is parametrized the more >> complex it become. when there are many func signature as you demonstrate, >> it will get worse. >> >> Named type might help, could be vetted too ? >> >> Also >> none of this is as powerful as code gen. >> None of those examples are better than interface{}. >> >> On Thursday, August 24, 2017 at 5:14:58 PM UTC+2, JuciÊ Andrade wrote: >>> >>> A lot of people like Go because code is very readable even for beginners. >>> >>> func f(x, y int) >>> >>> f is a function that receives x and y as int parameters, returning >>> nothing. Simple enough. >>> >>> func f(x, y int) int >>> >>> f is a function that receives x and y as int parameters, returning yet >>> another int. Fine. >>> >>> func f(x, y int) (z int, err error) >>> >>> f is a function that receives x and y as int parameters, returning two >>> values: a first int, that we name z and an error named err. A little bit >>> weird, but ok. >>> >>> func (r MyType) f(x, y int) (z int, err error) >>> >>> f is a method for a value of type MyType, henceforth named r, that >>> receives x and y as int parameters, returning two values: a first int, that >>> we name z and an error named err. Definitely not so simple. >>> >>> <genType1, genType2> func (r genType1) f(x, y genType2) (z getType2, err >>> error) >>> >>> You must be kidding. STOP RIGHT THERE! >>> >>> -- > 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. > -- 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.