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.

Reply via email to