News for hackers. Stuff that matters.
Re:Background: how we got the generics we have (2020) by josefx on Thursday April 01, 2021 @09:02AM (#26659927)
What operations can you perform on an L<Integer>? Does it work based on duck typing instead of explicitly declaring what base interface (Collection<Integer>) it requires?
Re:Background: how we got the generics we have (2020) by thinkharderdev on Thursday April 01, 2021 @09:43AM (#26660425)
Generally you are using a typeclass to specify behavior (which I guess is a kind of duck-typing).

For example, there is a typeclass Foldable[F[_]] which provides the ability to "fold" (i.e. recurse over) some type F[_] which takes a type parameter. Then you have typeclass definitions for Foldable[Set], Foldable[List], Foldable[Tree], Foldable[Option], etc.

Then if you have an operation and you want it to work on any collection that can be folded, then you can just define it in terms of a generic type that has a Foldable typeclass. For instance to generically sum a collection of ints, you might do

def sum[F[_] : Foldable](ints: F[Int]): Int = ...

Now you can call sum(List(1,2,3)), sum(Set(1,2,3)), sum(Option(1)), etc...

Re:Background: how we got the generics we have (2020) by Joker_vD on Thursday April 01, 2021 @01:20PM (#26663462)
Typeclass instance = Adaptor/Decorator in OOP terms, automatically derived (and wrapped in) for you by the compiler.

You want to fold over Options? Make a FoldableOption class implementing Foldable<Option> and pass "new FoldableOption(myOptionValue)" to whatever places you need. Haskell does pretty much the same (unless they moved away from dictionary passing).

Re:Background: how we got the generics we have (2020) by dboreham on Thursday April 01, 2021 @09:20AM (#26660140)
It's a similar idea to inheriting from a base collection class (iterable, etc). Not quite the same though. It is a kind of duck typing I suppose. You get to specify the nature of a class of types. e.g. it can be ordered, behaves like a number, etc.