FWIW, I've often wanted this too.
My question is really about allowing functions to be passed as single-method interfaces where the signatures match, so users and libraries do not have create wrapper interfaces (like http.HandlerFunc) and create extra functions which take the wrapper interface (like http.HandleFunc).
I have also wanted this feature, but I wonder if the extra feature pulls its weight. There's a cost to adding the feature to the language. It's another thing for people to learn. It's not all that onerous to define and use a wrapper interface.
What if the language supported currying the receiver in a value.Method expression? With this feature, APIs can be designed to use functions instead of single method interfaces.
I'm against this idea. A function is not a method and conflating the
ideas saves a trivial amount of code at the cost of potentially
dangerous and confusing non-orthogonality. This proposal is similar
to the claim that
struct { int }
and
int
should be assignable to each other.
While I can see operational and
convenience arguments why that could be true, it breaks the model on
which the language is built.
darn, forgot to reply-all
---------- Forwarded message ----------
From: "roger peppe" <rogp...@gmail.com>
Date: Jun 1, 2012 7:34 PM
Subject: Re: [go-nuts] Re: Thoughts: Treat function as a single-method interface{} if signatures match
To: "Ugorji Nwoke" <ugo...@gmail.com>
I'm with rob, although I've thought on this idea a few times,
slightly wistfully.
It would be confusing for programs that reflect - what would would
the type of the underlying value inside the interface have,
and would it have any methods?
If the underlying type is exactly the original function type (and
I think it would be very confusing if this was *not* the
case) then this code would break, because when it's not in
an interface, the underlying value has no methods:
type X interface{ F func() }
var x X = func(){} // x has method X
y := reflect.ValueOf(x)
y.MethodByName("F").Call()
I suppose an alternative would be to say that
a function had an infinite number of methods
with all possible names, each with the same type
signature, but that's just getting silly.
This would IMO significantly raise the barriers for entry to go. Interfaces were definitely the hardest part (for me at least) of go syntax to grok, please don't make it harder. It may be orthogonal (I'm not sure I know what that means anymore) but it is damn confusing to read in one pass because it disguises function signatures in the call, or at least appears to.
darn, forgot to reply-all---------- Forwarded message ----------
Date: Jun 1, 2012 7:34 PM
Subject: Re: [go-nuts] Re: Thoughts: Treat function as a single-method interface{} if signatures matchI'm with rob, although I've thought on this idea a few times,slightly wistfully.
It would be confusing for programs that reflect - what would would
the type of the underlying value inside the interface have,
and would it have any methods?If the underlying type is exactly the original function type (and
I think it would be very confusing if this was *not* the
case) then this code would break, because when it's not in
an interface, the underlying value has no methods:type X interface{ F func() }
var x X = func(){} // x has method X
y := reflect.ValueOf(x)
y.MethodByName("F").Call()
Rémy.
I mentioned that interfaces were the hardest part of the go syntax to grok, and I feel that I'm not the only one in this position.
It is not a matter of patterns learned in other languages as before go, I had almost never used "interfaces" or templates or other such structures. In fact most of the programming I've done in other languages resembles a sort of C, with or without OO depending on the language. (a note here, I also never liked type hierarchies and inheritance so I avoided them altogether, preferring closures where available)
That out of the way, I still feel that interfaces in go are "hard" for one major reason that you guys may have overlooked: they do not do what you might expect them to do, they do the opposite.
They are often described in the documentation as easing function design, with plenty of examples to support that, among other things. What is not often or clearly mentioned is that interfaces are not real, in the sense that they contain no programmer accessible (barring unsafe) data. They are not actually interfaces in the sense of the english word, they are archetype definitions. (I have trouble here describing them without using words that have meaning in other programming languages so bear with me). An interface type does not describe data at all, it describes the datas signature and therein lies the problem.
I can identify the moment that I actually understood what interfaces do: when somebody on the group pointed out that you cannot instantiate a variable of type interface and expect go to figure out what it should actually contain. This needs to be made _much_ clearer in the documentation.
For a long time I was living with the assumption that the compiler/runtime did a sort of magic trick, and that the underlying type of an interface was unknown until the method set had been winnowed down to one applicable type, and further that given a rigorous naming scheme this should be irrelevant and the runtime would just pick a valid type from a hat or something. Obviously this was wrong.
You asked for a clarification and that's the best I can come up with, hopefully it is helpful and as always thanks for listening, and for go.
-Simon Watt
That out of the way, I still feel that interfaces in go are "hard" for one major reason that you guys may have overlooked: they do not do what you might expect them to do, they do the opposite.
Thomas
I would add something like this to the description (right before the para that starts " A type can implement multiple interfaces "):"A type is said to implement an interface if it contains the method signatures listed in the interface definition. For example:"
(code example with an interface definition and two types with method sets, one that implements the interface and one that doesn't and comments describing why/why not)"If a type implements an interface, then it can be passed wherever that interface is accepted, or assigned to a variable of that interface type."(code example with an interface definition, a type that implements it, a function with interface input and a main() that calls that function and assigns to the interface type)
"Once a type is passed as or assigned to an interface value, it's member variables cannot be accessed, except through/after a type assertion(link)."(the "A type can implement multiple interfaces" part goes after here)The language and structure here may not be best, but I hope the intent of my suggestion is clear. The idea being to demonstrate how interfaces are not the same as values.
Dne 5.6.2012 17:43 "si guy" <sjw...@gmail.com> napsal(a):
>
> I would add something like this to the description (right before the para that starts " A type can implement multiple interfaces "):
>
> "A type is said to implement an interface if it contains the method signatures listed in the interface definition. For example:"
> (code example with an interface definition and two types with method sets, one that implements the interface and one that doesn't and comments describing why/why not)
> "If a type implements an interface, then it can be passed wherever that interface is accepted, or assigned to a variable of that interface type."
> (code example with an interface definition, a type that implements it, a function with interface input and a main() that calls that function and assigns to the interface type)
> "Once a type is passed as or assigned to an interface value, it's member variables cannot be accessed, except through/after a type assertion(link)."
> (the "A type can implement multiple interfaces" part goes after here)
>
> The language and structure here may not be best, but I hope the intent of my suggestion is clear. The idea being to demonstrate how interfaces are not the same as values.
I don't like the idea of even mentioning type's field members. Not every type has them and type's data (its value) is fuly orthogonal to an interface. Actually, that orthogonality is the very concept of an interface (in Go).
-j
Isn't value already the accepted term in this case.