Stunned by Go
how-bazaar.blogspot.co.nz
Stunned by Go
1–10 of 115 posts
Re: Stunned by Go
#2It'll be interesting to see if someone familiar with Go has a response to this, but from the blog post it doesn't appear that this contract is being habitually violated, only that it can be, which is still a problem in practice.
Re: Stunned by Go
#3Re: Stunned by Go
#4Re: Stunned by Go
#5In large part this is because Go's type system is not very expressive. I would just like to point out that OCaml did the same things as Go (i.e. structural sub-typing). But with (global) type inference. And variants (including structural subtyping for those too). And generics (parametric polymorphism). Years before Go was developed.
In OCaml, this sort of thing probably would be much less likely to come up. After having used the OCaml object system a bit (but still more than most people!), I am actually very happy with it. It certainly has issues--oh boy, does it ever--but the issues are superficial. They are the result of very limited manpower in the project, not fundamental shortcomings of the design.
In OCaml, the compiler can figure out what methods you used without your telling it. So it would automatically realize that the function called the close method, and infer the appropriate type. You wouldn't even have to write an interface (called a class type in OCaml) for it. If you did write an interface, but it did not expose a close method, the code would give you a type error.
I suppose you could try to do some sort of runtime casting and duck-typing, but I am not sure how. It would certainly not be a common thing to do, at all! Instead, the type would reflect exactly how the object is used in the function. It would be more explicit, more predictable and safer.
And, harping back on the same theme, it would be fully inferred for you.
The best of both worlds, really.
Re: Stunned by Go
#6The fix is to document that Close is called: https://codereview.appspot.com/11432044/
Re: Stunned by Go
#7Anyone proficient in GO would care to provide the minimal code that illustrate that extremely weird behavior ? I find that post so disturbing that i still believe i've missed something.
http://golang.org/src/pkg/io/io.go?s=11741:11801#L336
Line 336. io.Copy takes a writer and a reader, but actually asserts whether they implement ReaderFrom/WriterTo, then use their methods, ReadFrom and WriteTo, if they do. (Same thing with the http package checking if the reader implements Closer, and calling Close if it does, though admittedly 'we should be able to call Close' is a much more unsafe assumption than 'if it implements ReadFrom, and it has the right type signature, we can just call that function instead'.)
The reason it doesn't take values implementing the interfaces ReaderFrom and WriterTo is that io.Copy works even if you don't implement those interfaces.
It's an unfortunate and regrettable predicament, but it's not something that comes up a lot. As others have mentioned in this thread, Go certainly isn't a language with referential transparency by any means--the type system provides minimal sanity checking, and the language itself is memory-safe, but it's not trying to be a "high-assurance language."
Re: Stunned by Go
#8Wow, this is pretty unfortunate. Also a very good example of why so many people maintain that Go is not nearly as statically typed as languages like Haskell or OCaml: casting (essentially subverting the type system) is very common, and limits most of the type system's advantages. In large part this is because Go's type system is not very expressive. I would just like to point out that OCaml did the same things as Go…
I'm confused why "so many people maintain that" -- not because its a position I disagree with, because its not really a controversial position such that you'd need to "maintain" it.
Go is, pretty overtly C-like, but with some language-level concurrency features, plus type system features -- interfaces and methods and reflection -- to support OOP (though its definitely not a class-based OO language) and dynamic typing, plus GC, plus filing some of the sharp edges off of pointers.
It doesn't even begin to pretend to be like OCaml or Haskell in terms of strict typing.
Re: Stunned by Go
#9So if I implemented my own object with a Reader interface and passed it to this HTTP library, could it find some other method on my object named Close() and it could call it?
Is it pure duck typing happening here, or is the HTTP library looking for a commonly-defined interface with documented semantics for Close()?
Re: Stunned by Go
#10> The standard http library was calling Close on my io.Reader. This is not expected behaviour when the interface clearly just takes an io.Reader (which exposes one and only one method Read). So if I implemented my own object with a Reader interface and passed it to this HTTP library, could it find some other method on my object named Close() and it could call it? Is it pure duck typing happening here, or is the HTTP…
If a type has a Close() method, then it is a Closer. The code that tries to cast it to a Closer will succeed. So to answer your question, it doesn't matter what the semantics of your Close() method are, it will succeed solely based on the fact that your type has a method with that name.