Go 2 and generics

I had found thheese 3 lines in Go 1.5.1 $GOROOT/src/time/time.go lines 916 to 918.

   916	// TODO(rsc): Remove GobEncoder, GobDecoder, MarshalJSON, UnmarshalJSON in Go 2.
   917	// The same semantics will be provided by the generic MarshalBinary, MarshalText,
   918	// UnmarshalBinary, UnmarshalText.

I have only have this comment about that:
Either an internal joke or - very interesting. Definitely not now, maybe a couple of years from now on.

4 Likes

This could also be implemented with interfaces though.

Also as per my colleague:

a) Go already has generics, just not user defined ones.
b) the marshalers already use reflection so they can continue to do that to provide this functionality.

So this comment is no evidence that user defined generics are coming to go.

Generic in this context just means “a function that is not specifically tailored to a single encoding” … i.e. - it was a bad idea to put the word “JSON” in MarshalJSON. If it had been MarshalText, then you could easily write a function that takes an interface to work with values that can be marshaled… and not care how they’re being marshaled. But because it’s encoding specific, you have to write dumb wrappers right now to do so.

It’s english, we have a lot of definitions for the same words. Sometimes generic just means generic.

7 Likes

I’d certainly appreciate the arrival of Generics into Go. I have a very cringeworthy time whenever I’m forced to use reflection and/or interface{} to solve a problem that has had a zero cost abstraction based solution for ages.

Having said that, even a system defined interface that groups all the basic types and then just the integer types, just the float types and finally all numeric types together in an interface each should go a long way.

This way work on numerical libraries would look a lot cleaner even without full fledged interfaces.

I’d seek advice from your physician before holding your breath for that long.

Use code generation instead.

I find your lack of faith disturbing. It isn’t very long before Go would have the speed of hand written assembly and instead of the current syntax we’d use brainwaves and think about exactly what we’re trying to build. We’d still need to use gofmt to normalize thoughts.

And in a parallel universe, that’s exactly what the alter-me has decided to do.

1 Like

I think the type system of go is hard to implement generics…

I think you are wrong. The compiler can use delayed code generation.

An exampe is the Free Pascal compiler (fpc):

  1. The compiler parses a generic, but instead of generating code it stores all tokens in a token buffer inside the PPU file.
  2. The compiler parses a specialization; for this it loads the
    token buffer from the PPU file and parses that again. It replaces the
    generic parameters (in most examples “T”) by the particular given type
    (e.g. LongInt, TObject).
    The code basically appears as if the same class had been written as the generic but with T replaced by the given type.
    http://wiki.freepascal.org/Generics#Technical_details

That doesn’t look too complicated.

1 Like

It’s got nothing to do with coming up with an appropriate syntax, or figuring out how to write a compiler. Generics in Go are not possible without inheritance and subtype polymorphism, neither of which Go supports, so you’d be talking about adding three things to the language, not just generics.

Inheritance is not necessary. You can define generics over interfaces.

However there are technical issues, i.e. achieving good performance and optimal memory usage that are problematic. SOGD

1 Like

I don’t believe this is correct. If I want to write a generic function called Add which adds two numbers, how do I prevent the following

x := Add(true, false)

Without some way of expressing that basic types like int8 or float64 inherent from some abstract number type, where other type, like bool and map, do not.

A really stupid example, with package level specialization and interface checking:

package math

type Numeric interface {
	Add(b Numeric) Numeric
}

func Add(a, b Numeric) Numeric {
	return a.Add(b)
}

// usage
package main

import f64math "math" with { Numeric = Float64 }

type Float64 float64
func (a Float64) Add(b Float64) Float64 {
	return a + b
}

func main() {
	var a, b, c Float64

	a = 125.241
	b = 3251.321
	c = f64math.Add(a, b)

	fmt.Println(c)
}

It’s invariant and uses interfaces as it’s template contract. There are numerous ways of implementing generics, each with their own pros/cons. This approach, of course, is not an exception see “Package Level” templates for its summary. It solves very well “Data Structures” and “Generic Algorithms” problems; however not the “Functional Code” and “Language Extension” part.

You’ve moved code generation into the import mechanism of the compiler. Gross.

You are missing the point. I was simply demonstrating that inheritance is not required. There are plenty of variations possible for syntax.

You could just as well have:

package math

type Numeric generic { Add(b Numeric) Numeric }
func Add(a, b Numeric) Numeric {
	return a.Add(b)
}

package main

import "math"

type Float64 float64
func (a Float64) Add(b Float64) Float64 { return a + b }

func main() {
	var a, b, c Float64

	a = 125.241
	b = 3251.321
	c = math.Add(a, b)

	fmt.Println(c)
}

Or:

package main

template Math<Numeric> {
	// implicitly derive contract/interface
	func Add(a, b Numeric) Numeric {
		return a + b
	}
}

type Float64 float64

func main() {
	var a, b, c Float64

	a = 125.241
	b = 3251.321
	c = Math<Float64>.Add(a, b)

	fmt.Println(c)
}

I used the previous example, because it requires the least amount of change to the existing language syntax and can start working with packages, such as sort, without any modification to sort. I.e. minimal generics implementation.

2 Likes

And, although the syntax may look like code-generation, this doesn’t mean it will do it internally. It could use boxing, out-of-bounds boxing, template specialization or more likely, something completely new.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.