Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generalization based on common fields #9

Open
ufukty opened this issue Jul 4, 2024 · 0 comments
Open

Generalization based on common fields #9

ufukty opened this issue Jul 4, 2024 · 0 comments

Comments

@ufukty
Copy link
Owner

ufukty commented Jul 4, 2024

Preface

A data file can contain structures in similar schemas in many places. Making their commonalities explicit may be useful as they enable writing functions that can work with many types at once.

Go provides a way to generalize multiple types based on their common methods via interfaces. This is not helpful in the context of data mapping. Although can be leveraged from to enable generalization that is based on common fields.

Example for generalization based on common fields from stdlib

An example usage can be seen in go/types package which defines accessors (getter/setter) on fields of a type struct object which is embedded by struct Func, struct Const, struct Var etc.

// provides generalization
type Object interface {
  // ...
  setType(...)
  setOrder(...)
  setColor(...)
  setParent(...)
  sameId(...)
  scopePos(...)
  setScopePos(...)
}

// provides the common fields for many "derived" type
type object struct {
  parent    *Scope
  pos       token.Pos
  pkg       *Package
  name      string
  typ       Type
  order_    uint32
  color_    color
  scopePos_ token.Pos
}

// accessors make every type embeds "object" to comply "Object" by their common fields rather than methods
func (obj *object) setParent(...)   { ... }
func (obj *object) setType(...)     { ... }
func (obj *object) setOrder(...)    { ... }
func (obj *object) setColor(...)    { ... }
func (obj *object) setScopePos(...) { ... }

// declares types derived from "object" conforms "Object"
// each contain "object" as embedded type, in addition to custom fields
type (
  PkgName struct {
    object
    // ...
    // ...
  }

  Const struct {
    object
    // ...
  }

  TypeName struct {
    object
  }

  Var struct {
    object
    // ...
    // ...
    // ...
    // ...
  }

  Func struct {
    object
    // ...
    // ...
  }

  Label struct {
    object
    // ...
  }

  Builtin struct {
    object
    // ...
  }

  Nil struct {
    object
  }
)

// usecases of generalization;
// as in storing, accepting or returning generalized "Object" values

type declInfo struct {
  deps map[Object]bool
}

func (check *Checker) objDecl(obj Object, def *TypeName) {
  ...

  if obj.color() == white && obj.Type() != nil {
    obj.setColor(black)
    return
  }

  switch obj.color() {
  case white:
    assert(obj.Type() == nil)

  ...

  case grey:
    ...
    switch obj := obj.(type) {
    case *Const:
      if !check.validCycle(obj) || obj.typ == nil {
        obj.typ = Typ[Invalid]
      }

    case *Var:
      if !check.validCycle(obj) || obj.typ == nil {
        obj.typ = Typ[Invalid]
      }

    case *TypeName:
      if !check.validCycle(obj) {
        ...
        obj.typ = Typ[Invalid]
      }

    case *Func:
      if !check.validCycle(obj) {
        ...
      }

    default:
      unreachable()
    }
    assert(obj.Type() != nil)
    return
  }

  d := check.objMap[obj]
  if d == nil {
    check.dump("%v: %s should have been declared", obj.Pos(), obj)
    ...
  }

  ...
}

Purpose of issue

To open discussions about the use cases of a feature that is related to allowing generalization based on common fields.

Example usages

  • Iterating over similar items stored in a list
  • Passing items in similar schemas to functions that won't need to work on the excluded fields.

Candidate method to allow generalization

  • Allowing user to specify target dicts and keys, that will get accessors implemented on by Gonfique. So, users can define interface's to generalize types implementing same accessors, to enable themselves accepting those types at once for functions or storing them in a sequence.

Sources

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant