On Thursday, June 16, 2016 at 3:20:10 PM UTC+2, Sean Russell wrote: > > I'm sorry -- the "share" button doesn't seem to be working, or doesn't > work in Firefox or Chrome. And I have a window hung on "waiting for remote > server," so I might have broken your playground. > TL:DR type conversion from arbitrary type to another arbitrary type is not directly possible with my proposal and needs to be done in two passes via a common type.
This is a tough task, and won't work directly using single parametric polymorphism the way you propose. Type conversion between two arbitrary types could become the single most significant weak spot of single parametric polymorphism and a huge argument for multi parametric . > Here's my code in (hopefully) compileable form for your processor: > > package main > > impoort "strconv" > > // Given: > func map(f(*), a []*, result []*) { > for i, k := range a { > result[i] = f(k) > } > } > > This function would compile, but would not do what you want. map() would not convert arbitrary types. It would simply duplicate slices. map() would not be callable with different types of *a* and *result, * > func main() { > a := "a" ; aa := "aa"; aaa = "aaa" > mylen := func(k *string) *int { > rv := len(*k) > return &rv > } > map(mylen, []*string{&a, &aa, &aaa}, make([]*int, 3)) // Is this > possible? > > one := 1; two := 2; three := 3 > myItoA := func(k *int) *string { > rv := strconv.Itoa(*k) > return &rv > } > map(myItoa, []*int{&one,&two,&three}, make([]*string, 3)) // once > more, for profit > > map(strconv.Itoa, []*int{&a}, make([]*float, 1)) // Is this a > runtime error? > } > The way to solve this example (slice type conversion), while keeping the style, would be to do it in two passes: First pass: convert []*anything to []interface{} Second pass: convert []interface{} to []*something_else //First pass just wraps the values to interface{}: func wrapvalues(in []*, out *[]interface{}) { for i:=0; i < len(in), i++ { *out = append(*out, in[i]) } } //Second pass does the heavy lifting and conversion: func toslice(convert func(*,interface{}), in *[]interface{}, out []*) { for i:=0; i < len(in), i++ { convert( out[i], in[i]) } } // conversion function from *int to *string func int_to_str(in interace{}, out *string) { var i = in.(int) *out = strconv.Itoa(i) } // called like this var originalslice []*int var intermediate []interface{} var result []*string = make( []*string, len(originalslice)) wrapvalues(originalslice, &intermediate) toslice(int_to_str, &intermediate, result) Other solutions: An one-liner, simply traverse the original slice, and convert elements on the go: func foreach_slice(slice []*, call func(*)) { for i := range slice { call(slice[i]) } } foreach_slice(as, func(arg *string){var i int; i = len(*arg); bs = append(bs,&i)}) http://tsoh.host/test.html#075b8a23 Reusable conversion routine, is able to convert arbitrary slice to another arbitrary slice. Each element is converted via string and then to the target type Routine can be called using one-liner and is fully type safe: slice_via_str_from(as, my_float64_to_string).to(bs, my_string_to_int) http://tsoh.host/test.html#eaa6317e > > And, yeah... the pointers are a bit of trouble. By the time all of the > wrapping and referencing is done, it's only a little easier than just using > interface{} everywhere with casts. If you don't get type safety with this, > I feel like the syntactic sugar value is pretty modest. > > --- SER > I feel that the type safety is preserved -- 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.