Go has generics. Right?

1,992 views
Skip to first unread message

Peter Kleiweg

unread,
Dec 14, 2014, 6:19:07 AM12/14/14
to golan...@googlegroups.com
I think the Sort function in the sort package is a good example of a generic function. Then why keep people asking for generics? What am I missing?

Jan Mercl

unread,
Dec 14, 2014, 6:58:55 AM12/14/14
to Peter Kleiweg, golan...@googlegroups.com
> missing?

But, but, but one must _manually_ write 3 lines of the adaptor code per type. </irony>

-j

branimir....@gmail.com

unread,
Dec 14, 2014, 7:02:42 AM12/14/14
to golan...@googlegroups.com
What you missing is that generics are parametric polymorphism, see http://en.wikipedia.org/wiki/Polymorphism_%28computer_science%29

Peter Kleiweg

unread,
Dec 14, 2014, 9:11:44 AM12/14/14
to golan...@googlegroups.com, branimir....@gmail.com
Op zondag 14 december 2014 13:02:42 UTC+1 schreef branimir....@gmail.com:

What you missing is that generics are parametric polymorphism, see http://en.wikipedia.org/wiki/Polymorphism_%28computer_science%29

It don't understand that, so I think it's a good thing Go doesn't have that. I'm a programmer, not a programming language theorist. 

Show me something practical that you can do with generics and not with Go.

Matthew Kane

unread,
Dec 14, 2014, 9:20:47 AM12/14/14
to Peter Kleiweg, branimir....@gmail.com, golang-nuts

A function that takes a variable of some type and returns that type, not an interface variable.

Sent from my mobile.

--
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...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Peter Kleiweg

unread,
Dec 14, 2014, 9:27:05 AM12/14/14
to golan...@googlegroups.com, pkle...@xs4all.nl, branimir....@gmail.com
Op zondag 14 december 2014 15:20:47 UTC+1 schreef mkb:

A function that takes a variable of some type and returns that type, not an interface variable.

You mean...

func Foo(s someType) someType {
   
// ...
}
 
What is the problem with that?

Please, give an example.

Kostarev Ilya

unread,
Dec 14, 2014, 9:39:30 AM12/14/14
to golan...@googlegroups.com
type TypeVar1;
type TypeVar2;

func Map (list []TypeVar1, mapper func(TypeVar1) TypeVar2) []TypeVar2{
result:=make([]TypeVar2)
for k, v:=range list {
result[k] = v
}
return result
}


-- 
Kostarev Ilya

On 14 Dec 2014 at 17:11:48, Peter Kleiweg (pkle...@xs4all.nl) wrote

Kostarev Ilya

unread,
Dec 14, 2014, 9:45:05 AM12/14/14
to golan...@googlegroups.com
Sorry, typo.

type TypeVar1;
type TypeVar2;

func Map (list []TypeVar1, mapper func(TypeVar1) TypeVar2) []TypeVar2{
result:=make([]TypeVar2)
for k, v:=range list {
result[k] = mapper(v)
}
return result
}

-- 
Kostarev Ilya

On 14 Dec 2014 at 17:11:48, Peter Kleiweg (pkle...@xs4all.nl) wrote


egon

unread,
Dec 14, 2014, 9:47:39 AM12/14/14
to golan...@googlegroups.com, branimir....@gmail.com
1. Rx -> for reactive programming, 

2. LINQ -> i.e. concise data manipulation (map/reduce/fold etc.)

3. Generic Data Structures -> Sets/Trees/Matrices e.g. https://github.com/egonelbre/spexs2/blob/master/set/set.go

Currently it implements only for a concrete case of ints.

4. Generic Algorithms
e.g. https://gist.github.com/egonelbre/10578266, you have type conversion scattered around.

5. Type-Safe interface implementations -> e.g. https://github.com/egonelbre/event/blob/master/example/guestlist/counter.go#L14 see how the Apply takes a interface instead of a concrete type.

They have their benefits, mainly type-safety/speed, but I won't go over those...

My opinion regarding those with Generics:
1, 2 = I'm not sure whether trying to retrofit a different paradigm into Go is a such good idea. A DSL instead of Generics might be better, although it will be more work.

2 = Such data-processing is probably better suited for the DB side, because it has more information how to do the processing efficiently.

3 = There aren't that many data-structures that can be generic and fast/useful at the same time. A collection for different concrete use cases might be better than a generic data-structure. Also for the rare cases go generate with map/slices suffices.

4 = The same as before it might be more beneficial to have concrete use-case implementation than a generic package.

5 = Type conversion isn't that bad. Also, there might be a way to write a tool that does vetting/linting for such particular cases.

+ Egon

Peter Kleiweg

unread,
Dec 14, 2014, 9:57:20 AM12/14/14
to golan...@googlegroups.com


Op zondag 14 december 2014 15:45:05 UTC+1 schreef Uvelichitel:

type TypeVar1;
type TypeVar2;

What is this supposed to do?

Kostarev Ilya

unread,
Dec 14, 2014, 10:23:42 AM12/14/14
to golan...@googlegroups.com


-- 
Kostarev Ilya

It’s supposed to state that

a and b in

func copy(a TypeVar) b TypeVar{

b:=a

return b

}

must have any, but the same type instead of untyped

func (a interface{}) b interface{}

-- 

Kostarev Ilya 

atd...@gmail.com

unread,
Dec 14, 2014, 12:04:01 PM12/14/14
to golan...@googlegroups.com
I can do that in a type safe way with interfaces but I agree that it is not overly convenient. Interfaces are a lattice of types but discriminating over them is a bit annoying (for now)
Alternatively, you have Kinds in the reflect package so it should be possible at some point to do what you want.

Some people complain and they seem to be the most vocal about it, but otherwise, a lot of people are busy coding and don't even bother.

No worries. :)

atd...@gmail.com

unread,
Dec 14, 2014, 12:08:30 PM12/14/14
to golan...@googlegroups.com
And you have the people who don't even use Go but are vocal about it but that's another story lol. (the internetz)

Matt Sherman

unread,
Dec 14, 2014, 12:09:22 PM12/14/14
to golan...@googlegroups.com
The gen tool exists for this purpose -- to generate strongly-typed implementations where one would otherwise use an interface{}: https://clipperhouse.github.io/gen/

Monosij Dutta-Roy

unread,
Dec 14, 2014, 1:51:51 PM12/14/14
to golan...@googlegroups.com
Thanks for this discussion thread and raising the issues.

I am new to Go. Am using Go 1.4 on Ubuntu.

1 problem I am having is that I want to use a struct to read data into its fields - say lastName, firstName, middleInitial and define them as string.

I can read the data into them from a SQL DBMS from CHAR / VARCHAR fields as long they are NOT NULL.

If there are NULL values - I have to define a field, say middleInitial as sql.NullString.

I find this totally counter-intuitive and counter-productive. Because now I cannot use the struct to read data from a CSV file or a JSON impl. such as MongoDB.

Btw I have read the JSON marshaling so I think I can read from JSON but it is not elegant.

I am not understanding why my struct needs to be connected to a SQL implementation.

If there is a better way to think about this I would like to know. I mean is there a way to make middleInitial an empty string w/o having to redefine the type?

I even tried initializing middleInitial to empty string as in middleInitial := "" outside a struct. Cannot seem to do it inside the struct.

Because there may be lots of fields over different structs which may be null and I do not want to redefine all of them.

Would love to know your thoughts and get your help in what I may be missing here - or how I need to think differently to ue Go.

Again much appreciated the discussion.

Mono

akwillis

unread,
Dec 14, 2014, 2:30:19 PM12/14/14
to golan...@googlegroups.com, pkle...@xs4all.nl
It is more like 20% of the non-comment lines need to be edited. A simple method set(insert, delete,contain, difference, intersect, super, sub) for a Set struct wrapping a slice is about 100 lines of gofmt formatted code - 22 lines need editing every time I change the type. I've gave my two cents why generics should be added at a syntactic level, so I won't get into again - other than stating code reuse, and that alone should be a big enough reason to consider it. I find it ironic that the authors put so much effort into keeping the language syntactically light to reduce source sizes but left out a feature such as type parameterization.

Peter Kleiweg

unread,
Dec 14, 2014, 2:44:37 PM12/14/14
to golan...@googlegroups.com
What I would like to see is a small, readable, working example of C++ with generics doing something that can't be done in Go efficiently.

flat...@users.sourceforge.net

unread,
Dec 14, 2014, 2:44:54 PM12/14/14
to golan...@googlegroups.com
On Sunday, December 14, 2014 9:51:51 PM UTC+3, Monosij Dutta-Roy wrote:

First, what you have just did is called "thread hijacking": taking a thread busy discussing
some problem and posting there a message which has absolutely no relation to the
problem being discussing.  Please do not do this next time -- start a new thread instead
by simply posting a message to the group.

[...]

1 problem I am having is that I want to use a struct to read data into its fields - say lastName, firstName, middleInitial and define them as string.

I can read the data into them from a SQL DBMS from CHAR / VARCHAR fields as long they are NOT NULL.

If there are NULL values - I have to define a field, say middleInitial as sql.NullString.

I find this totally counter-intuitive and counter-productive. Because now I cannot use the struct to read data from a CSV file or a JSON impl. such as MongoDB.
[...]
I am not understanding why my struct needs to be connected to a SQL implementation.
[...]

This is quite simple in fact: your implementation must be aware of SQL peculiarities
simply because these peculiarities do exist.  Since SQL defines the existence of the
NULL value, any column not explicitly marked as "NOT NULL" in the table's schema
now might legitimately has the value NULL when returned by the database to your
program, and you *must* somehow deal with this.

There are various ways to do that:
* Fix the schema.  If you're sure you don't want NULLs for those part of the human's
  name, fix the schema and use plain `string` type in your struct fields.
* Use `sting` and let the program crash if it ever receives a NULL value for one
  of those fields.  This is normal even if looks counter-intuitive: if you can guarantee
  you won't ever have NULL inserted into those columns in the table (say, all inserts
  are done by a program which verifies its input from the user).
* Use two step approach: have a layer of "marshaling" code sit between your SQL-facing
  code and a higher-level layer which thinks all your possible data sources have no
  concept of NULLs.  That is, wrap the SQL row reader's implementation.

Peter Kleiweg

unread,
Dec 14, 2014, 2:49:04 PM12/14/14
to golan...@googlegroups.com, pkle...@xs4all.nl
Op zondag 14 december 2014 20:30:19 UTC+1 schreef akwillis:

It is more like 20% of the non-comment lines need to be edited. A simple method set(insert, delete,contain, difference, intersect, super, sub) for a Set struct wrapping a slice is about 100 lines of gofmt formatted code - 22 lines need editing every time I change the type. 

Why do you need to change the type? Use an interface. Any type that satisfies the interface can be used as arguments. Any type that doesn't... if it ain't food, you can't eat it.

Kostarev Ilya

unread,
Dec 14, 2014, 2:56:04 PM12/14/14
to golan...@googlegroups.com
On 14 Dec 2014 at 22:30:22, akwillis (akwi...@gmail.com) wrote:
 A simple method set(insert, delete,contain, difference, intersect, super, sub) for a Set struct wrapping a slice is about 100 lines of gofmt formatted code - 22 lines need editing every time I change the type. I've gave my two cents why generics should be added at a syntactic level, so I won't get into again - other than stating code reuse, and that alone should be a big enough reason to consider it. I find it ironic that the authors put so much effort into keeping the language syntactically light to reduce source sizes but left out a feature such as type parameterization.

You can write code in generic manner "var x $Type” and then generate needed instances for $Type with “go generate” or thirdparty tools. Unfortunately such generic code can’t be typechecked by compiler. Fullblown type checker implementing Hindley–Milner would be quite sophisticated system. Say Haskell type checker is Turing complete, which means it can consume unpredictable time to process, even never stop. But Go compiler must be fast, it’s a design goal. So I can understand tradeoff. Personally I fill comfortable without generic.

-- 

Kostarev Ilya

atd...@gmail.com

unread,
Dec 14, 2014, 3:02:16 PM12/14/14
to golan...@googlegroups.com, pkle...@xs4all.nl
In his case an interface brings overhead. He doesn't really need the genericity, but he just finds the process of changing types on his datastructures tedious.

I think that using gorename should be fine though, without having to modify the whole language.

However an interface would be the right thing to use if you have nodes which types can vary at runtime. i have had that case myself.
Actually, I didn't even use an interface but created my own constrained generic datatype (just a struct of three pointers of different type was sufficient)

No need to penalize everybody with type parametrization just because of my use case.

akwillis

unread,
Dec 14, 2014, 3:04:49 PM12/14/14
to golan...@googlegroups.com, pkle...@xs4all.nl
Then data types are wrapped in interfaces, 10 to 50 million adds up to a big chunk of resources, and with the simplest of types that could add up to 20-50% overhead. Other suggestions would be to write or use third party tools and frameworks. Maybe on another project, but right now I'm working with a very limited language-only toolset - its how my employer wants it. And, I will be the first to admit I suck with go, and maybe I will find ways to reduce my workload as I learn more, but right now writing a few data types has been a pain.

atd...@gmail.com

unread,
Dec 14, 2014, 3:05:57 PM12/14/14
to golan...@googlegroups.com
Well, and I would even add that the code that is generated has to be typesafe. You are not using the template in your code. You just have a file that generates typed code. It is an external process. The client of your code is not supposed to see this.

atd...@gmail.com

unread,
Dec 14, 2014, 3:06:46 PM12/14/14
to golan...@googlegroups.com, pkle...@xs4all.nl
Why did I say gorename, I wonder...
go generate.

akwillis

unread,
Dec 14, 2014, 3:38:51 PM12/14/14
to golan...@googlegroups.com
go is fine. I'm just an outsider with a two-bit opinion on how I think it could be better. The project I'm working on has restrictions, and if I was more experienced with go I would have known what I was getting into. With the restrictions in place I found myself thinking that type parameterization would be a great feature.

Nick Craig-Wood

unread,
Dec 15, 2014, 11:47:12 AM12/15/14
to akwillis, golan...@googlegroups.com, pkle...@xs4all.nl
On 14/12/14 19:30, akwillis wrote:
> It is more like 20% of the non-comment lines need to be edited. A simple
> method set(insert, delete,contain, difference, intersect, super, sub)
> for a Set struct wrapping a slice is about 100 lines of gofmt formatted
> code - 22 lines need editing every time I change the type.

Write a gotemplate, or even use the Set type provided. Add a single go
generate line to your code and you are done.

https://github.com/ncw/gotemplate

http://godoc.org/github.com/ncw/gotemplate/set


--
Nick Craig-Wood <ni...@craig-wood.com> -- http://www.craig-wood.com/nick

adon...@google.com

unread,
Dec 15, 2014, 1:36:37 PM12/15/14
to golan...@googlegroups.com
On Sunday, 14 December 2014 06:19:07 UTC-5, Peter Kleiweg wrote:
I think the Sort function in the sort package is a good example of a generic function. Then why keep people asking for generics? What am I missing?

Whether or not one thinks that generics would be a good addition to Go (and the apparent consensus around here is that it would not), it is a fact of life that without generics, there are many little routines that one must implement over and over again, such as the max() function over numbers:

func max(x, y int) int {
   if y > x { 
      return y
   }
   return x
}

The definition above is good for int, but not for int64, or float32, or string.  I'm sure you've encountered other examples in your own work.

Generics is one way to let you express this algorithm once so that it works for all appropriate data types.
Macro expansion (such as Matt Sherman's gen tool) is another.

Interface (subtype) polymorphism doesn't help in this case, though it does in some others.

Rick

unread,
Dec 15, 2014, 2:07:46 PM12/15/14
to golan...@googlegroups.com


On Sunday, 14 December 2014 03:19:07 UTC-8, Peter Kleiweg wrote:
I think the Sort function in the sort package is a good example of a generic function. Then why keep people asking for generics? What am I missing?

Concerning the max() example, it isn't generics but I think supporting duplicate function names with distinct signatures would be nice:

func max(x, y int) int
func max(x, y int32) int32
func max(x, y int64) int64

etc.

The compiler uses the name of the function + the types of the arguments that were passed to resolve the call to the correct definition. It does require repetition of the function definition for each desired calling signature but you only do it once and then forget about it.

I'm not a compiler guy so I have no idea whether this would be practical, but it's one of the things I miss from Java.

Ian

unread,
Dec 15, 2014, 2:11:31 PM12/15/14
to golan...@googlegroups.com
The thing about generics isn't that they can't be "replicated" by writing endlessly adapted code, it's that they're a *tool* that can be used to get the compiler to do the mindless, boring work of endlessly copying, pasting and changing type-specific code! Sometimes it's three lines of code that needs to be copied/pasted/changed; other times, it might be thirty or more! I get the impression that a good many folk are happy to indulge, because it's just "a few lines", "a few times". 

Just out of curiosity, I looked up generics in Apple's new Swift language. Here's what it says:
"Generic code enables you to write flexible, reusable functions and types that can work with any type, subject to requirements that you define. You can write code that avoids duplication and expresses its intent in a clear, abstracted manner."

Doesn't that say it all?

As an aside, and not to distract from the topic of conversation, Go seems to have a lot of "it's just a few lines" going on. A few lines here, a few lines there - pretty soon you're talking about significant quantities of "a few lines"! 

Anyhoo, I believe Dave Cheney recently declared the whole discussion about generics to be a thoroughly deceased equine.

Ian

unread,
Dec 15, 2014, 2:24:44 PM12/15/14
to golan...@googlegroups.com
That's not to imply that discussion should end!

Personally, I believe Go should have generics (because I hate rewriting the same function over and over and over, as I just had to do) and would like to see a comprehensive discussion about the topic. Mostly because I think such a conversation has a good chance of leading to Go getting Generics! :-) I merely noted it because the ending of the previous conversation on the topic was pretty definitive.


On Monday, December 15, 2014 2:11:31 PM UTC-5, Ian wrote:
 [...]

Ian Lance Taylor

unread,
Dec 15, 2014, 2:39:07 PM12/15/14
to Rick, golang-nuts
On Mon, Dec 15, 2014 at 11:07 AM, Rick
<thesuggested...@gmail.com> wrote:
>
> Concerning the max() example, it isn't generics but I think supporting
> duplicate function names with distinct signatures would be nice:
>
> func max(x, y int) int
> func max(x, y int32) int32
> func max(x, y int64) int64
>
> etc.
>
> The compiler uses the name of the function + the types of the arguments that
> were passed to resolve the call to the correct definition. It does require
> repetition of the function definition for each desired calling signature but
> you only do it once and then forget about it.

That is overloading, not generics.

http://golang.org/doc/faq#overloading

Ian

Ian Lance Taylor

unread,
Dec 15, 2014, 2:50:27 PM12/15/14
to Ian, golang-nuts
On Mon, Dec 15, 2014 at 11:11 AM, Ian <ian.gr...@gmail.com> wrote:
>
> The thing about generics isn't that they can't be "replicated" by writing
> endlessly adapted code, it's that they're a *tool* that can be used to get
> the compiler to do the mindless, boring work of endlessly copying, pasting
> and changing type-specific code! Sometimes it's three lines of code that
> needs to be copied/pasted/changed; other times, it might be thirty or more!
> I get the impression that a good many folk are happy to indulge, because
> it's just "a few lines", "a few times".
>
> Just out of curiosity, I looked up generics in Apple's new Swift language.
> Here's what it says:
> "Generic code enables you to write flexible, reusable functions and types
> that can work with any type, subject to requirements that you define. You
> can write code that avoids duplication and expresses its intent in a clear,
> abstracted manner."
>
> Doesn't that say it all?
>
> As an aside, and not to distract from the topic of conversation, Go seems to
> have a lot of "it's just a few lines" going on. A few lines here, a few
> lines there - pretty soon you're talking about significant quantities of "a
> few lines"!

Nobody sensible denies that there is a benefit to having generics.
But there are also costs. The discussion is whether the costs are
worth the benefits. And it's quite difficult to have a sensible
discussion on that point without a detailed implementation proposal.

I appreciate that few people are willing to make a detailed
implementation with no guarantee that it will be adopted. But I
honestly don't see how we can discuss costs if we don't know what we
are talking about.

Ian

Ian

unread,
Dec 15, 2014, 3:47:29 PM12/15/14
to golan...@googlegroups.com, ian.gr...@gmail.com
The circle of doom? 

I disagree on the first thing that has to happen. Before the time spent on detailing an implementation can be considered worthwhile is that first, the Go team has to be *sold* on the concept! That simply isn't going to happen. 

If I had the time, I'd consider doing a proposal simply for the intellectual exercise. But I'm a one-man band; on average, I spend 16+ hours a day, 7 days a week, working on my business; for me, for instance, to dedicate the time to what is essentially a meaningless quest, I'd have to take time away from my business! Go has a corporate management structure; that and the "more than a few" previous discussions have to be taken into consideration before any substantive change could be seriously proposed. Knowing that and reckoning that, in all likelihood, any proposal *would* either be rejected for valid reasons (e.g. who maintains the implementation?) or it would be nitpicked to death (with the resulting nitpick/response cycle consuming vast amounts of time and effort), there's simply no incentive to produce a detailed implementation specification. (Yes, that was a slightly long-winded, but perfectly reasonable, way of arguing generics really have to be implemented either by the core Go team or some other corporation that can spare both the man- or woman-power and the funding; arguably, they'd have to be such an intrinsic part of the language it really should be Google's job.)

But generics in Go aren't going to happen, so there's no reason to produce a detailed specification, never mind an implementation that can be examined and critiqued! In short, that particular circle of doom is quite robust.

atd...@gmail.com

unread,
Dec 15, 2014, 5:25:25 PM12/15/14
to golan...@googlegroups.com, ian.gr...@gmail.com
The thing is, there is no generic solution to the issue of generic programming. So don't be too attached to the brand of generic programming that you want/ know because it might not suit Go. Just as the solution implemented in C++ is not the same as in Java, C#, Haskell etc, etc.

By the way, I know you do not have much time but you could look at how the topic of Generic programming has been tackled in Ada. It is quite interesting. (just in case you are curious about another way to do "generic" things)

matthew...@gmail.com

unread,
Dec 15, 2014, 6:13:11 PM12/15/14
to golan...@googlegroups.com, thesuggested...@gmail.com
They lack of overloading/operators is a major pain for some types of applications such a vector/matrix math. If you consider the equivalent C++ code that you can produce there is little doubt that while lack of overloading/operators may be simpler for the compiler writer it is definitely not simpler for the user of the langauge.

Consider:

glm::vec3 v1 = ...;
glm::vec3 v2 = ...;
glm::vec3 v3 = ...;

glm::vec3 v = ((v1 - v2) * v2) / 2.0

vs

v1.Sub(v2).Mul(v2).DivN(2.0)

It doesn't take much imagination to see which is simpler to read and understand. And then it gets much worse with no overloading so you end up with Mul, MulV3, MulMat3, MulN and so forth.

Andrew Gerrand

unread,
Dec 15, 2014, 8:50:52 PM12/15/14
to Ian, golang-nuts
On 16 December 2014 at 06:24, Ian <ian.gr...@gmail.com> wrote:
Personally, I believe Go should have generics (because I hate rewriting the same function over and over and over, as I just had to do) and would like to see a comprehensive discussion about the topic.

Go doesn't have generics, but it has provoked the most thorough, comprehensive, and tedious discussions of them that I have seen anywhere. If you missed it, you should look harder.
 
Mostly because I think such a conversation has a good chance of leading to Go getting Generics! :-)

There is zero chance of these threads evolving into something productive.

Andrew

Alan Donovan

unread,
Dec 15, 2014, 9:08:48 PM12/15/14
to matthew...@gmail.com, golang-nuts, thesuggested...@gmail.com
On 15 December 2014 at 18:13, <matthew...@gmail.com> wrote:
They lack of overloading/operators is a major pain for some types of applications such a vector/matrix math. If you consider the equivalent C++ code that you can produce there is little doubt that while lack of overloading/operators may be simpler for the compiler writer it is definitely not simpler for the user of the langauge.

Consider:

glm::vec3 v1 = ...;
glm::vec3 v2 = ...;
glm::vec3 v3 = ...;

glm::vec3 v = ((v1 - v2) * v2) / 2.0

vs

v1.Sub(v2).Mul(v2).DivN(2.0)

It doesn't take much imagination to see which is simpler to read and understand. And then it gets much worse with no overloading so you end up with Mul, MulV3, MulMat3, MulN and so forth.

My colleague David Crawshaw observed that much of the desire for generic functions, operator overloading, multidimensional slices, etc.,  come from mathematical programming, and wondered whether it might not be worth inventing a domain-specific language for writing mathematical kernels that compiles to efficient Go and interoperates well with its data types.

Obviously this approach assumes it's possible to make a clean separation of "math" and "logic" in these kind of applications, but it's a much smaller project than building a real compiler for a new language, and less quixotic than adding generics in the Go spec.  Since those that don't want it needn't use it, there are no political hurdles.

Ian

unread,
Dec 15, 2014, 9:34:27 PM12/15/14
to golan...@googlegroups.com, ian.gr...@gmail.com
I'm not attached to any particular "brand" of generic! 

Ada... Yeah, I remember something intriguing about how that language handled generic data types. I'll have to go look it up, as you said! (I did start looking at Haskell's type system; there are some really interesting ideas in that!)

Ian

unread,
Dec 15, 2014, 9:37:01 PM12/15/14
to golan...@googlegroups.com, ian.gr...@gmail.com
No one is forcing you to read the discussions, Andrew.

And so far I've not seen *anything* that contradicts a claim I made in previous thread that Go doesn't have generics because the team doesn't like 'em! So there's zero chance Go will ever have generics. But I'm an optimist. :-)

Oh, nearly forgot - thanks for the condescension.

Ian Lance Taylor

unread,
Dec 15, 2014, 9:49:18 PM12/15/14
to Ian, golang-nuts
On Mon, Dec 15, 2014 at 12:47 PM, Ian <ian.gr...@gmail.com> wrote:
>
> I disagree on the first thing that has to happen. Before the time spent on
> detailing an implementation can be considered worthwhile is that first, the
> Go team has to be *sold* on the concept! That simply isn't going to happen.

You're right, that isn't going to happen. It doesn't even make sense.
You can't sell the Go team on a concept without details. Go is a
language where the details matter. It's not a language for trying out
concepts. It's a language where every new concept needs to pass a
high bar to get in. That's not to say that Go is perfect--in fact
it's clearly imperfect; not every decision was correct in retrospect.
But every new feature must prove that the benefits are worth the cost,
and that has been true throughout the development of the language.
There is no way to even discuss benefits and costs without a clear and
complete proposal.

That may mean that generics will never happen, but it has to work that
way for Go. It can't work any other way.

To be clear, I'm on the Go team, but I'm only speaking for myself.


> If I had the time, I'd consider doing a proposal simply for the intellectual
> exercise. But I'm a one-man band; on average, I spend 16+ hours a day, 7
> days a week, working on my business; for me, for instance, to dedicate the
> time to what is essentially a meaningless quest, I'd have to take time away
> from my business! Go has a corporate management structure; that and the
> "more than a few" previous discussions have to be taken into consideration
> before any substantive change could be seriously proposed. Knowing that and
> reckoning that, in all likelihood, any proposal *would* either be rejected
> for valid reasons (e.g. who maintains the implementation?) or it would be
> nitpicked to death (with the resulting nitpick/response cycle consuming vast
> amounts of time and effort), there's simply no incentive to produce a
> detailed implementation specification. (Yes, that was a slightly
> long-winded, but perfectly reasonable, way of arguing generics really have
> to be implemented either by the core Go team or some other corporation that
> can spare both the man- or woman-power and the funding; arguably, they'd
> have to be such an intrinsic part of the language it really should be
> Google's job.)

I agree that some member of the Go team has to be involved at some
point for any proposal to succeed. I've always carefully read every
generics proposal that has been made on the mailing list. I've
explained why each one is not satisfactory.

(And for what it's worth, I would not say that the Go open source
project has a corporate management structure.)

Ian

Ian Lance Taylor

unread,
Dec 15, 2014, 9:53:17 PM12/15/14
to matthew...@gmail.com, golang-nuts, Rick Morrison
On Mon, Dec 15, 2014 at 3:13 PM, <matthew...@gmail.com> wrote:
>
> They lack of overloading/operators is a major pain for some types of
> applications such a vector/matrix math. If you consider the equivalent C++
> code that you can produce there is little doubt that while lack of
> overloading/operators may be simpler for the compiler writer it is
> definitely not simpler for the user of the langauge.

It's a bit of myth that avoiding overloading/operators is simpler for
the compiler writer. It would be trivial to add them from a compiler
perspective (assuming they did not require C++ style implicit type
conversion, which I don't think anybody would want for Go).

The FAQ explains why Go doesn't have them
(http://golang.org/doc/faq#overloading). Permitting method and
operator lookup only by name is very simple. Simple to understand,
simple to write, simple to read.

You're entirely correct that for the limited subset of mathematical
programming, where there can be clear meanings for certain operators,
it would be nice to be able to use operators. That is a very limited
subset of programs, though. The question is: is it worth the cost of
considerable conceptual complexity when reading all Go programs to
make it easier to write a small number of mathematical programs?
Perhaps it is, but it's not an obvious choice.

Ian

Andrew Gerrand

unread,
Dec 15, 2014, 10:01:11 PM12/15/14
to Ian, golang-nuts
On 16 December 2014 at 13:37, Ian <ian.gr...@gmail.com> wrote:
No one is forcing you to read the discussions, Andrew.

Well, I do maintain this mailing list. I should be reading it. Plus, this is already a high traffic mailing list. I'd prefer that people used it to help people use actual Go, rather than debate some hypothetical Go.

And so far I've not seen *anything* that contradicts a claim I made in previous thread that Go doesn't have generics because the team doesn't like 'em! So there's zero chance Go will ever have generics. But I'm an optimist. :-)

Whether or not we "like" generics is irrelevant. I like rabbits, but they don't belong in Go.

Maybe you can't see it, but to me your attitude is condescending. You're saying the reason Go doesn't have generics is because the Go team feels negatively about them. Yet we have repeated over and over the technical, philosophical, and design reasons why Go doesn't have them. Do those arguments mean nothing to you?

There are practical concerns, too: Go with generics would be something else entirely, as you'd at least have to rewrite the entire standard library. All user programs would be rewritten, too. In other words, we would be starting over again. That's not going to happen.
 
Oh, nearly forgot - thanks for the condescension.

No condescension implied. I'm being totally sincere.

Andrew 

Bakul Shah

unread,
Dec 15, 2014, 10:39:52 PM12/15/14
to Ian, golan...@googlegroups.com
On Mon, 15 Dec 2014 18:37:01 PST Ian <ian.gr...@gmail.com> wrote:
>
> And so far I've not seen *anything* that contradicts a claim I made in
> previous thread that Go doesn't have generics because the team doesn't like
> 'em! So there's zero chance Go will ever have generics.

With this attitude why even bother?

But if you really want generics added to Go, there is a way.
Not an easy way though.

1. Come up with a *complete* generics proposal that integrates
*well* with the language. You will have consider its impact
on *every* other go feature.

2. Compute the cost of implementation & its effect on other
things such as GC or concurrency etc. (just in case it
matters).

3. Prototype it -- may be with a source level converter.

4. Play with enough examples (and not just toy examples) that
you yourself are convinced your design actually works well.

5. Refine your proposal based on #4. until you are happy.

6. Make a strong & objective technical case.

If your proposal is /really/ better, people will see it -- it
is clear from the number of discussion threads that a lot of
people are interested. But if it isn't good enough or you
don't do a good job of selling it, they will reject it.
Either way you will learn a tremendous amount and you will get
a much better sense for just what it takes to design language
features. Even with this much work I'd say the chances of
success are very low. Not because of anyone's likes or
dislikes but because it is a very hard problem to seamlessly
integrate a new feature in a mature language.

Obviously, speaking for myself, just as a fan of the language.

Ian

unread,
Dec 15, 2014, 10:56:51 PM12/15/14
to golan...@googlegroups.com, ian.gr...@gmail.com
I'm quite at a loss why you would think I was being condescending! Because I don't agree with the decisions and am not particularly convinced by the explanations? Yes, the technical and design reasons mean something. I don't have to agree with them; I merely have to accept them, which I do. But the philosophical ones? I've not seen any philosophical reasons substantively advanced! Well, nothing beyond "Go embraces simplicity"! I've previously noted that Go's notions of simplicity are, arguably, somewhat vague and occasionally arbitrary! That is *not* to denigrate the incredible work that is the Go language; it is to acknowledge that sometimes, for someone such as myself, complexity can have a variety of origins. One of the things that I really do like about Go is its structural simplicity; to ignore the double-edged sword of that simplicity would, however, be a disservice to the very concept of simplicity! But a discussion about the  philosophy of simplicity is a totally different set of conversations. 

When I read up on Go and generics, I discovered that the concerns and thoughts I had weren't addressed. Perhaps I didn't read the mailing list as fully as you would have liked me to, but I am only cursorily interested in the topic of generics and Go. I simply wasn't prepared or willing to read every last word anyone has written on the topic; such a demand would be unreasonable, wouldn't you agree? I read as much as I felt I needed to. I take it you disagree on where the rather arbitrary limit I set myself was placed? 

Y'know, with one exception, I'm going to stop writing about generics in Go on this mailing list. They're not, as we all seem to crossly agree, going to happen in Go. So there's absolutely nothing to be gained by further discussion except bruised feelings and a general anger that is creeping into the conversation. I'll simply (sorry... :-) ) enjoy the power of Go in my projects!

Ian

unread,
Dec 15, 2014, 11:05:42 PM12/15/14
to golan...@googlegroups.com, ian.gr...@gmail.com
My one exception...

We seem to be cross agreement about the prospects of generics in Go. 

We'll have to agree to disagree on the corporate-ness of the Go project; your impressions are from one side of the fence, mine are from the other!

As I've stated in a response to Andrew Garrand, I'm going to refrain from any further response to anything generics-related on this mailing list, so please forgive me if I have to be rude and not reply in the future.

Thanks for an entertaining and informative discussion. Sincerely, thanks.

egon

unread,
Dec 16, 2014, 3:40:09 AM12/16/14
to golan...@googlegroups.com, branimir....@gmail.com
The generics discussions seem to be going around in circles... anyways.. please help me to add more information to summarize the state of the discussion:


Simply to avoid going over the same points over again and again. Also getting a good overview of how much generics has actually been discussed for someone new is really difficult.

Any suggestions regarding structure, additional sections, examples, corrections etc. are very welcome... I will try to go over the suggestions once a day and incorporate them.

Obviously the whole document is highly biased towards my way of looking at things - so also correct if I'm not being objective.

+ Egon

On Sunday, 14 December 2014 16:47:39 UTC+2, egon wrote:
On Sunday, 14 December 2014 16:11:44 UTC+2, Peter Kleiweg wrote:
Op zondag 14 december 2014 13:02:42 UTC+1 schreef branimir....@gmail.com:
What you missing is that generics are parametric polymorphism, see http://en.wikipedia.org/wiki/Polymorphism_%28computer_science%29

It don't understand that, so I think it's a good thing Go doesn't have that. I'm a programmer, not a programming language theorist. 

Show me something practical that you can do with generics and not with Go.

1. Rx -> for reactive programming, 

2. LINQ -> i.e. concise data manipulation (map/reduce/fold etc.)

3. Generic Data Structures -> Sets/Trees/Matrices e.g. https://github.com/egonelbre/spexs2/blob/master/set/set.go

Currently it implements only for a concrete case of ints.

4. Generic Algorithms
e.g. https://gist.github.com/egonelbre/10578266, you have type conversion scattered around.

5. Type-Safe interface implementations -> e.g. https://github.com/egonelbre/event/blob/master/example/guestlist/counter.go#L14 see how the Apply takes a interface instead of a concrete type.

They have their benefits, mainly type-safety/speed, but I won't go over those...

My opinion regarding those with Generics:
1, 2 = I'm not sure whether trying to retrofit a different paradigm into Go is a such good idea. A DSL instead of Generics might be better, although it will be more work.

2 = Such data-processing is probably better suited for the DB side, because it has more information how to do the processing efficiently.

3 = There aren't that many data-structures that can be generic and fast/useful at the same time. A collection for different concrete use cases might be better than a generic data-structure. Also for the rare cases go generate with map/slices suffices.

4 = The same as before it might be more beneficial to have concrete use-case implementation than a generic package.

5 = Type conversion isn't that bad. Also, there might be a way to write a tool that does vetting/linting for such particular cases.

+ Egon

Sebastien Douche

unread,
Dec 16, 2014, 4:01:06 AM12/16/14
to egon, golang-nuts
On Tue, Dec 16, 2014 at 9:40 AM, egon <egon...@gmail.com> wrote:
> The generics discussions seem to be going around in circles... anyways..
> please help me to add more information to summarize the state of the
> discussion:
>
> https://docs.google.com/document/d/1vrAy9gMpMoS3uaVphB32uVXX4pi-HnNjkMEgyAHX4N4/edit?usp=sharing

Nice summary, thanks Egon.


--
Sebastien Douche <sdo...@gmail.com>
Twitter: @sdouche / G+: +sdouche

mat...@rocketcitystudios.com

unread,
Dec 16, 2014, 7:53:24 AM12/16/14
to golan...@googlegroups.com, branimir....@gmail.com
Did you look at how C# does generics? It doesn't require boxing and unboxing as Java does and also doesn't appear to require the linker to strip out all sorts of unused code like C++ templates.

egon

unread,
Dec 16, 2014, 8:48:12 AM12/16/14
to golan...@googlegroups.com, branimir....@gmail.com, mat...@rocketcitystudios.com
On Tuesday, 16 December 2014 14:53:24 UTC+2, mat...@rocketcitystudios.com wrote:
Did you look at how C# does generics? It doesn't require boxing and unboxing as Java does and also doesn't appear to require the linker to strip out all sorts of unused code like C++ templates.

No, I'm fairly ignorant of different ways of implementing generics. I'm simply trying to condense the information from threads down to a document... I don't remember nor have seen all the different generics discussions.

You can add other generic approaches as suggestions, some simple starting point is already good enough. Alternatively maybe you have a good link describing how it works?

+ Egon

Ian Lance Taylor

unread,
Dec 16, 2014, 9:21:28 AM12/16/14
to mat...@rocketcitystudios.com, golang-nuts, branimir....@gmail.com
On Tue, Dec 16, 2014 at 4:53 AM, <mat...@rocketcitystudios.com> wrote:
> Did you look at how C# does generics? It doesn't require boxing and unboxing
> as Java does and also doesn't appear to require the linker to strip out all
> sorts of unused code like C++ templates.

FYI, I mentioned C# back in
https://groups.google.com/d/msg/golang-nuts/smT_0BhHfBs/MWwGlB-n40kJ .

Ian

Francisco Dalla Rosa Soares

unread,
Dec 16, 2014, 10:59:44 AM12/16/14
to Ian Lance Taylor, mat...@rocketcitystudios.com, golang-nuts, branimir....@gmail.com
I was gonna mention that thread :)

 which by the way was running  really recently so for the people who said they couldn't find any threads, that one has its last email like 2 weeks ago.


--
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...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Gustavo Niemeyer

unread,
Dec 16, 2014, 2:42:59 PM12/16/14
to Sebastien Douche, egon, golang-nuts

Indeed, that's a good idea. It's curious that with such a popular topic we still don't have a blog post on the official blog which summarizes these conversations in a sensible way, and is kept up-to-date, so that we can simply refer to it instead of cooking an answer every time, or asking people to dig through the archives to find out answers.




--
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+unsubscribe@googlegroups.com.

snes...@gmail.com

unread,
Dec 19, 2014, 8:03:02 PM12/19/14
to golan...@googlegroups.com

I think the Sort function in the sort package is a good example of a generic function. Then why keep people asking for generics? What am I missing?

optimal speed 

branimir....@gmail.com

unread,
Dec 19, 2014, 8:10:04 PM12/19/14
to golan...@googlegroups.com, snes...@gmail.com
If one wants optimal speed why not just add macros and be done with it?

Matt Harden

unread,
Dec 19, 2014, 10:42:13 PM12/19/14
to branimir....@gmail.com, golan...@googlegroups.com, snes...@gmail.com
On Fri Dec 19 2014 at 7:10:14 PM <branimir....@gmail.com> wrote:
If one wants optimal speed why not just add macros and be done with it?

Because macros are even harder to get right than generics. C preprocessor macros definitely would NOT fly.

Matt Sherman

unread,
Dec 19, 2014, 11:51:47 PM12/19/14
to golan...@googlegroups.com, branimir....@gmail.com, snes...@gmail.com
gen offers a strongly-typed version of sort.Sort: https://clipperhouse.github.io/gen/slice/#sort 

akwillis

unread,
Dec 21, 2014, 1:35:15 AM12/21/14
to golan...@googlegroups.com, ian.gr...@gmail.com

Nick Craig-Wood

unread,
Dec 21, 2014, 7:49:36 AM12/21/14
to Matt Sherman, golan...@googlegroups.com, branimir....@gmail.com, snes...@gmail.com
On 20/12/14 04:51, Matt Sherman wrote:
> gen offers a strongly-typed version of sort.Sort:
> https://clipperhouse.github.io/gen/slice/#sort

Or for a slightly different approach

https://github.com/ncw/gotemplate

//go:generate gotemplate "github.com/ncw/gotemplate/sort"
"SortGt(string, func(a, b string) bool { return a > b })"

Which generates a fully inlined, non generic sort for a slice of a
custom type and comparison function. It does this by doing
substitutions in the Go sort routine abstract syntax tree. In this case
it sorts a slice of strings with the comparison function passed in.

This generates a lot of code but it will run at the highest possible
speed not having to look up any interfaces and having the comparison
function inlined.

YMMV

--
Nick Craig-Wood <ni...@craig-wood.com> -- http://www.craig-wood.com/nick

Jan Mercl

unread,
Dec 21, 2014, 8:06:02 AM12/21/14
to golan...@googlegroups.com
On Sun Dec 21 2014 at 13:49:22 Nick Craig-Wood <ni...@craig-wood.com> wrote:

> This generates a lot of code but it will run at the highest possible
> speed not having to look up any interfaces and having the comparison
> function inlined.

The "highest possible speed" is, unfortunately, a myth. It can easily be true for one program and it can be as easily false for another one. Especially with Go, where the things a thread/core is working on may get switched more often than in some other languages, the bigger size of the code due to the specialization can have enough negative effects on the CPU caches to make such code run actually slower from the point of view of the sum of all the different tasks the program needs to complete. Even benchmarking is not enough of a [dis]proof - the negative effects may be sensitive to a particular environment: other processes not under one's control, system load, memory size and speed, throughput of a NIC, CPU model/stepping, etc.

-j

akwillis

unread,
Dec 21, 2014, 12:44:17 PM12/21/14
to golan...@googlegroups.com, ian.gr...@gmail.com
Why would you have to change anything if the feature was added at a syntactic level and used as an extension. Most of the work could be done after lexing, and the lexer would just have a few extra stateFn functions generating a few extra tokens. Nothing would have to change at runtime. Instead its been forced into the realm of tools.

If parameterizing types are so bad then why does make take advantage of this feature for builtin types.

A few relics from bell labs and a harvard grad hailed as the golang guardian should have no problem implementing these features language-wide.

akwillis

unread,
Dec 21, 2014, 12:49:08 PM12/21/14
to golan...@googlegroups.com
Too bad this issue gets drowned by rhetorical cs everytime.

Dave Cheney

unread,
Dec 21, 2014, 7:27:11 PM12/21/14
to golan...@googlegroups.com
akwills, that insult was uncalled for. I'd ask that you refrain from posting on this topic in the future.

anl...@gmail.com

unread,
Dec 21, 2014, 9:05:28 PM12/21/14
to golan...@googlegroups.com

if it's so easyakwillis why haven't you done it already? come on show us your projects?

the truth is only people who are actively working in the area of go generics except me is egonelbre and the research done by the tom wilde.
we do it in our free time and as an open source project. so you can be more respectful. we're all academics or programmers so pay due respect.

the google team does a great job and its obvious they fix stuff before adding features managing the project with over 9000 bugs github migration, compiler to go migration etc.

Benjamin Measures

unread,
Dec 22, 2014, 4:49:56 AM12/22/14
to golan...@googlegroups.com
On Sunday, 14 December 2014 11:19:07 UTC, Peter Kleiweg wrote:
I think the Sort function in the sort package is a good example of a generic function. Then why keep people asking for generics? What am I missing?

I don't think you're missing much.

A perhaps valid concern with interface-based generics is the lack of compile-time checking: type assertions can fail at runtime[1]. However, I don't think this isn't anything that can't be resolved by static code analysis, perhaps by a tool separate to the compiler[2].

[1] In practice though, I suspect this is more of a theoretical concern.
[2] Similarly to how the C# compiler performs "specialization" for reference types, a static analysis tool could pretend the interface type is "the" specialization and verify subsequent type assertions as being impossible to fail.

Nick Craig-Wood

unread,
Dec 22, 2014, 6:27:10 AM12/22/14
to golan...@googlegroups.com
On 21/12/14 13:05, Jan Mercl wrote:
> On Sun Dec 21 2014 at 13:49:22 Nick Craig-Wood <ni...@craig-wood.com
You are right of course. I probably should have said for minimum
indirection or something like that!

Eric Smith

unread,
Dec 22, 2014, 8:04:12 AM12/22/14
to golan...@googlegroups.com
What you're missing is that people (like me) who use generics in other languages really miss them in languages that don't have them. This is particularly true when you combine them with functions like map, filter and of course sort.  

That said it's perfectly possible to write something very close to these functions in Go, especially if you stick to the types and methods you actually care about.  A lot of people get tempted to write an entire generics implementation, and then stop because they can't. If you limit yourself to the functions your program actually needs it's not as tedious as it sounds.

So if you were writing this a lot:

numbers := []int{1, 2, 3}
newSlice := make([]int, 0, 3)

for _, num := range numbers {
  newSlice = append(newSlice, num+2)
}
You can write this:

type mapper func(int) int

func collect(s []int, f mapper) []int {
  return []int{3, 4, 5}
}

And call it like this.

numbers := []int{1, 2, 3}

newSlice := collect(numbers, func(x int) int {
  return (x + 2)
})
Of course if you need one for float64 then you'll have to write another one. That's why some people are writing code generators for this. 

I wrote a blog on this just this week if you're interested:

DV

unread,
Dec 22, 2014, 9:08:06 AM12/22/14
to golan...@googlegroups.com
Go definitely has "generics", if by "generics" we mean parametric polymorphism. Channels, maps, arrays, slices - all have that behavior. So "generics" is part of the *language*, part of the runtime, but it's *not* for you to use on your own data types/functions. 

As to how they're useful, well, just like with slices, you can have compile-time type checking on the type of the objects that go into the container. In Go:

ints := make([]int, 10)
strings := make([]string, 10)

strings = append(strings, 5) // error

In C#:

var ints = new List<int>();
var strings = new List<string>();
strings.Add(5); //error

So far, Go and C# are "equal", but - key difference here - *any* C# class/interface can be made generic, not just built-in ones. So, I can have a useful library of containers, such as queues, sets, etc, in C#, and they can all be type safe at compile time:  You can't do that in Go.

class Set<TElem>{
   void Add(TElem e){.....}
}

Now, Set<string> is different from Set<Person>. Can't have that Set type in Go with the same characteristics. It'd have to be something like

type Set map[interface{}]bool
func(s *Set)Add(elem interface{}){....}

Which is why you don't see many reusable container pieces in Go - people pretty much write their own, if they want type safety, or, you lose safety and force interface wrapping/unwrapping. 

Not a big deal. So far. But I'd really like to have this in Go:

func map([]<TElem>items, func(e TElem) TElem{....}) []TElem{.......}

So I can do
intsPlusOne := map([]int{1,2,3}, func(e int) int { return e + 1; })
fmt.Println(intsPlusOne) /// 2,3,4

I really miss these generic transformations and functions that I love in C#/Clojure, especially map and reduce. 
Can we live without them? Yes. We can also live without all kinds of modern programming luxuries and just go back to assembly. Heck, even that is not technically "needed", in the hunter-gatherer sense, we could just flip switches to set the bits, I guess. 

For me, Go's type system is a bit weak. You can't write fully elegant code like in a dynamic language, and you can't be safe/flexible with a truly powerful type system like Haskell's. Heck, even C++'s type system allows for some nice reusable, safe, performant algorithms that you just can't do with Go. 

Interfaces don't cut it. 

Kostarev Ilya

unread,
Dec 22, 2014, 9:51:08 AM12/22/14
to DV, golan...@googlegroups.com
On 22 Dec 2014 at 17:08:10, DV (dimiter....@gmail.com) wrote:
For me, Go's type system is a bit weak. You can't write fully elegant code like in a dynamic language, and you can't be safe/flexible with a truly powerful type system like Haskell's. Heck, even C++'s type system allows for some nice reusable, safe, performant algorithms that you just can't do with Go. 

Interfaces don't cut it. 


In my personal opinion interfaces are not about generics or polymorphism at all. They are more about design by contract.

-- 

Kostarev Ilya

Axel Wagner

unread,
Dec 22, 2014, 11:05:57 AM12/22/14
to Eric Smith, golan...@googlegroups.com
Hi,

Eric Smith <payto...@gmail.com> writes:
> What you're missing is that people (like me) who use generics in other
> languages really miss them in languages that don't have them. This is
> particularly true when you combine them with functions like map, filter and
> of course sort.
>
> That said it's perfectly possible to write something very close to these
> functions in Go, especially if you stick to the types and methods you
> actually care about. A lot of people get tempted to write an entire
> generics implementation, and then stop because they can't. If you limit
> yourself to the functions your program actually needs it's not as tedious
> as it sounds.

That is only half of it, though. That is just function polymorphism,
which is usefull, but not the reason I personally would want generics. I
want generic *types*, so for example I want a Graph-Datatype which is
parameterized by a Node datatype, so e.g.

type Strategy interface {
...
}

type Node interface{}

type Graph interface {
Neighbors(n Node) []Node
Walk(s Strategy, start Node, f func(Node) bool)
}

but with performance (in here, if you save the neighbors of a node as a
[]*NodeStruct or something similar, you have to first copy every the
[]*NodeStruct to a []Node to fulfill the interface) and compile-time
checking (i.e. I want the compiler to guarantee, even if I don't care
about *what* a Node is, I want the guarantee, that Node is always the
same datatype).

go generate *can* take a part of the itch off here, but from what I
heard, some people where pretty unhappy about that and called it an
abuse of go generate. Oh well.

That being said, while I miss it and wish it was there, it does not
really bother me that it's not and I am quite happy, that the go team
did not include it (yet), as paradoxical as it sounds. The go team has a
history of creating well-thought-through APIs and features and if they
are not happy with the ideas so far, then I can certainly do without it
for a while longer.

Best,

Axel Wagner

Eduard Castany

unread,
Dec 22, 2014, 7:23:01 PM12/22/14
to golan...@googlegroups.com, adon...@google.com
type Number interface {
    Less(Number)
}
func (a int) Less(b int) bool {
    return a < b
}

func max(x, y Number) Number.Type {
   if x.Less(y.Value) { 
      return y.Value
   }
   return x.Value
}

Maybe this kind of definitions for all core types would help..?

El dilluns 15 de desembre de 2014 19:36:37 UTC+1, adon...@google.com va escriure:
On Sunday, 14 December 2014 06:19:07 UTC-5, Peter Kleiweg wrote:
I think the Sort function in the sort package is a good example of a generic function. Then why keep people asking for generics? What am I missing?

Whether or not one thinks that generics would be a good addition to Go (and the apparent consensus around here is that it would not), it is a fact of life that without generics, there are many little routines that one must implement over and over again, such as the max() function over numbers:

func max(x, y int) int {
   if y > x { 
      return y
   }
   return x
}

The definition above is good for int, but not for int64, or float32, or string.  I'm sure you've encountered other examples in your own work.

Generics is one way to let you express this algorithm once so that it works for all appropriate data types.
Macro expansion (such as Matt Sherman's gen tool) is another.

Interface (subtype) polymorphism doesn't help in this case, though it does in some others.

Axel Wagner

unread,
Dec 23, 2014, 12:26:08 PM12/23/14
to Eduard Castany, golan...@googlegroups.com, adon...@google.com
Hi,

Eduard Castany <eduard....@gmail.com> writes:

> type Number interface {
> Less(Number)
> }
> func (a int) Less(b int) bool {
> return a < b
> }
>
> func max(x, y Number) Number.Type {
> if x.Less(y.Value) {
> return y.Value
> }
> return x.Value
> }
>
> Maybe this kind of definitions for all core types would help..?

I don't know what you are trying to say, but int does not satisfy the
Number interface in your example (if you intended to do so), because
Less does not take a number. Also, at least this specific example is
fairly useless, as a < b is always faster to write and simpler than
a.Less(b).
Reply all
Reply to author
Forward
0 new messages