Re: [go-nuts] Generic member of recursive struct

2021-12-20 Thread Robert Engels
This is a task for a parser - and the parser can be type safe -but the 
constraints for something as complex as html aren’t typically  expressed in 
types but rather bnf or similar. 

You can look at the Java html renderer/parser and it uses type safe nodes but 
it still has a resilient parser layer to produce the nodes. 



> On Dec 20, 2021, at 3:06 PM, Michael Ellis  wrote:
> 
> Thanks, Axel & Robert.  As I said in the first post, the package already 
> works well for my purposes (and apparently for the few others who use it).  
> It allows defining web content more concisely than raw HTML and makes the 
> full power of Go available for composing repetitive page structures.
> 
> I was mostly just curious about the possibility of detecting bad content at 
> compile time instead of at run time. In practice, that's turned out not to be 
> a significant problem so I'm ok with learning generics don't support a fix.
> 
>> On Monday, December 20, 2021 at 2:31:32 PM UTC-5 axel.wa...@googlemail.com 
>> wrote:
>> Oh, forgot the footnote:
>> 
>> [1] Note that even that doesn't *actually* work, as `*HtmlNode` would become 
>> a parametric type, so it would have to be instantiated to be used in the 
>> constraint - you'd have to write `type HtmlNode[T string | 
>> *HtmlNode[Something]]`. And the fact that there is no actual answer to what 
>> "Something" would be should be a strong indicator for how much generics are 
>> not what you want for this.
>> 
>>> On Mon, Dec 20, 2021 at 8:29 PM Axel Wagner  
>>> wrote:
>>> 
>>> 
 On Mon, Dec 20, 2021 at 7:07 PM Michael Ellis  wrote:
 >Just to be clear, the way I understood you is that you want HtmlTree.C to 
 >be a slice which has elements which can each either be a string or an 
 >*HtmlTree - i.e. you want these to be mixed in a single slice. Correct?
 
 Actually, no.  An HtmlTree instance whose content is a string is a 
 terminal node.  The recursion in the Render() func looks like:
 
   for _, c := range h.C {
 switch c := c.(type) {
 case string:
 b.WriteString(c)
 case *HtmlTree:
 err = Render(c, b, rindent)
 if err != nil {
 return fmt.Errorf("%s : %v", h.T, err)
 }
 default:
 return fmt.Errorf("Bad content %v. Can't render 
 type %T! ", h.C, c)
 }
 }
>>> 
>>> That's pretty much what I meant, yes. You want a sum type (and in lieu of 
>>> sum types, an interface), not generics. 
>>> The "union" aspect of Go generics (the `a | b` syntax) only applies to 
>>> using interfaces as *constraints*, not as *types* - you want to do the 
>>> latter. You want to have a field which is either a string or an *HtmlNode - 
>>> but Go only gives you a convenient way to write the two distinct types 
>>> `type HtmlNodeString struct { /*…*/ C string }` and `type HtmlNodeNode 
>>> struct { /* … */ C *HtmlNode }` into one¹ type declaration and write 
>>> function which can work on either. It's just not what you want.
>>> 
>>> The best option for you is (as Robert mentions) to use an interface, which 
>>> is an "open sum" - meaning you can't have the guarantee that its dynamic 
>>> type is of a limited set of options, but you *can* have a value whose 
>>> actual type is dynamic. You can look at e.g. ast.Node, which is de-facto 
>>> the same thing - it's supposed to be a limited set of options, but in lieu 
>>> of sum types, it's an interface.
>>> 
>>> Go might, at some point, allow the union-elements of constraint interfaces 
>>> to be used as actual types, which *would* be a form of sum types. But 
>>> probably not for a while - it's more complicated than it may seem.
>>> 
 
 
 I suppose it's still a problem, though, since the compiler doesn't have 
 any way of knowing that's how trees of HtmlTree meant to be constructed. I 
 should have expressed the intended constraint on HtmlTree.C as `string | 
 []*HtmlTree`.  Does that make a difference?
> On Monday, December 20, 2021 at 10:25:26 AM UTC-5 
> axel.wa...@googlemail.com wrote:
> Just to be clear, the way I understood you is that you want HtmlTree.C to 
> be a slice which has elements which can each either be a string or an 
> *HtmlTree - i.e. you wan these to be mixed in a single slice. Correct?
> Because that is not a use case for generics, it's a use case for sum 
> types (which Go does not have).
> 
>> On Mon, Dec 20, 2021 at 4:11 PM Michael Ellis  
>> wrote:
>> > They can't, sorry.
>> Ok. Thanks, Axel. 
>> Saves me wasting more time.  In the past 3 years of using Go, this is 
>> the only use case where I've  really wanted generics (other cases I've 
>> encountered so far are easily handled with code generation). 
> 

Re: [go-nuts] Generic member of recursive struct

2021-12-20 Thread Michael Ellis
Thanks, Axel & Robert.  As I said in the first post, the package already 
works well for my purposes (and apparently for the few others who use it).  
It allows defining web content more concisely than raw HTML and makes the 
full power of Go available for composing repetitive page structures.

I was mostly just curious about the possibility of detecting bad content at 
compile time instead of at run time. In practice, that's turned out not to 
be a significant problem so I'm ok with learning generics don't support a 
fix.

On Monday, December 20, 2021 at 2:31:32 PM UTC-5 axel.wa...@googlemail.com 
wrote:

> Oh, forgot the footnote:
>
> [1] Note that even that doesn't *actually* work, as `*HtmlNode` would 
> become a parametric type, so it would have to be instantiated to be used in 
> the constraint - you'd have to write `type HtmlNode[T string | 
> *HtmlNode[Something]]`. And the fact that there is no actual answer to what 
> "Something" would be should be a strong indicator for how much generics are 
> not what you want for this.
>
> On Mon, Dec 20, 2021 at 8:29 PM Axel Wagner  
> wrote:
>
>>
>>
>> On Mon, Dec 20, 2021 at 7:07 PM Michael Ellis  
>> wrote:
>>
>>> >Just to be clear, the way I understood you is that you want HtmlTree.C 
>>> to be a slice which has elements which can each either be a string or an 
>>> *HtmlTree - i.e. you want these to be mixed in a single slice. Correct?
>>>
>>> Actually, no.  An HtmlTree instance whose content is a string is a 
>>> terminal node.  The recursion in the Render() func looks like:
>>>
>>>   for _, c := range h.C {
>>> switch c := c.(type) {
>>> case string:
>>> b.WriteString(c)
>>> case *HtmlTree:
>>> err = Render(c, b, rindent)
>>> if err != nil {
>>> return fmt.Errorf("%s : %v", h.T, err)
>>> }
>>> default:
>>> return fmt.Errorf("Bad content %v. Can't render 
>>> type %T! ", h.C, c)
>>> }
>>> }
>>>
>>
>> That's pretty much what I meant, yes. You want a sum type (and in lieu of 
>> sum types, an interface), not generics. 
>> The "union" aspect of Go generics (the `a | b` syntax) only applies to 
>> using interfaces as *constraints*, not as *types* - you want to do the 
>> latter. You want to have a field which is either a string or an *HtmlNode - 
>> but Go only gives you a convenient way to write the two distinct types 
>> `type HtmlNodeString struct { /*…*/ C string }` and `type HtmlNodeNode 
>> struct { /* … */ C *HtmlNode }` into one¹ type declaration and write 
>> function which can work on either. It's just not what you want.
>>
>> The best option for you is (as Robert mentions) to use an interface, 
>> which is an "open sum" - meaning you can't have the guarantee that its 
>> dynamic type is of a limited set of options, but you *can* have a value 
>> whose actual type is dynamic. You can look at e.g. ast.Node 
>> , which is de-facto the same thing - 
>> it's supposed to be a limited set of options, but in lieu of sum types, 
>> it's an interface.
>>
>> Go might, at some point, allow the union-elements of constraint 
>> interfaces to be used as actual types, which *would* be a form of sum 
>> types. But probably not for a while - it's more complicated than it may 
>> seem.
>>
>>
>>>
>>> I suppose it's still a problem, though, since the compiler doesn't have 
>>> any way of knowing that's how trees of HtmlTree meant to be constructed. I 
>>> should have expressed the intended constraint on HtmlTree.C as `string | 
>>> []*HtmlTree`.  Does that make a difference?
>>> On Monday, December 20, 2021 at 10:25:26 AM UTC-5 
>>> axel.wa...@googlemail.com wrote:
>>>
 Just to be clear, the way I understood you is that you want HtmlTree.C 
 to be a slice which has elements which can each either be a string or an 
 *HtmlTree - i.e. you wan these to be mixed in a single slice. Correct?
 Because that is not a use case for generics, it's a use case for sum 
 types (which Go does not have).

 On Mon, Dec 20, 2021 at 4:11 PM Michael Ellis  
 wrote:

> > They can't, sorry.
> Ok. Thanks, Axel. 
> Saves me wasting more time.  In the past 3 years of using Go, this is 
> the only use case where I've  really wanted generics (other cases I've 
> encountered so far are easily handled with code generation). 
>
> -- 
>
 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...@googlegroups.com.
>
 To view this discussion on the web visit 
> https://groups.google.com/d/msgid/golang-nuts/ac75dc32-733d-4a73-9735-619c33cb4cd4n%40googlegroups.com
>  
> 

Re: [go-nuts] Generic member of recursive struct

2021-12-20 Thread 'Axel Wagner' via golang-nuts
Oh, forgot the footnote:

[1] Note that even that doesn't *actually* work, as `*HtmlNode` would
become a parametric type, so it would have to be instantiated to be used in
the constraint - you'd have to write `type HtmlNode[T string |
*HtmlNode[Something]]`. And the fact that there is no actual answer to what
"Something" would be should be a strong indicator for how much generics are
not what you want for this.

On Mon, Dec 20, 2021 at 8:29 PM Axel Wagner 
wrote:

>
>
> On Mon, Dec 20, 2021 at 7:07 PM Michael Ellis 
> wrote:
>
>> >Just to be clear, the way I understood you is that you want HtmlTree.C
>> to be a slice which has elements which can each either be a string or an
>> *HtmlTree - i.e. you want these to be mixed in a single slice. Correct?
>>
>> Actually, no.  An HtmlTree instance whose content is a string is a
>> terminal node.  The recursion in the Render() func looks like:
>>
>>   for _, c := range h.C {
>> switch c := c.(type) {
>> case string:
>> b.WriteString(c)
>> case *HtmlTree:
>> err = Render(c, b, rindent)
>> if err != nil {
>> return fmt.Errorf("%s : %v", h.T, err)
>> }
>> default:
>> return fmt.Errorf("Bad content %v. Can't render
>> type %T! ", h.C, c)
>> }
>> }
>>
>
> That's pretty much what I meant, yes. You want a sum type (and in lieu of
> sum types, an interface), not generics.
> The "union" aspect of Go generics (the `a | b` syntax) only applies to
> using interfaces as *constraints*, not as *types* - you want to do the
> latter. You want to have a field which is either a string or an *HtmlNode -
> but Go only gives you a convenient way to write the two distinct types
> `type HtmlNodeString struct { /*…*/ C string }` and `type HtmlNodeNode
> struct { /* … */ C *HtmlNode }` into one¹ type declaration and write
> function which can work on either. It's just not what you want.
>
> The best option for you is (as Robert mentions) to use an interface, which
> is an "open sum" - meaning you can't have the guarantee that its dynamic
> type is of a limited set of options, but you *can* have a value whose
> actual type is dynamic. You can look at e.g. ast.Node
> , which is de-facto the same thing - it's
> supposed to be a limited set of options, but in lieu of sum types, it's an
> interface.
>
> Go might, at some point, allow the union-elements of constraint interfaces
> to be used as actual types, which *would* be a form of sum types. But
> probably not for a while - it's more complicated than it may seem.
>
>
>>
>> I suppose it's still a problem, though, since the compiler doesn't have
>> any way of knowing that's how trees of HtmlTree meant to be constructed. I
>> should have expressed the intended constraint on HtmlTree.C as `string |
>> []*HtmlTree`.  Does that make a difference?
>> On Monday, December 20, 2021 at 10:25:26 AM UTC-5
>> axel.wa...@googlemail.com wrote:
>>
>>> Just to be clear, the way I understood you is that you want HtmlTree.C
>>> to be a slice which has elements which can each either be a string or an
>>> *HtmlTree - i.e. you wan these to be mixed in a single slice. Correct?
>>> Because that is not a use case for generics, it's a use case for sum
>>> types (which Go does not have).
>>>
>>> On Mon, Dec 20, 2021 at 4:11 PM Michael Ellis 
>>> wrote:
>>>
 > They can't, sorry.
 Ok. Thanks, Axel.
 Saves me wasting more time.  In the past 3 years of using Go, this is
 the only use case where I've  really wanted generics (other cases I've
 encountered so far are easily handled with code generation).

 --

>>> 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...@googlegroups.com.

>>> To view this discussion on the web visit
 https://groups.google.com/d/msgid/golang-nuts/ac75dc32-733d-4a73-9735-619c33cb4cd4n%40googlegroups.com
 
 .

>>> --
>> 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.
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/golang-nuts/2de22684-0263-465c-8ac0-ff288c535fb7n%40googlegroups.com
>> 
>> .
>>
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.

Re: [go-nuts] Generic member of recursive struct

2021-12-20 Thread 'Axel Wagner' via golang-nuts
On Mon, Dec 20, 2021 at 7:07 PM Michael Ellis 
wrote:

> >Just to be clear, the way I understood you is that you want HtmlTree.C to
> be a slice which has elements which can each either be a string or an
> *HtmlTree - i.e. you want these to be mixed in a single slice. Correct?
>
> Actually, no.  An HtmlTree instance whose content is a string is a
> terminal node.  The recursion in the Render() func looks like:
>
>   for _, c := range h.C {
> switch c := c.(type) {
> case string:
> b.WriteString(c)
> case *HtmlTree:
> err = Render(c, b, rindent)
> if err != nil {
> return fmt.Errorf("%s : %v", h.T, err)
> }
> default:
> return fmt.Errorf("Bad content %v. Can't render
> type %T! ", h.C, c)
> }
> }
>

That's pretty much what I meant, yes. You want a sum type (and in lieu of
sum types, an interface), not generics.
The "union" aspect of Go generics (the `a | b` syntax) only applies to
using interfaces as *constraints*, not as *types* - you want to do the
latter. You want to have a field which is either a string or an *HtmlNode -
but Go only gives you a convenient way to write the two distinct types
`type HtmlNodeString struct { /*…*/ C string }` and `type HtmlNodeNode
struct { /* … */ C *HtmlNode }` into one¹ type declaration and write
function which can work on either. It's just not what you want.

The best option for you is (as Robert mentions) to use an interface, which
is an "open sum" - meaning you can't have the guarantee that its dynamic
type is of a limited set of options, but you *can* have a value whose
actual type is dynamic. You can look at e.g. ast.Node
, which is de-facto the same thing - it's
supposed to be a limited set of options, but in lieu of sum types, it's an
interface.

Go might, at some point, allow the union-elements of constraint interfaces
to be used as actual types, which *would* be a form of sum types. But
probably not for a while - it's more complicated than it may seem.


>
> I suppose it's still a problem, though, since the compiler doesn't have
> any way of knowing that's how trees of HtmlTree meant to be constructed. I
> should have expressed the intended constraint on HtmlTree.C as `string |
> []*HtmlTree`.  Does that make a difference?
> On Monday, December 20, 2021 at 10:25:26 AM UTC-5
> axel.wa...@googlemail.com wrote:
>
>> Just to be clear, the way I understood you is that you want HtmlTree.C to
>> be a slice which has elements which can each either be a string or an
>> *HtmlTree - i.e. you wan these to be mixed in a single slice. Correct?
>> Because that is not a use case for generics, it's a use case for sum
>> types (which Go does not have).
>>
>> On Mon, Dec 20, 2021 at 4:11 PM Michael Ellis 
>> wrote:
>>
>>> > They can't, sorry.
>>> Ok. Thanks, Axel.
>>> Saves me wasting more time.  In the past 3 years of using Go, this is
>>> the only use case where I've  really wanted generics (other cases I've
>>> encountered so far are easily handled with code generation).
>>>
>>> --
>>>
>> 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...@googlegroups.com.
>>>
>> To view this discussion on the web visit
>>> https://groups.google.com/d/msgid/golang-nuts/ac75dc32-733d-4a73-9735-619c33cb4cd4n%40googlegroups.com
>>> 
>>> .
>>>
>> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/2de22684-0263-465c-8ac0-ff288c535fb7n%40googlegroups.com
> 
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAEkBMfG0v3S8R_MyvNgMev1TjKZYQ4PZ8d03r5897evJf2QQxg%40mail.gmail.com.


Re: [go-nuts] Generic member of recursive struct

2021-12-20 Thread Robert Engels
You create structs like StringNode and HtmlNode that implement the common 
needed operations. 

Imagine a Render() method for a string you convert to html, for an html node 
you render recursively. 

Or similar. If an HtmlNode is not a leaf node it needs recursive operations. 

> On Dec 20, 2021, at 12:52 PM, Michael Ellis  wrote:
> 
> 
> 
>> On Monday, December 20, 2021 at 1:33:49 PM UTC-5 ren...@ix.netcom.com wrote:
>> You should use interfaces and a “node” type.
> 
> Hmm, I tried 
> 
> type Node interface {
> string | []*HtmlTree
> }
> 
> type HtmlTree struct {
> T string // html tagname, e.g. 'head'
> A string // zero or more html attributes, e.g 'id=1 class="foo"'
> C Node   // a slice of content whose elements may be strings or 
> *HtmlTree
> empty bool   // set to true for empty tags like 
> }
> 
> and the compiler said: 
> ./prog.go:21:8: interface contains type constraints.
> 
> (line 21 is the declaration of HtmlTree.C as type Node)
> 
> What's the syntax you have in mind?
> 
> 
>  
> -- 
> 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.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/golang-nuts/c619d54d-5a69-4828-b10b-771722f8f646n%40googlegroups.com.

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/88DB1537-6360-4D34-96BC-C9F2CEB01C0A%40ix.netcom.com.


Re: [go-nuts] Generic member of recursive struct

2021-12-20 Thread Michael Ellis


On Monday, December 20, 2021 at 1:33:49 PM UTC-5 ren...@ix.netcom.com wrote:

> You should use interfaces and a “node” type.
>

Hmm, I tried 

type Node interface {
string | []*HtmlTree
}

type HtmlTree struct {
T string // html tagname, e.g. 'head'
A string // zero or more html attributes, e.g 'id=1 class="foo"'
C Node   // a slice of content whose elements may be strings or 
*HtmlTree
empty bool   // set to true for empty tags like 
}

and the compiler said: 
./prog.go:21:8: interface contains type constraints.

(line 21 is the declaration of HtmlTree.C as type Node)

What's the syntax you have in mind?


 

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/c619d54d-5a69-4828-b10b-771722f8f646n%40googlegroups.com.


Re: [go-nuts] Generic member of recursive struct

2021-12-20 Thread Robert Engels
You should use interfaces and a “node” type. 

> On Dec 20, 2021, at 12:07 PM, Michael Ellis  wrote:
> 
> >Just to be clear, the way I understood you is that you want HtmlTree.C to 
> be a slice which has elements which can each either be a string or an 
> *HtmlTree - i.e. you want these to be mixed in a single slice. Correct?
> 
> Actually, no.  An HtmlTree instance whose content is a string is a terminal 
> node.  The recursion in the Render() func looks like:
> 
>   for _, c := range h.C {
> switch c := c.(type) {
> case string:
> b.WriteString(c)
> case *HtmlTree:
> err = Render(c, b, rindent)
> if err != nil {
> return fmt.Errorf("%s : %v", h.T, err)
> }
> default:
> return fmt.Errorf("Bad content %v. Can't render type 
> %T! ", h.C, c)
> }
> }
> 
> I suppose it's still a problem, though, since the compiler doesn't have any 
> way of knowing that's how trees of HtmlTree meant to be constructed. I should 
> have expressed the intended constraint on HtmlTree.C as `string | 
> []*HtmlTree`.  Does that make a difference?
>> On Monday, December 20, 2021 at 10:25:26 AM UTC-5 axel.wa...@googlemail.com 
>> wrote:
>> Just to be clear, the way I understood you is that you want HtmlTree.C to be 
>> a slice which has elements which can each either be a string or an *HtmlTree 
>> - i.e. you wan these to be mixed in a single slice. Correct?
>> Because that is not a use case for generics, it's a use case for sum types 
>> (which Go does not have).
>> 
>>> On Mon, Dec 20, 2021 at 4:11 PM Michael Ellis  wrote:
>>> > They can't, sorry.
>>> Ok. Thanks, Axel. 
>>> Saves me wasting more time.  In the past 3 years of using Go, this is the 
>>> only use case where I've  really wanted generics (other cases I've 
>>> encountered so far are easily handled with code generation). 
>> 
>>> -- 
>> 
>>> 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...@googlegroups.com.
>> 
>>> To view this discussion on the web visit 
>>> https://groups.google.com/d/msgid/golang-nuts/ac75dc32-733d-4a73-9735-619c33cb4cd4n%40googlegroups.com.
> 
> -- 
> 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.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/golang-nuts/2de22684-0263-465c-8ac0-ff288c535fb7n%40googlegroups.com.

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/9ABD0D98-6041-4A45-A2C3-D924E298BF16%40ix.netcom.com.


Re: [go-nuts] Generic member of recursive struct

2021-12-20 Thread Michael Ellis
>Just to be clear, the way I understood you is that you want HtmlTree.C to 
be a slice which has elements which can each either be a string or an 
*HtmlTree - i.e. you want these to be mixed in a single slice. Correct?

Actually, no.  An HtmlTree instance whose content is a string is a terminal 
node.  The recursion in the Render() func looks like:

  for _, c := range h.C {
switch c := c.(type) {
case string:
b.WriteString(c)
case *HtmlTree:
err = Render(c, b, rindent)
if err != nil {
return fmt.Errorf("%s : %v", h.T, err)
}
default:
return fmt.Errorf("Bad content %v. Can't render 
type %T! ", h.C, c)
}
}

I suppose it's still a problem, though, since the compiler doesn't have any 
way of knowing that's how trees of HtmlTree meant to be constructed. I 
should have expressed the intended constraint on HtmlTree.C as `string | 
[]*HtmlTree`.  Does that make a difference?
On Monday, December 20, 2021 at 10:25:26 AM UTC-5 axel.wa...@googlemail.com 
wrote:

> Just to be clear, the way I understood you is that you want HtmlTree.C to 
> be a slice which has elements which can each either be a string or an 
> *HtmlTree - i.e. you wan these to be mixed in a single slice. Correct?
> Because that is not a use case for generics, it's a use case for sum types 
> (which Go does not have).
>
> On Mon, Dec 20, 2021 at 4:11 PM Michael Ellis  
> wrote:
>
>> > They can't, sorry.
>> Ok. Thanks, Axel. 
>> Saves me wasting more time.  In the past 3 years of using Go, this is the 
>> only use case where I've  really wanted generics (other cases I've 
>> encountered so far are easily handled with code generation). 
>>
>> -- 
>>
> 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...@googlegroups.com.
>>
> To view this discussion on the web visit 
>> https://groups.google.com/d/msgid/golang-nuts/ac75dc32-733d-4a73-9735-619c33cb4cd4n%40googlegroups.com
>>  
>> 
>> .
>>
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/2de22684-0263-465c-8ac0-ff288c535fb7n%40googlegroups.com.


Re: [go-nuts] Generic member of recursive struct

2021-12-20 Thread 'Axel Wagner' via golang-nuts
Just to be clear, the way I understood you is that you want HtmlTree.C to
be a slice which has elements which can each either be a string or an
*HtmlTree - i.e. you wan these to be mixed in a single slice. Correct?
Because that is not a use case for generics, it's a use case for sum types
(which Go does not have).

On Mon, Dec 20, 2021 at 4:11 PM Michael Ellis 
wrote:

> > They can't, sorry.
> Ok. Thanks, Axel.
> Saves me wasting more time.  In the past 3 years of using Go, this is the
> only use case where I've  really wanted generics (other cases I've
> encountered so far are easily handled with code generation).
>
> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/ac75dc32-733d-4a73-9735-619c33cb4cd4n%40googlegroups.com
> 
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAEkBMfEQH4aBzXFFyKvyXo8b6pbdGHa-6Ueughffasq4mWCpNQ%40mail.gmail.com.


Re: [go-nuts] Generic member of recursive struct

2021-12-20 Thread Michael Ellis
> They can't, sorry.
Ok. Thanks, Axel. 
Saves me wasting more time.  In the past 3 years of using Go, this is the 
only use case where I've  really wanted generics (other cases I've 
encountered so far are easily handled with code generation). 

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/ac75dc32-733d-4a73-9735-619c33cb4cd4n%40googlegroups.com.


Re: [go-nuts] Generic member of recursive struct

2021-12-20 Thread 'Axel Wagner' via golang-nuts
On Mon, Dec 20, 2021 at 3:20 PM Michael Ellis 
wrote:

> I've got a package, github.com/Michael-F-Ellis/goht, that supports
> creating HTML docs in Go.  It works well, for my purposes at least, but
> I've always been bothered by having to use []interface{} to define the
> struct member, C, that supports recursion.
>
> type HtmlTree struct {
> T string// html tagname, e.g. 'head'
> A string// zero or more html attributes, e.g 'id=1
> class="foo"'
> C []interface{} // a slice of content whose elements may be
> strings or *HtmlTree
> empty bool  // set to true for empty tags like 
> }
>
> I've created a minimal extract of the package on the playground at
> https://go.dev/play/p/-_7JKRZYLC_J?v=gotip.  Assuming the new generics
> can support constraining HtmlTree.C to be a slice of string | *HtmlTree,
> what is the right syntax for doing so?
>

They can't, sorry.


>
> Thanks!
>
>
> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/a8817b41-85dd-4fd1-a946-00764713c008n%40googlegroups.com
> 
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAEkBMfFR7FXKAdEgwZ4yrG3x5b1C18CfaNzk-FGSLrBzby9O%3DQ%40mail.gmail.com.