[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)