<commit_before>Generics in Go
==============

a wishlist
----------

This file contains experiences and desiderata for a Go implementation of generics,
i.e. polymorphic types and functions.

It is a feature present in many other languages with varying names. A few examples:
* C++ [templates](https://www.geeksforgeeks.org/templates-cpp)
* Java [generics](https://en.wikipedia.org/wiki/Generics_in_Java)
* Haskell [generics](https://wiki.haskell.org/Generics)

The author has experience using generics in the three languages listed above,
which will also be used for comparison and reference in the rest of this document.

In addition, the author personally added generics to three programming languages:
* Go: the unofficial interpreter [gomacro](https://github.com/cosmos72/gomacro)
  contains a Go implementation of generics, modeled after C++ templates.
* Common Lisp: the library [cl-parametric-types](https://github.com/cosmos72/cl-parametric-types)
  contains a Common Lisp implementation of generics, again modeled after C++ templates.
* the [lfyre](https://sourceforge.net/projects/lfyre) programming language,
  created by the author, used to contain an implementation of generics.
  It now has a different maintainer.

# Goals

The reasons to implement generics in Go can be many, and sometimes contradicting.
The author's personal list of reasons, which can also be interpreted as goals
that Go generics are expected to achieve, are:

* reusable, flexible algorithms and types. Examples:

  a single `sort` function that can sort any slice of any ordered type.

  a single `cache` type that can cache key/value pairs of any type,
  provided that keys can be compared.

* type-safety:

  generic functions and types should be instantiable on arbitrary,
  concrete types - for example `sort#[int]` would only accept `[]int` slices
  and `cache#[uint64, []byte]` would only accept `uint64` keys and `[]byte` values.
  In particular, generic functions and types should not need to use `interface{}`,
  either internally or in they exported API, and should not need type assertions at runtime.

* high runtime speed, low runtime overhead:

  generic functions and types should be reified in order to maximize code execution speed
  and have low or zero data representation overhead in memory.

  Reified means that `sort#[int]` and `sort#[uint]` will be two different and unrelated functions,
  one only dealing with `int` slices and the other only dealing with `uint` slices,
  and that `cache#[uint64, []byte]` and `cache#[uint32, []byte]` will be two different
  and unrelated types, with (possibly) different layout in memory.

  While reified generics also have disadvantages - see for example
  (https://gbracha.blogspot.com/2018/10/reified-generics-search-for-cure.html) -
  the author has extensive experience with Java, which does **not** reify generics,
  and he is convinced that reified generics are a better fit for Go
  (the reasons can be explained if needed).
<commit_msg>update doc/generics-wishlist.md<commit_after>Generics in Go
==============

a wishlist
----------

This file contains experiences and desiderata for a Go implementation of generics,
i.e. polymorphic types and functions.

It is a feature present in many other languages with varying names. A few examples:
* C++ [templates](https://www.geeksforgeeks.org/templates-cpp)
* Java [generics](https://en.wikipedia.org/wiki/Generics_in_Java)
* Haskell [generics](https://wiki.haskell.org/Generics)

The author has experience using generics in the three languages listed above,
which will also be used for comparison and reference in the rest of this document.

In addition, the author personally added generics to three programming languages:
* Go: the unofficial interpreter [gomacro](https://github.com/cosmos72/gomacro)
  contains a Go implementation of generics, modeled after C++ templates.
* Common Lisp: the library [cl-parametric-types](https://github.com/cosmos72/cl-parametric-types)
  contains a Common Lisp implementation of generics, again modeled after C++ templates.
* the [lfyre](https://sourceforge.net/projects/lfyre) programming language,
  created by the author, used to contain an implementation of generics.
  It now has a different maintainer.

# Goals

The reasons to implement generics in Go can be many, and sometimes contradicting.
The author's personal list of reasons, which can also be interpreted as goals
that Go generics are expected to achieve, are:

* reusable, flexible algorithms and types. Examples:

  a single `sort` function that can sort any slice of any ordered type.

  a single `cache` type that can cache key/value pairs of any type,
  provided that keys can be compared.

* type-safety:

  generic functions and types should be instantiable on arbitrary,
  concrete types - for example `sort#[int]` would only accept `[]int` slices
  and `cache#[uint64, []byte]` would only accept `uint64` keys and `[]byte` values.
  In particular, generic functions and types should not need to use `interface{}`,
  either internally or in they exported API, and should not need type assertions at runtime.

* high runtime speed, low runtime overhead:

  generic functions and types should be reified in order to maximize code execution speed
  and have low or zero data representation overhead in memory.

  Reified means that `sort#[int]` and `sort#[uint]` will be two different and unrelated functions,
  one only dealing with `int` slices and the other only dealing with `uint` slices,
  and that `cache#[uint64, []byte]` and `cache#[uint32, []byte]` will be two different
  and unrelated types, with (possibly) different layout in memory.

  While reified generics also have disadvantages (see for example
  https://gbracha.blogspot.com/2018/10/reified-generics-search-for-cure.html)
  the author has extensive experience with both reified generics (C++, Haskell)
  and non reified generics (Java), and he is convinced that reified generics
  are a better fit for Go - the reasons can be explained if needed.

{'fraction_non_alphanumeric': 0.08221448698823139, 'fraction_numerical': 0.005967180507210343, 'mean_word_length': 4.5408631772268135, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 14, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6925529', 'n_tokens_mistral': 1661, 'n_tokens_neox': 1571, 'n_words': 771}