[HN Gopher] When to use generics ___________________________________________________________________ When to use generics Author : mfrw Score : 56 points Date : 2022-04-12 20:56 UTC (2 hours ago) (HTM) web link (go.dev) (TXT) w3m dump (go.dev) | Groxx wrote: | > _For type parameters, prefer functions to methods | | >The Tree example illustrates another general guideline: when you | need something like a comparison function, prefer a function to a | method. | | >We could have defined the Tree type such that the element type | is required to have a Compare or Less method. This would be done | by writing a constraint that requires the method, meaning that | any type argument used to instantiate the Tree type would need to | have that method._ | | Yes yes a thousand times yes. | | If you have an interface with a single method, or something with | a single varying piece of behavior, please _strongly_ consider | accepting a function instead. Going from method to function is | trivial - pass `thing.method`. Going the other way _is impossible | at runtime_ , it requires package-level code at compile-time. | | This is true for many/most? languages, but it feels like a lot of | Go libraries have forgotten it, and they're sometimes a huge | unnecessary pain to deal with for that reason. | cube2222 wrote: | Agreed. I almost never use sort.Sort in practice, sort.Slice is | just so much more usable. | | Also, based on the recent blog post[0] a method-based approach | will be a tiny bit slower than the function-based approach. Not | that it matters for most code though. | | [0]: https://planetscale.com/blog/generics-can-make-your-go- | code-... | enw wrote: | Last sentence covers it well: | | > _Another way to say this is that you should avoid type | parameters until you notice that you are about the write the | exact same code multiple times._ | | (The above will make design pattern astronauts shudder) | orblivion wrote: | All of the "when it's useful" examples are either of `any` or | `comparable`. There are no examples restricted to an interface | (other than `comparable` if that counts). Only the "when it's not | useful" examples include a generic restricted to an interface, | `[T io.Reader]`. | | Since the language allows for restricting to an interface, and | this is the language's official blog, surely there must be a | recommended use case for it. | MichaelMoser123 wrote: | I used generics as an exercise: for a circular buffer [1] is that | ok? The exercise project is a grep that greps through the content | of archives [2] i needed a circular buffer to keep the last n | lines for displaying the context of a match. | | [1] | https://github.com/MoserMichael/rzgrep/blob/master/src/cbuf/... | | [2] https://github.com/MoserMichael/rzgrep | beastman82 wrote: | I'm curious how parametric polymorphism got the name generics? | wk_end wrote: | This lead me down an interesting path. | | So, first of all, my (possibly incorrect) understanding is that | pure parametric polymorphism doesn't allow you to specify | constraints - in Haskell terms, `a -> IO a` is a case of | parametric polymorphism, but `Showable a => a -> IO a` or | whatever isn't (entirely) - you've got ad hoc polymorphism in | there too. So just calling it "parametric polymorphism" would | be inaccurate. | | My assumption was that they took the terminology from Java, but | as I looked more into it I started to doubt this. Java called | them Generics because the implementation in Java 5 was | descended from a research project called "Generic Java". The | Generic Java paper [0] uses the term - and the term | "Genericity" - freely but doesn't give an original source for | it at a glance. They do note that "Modula 3, Ada 95, Eiffel, | and Sather" all support them though. | | Wikipedia has an article on "Generic programming" [1] which | notes that "[they] are known as generics in Ada, C#, Delphi, | Eiffel, F#, Java, Nim, Python, Go, Rust, Swift, TypeScript and | Visual Basic .NET", so this isn't exclusive to Go. It cites a | paper from 1989 called "Generic programming" as an origin of | the term, although it also claims that "Ada has had generics | since it was first designed in 1977-1980", and indeed "generic" | is a keyword in Ada 83 [2]. The "Generic programming" paper is | written about Ada [3]; my hunch is that Ada's where the term | comes from. I'd be curious to see if anyone can find an earlier | use of that term. | | [0] https://homepages.inf.ed.ac.uk/wadler/gj/Documents/gj- | oopsla... | | [1] https://en.wikipedia.org/wiki/Generic_programming | | [2] https://en.wikibooks.org/wiki/Ada_Programming/Ada_83 | | [3] http://stepanovpapers.com/genprog.pdf | cmrdporcupine wrote: | That the term came from Ada (or the research that went into | it) is my understanding, too. | | It _may_ be associated specifically with Alexander Stepanov | [original C++ STL author, but also active in early Ada], or | work he did in the early 80s (which contributed to Ada, I | believe, and then into C++): http://stepanovpapers.com/ | | _" David R. Musser, and Alexander A. Stepanov: Tecton: A | Language for Manipulating Generic Objects. In Program | Specification, Proceedings of a Workshop, Aarhus, Denmark, | August 1981"_ | | and | | https://www.oreilly.com/library/view/from-mathematics- | to/978... | | _" Generic Programming. The language Tecton, which first | used generic programming concepts, is described in "Tecton: A | Language for Manipulating Generic Objects" by Kapur, Musser, | and Stepanov (1981). The Ada library is described in the | paper "Generic Programming" by Musser and Stepanov (1988), | and C++ STL in "The Standard Template Library" by Stepanov | and Lee (1994). All of these materials are available on | www.stepanovpapers.com."_ | | Parametric polymorphism though was present in Standard ML and | other functional lanagages from the mid-70s on. But not | called generics, and not "generic programming" per se. So, | hm. | tialaramex wrote: | I think probably you should think of genericity as a _style_ | and like say, OOP this style can be supported by language | features but you can insist on writing BBC Basic in an OO | style, the language just gets in your way all the time. | | So you could insist on doing generic programming in Go 1.17 | say, but it feels very awkward and is slower and anybody | reviewing your code is probably going to say "This is the | wrong way to use Go" whereas with 1.18 there are more places | where this is a reasonable solution. | | If you hate OOP, you can write a Java program that's just one | main function, it will _really suck_ but it isn 't | impossible. If you hate Functional Programming you could | write SML that's all imperatives and again that's going to be | possible but the language is fighting you. | | Parametric Polymorphism isn't a style it's a feature, like Ad | Hoc Polymorphism (e.g. C++ function overloading) or Subtype | Polymorphism (C++ inheritance) which you could choose to use | in your programs or not, but doesn't go away just because you | aren't using it. | [deleted] | bjackman wrote: | Sibling comment has some evidence to the contrary but I've | always thought of it as a Java marketing term. | | It lets you write generic classes e.g. "I can write a generic | container class that automatically works for any contained | type". It's imprecise (you can describe lots of programming | language features as enabling "genericity") but I think it | makes sense as a descriptive term. | whateveracct wrote: | It's extra confusing because Haskell has capital-G Generics | which are not at all this :) | candiddevmike wrote: | So far, I'm planning on using them to replace interface{}. I | wrote a stupid simple test assert library that abuses | []interface{} for inputs/outputs with the assumption that a panic | is fine because it'll make the test fail. | kccqzy wrote: | TL;DR use it only when you need parametric polymorphism | | > If a function has parameters with those types, and the function | code doesn't make any particular assumptions about the element | types, then it may be useful to use a type parameter. | | In some languages when a type variable is universally quantified | the language simply doesn't allow you to make assumptions about | these types. This is of course the right thing to do. | | > Another case where type parameters can be useful is when | different types need to implement some common method, and the | implementations for the different types all look the same. | | Looking the same is a clear indication that your code isn't | making assumptions about the type. So this is just a restatement | of the above point. | | Overall this is very good advice. At the risk of sounding | elitist, I think this is something everyone should already know, | regardless of whether they use Go or not. Of course the article | is aimed at beginners, so there's nothing wrong with that, but at | HN we can just use the proper terminology such as parametric | polymorphism or a universally quantified type variable. | uluyol wrote: | I think it's also aimed at the C++ crowd where generics = | static dispatch and interfaces = dynamic dispatch and people | try to eek out the extra performance. ___________________________________________________________________ (page generated 2022-04-12 23:00 UTC)