On Thu, Oct 18, 2018 at 10:13 AM robert engels <reng...@ix.netcom.com> wrote:
>
> I guess you could do it that way, but still, then you need to document every 
> private field as if it were public, leading to very brittle code… imagine the 
> compiler error - struct X does not have field xyz… ? Then I need to go to the 
> source of Y and look at how xyz is documented (hopefully), and then hope the 
> implementation never changes… That’s a lot of hoping.

Maybe we're thinking this all wrong. So far we've been talking about
template functions, but not template types.


Let's write the linked list type contract:

package linkedlist

type LinkedList like struct {
  head *like Node
}

type Node like struct {
  next *like Node
}

func (l *LinkedList) Add(in *Node) {
  ...
}


Now let's use the linked list:

type TheLinkedList linkedlist.LinkedList {
  head *TheNode
}

type TheNode linkedlist.Node {
  next *TheNode
  more stuff
}

var myLinkedList TheLinkedList


myLinkedList.Add() works now.

I do not like the "type name templatename" syntax, something else is
needed there.

>
> > On Oct 18, 2018, at 11:08 AM, Burak Serdar <bser...@ieee.org> wrote:
> >
> > On Thu, Oct 18, 2018 at 10:03 AM robert engels <reng...@ix.netcom.com> 
> > wrote:
> >>
> >> Right, that is a big limitation - that means that internal details must be 
> >> made public, or everything in the same package - which is even worse, 
> >> because then you have other private details accessible. Breaks 
> >> encapsulation.
> >
> > That is not correct. This does not require that everything should be
> > in the same package. It requires that the private fields must be
> > accessible where the template is instantiated.
> >
> > If the Add function is declared in package A and used in package B,
> > then Add() would have access to all private fields of package B,
> > because that's where it is instantiated.
> >
> >>
> >> Field access just seems unworkable to me. To much to understand (and 
> >> document) rather than just using interfaces which already need to be 
> >> understood and documented.
> >>
> >> Only allow interfaces as types and I’m fine. The primitives just need 
> >> pseudo interfaces defined for their operations and all is good.
> >>
> >> granted, you would never write a LinkedList like that with embedded 
> >> pointers in the elements - not if you want safe code - but it was just 
> >> used an example of the abuse that will occur.
> >>
> >>
> >> On Oct 18, 2018, at 10:56 AM, Burak Serdar <bser...@ieee.org> wrote:
> >>
> >> On Thu, Oct 18, 2018 at 9:37 AM robert engels <reng...@ix.netcom.com> 
> >> wrote:
> >>
> >>
> >> That is true, it would be done that way, so not an issue. Sorry for the 
> >> tangent.
> >>
> >> I still don’t understand when ‘like T’ when T is a concrete type. It seems 
> >> daunting, unless you use the containment as outlined previously - but a X 
> >> containing T, is far different than X being a T, and I am not sure the 
> >> semantics of the function will hold.
> >>
> >> Imagine a
> >>
> >> type Node struct {
> >>  link *Node
> >> }
> >>
> >> then you have a linked list
> >>
> >> type LinkedList struct {
> >>   head *node
> >> }
> >>
> >> with
> >>
> >> func (LinkedList *) Add(n like Node){ blah..}
> >>
> >> passing a
> >>
> >> struct MyNode {
> >>  Node
> >>  value int
> >> }
> >>
> >> will not work, because the reference passed to Add() points to inner 
> >> instance.
> >>
> >>
> >> In this example, neither LinkedList nor Node are templates, but Add is
> >> a template. Let's try to write the Add function.
> >>
> >> func (l *LinkedList) Add(n type *T like(Node)) {
> >> if l.head==nil {
> >>   l.head=n
> >>   n.link=nil
> >>   return
> >> }
> >> tail:=l.head
> >> for tail.link!=nil {
> >>    tail=tail.link
> >> }
> >> n.link=nil
> >> tail.link=n
> >> }
> >>
> >> This should compile for:
> >>
> >> l.Add(&MyNode{value:1})
> >>
> >> if private values of MyNode is accessible where it is used. That means
> >> the following won't work:
> >>
> >> package A
> >>
> >> struct MyNode {private fields}
> >>
> >> package B
> >>
> >> l.Add(&A.MyNode{})
> >>
> >> However, if private fields of MyNode is accessible where Add() is
> >> instantiated, Add should compile without any errors.
> >>
> >>
> >>
> >>
> >>
> >>
> >>
> >> you would need to create:
> >>
> >> struct MyNode {
> >>   Link *Node
> >>   value int
> >> }
> >>
> >> and make link exported - meaning you need to understand the internal 
> >> details of LinkedList in order to use it.
> >>
> >> At least I think so… :)
> >>
> >>
> >>
> >>
> >>
> >>
> >> On Oct 18, 2018, at 10:03 AM, Burak Serdar <bser...@ieee.org> wrote:
> >>
> >> On Thu, Oct 18, 2018 at 8:53 AM Robert Engels <reng...@ix.netcom.com> 
> >> wrote:
> >>
> >>
> >>
> >>
> >> On Oct 18, 2018, at 9:41 AM, Burak Serdar <bser...@ieee.org> wrote:
> >>
> >> If X is a struct type, any type implementing all the methods of X and
> >> containing all the fields of X can be substituted
> >>
> >>
> >> The above is the problem. This almost certainly requires dynamic access to 
> >> fields, essentially making all method and field access dynamic, and I 
> >> don’t think the Go performance hounds will go for it. I am
> >>
> >>
> >> I don't understand this concern either.
> >>
> >> func F(in like T)
> >>
> >> is a template. When the compiler instantiates F with a concrete type
> >> T, a new copy of F is compiled using that type. There is no dynamic
> >> access involved there, everything is statically resolved.
> >>
> >> not even certain it can be done without runtime reflection.
> >>
> >>
> >> But still a developer having to create a Bar with all of the exported 
> >> methods and fields of Foo seems daunting.
> >>
> >>
> >> --
> >> You received this message because you are subscribed to the Google Groups 
> >> "golang-nuts" group.
> >> To unsubscribe from this group and stop receiving emails from it, send an 
> >> email to golang-nuts+unsubscr...@googlegroups.com.
> >> For more options, visit https://groups.google.com/d/optout.
> >>
> >>
> >>
> >> --
> >> You received this message because you are subscribed to the Google Groups 
> >> "golang-nuts" group.
> >> To unsubscribe from this group and stop receiving emails from it, send an 
> >> email to golang-nuts+unsubscr...@googlegroups.com.
> >> For more options, visit https://groups.google.com/d/optout.
> >>
> >>
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to