[go-nuts] Re: "interface{} says nothing", lets consider it destroys information

2017-07-20 Thread 'Eric Johnson' via golang-nuts
Again, I'm mostly for generics being added to Go, because I've found 
occasion where they would be useful...

On Thursday, July 20, 2017 at 6:40:00 AM UTC-7, M P r a d e s wrote:
>
> Go could have least have parametric functions (ex :
>
> func Foo(value T)T { /.../ }
>
> bar := Foo(3) //types are verified at compile time, no need for 
> reflection or interface {} on any runtime trick.
>
> ).
>

To get at the value of adding generics, knowing what "Foo" is doing is 
important. Presumably, the function operates on "value" in some way.

Can we say that it implements an interface? Then let's suppose the 
existence of an interface "X". I can currently rewrite your "Foo" function 
as:

type X interface {
Clone() X // documentation needed to clarify that the clone is really 
of the derived type implementing X.
DoFoo()
}

func Foo(value X) X {
   result := value.Clone()
   result.DoFoo()
   return result
}

Now supposing I have a struct B, where *B implements "X", and is currently 
in variable "orig".

When calling this, to reflect that the result of Foo is still of type *B, 
the following is required.
   fooClone:=(*B).(Foo(orig))

What I want to be able to write, and have *B as the type of "clone":
   fooClone:=Foo(orig)

What we need the function signature to specify, then, is two pieces of 
information, that the parameter "value" is of the same type as its return, 
and that it implements interface "X". Also, my intuition suggests 
distinguishing generic types from concrete ones syntactically, so add an 
indication that's true. Perhaps try a few (+, ^, %).

A bunch of options that all get at the same idea, using different 
characters and different approaches:
func Foo(value T^->X) T^
func Foo(value T%:X) T%
func Foo(value T+:X) T+
func FooX>(value T^) T^
func FooX>(value T%) T%
func FooX>(value T+) T+

where the "->" could really be anything syntactically appropriate, but what 
it means is "T" implements X. Again, not sure of the right syntax, and not 
sure this is required.

In the "X" interface itself, we have a slightly different problem for the 
"Clone" method. We need someway to indicate "the concrete type of the 
thing". For that, we use the syntax indication of a generic type (^, %, or 
+, above) appended to something. "@" seems like a natural fit. That 
probably needs to look something like this:

Clone() @^

Putting it all together, choosing my favorite representation from above:
type X interface {
Clone() @+
DoFoo()
}

func Foo(value T+:X) T+ {
   result := value.Clone()
   result.DoFoo()
   return result
}

Now, I can write what I wanted to write:

fooClone := Foo(orig)

There's a *completely separate question* as to whether the compiler 
generates code that is effectively of the form:
fooClone := (*B).(Foo(orig))

I'm not sure I care about that. I'm more concerned about the correctness of 
the code.

Eric.
 

>
> But talking about this is kind of useless until Go rids itself of its over 
> reliance on runtime features like reflection. I suspect Go reflection 
> capabilities are why the language stopped evolving significantly at first 
> place. String tags are another symptom of that "disease".
>
> It's possible to write the snippet above with reflection today 
> (reflect.MakeFunc) , it shouldn't be.
>
>
>

-- 
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.


[go-nuts] Re: "interface{} says nothing", lets consider it destroys information

2017-07-20 Thread mhhcbon
In func Foo(value T)T { /.../ }

It makes sense to anchor the definition of T to the func name.

I feel like it is not needed, and i wonder about multiple T parameters.

Where the question here is about

func Foo(x , y ) (, ){}
Or
func Foo(x t, y u) (t, u){}


At least, it is possible to say your version has more impact on the overall 
syntax than my initial proposal,
because using your version there will be new things like

bar := Foo(3)

In my proposal, because 3 is an int,  is solved.


another very questionable thing, 
if you have  (basic type), you can return only a (string), or 
destruct it into another type (strconv.Atoi).
that happens because string does not match any interface, its basic.
So f() seems totally useless and redundant to f(string).

  is really interesting with structs and interfaces,
because struct can have as many facets as there is interface it satisfies.
- its open for the caller, you can inject and receive any type that 
satisfies the contract
- closed to the declarer, it must become a meaningful type before you 
actually interact with it




Aside of this, i have lots of troubles to write the clear distinction 
between interface{} and interface.
I d really like we had another keyword like *contract* to define an 
interface.
or empty{} rather than interface{}.

Anything that get rides of this naming problem.

On Thursday, July 20, 2017 at 3:40:00 PM UTC+2, M P r a d e s wrote:
>
> Go could have least have parametric functions (ex :
>
> func Foo(value T)T { /.../ }
>
> bar := Foo(3) //types are verified at compile time, no need for 
> reflection or interface {} on any runtime trick.
>
> ).
>
> But talking about this is kind of useless until Go rids itself of its over 
> reliance on runtime features like reflection. I suspect Go reflection 
> capabilities are why the language stopped evolving significantly at first 
> place. String tags are another symptom of that "disease".
>
> It's possible to write the snippet above with reflection today 
> (reflect.MakeFunc) , it shouldn't be.
>
>
>

-- 
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.


[go-nuts] Re: "interface{} says nothing", lets consider it destroys information

2017-07-20 Thread prades . marq
Go could have least have parametric functions (ex :

func Foo(value T)T { /.../ }

bar := Foo(3) //types are verified at compile time, no need for 
reflection or interface {} on any runtime trick.

).

But talking about this is kind of useless until Go rids itself of its over 
reliance on runtime features like reflection. I suspect Go reflection 
capabilities are why the language stopped evolving significantly at first 
place. String tags are another symptom of that "disease".

It's possible to write the snippet above with reflection today 
(reflect.MakeFunc) , it shouldn't be.


-- 
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.


[go-nuts] Re: "interface{} says nothing", lets consider it destroys information

2017-07-19 Thread mhhcbon
I think your example is not relevant, as it clearly intend to change the 
input type,
the goal is to preserve it, while still working with its value.


interface{} value type destroys the input type information,
so you might have the opposite value type, 
a type that preserves.
A type that let you write, *func, please, return the type i got*.

I did not mention templating, code generate / whatever/  like in 
https://en.wikipedia.org/wiki/Generic_programming

I read something related in "*Generic programming* is a style of computer 
programming  in which 
algorithms  are written in terms 
of types  *to-be-specified-later* 
that are then *instantiated* when needed for specific types provided as 
parameters 
." 

...*to-be-specified-later... *runtime leaks in the static type system, 
mostly a question of pov.

-  behaves like interface{} value type, because it does still say 
absolutely nothing. Not because it lacks of identity, but because it 
represents too many possible type.
-  is a shorthand to avoid a, probably, very repetitive type 
assert in order to use a , much like an interface{}, but better, because 
its shorter
-  can be use only in func/method parameter (*excluded *receiver) ? I 
have not been able to find it meaningful elsewhere. 
- if you don t need to return the input type, you don t need 
- ultimately, []interface{} == [], they both are list of stuff we have 
no idea what its about, but  has no sense if it is not scoped to a 
function call stack.
- ultimately, [] does not make sense.

- when you receive a func (x )  {}, it does actually says nothing to 
you, the declarer of the func, not because it lacks of identity, but 
because it represents too many possible types. If you d want to do 
something of it, you need to type assert it, to narrow it to something 
meaningful.
- when you receive a constrained , you can work on value of 
type Interface, and you can return whatever, including the input parameter 
type
- when you call a func with a constrained type, you can actually statically 
verify that the input value satisfies the constraint.
- when you call a , anything is as good as nil (i guess)



On Wednesday, July 19, 2017 at 11:47:40 PM UTC+2, Eric Johnson wrote:
>
> While I lean towards the view that Go should add support for type 
> generics, I'm not sure your example actually provides sufficient detail to 
> be an argument for them.
>
> On Monday, July 17, 2017 at 2:07:46 AM UTC-7, mhh...@gmail.com wrote:
>>
>> in func do(i interface{}) interface{} (return i), do says nothing because 
>> "interface{} says nothing", 
>>
>> from the caller pov, it looses information at the return call, 
>>
>> var x = "o"
>> do(x) // <- return lost the track it was a string
>>
>> if you delegate that func to another func, 
>> it can t says anything else rather than nothing unless it introduces type 
>> assertion.
>> func to(do func(interface{})interface{}) func (interface{}) interface{} { 
>> return func (i interface{}) interface{} {return do(i)} }
>>
>> if the observation become "interface{} destroys information", 
>> does it make sense to consider a "value type of any type that carries out 
>> its input type" ?
>> func do(any )  {return any}
>> do("thing") <- this is explicitly string
>>
>> Acting the same way as interface, except that little thing about 
>> destroying/preserving an information.
>>
>> It can be delegated to func that works on anything, still returns 
>> concrete types.
>> func to(do func(**)) func () ** { return func (i )  
>> {return do(i)} }
>>
>> to(do)("whatever") // got a string, right ?
>>
>> One step forward, 
>> what if  might be able to say "any type with a constraint on that 
>> interface",
>> func do(any )  {return any}
>> do(WhateverStringerCapable{}) <- much like using a regular parameter of 
>> type Stringer/interface{}, but now the return call reflects the invoke call 
>> , so its more complete than interface{}/Stringer.
>>
>
> If the "do" method takes and returns a Stringer, then why not just declare 
> it that way? To make this a more interesting discussion, you have to get 
> into the details of what the "do" function actually needs to do? Why can't 
> it just use standard interfaces?
>
> As I see it, one of the generics problems comes from using the built-in 
> slices and maps. As it current stands, if I create a method:
>
> func concat(foo []Stringer) String {
> result = ""
> for _, s := range foo {
> result = result + s.String() + ";
> }
> return result
> }
>
> but suppose I have two structs, Foo, and Bar, and both *Foo, and *Bar 
> implement Stringer.
>
> I cannot do this:
> func myFunc(f []*Foo, b []*Bar) string {
> return concat(f) + concat(b)
> }
>
> This seems like a more concrete scenario than the one you identified.
>
> Eric.
>  
>

[go-nuts] Re: "interface{} says nothing", lets consider it destroys information

2017-07-19 Thread 'Eric Johnson' via golang-nuts
While I lean towards the view that Go should add support for type generics, 
I'm not sure your example actually provides sufficient detail to be an 
argument for them.

On Monday, July 17, 2017 at 2:07:46 AM UTC-7, mhh...@gmail.com wrote:
>
> in func do(i interface{}) interface{} (return i), do says nothing because 
> "interface{} says nothing", 
>
> from the caller pov, it looses information at the return call, 
>
> var x = "o"
> do(x) // <- return lost the track it was a string
>
> if you delegate that func to another func, 
> it can t says anything else rather than nothing unless it introduces type 
> assertion.
> func to(do func(interface{})interface{}) func (interface{}) interface{} { 
> return func (i interface{}) interface{} {return do(i)} }
>
> if the observation become "interface{} destroys information", 
> does it make sense to consider a "value type of any type that carries out 
> its input type" ?
> func do(any )  {return any}
> do("thing") <- this is explicitly string
>
> Acting the same way as interface, except that little thing about 
> destroying/preserving an information.
>
> It can be delegated to func that works on anything, still returns concrete 
> types.
> func to(do func(**)) func () ** { return func (i )  
> {return do(i)} }
>
> to(do)("whatever") // got a string, right ?
>
> One step forward, 
> what if  might be able to say "any type with a constraint on that 
> interface",
> func do(any )  {return any}
> do(WhateverStringerCapable{}) <- much like using a regular parameter of 
> type Stringer/interface{}, but now the return call reflects the invoke call 
> , so its more complete than interface{}/Stringer.
>

If the "do" method takes and returns a Stringer, then why not just declare 
it that way? To make this a more interesting discussion, you have to get 
into the details of what the "do" function actually needs to do? Why can't 
it just use standard interfaces?

As I see it, one of the generics problems comes from using the built-in 
slices and maps. As it current stands, if I create a method:

func concat(foo []Stringer) String {
result = ""
for _, s := range foo {
result = result + s.String() + ";
}
return result
}

but suppose I have two structs, Foo, and Bar, and both *Foo, and *Bar 
implement Stringer.

I cannot do this:
func myFunc(f []*Foo, b []*Bar) string {
return concat(f) + concat(b)
}

This seems like a more concrete scenario than the one you identified.

Eric.
 

>
> no?
>
> Or maybe there is a reason in destroying that information ?
>

-- 
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.