Skip to content

proposal: Go 2: deriving code ala Haskell #54799

Closed as not planned
Closed as not planned
@fkuehnel

Description

@fkuehnel

It's already discussed in 19412 that sum (discriminated union) types are nothing for GO 1.xx. However, unrelated to this is the fact that I find myself frequently writing boilerplate code for the interface type replacement of a discriminated union:

type Node interface {
   Show() string
   Read(string) bool
}

// here are some Node implementations
type IntNode struct {
   value int64
}

func (n IntNode) Show() string {
   fmt.Sprintf("%d", n.value)
}

func (n IntNode) Read(s string) bool {
   if val, err := strconv.ParseInt(s, 10, 64); err != nil {
      return false
   } else {
     n.value = val
     return true
  }
}

// The boilerplate code becomes worse with const types
type MathConstant uint16
const (
   Pi MathConstant = iota
   Euler
   Catalan
)

type MathNode struct {
  value MathConstant
}

func (n MathNode) Show() string {
  switch n.value {
  case Pi:
     return "Pi"
  case Euler:
     return "Euler"
  case Catalan:
    return "Catalan"
  }

  return "Must never happen"
}

func (n MathNode) Read(s string) bool {
  switch s {
  case "Pi":
    n.value = Pi
  ...
  default:
    return false
  }
  return true
}

And this is just a small example of how it could go.

Now to the Haskell deriving inspired proposal:

The idea here is like in Haskell to have a well-defined way to generate common implementations, i.e. Show, Read for algebraic types. This makes code reviews much easier and helps avoid making errors. Obviously, writing and reading less code is beneficial. Here, one could eliminate most of the boilerplate code with the 'deriving' syntax,
but one could still choose to implement custom versions if needed. This means it would be backward compatible to GO 1.xx versions:

type Node interface deriving (Show, Read)
// This will autogenerate functions with the following signature
// Show() string
// Read(string) bool

type IntNode struct {
  value int64
} deriving (Show, Read)

type MathConstant uint16
const (
   Pi MathConstant = iota
   Euler
   Catalan
)

type MathNode struct {
  value MathConstant
} deriving (Show, Read)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions