
Gen - a generics library for Go - hebz0rl
http://clipperhouse.github.io/gen/
======
shurcooL
Here is someone trying to come up with a good solution for generics, rather
than simply complaining it don't exist. I am thankful for the effort.

~~~
stefantalpalaru
Good? It's an ugly hack with limited functionality (due to Go's design, not
the developers' skill and good will). A good solution would be forking the
reference compiler and doing a proper implementation.

~~~
KevinEldon
The library is Go. What you're suggesting seems to be extending Go so that it
becomes some other language derived from Go. Extending Go might make for a
cleaner and/or better generics solution but if you have to have customized
compiler to run the code then you're no longer running Go.

~~~
graetzer
It would be like Java to the Pizza Language:
[http://en.wikipedia.org/wiki/Pizza_%28programming_language%2...](http://en.wikipedia.org/wiki/Pizza_%28programming_language%29)

~~~
saryant
Historical tidbit: Pizza is the precursor to Java's own generics
implementation (introduced in Java 5), both were written by Martin Odersky who
then went on to create Scala.

~~~
elwell
Wow, 12 years old:
[http://pizzacompiler.sourceforge.net/](http://pizzacompiler.sourceforge.net/)

~~~
judk
\- Generics (aka Parametric polymorphism) \- Function pointers (aka First-
class functions) \- Class cases and pattern matching (aka Algebraic types)

13 years, and only it's three features has made it into Java

I wish Sun found a way to transfer the Java trademark to Odersky before dying.
Scala has so many nice features that companies prohibit because the language
isn't called "Java".

------
mwsherman
Author here, pleasantly surprised to see this on HN.

There is a substantial set of changes happening out on this branch:
[https://github.com/clipperhouse/gen/tree/projection](https://github.com/clipperhouse/gen/tree/projection).

… for this reason:
[https://github.com/clipperhouse/gen/issues/8](https://github.com/clipperhouse/gen/issues/8)

------
stiff
I really hope this will get solved in the language itself, I like Go quite a
bit, but there are quite ugly places, all related to generics I guess:

\- No min/max for integers (and Go doesn't have the ternary operator)

\- No IsMember for checking if an object is in a collection

\- Directly from the Gen page: _Go’s sort package requires the fulfillment of
three interface members, two of which are usually boilerplate. If you want to
sort by different criteria, you need to implement multiple ‘alias’ types._

Also, unrelated to generics, but no multidimensional arrays.

~~~
mseepgood
> no multidimensional arrays

That's not true, e.g. [4][4]byte is a multi-dimensional array. It's a
contiguous block of 16 bytes of memory.

~~~
stiff
The size has to be known at compile time, though. One can do a slice of
slices, but then it's not necessarily continuous in memory. So you are left
with allocating a one dimensional array of size x*y and doing index
calculations by hand like in the good old 70's or something.

~~~
a-nom-a-ly
(Can't reply to your post below)

> I edited that part of the comment out because it was not really related to
> anything, but I meant that all identifiers go into a single namespace, e.g
> if you have a package called bytes you can't call a variable bytes, if you
> have a struct type called bytes, you can't call the instance bytes

[http://play.golang.org/p/98vt2YLslY](http://play.golang.org/p/98vt2YLslY)

~~~
stiff
I got confused about the details, but this does hit me, the example I had in
mind is this:

    
    
      package main
    
      import (
      	"container/list"
    	"fmt"
      )
    
      func main() {
      	list := list.New()
      	list.PushBack(10)
      	list2 := list.New()
      	list2.PushBack(10)
      	fmt.Println(list)
      	fmt.Println(list2)
      }
    

This does not compile, list variable shadows the list package. I would much
prefer doing list::New() for package access like in C++, and being free to use
obvious variable names (all the time the most obvious variable name is also
the name of the package).

~~~
a-nom-a-ly
Adding `::` just to separate package namespace adds nothing useful IMO; just
more noise and one more needless concept.

If I decided to re-use the package name more than once it'd be `list1, list2`

I guess it's probably a programming culture thing, but I wouldn't use the word
`list` to begin with. I'd use `l1`, `l2` etc. in the case where the name isn't
important. It conveys no less information than `list` and short variable names
AFAIK are already idiomatic so it's not even unconventional... But with all
that said, `list2` wasn't a very good variable name to begin with. If you
needed more than one list, then they clearly served different purposes and in
that case it makes sense to name them as such: `apples`, `oranges`, `input`,
`output`.

~~~
stiff
It's an example, not a real program, I do like however to call my variables
"file", "path", "buffer" instad of having "f", "p" and "b" or "buf",
especially when there is a lot going on in the algorithm. I don't think there
is a lot of baggage in having a separate namespace for packages and being able
to say:

file = File:open("file")

------
c-a
Why call it a library when it's a code generator/compiler?

~~~
Refefer
I would argue this is a new language which just happens to compile to go.

~~~
c-a
Actually it's a code generator with a library of functions it can generate.
This is how the "generics" are implemented:
[https://github.com/clipperhouse/gen/blob/master/templates.go](https://github.com/clipperhouse/gen/blob/master/templates.go)

------
LukeShu
This looks similar to an older generics system for Go, `got` (GO Templates).
Got was pretty cool, but Go 1.0 broke it due to the parser getting stricter.

Edit: found it:
[https://github.com/droundy/gotgo](https://github.com/droundy/gotgo)

------
mseepgood
These higher-order functions are a very inefficient way to write loops in Go.
When you chain them you will end up with multiple sequential iterations
instead of only one. Sort should not allocate and return a new slice, it's
better to sort in-place, etc.

~~~
rybosome
That's functional programming for you. It's definitely less efficient, but
there are other major advantages. For one thing, given the propagation of
immutable data, things can be parallelized effortlessly - look at 'pmap' in
Clojure for example. Once you're familiar with the style, it's significantly
more concise and readable.

That being said, a systems programming language may not be the right place for
FP concepts.

~~~
coolsunglasses
>That's functional programming for you.

Uhm, what? No it's not.

Haskell has stream fusion, thereby generating assembler that looks a lot like
the optimal imperative version.

~~~
burntsushi
This is kind of misleading. Stream fusion isn't baked into Haskell; you need
to use a library. [1,2]

    
    
        [1] - https://ghc.haskell.org/trac/ghc/ticket/915
        [2] - http://hackage.haskell.org/package/stream-fusion

~~~
coolsunglasses
[http://hackage.haskell.org/package/text-0.1/docs/Data-
Text-F...](http://hackage.haskell.org/package/text-0.1/docs/Data-Text-
Fusion.html)

[http://hackage.haskell.org/package/vector-0.9.1/docs/Data-
Ve...](http://hackage.haskell.org/package/vector-0.9.1/docs/Data-Vector-
Fusion-Stream.html)

Except it's bloody everywhere in the libraries you use and you can design your
own libraries around it.

A language powerful enough that things like this can be done in libraries
instead of in the compiler is a good thing.

------
Xelom
Thanks for your effort. This is not about the library. Your site's mobile
version is kinda broken. The left menu thingy always remain in the site and
you can't read the main context. This happened to me on my Android Firefox
Browser.

~~~
StavrosK
Same here, I couldn't read it at all.

