Interfaces: Difference between revisions

From Adam Colton
Jump to navigation Jump to search
Created page with "This is one of the areas with the largest difference from Go. == Built In and Operators == The built in types will have methods. The operators are defined as methods. This me..."
 
No edit summary
Line 42: Line 42:
     mut Insert(elem)
     mut Insert(elem)
   }
   }
== Substitution (Generics) ==
When defining a type, an interface signature can be provided for substitution
  type MyMap <
    Elem Stringer
  > map[string]Elem
 
  func (MyMap) New() *MyMap{
    return make(MyMap)
  }
 
  func (m *MyMap) Add(e Elem){
    m[e.String()]=e
  }
 
  func (m MyMap) Get(str string) (Elem, bool){
    return m[str]
  }
This could now be called as:
  mStr := MyMap<Elem:string>.New()
  mFoo := MyMap<Elem:Foo>.New()
  mStr = mFoo // error, types do not match
  baseM := MyMap<Elem:Stringer>.New()
  baseM = MyMap<Elem:Stringer>(mStr) // can't actually do this because you can't convert Add(e string) to Add(e Stringer)


[[Category:Gryphon]]
[[Category:Gryphon]]

Revision as of 19:04, 17 September 2019

This is one of the areas with the largest difference from Go.

Built In and Operators

The built in types will have methods. The operators are defined as methods. This means that you can define interfaces that will include the built in types.

See Operator Methods

Unions

This is a tagged union, like the Enum from Rust

 type IntN union [
   int8
   int16
   int32
   int64
 ]

What makes it an interface is that any method shared by all members is a method on the union.

Coercion

Not sure about this, but I would like returns on concretes to be coerced to more general types and arguments to be coerced to more specific types. So

 func Foo(s *MyStringer) IFooer

on an interface would match

 func Foo(s Stringer) Foo

on a concrete.

However, I think the syntax should be explicit to allow coercion, so maybe

 func Foo(s <*MyStringer>) <IFooer>

or

 func Foo(s ~*MyStringer) ~IFooer

One of the cases where I want this is for graph structures.

 type BinaryTreeNode <
   elem interface{
     <Less(elem) bool
   }
 >interface{
   Parent() Null<BinaryTreeNode>
   Left() Null<BinaryTreeNode>
   Right() Null<BinaryTreeNode>
   Value() elem
   mut Insert(elem)
 }

Substitution (Generics)

When defining a type, an interface signature can be provided for substitution

 type MyMap <
   Elem Stringer
 > map[string]Elem
 
 func (MyMap) New() *MyMap{
   return make(MyMap)
 }
 
 func (m *MyMap) Add(e Elem){
   m[e.String()]=e
 }
 
 func (m MyMap) Get(str string) (Elem, bool){
   return m[str]
 }

This could now be called as:

 mStr := MyMap<Elem:string>.New()
 mFoo := MyMap<Elem:Foo>.New()
 mStr = mFoo // error, types do not match
 baseM := MyMap<Elem:Stringer>.New()
 baseM = MyMap<Elem:Stringer>(mStr) // can't actually do this because you can't convert Add(e string) to Add(e Stringer)