Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.
Sign upproposal: Default implementation for interface #16254
Comments
mkideal
changed the title
Default implementation for interface
proposal: Default implementation for interface
Jul 3, 2016
This comment has been minimized.
This comment has been minimized.
mezoni
commented
Jul 3, 2016
•
What means type Transaction interface {
Begin()
Exec() error
End()
// Process() error
}Sorry, but I cannot understand how an |
This comment has been minimized.
This comment has been minimized.
mkideal
commented
Jul 3, 2016
|
Did you know trait Transaction {
fn begin(&self);
fn exec(&self) -> Result;
fn end(&self);
fn process(&self) -> Result {
...
}
}And class Transaction {
public:
virtual void begin() = 0;
virtual int exec() = 0;
virtual void end() = 0;
int process() {
...
}
}; |
This comment has been minimized.
This comment has been minimized.
mezoni
commented
Jul 3, 2016
Mixins, traits used in OOP. P.S. I think that these terms are not an applicable to the Go language.
The Go language supports only a value based types. |
This comment has been minimized.
This comment has been minimized.
creker
commented
Jul 3, 2016
|
You can achieve kind of the same thing with embedding. Here's an example
https://play.golang.org/p/MHo14zUpq1 Given that interfaces are implemented implicitly, it would be difficult to track down where exactly all the methods are implemented with this proposal. |
This comment has been minimized.
This comment has been minimized.
mkideal
commented
Jul 3, 2016
•
|
In essence, For example, type Reader interface {
Read(b []byte) (n int, err error)
}
func ReadFull(r Reader, buf []byte) (n int, err error) { ... }Can we use func (r Reader) ReadFull(buf []byte) (n int, err error) { ... }It's just a syntactic sugar Certainly, Any structure which implements |
This comment has been minimized.
This comment has been minimized.
starius
commented
Jul 3, 2016
|
If your proposal is implemented, one will be able to add any methods to any types by creating an empty interface with desired methods with default implementation, because any type satisfies the empty interface. |
This comment has been minimized.
This comment has been minimized.
mkideal
commented
Jul 3, 2016
Can you tell how to to this? If you write: type Any interface {}
func (any Any) MyMethod() { ... }In this case, |
This comment has been minimized.
This comment has been minimized.
|
What problem does this proposal solve? |
This comment has been minimized.
This comment has been minimized.
mezoni
commented
Jul 4, 2016
Possible the idea of this proposal (default implementation for interface) is useful but this is impossible in the Go language, with it it structural type system. This is because nominal subtyping means that one type is a subtype of another if and only if it is explicitly declared to be so in its definition. In structural typing, an element is considered to be compatible with another if, for each feature within the second element's type, a corresponding and identical feature exists in the first element's type. That is, this is impossible to have a default implementation only because it (implementation of the interface, as the first element) should be defined explictly in the second element (interface implementer) to be compatible with the interface, as the first element. |
This comment has been minimized.
This comment has been minimized.
starius
commented
Jul 4, 2016
I'll continue your example: type Any interface {}
func (any Any) MyMethod() { ... }
type Foo struct {
// some members
}
func main() {
var foo Foo
foo.MyMethod()
}In this example, Foo satisfies Any interface and (according to your proposal) gets default method MyMethod from it. |
This comment has been minimized.
This comment has been minimized.
mezoni
commented
Jul 4, 2016
•
|
Possible an author want to say about the following: type Foo interface {
Baz() Baz
SomeFoo() Baz
}
func (r Foo) SomeFoo() Baz {
return r.Baz()
}
type foo struct {
baz Baz
}
func (r *foo) Baz() Baz {
return r.baz
}
// Abstract method, to be compatible with: interface { SomeFoo() Baz }
abstract func (r *foo) SomeFoo() Baz
func main() {
var foo Foo
foo = &Foo{}
baz := foo.SomeBaz()
}
|
This comment has been minimized.
This comment has been minimized.
mezoni
commented
Jul 4, 2016
|
The above example is a trivial example but in a real life it can save a lot of time. Eg. type Expr interface {
// Some members
String() string
}
type UnaryExpr interface {
Expr
GetExpr() Expr
}
type PrefixExpr interface {
UnaryExpr
GetPrefix() string
}
// Default impl
func (r PrefixExpr) String() string {
retrun Sprintf(%s%s, r.GetPrefix(), r.GetExpr())
}
type NotPredicateExpr struct {
}
abstract func (r *NotPredicateExpr) String() string
func (r *NotPredicateExpr) GetPrefix() string {
return "!"
}Currently this is impossible. // Somewhere not far from `type PrefixExpr interface`
// Implementation of the `type PrefixExpr intrface { String() } `
func PrefixExpr_String(r PrefixExpr) string {
retrun Sprintf(%s%s, r.GetPrefix(), r.GetExpr())
}
// Should take into account about the existing `PrefixExpr_String` default implementation
func (r *NotPredicateExpr) String() string {
return PrefixExpr_String(r)
}
Which is not a very graceful. |
This comment has been minimized.
This comment has been minimized.
mezoni
commented
Jul 4, 2016
|
Another interesting approach: type Foo interface {
String()
}
// Default impl
func (r Foo) String() string {
return "Foo"
}
type Baz interface {
Foo
}
// Default impl
func (r Baz) String() string {
return "Baz"
}
type baz struct {
}
func main() {
var baz Baz
var foo Foo
baz := &baz{}
fmt.Prinln(baz) // => "baz"
foo := &baz{}
fmt.Prinln(foo) // => "foo"
}How this works? The The |
This comment has been minimized.
This comment has been minimized.
|
I have no idea what this proposal is proposing. There are too many Foo's and Bar's and so on to make sense of what you are proposing. Can you please write a piece of code that uses this feature, it does to have to compile, but it has to show how to this would be used in the real world. Thanks Dave |
This comment has been minimized.
This comment has been minimized.
|
What would fmt.Println(&baz{}) print? In other words if a type implements two interfaces that have default
|
This comment has been minimized.
This comment has been minimized.
mezoni
commented
Jul 4, 2016
Do you need a very easy example for the very small real world? I think thet this comment explains a lot: // Somewhere not far from `type PrefixExpr interface`
// Implementation of the `type PrefixExpr intrface { String() } `
func PrefixExpr_String(r PrefixExpr) string {
retrun Sprintf(%s%s, r.GetPrefix(), r.GetExpr())
}
// Should take into account about the existing `PrefixExpr_String` default implementation
func (r *NotPredicateExpr) String() string {
return PrefixExpr_String(r)
} |
This comment has been minimized.
This comment has been minimized.
The former would be preferred. Re. Your example, I don't understand what that is doing or why go need to change to support that. Is this a proposal that functions can be accessed as methods on a type assuming the reciever matches the first argument of the function? D has this. |
This comment has been minimized.
This comment has been minimized.
mezoni
commented
Jul 4, 2016
•
|
OK. |
This comment has been minimized.
This comment has been minimized.
dup2X
commented
Jul 4, 2016
|
No need to do this. |
This comment has been minimized.
This comment has been minimized.
|
My understanding of the proposal is to define methods on concrete types by defining them on interfaces that the types satisfies. In the example below method Println is defined for stringer extending the method set of type A satisfying stringer. The intention seems to be to save work if a method can be implemented using other functions of a type.
It doesn't compile because an interface type cannot be a receiver. On top
|
This comment has been minimized.
This comment has been minimized.
I second this request. Alternatively, please point to a real piece of Go code and show how it could be better written using this feature. All these tiny hypothetical examples demonstrate the what, but not the why. The "why' is critical. |
This comment has been minimized.
This comment has been minimized.
mezoni
commented
Jul 5, 2016
If you ask me then I already wrote that I was wrong in my judgements. |
This comment has been minimized.
This comment has been minimized.
|
@mezoni thanks for making that clear. My comments are addressed to anyone interested in pushing this proposal forward. |
This comment has been minimized.
This comment has been minimized.
mkideal
commented
Jul 5, 2016
•
|
Here is an exmaple from package // src/io.go
type Writer interface {
Write(b []byte) (n int, err error)
}
type stringWriter interface {
WriteString(s string) (n int, err error)
}
func WriteString(w Writer, s string) (n int, err error) {
if sw, ok := w.(stringWriter); ok {
return sw.WriteString(s)
}
return w.Write([]byte(s))
}But, if we have this feature( type Writer interface {
Write(b []byte) (n int, err error)
}
func (w Writer) WriteString(s string) (n int, err error) {
return w.Write([]byte(s))
}The strange interface |
This comment has been minimized.
This comment has been minimized.
|
I'm sorry, I cannot see how you could write down the rules for how the I vote to close this proposal. On Tue, 5 Jul 2016, 15:42 王仕晋 notifications@github.com wrote:
|
This comment has been minimized.
This comment has been minimized.
mkideal
commented
Jul 5, 2016
|
Thanks, bye bye! |
mkideal commentedJul 3, 2016
•
edited
Can we support default implementation for interface?
Here is an example:
Now, if I have a struct
DBTransactionwhich implementsBegin(),Exec() errorandEnd()methods(i.e. implements interfaceTransaction), thenDBTransactionautomatically ownsProcess() errormethod while it's used asTransaction.