Thanks right, technically Go supports a structural type system* which is a similar to, but different than duck typing. But the Go community often refers to Go as being duck-typed due as that term is more familiar to people coming from languages like Python.
Can you clarify why it can't be duck typing if it's static? For instance, in F# you can declare a function that can take any type that provides a specific method name and signature. You can pass any object to such a function as long as it has that method - there's no other similarities required in the types you pass to it. How is that not "duck typing"?
I think you could actually do this in C++, but not with runtime polymorphism. I think you should be able to define extractBody and extractTextBody as template functions. If the signatures (return type, name and parameters) of the functions of the interface are identical - and it looks like they are - then this would work as a C++ template function. Behind the scenes, the compiler would generate two different kinds of functions for you, one for each of the types you called it with.
(Please note I'm not saying this would be better, just pointing out that it's possible.)
Yes, it's possible to use C++ templates to accomplish this. But you'd still miss other features because the types of Header and MIMEHeader are not actually unified. Go would let you statically type-check at compile time, but also understand those types are the same (as "emailHeader") at runtime, so you could do this:
x := ... // Header, MIMEHeader, or whatever you want
v, ok := x.(emailHeader)
if !ok {
fmt.Println("It's not compatible with Get(string) -> string")
}
For runtime polymorphism you'd have to define a wrapper of some sort, which in this specific case would be completely trivial since it's only one method. In more complex cases it gets pretty awful compared to the Go version, but it's not impossible (although AFAIK if the methods you care about have different names in the different implementations you'll need a wrapper even in Go).
Great article. As a side note, you might want to consider reformatting the blog post using syntax highlighting to make the code more readable and obvious. Thanks for posting though.
I've been working in C/C++ for over 20 years now. I started playing with Go about two months ago, burnt through the tutorial in 2 afternoons, and was hooked. It's very easy coming from a C background, it has constructs I'm familiar with, but also picks out the best parts of Python-ish SmallTalk-ish languages, while still being compiled.
I'm looking forward to when I can write Android apps in it, instead of mucking around with Java.
I went into the article thinking it was going to be about some way of renaming functions or something. Probably just my limited internal definition of the word refactor. After reading I would say Go has a cool built in way of using the adapter pattern. More interesting than renaming functions.
Actually, Go makes this somewhat easy too. Check this: http://blog.golang.org/2013/01/go-fmt-your-code.html It's possible to do context aware source code substitutions. Works great. (Not that it's something new or groundbreaking though, just relevant to your expectation)
Folks, recursive data-strcutures are CS101. Processing them is also a trivial, template-filling exercise. First you specify the (recursive) datatype, consisting of the simple "leaf" elements, along with the complex forms. Then you write your program consisting of a series of mutually recursive functions.
What matters is that once you specify the data type, the code that processes it follows immediately from the grammar.
I think you're slightly missing the point. It's not the use of recursive functions or data structures that is interesting. It's that, in Go, you can add a new type which covers externally defined types, and those types are now instances of the new type automatically. In other languages, to unify two types like this with a common interface, you would probably have to define a wrapper class which proxies the calls to the real objects. Even though the methods for the two classes have matching type signatures and do the same thing already.
Haxe has a similar (but not quite identical) bag of tricks which act as a "gradient" of stronger/weaker couplings.
You have to specify that an implementation can use a specific interface, but you may overload an implementation with multiple interfaces. http://haxe.org/manual/2_types#interfaces
I don't completely seee the point - in more established OO languages you'd make two one-line wrapper classes that both implement Get() and be done with it. Not stuck at all.. Extra indirection, yes, but is your performance going to block on parsing mime mails?
I assumed you would do the same thing as was done in the article.
Create an interface and have a function that takes implementations of that interface as a parameter. The difference would be that in Java or C# you would need to explicitly mark Header and MIMEHeader as implementing emailHeader
I don't think much will come of discussing what is/isn't possible in a language given that they are all Turing complete. Usually posts like this are used for discussing what's easier or cleaner in a language.
For what it's worth I think having dynamic interfaces is cool, but I can only really think of one place I have actually relied on that capability.
Mostly the "dynamic"ness is nice for decoupling code. You can have a package(A) containing a function that takes an interface a parameter, a package(B) containing an implementation of the interface in A and a package (C) which passes the implementation in B to the function in A.
Given this situation C needs to import A and B but neither A nor B need to know about each-other.
> To be fair, you can do this in java by adding to Header and MIMEHeader "implements emailHeader".
Not if you aren't the author of the package. (You could modify your local copy, but requiring a fork is always a pain.) Without the ability to modify the sources, you would have to create custom subclasses of Header and MimeHeader which implement that interface, and find some way to make the library generate your custom subclasses instead of the defaults.
One potential downside is that it's a lot harder or more computationally expensive to figure out class/interface relationships in IDEs or other tools. (I haven't used Go, though, so I'm not sure what kinds of tools are available for it.)
Generally, "what classes implement this interface?" is a question I need to ask quite a bit when working with Java in Eclipse. The simple way in Go (looking through all classes) would generate a bunch of false positives in a large enough codebase, and the more precise way (looking through all implicit casts everywhere to find all classes that are implicitly casted to the interface) is probably pretty slow or memory intensive and could potentially have false negatives (e.g. implementing classes that haven't been hooked up yet, and uses that aren't contained in your source tree).
There are other Eclipse operations that rely on this that would also be a lot harder to implement (in the same way they're implemented in Eclipse):
-"Find callers" on a class method includes calls to that method on superclasses and superinterfaces.
-"Rename method" automatically renames all methods with that name that are reachable through a path of implementer/interface relationships.
[+] [-] dons|13 years ago|reply
An aside, it is not "duck typing" if it involves a static type system.
[+] [-] voidlogic|13 years ago|reply
* http://en.wikipedia.org/wiki/Structural_type_system
[+] [-] cwzwarich|13 years ago|reply
[+] [-] MichaelGG|13 years ago|reply
[+] [-] scott_s|13 years ago|reply
(Please note I'm not saying this would be better, just pointing out that it's possible.)
[+] [-] bslatkin|13 years ago|reply
x := ... // Header, MIMEHeader, or whatever you want v, ok := x.(emailHeader) if !ok { fmt.Println("It's not compatible with Get(string) -> string") }
So, it's a nice mix of static and dynamic typing.
(ps: http://golang.org/ref/spec#Type_assertions)
[+] [-] plorkyeran|13 years ago|reply
[+] [-] pdhborges|13 years ago|reply
[+] [-] VeejayRampay|13 years ago|reply
[+] [-] mseepgood|13 years ago|reply
Syntax highlighting is less common in the Go community since Rob Pike called syntax highlighting juvenile :D https://groups.google.com/d/msg/golang-nuts/hJHCAaiL0so/kG3B...
He also argued against keyword emphasizing: http://www.lysator.liu.se/c/pikestyle.html
[+] [-] zenocon|13 years ago|reply
[+] [-] shurcooL|13 years ago|reply
[+] [-] Tekker|13 years ago|reply
I'm looking forward to when I can write Android apps in it, instead of mucking around with Java.
[+] [-] jbrackett|13 years ago|reply
[+] [-] eknkc|13 years ago|reply
[+] [-] pkulak|13 years ago|reply
[+] [-] mahmud|13 years ago|reply
What matters is that once you specify the data type, the code that processes it follows immediately from the grammar.
[+] [-] adam-a|13 years ago|reply
[+] [-] chipsy|13 years ago|reply
You have to specify that an implementation can use a specific interface, but you may overload an implementation with multiple interfaces. http://haxe.org/manual/2_types#interfaces
You can use structure types instead of classes and rely on structural subtyping to match them. http://haxe.org/manual/2_types#structural-subtyping
And you can ask for dynamic type behavior wherever the code needs it. http://haxe.org/ref/dynamic
[+] [-] zcrar70|13 years ago|reply
[+] [-] skrebbel|13 years ago|reply
[+] [-] Djehngo|13 years ago|reply
Create an interface and have a function that takes implementations of that interface as a parameter. The difference would be that in Java or C# you would need to explicitly mark Header and MIMEHeader as implementing emailHeader
I don't think much will come of discussing what is/isn't possible in a language given that they are all Turing complete. Usually posts like this are used for discussing what's easier or cleaner in a language.
For what it's worth I think having dynamic interfaces is cool, but I can only really think of one place I have actually relied on that capability.
Mostly the "dynamic"ness is nice for decoupling code. You can have a package(A) containing a function that takes an interface a parameter, a package(B) containing an implementation of the interface in A and a package (C) which passes the implementation in B to the function in A.
Given this situation C needs to import A and B but neither A nor B need to know about each-other.
[+] [-] 6ren|13 years ago|reply
Structuring typing seems simpler. Are there any downsides? (apart from two types having an identical method signature by coincidence)
[+] [-] LeafStorm|13 years ago|reply
Not if you aren't the author of the package. (You could modify your local copy, but requiring a fork is always a pain.) Without the ability to modify the sources, you would have to create custom subclasses of Header and MimeHeader which implement that interface, and find some way to make the library generate your custom subclasses instead of the defaults.
[+] [-] alangpierce|13 years ago|reply
Generally, "what classes implement this interface?" is a question I need to ask quite a bit when working with Java in Eclipse. The simple way in Go (looking through all classes) would generate a bunch of false positives in a large enough codebase, and the more precise way (looking through all implicit casts everywhere to find all classes that are implicitly casted to the interface) is probably pretty slow or memory intensive and could potentially have false negatives (e.g. implementing classes that haven't been hooked up yet, and uses that aren't contained in your source tree).
There are other Eclipse operations that rely on this that would also be a lot harder to implement (in the same way they're implemented in Eclipse):
-"Find callers" on a class method includes calls to that method on superclasses and superinterfaces.
-"Rename method" automatically renames all methods with that name that are reachable through a path of implementer/interface relationships.
[+] [-] Benferhat|13 years ago|reply
[0] http://www.readability.com/shorten
[+] [-] Uchikoma|13 years ago|reply
And while Scala has "structural typing" I'd also wish it would implement it the way Go does not with explicit methods.
[+] [-] knodi|13 years ago|reply
[+] [-] signa11|13 years ago|reply
[+] [-] Ramonaxvh|13 years ago|reply
[+] [-] martinced|13 years ago|reply
I was expecting to see some advanced Emacs / vim or whatever texteditors or IDE support for refactoring Go code.
Not just manual extraction of common behavior into a tinier interface.
But I'm more and more impressed by Go and may give it a try one of these days.
[+] [-] est|13 years ago|reply
How could anyone refactor something like this in Python
getattr(myobj, 'myprop', None)
Where mypropis dynamically generated?
[+] [-] hakaaaaak|13 years ago|reply
Vim plugin. No refactoring available yet: http://go-lang.cat-v.org/text-editors/vim/
Eclipse plugin. No refactoring available yet: http://code.google.com/p/goclipse/
Others (afaik- no refactoring available yet): http://go-lang.cat-v.org/text-editors/