On Fri, 20 Oct 2023 at 07:51, Ian Lance Taylor <i...@golang.org> wrote:

> On Thu, Oct 19, 2023 at 5:14 PM Jason E. Aten <j.e.a...@gmail.com> wrote:
> >
> > Analogous to
> >
> > type IntSlice []int
> >
> > func (p IntSlice) Len() int { return len(p) }
> > func (p IntSlice) Less(i, j int) bool { return p[i].val < p[j].val }
> > func (p IntSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
> >
> > and then calling sort.Sort() on an IntSlice, I figured I
> > could create a type that is a new name for an instantiated generic type
> and
> > then call methods on that new type... but no?
> >
> > For example:
> > https://go.dev/play/p/K5FGtNi6hLM
> >
> > package main
> >
> > import "fmt"
> >
> > type Addable interface {
> > ~complex128 | ~complex64 | ~float64 | ~float32 |
> > ~byte | ~uint16 | ~uint32 | ~uint64 |
> > ~int8 | ~int16 | ~int32 | ~int64 | ~int
> > }
> >
> > type Matrix[T Addable] struct {
> > Nrow int
> > Ncol int
> > Dat  []T
> > }
> >
> > func (m *Matrix[T]) Col(j int) (res []T) {
> > for i := 0; i < m.Nrow; i++ {
> > res = append(res, m.At(i, j))
> > }
> > return
> > }
> >
> > // At reads out the [i,j]-th element.
> > func (m *Matrix[T]) At(i, j int) T {
> > return m.Dat[i*m.Ncol+j]
> > }
> >
> > func main() {
> > m := &Matrix[float64]{
> > Nrow: 2,
> > Ncol: 3,
> > Dat:  make([]float64, 2*3),
> > }
> > fmt.Printf("m.At(1,2) = '%v'", m.At(1, 2)) // this is fine, of course.
> > }
> >
> > // I assumed this would work... but go 1.21 rejects the call to At()
> below.
> > type MatrixF64 Matrix[float64]
> >
> > func UseMatrixF64(m *MatrixF64) {
> >        // so why won't this compile? if the same line in main() works?
> > fmt.Printf("m.At(1,2) = '%v'", m.At(1, 2)) // compile error: m.At
> undefined (type *MatrixF64 has no field or method At)
> > }
>
> Using "type MatrixF64 ..." defines a new type that doesn't inherit any
> of the method of the old type.  That's how type definitions work in
> Go.  It will work as you expect if you use a type alias: "type
> MatrixF64 = ...".
>
> Ian
>
> --
> 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/CAOyqgcUKo1n3BY5z1OWSFR4omZX4gFXpCgHg5%2BbHrb3jsk7E0w%40mail.gmail.com
> .
>

There are two ways to enable this, which are worth discussing further as of
why Go decided to behave this way.

   1. To use type alias as mentioned before `type MatrixF64 =
   Matrix[float64]`, this is generally works but unfortunately, doesn't worth
   it in the case of aliasing primitives type, i.e. `type String = string`
   won't allow you to bind new methods to `String` unlike `type String
   string`. I would like to know why.
   2. To use type embedding such as: type MatrixF64 struct {
   Matrix[float64] }, since struct/interface embedding will allow the parent
   struct to call embedded methods/fields directly.


Again, I would love to see the motivation between these design decisions,
pretty much I would like to allow new methods to be  attached to type
primitives without resorting to manual type casting / type assertion, but
that's another topic.

Regards.

-- 
regards,
Nurahmadie
--

-- 
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/CA%2BcQEWFRZJ8dN_YBo5qjvZ0cpijxGJikz5qws0ToUQa_OMaPDA%40mail.gmail.com.

Reply via email to