40 ms·
It is ridiculously easy to refactor Go
- chipsy 14y agoHaxe 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 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 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 http://haxe.org/ref/dynamic
- jbrackett 14y agoI 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.
- eknkc 14y agoActually, Go makes this somewhat easy too. Check this: http://blog.golang.org/2013/01/go-fmt-your-code.html 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)
- pjmlp 14y agoComparing gofmt with what refactoring tools allow is too far fetched.
- redbad 14y agoAre you aware of gofmt's rewrite rules? http://golang.org/cmd/gofmt/#hdr-Examples http://golang.org/cmd/gofmt/#hdr-Examples Pretty powerful stuff.
- pjmlp 14y agoI am. Refactoring is much more than that: - create functions and methods from code snippets - merge duplicate code - Semantic renaming of method names/variables/functions without affecting the same name being used in a different context - convert field direct access to wrapper functions/methods - remove dead code - add missing code to interface/module/class where it is being applied - validation of code references in comments - ...
- pkulak 14y agoI thought it was going to be about go-fmt, which is really cool.
- dons 14y agoWelcome to bounded polymorphism, circa 1989. A young Wadler would be pleased. An aside, it is not "duck typing" if it involves a static type system.
- voidlogic 14y agoThanks 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. * http://en.wikipedia.org/wiki/Structural_type_system http://en.wikipedia.org/wiki/Structural_type_system
- cgag 14y agoIsn't duck typing what would let it work without creating that new interface? Do you say it's like duck typing because you don't have to mention anywhere that your two previous interfaces satisfy your new interface?
- mseepgood 14y agoDuck typing: "When I see a bird that walks like a duck and swims like a duck and quacks like a duck, I call that bird a duck." Translated to Go: "When I see a type with methods that satisfy this interface, then it implements this interface."
- MatthewPhillips 14y agoBut you still have an explicit interface.
- VeejayRampay 14y agoGreat 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.
- mseepgood 14y agohttp://kyleisom.net/blog/2012/10/17/syntax-off/ http://kyleisom.net/blog/2012/10/17/syntax-off/ 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/kG3BHV6QFfIJ https://groups.google.com/d/msg/golang-nuts/hJHCAaiL0so/kG3B... He also argued against keyword emphasizing: http://www.lysator.liu.se/c/pikestyle.html http://www.lysator.liu.se/c/pikestyle.html
- quadhome 14y agoThere's syntax highlighting and various other editor support installed with and included in the Go source tree: http://code.google.com/p/go/source/browse#hg%2Fmisc http://code.google.com/p/go/source/browse#hg%2Fmisc Rob Pike may have an issue with it, but the Go team most certainly does not.
- aroberge 14y agoColour can help carry information. It is a lot easier to identify strings if you use colours rather than just rely on seeing opening and beginning quotes. I know that I find it very useful - and even more so my choice of colours for comments making them blend more in the background and making it easier to forget. I would liken it to the use of boldface letters to represent matrices (or vectors) in some math textbook: without this convention, you have to rely a lot more on memory to know what each symbol represents. Mathematicians and physicists everywhere have found this to be useful. When you have a huge majority of programmers using syntax highlighting, you have to ask yourself if there is not an instrinsic value to its use and, if so, perhaps try to use it to communicate with the larger community, rather than adopting a cliquish practice.
- 14y ago
- scott_s 14y agoI 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.)
- pdhborges 14y agoAnd he doesn't even have to define an interface.
- scott_s 14y agoConcepts were an attempt to allow people to explicitly state what that interface is: http://en.wikipedia.org/wiki/Concepts_(C%2B%2B) http://en.wikipedia.org/wiki/Concepts_(C%2B%2B)
- plorkyeran 14y agoFor 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).
- bslatkin 14y agoYes, 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") } So, it's a nice mix of static and dynamic typing. (ps: http://golang.org/ref/spec#Type_assertions http://golang.org/ref/spec#Type_assertions)
- Benferhat 14y agoOff-topic: I had to use Readability[0] to make your blog readable. [0] http://www.readability.com/shorten http://www.readability.com/shorten
- shurcooL 14y agoGo has really grown on me in the last few months, it's becoming my favourite language, coming from C++.
- Tekker 14y agoI'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.
- dualogy 14y agoExactly... the day Go compiles for mobile devices is the day I'll dig into mobile development. But the thing with mobile OSes is, you need a sane binding to the native GUI lib. However, it would be awesome to circumvent this and just be able to do what I can already do with GLFW and OpenGL across 3 different desktop OSes: open a blank window that's just a canvas for GPU (GL) commands. Seeing how OpenGL ES is on all smart phones, having an equivalent "mobile GLFW" library and GLES binding would be awesome and good enough to roll one's own snappy GUIs. Oh, all that only once Go compiles for said mobile OS / HW in the first place, which is probably still a few years off...
- Ramonaxvh 14y agoGo has been out for a while, it's really cool to see it finally starting to gain traction.
- knodi 14y agoI hope go 1.1 will be ready soon. A lot of goog stuff in it.
- zcrar70 14y agoTypescript allows you to do this also. It's extremely convenient.
- martinced 14y agoRefactoring is probably the one area where good IDEs shine the most. 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 14y agoI doubt it. How could anyone refactor something like this in Python getattr(myobj, 'myprop', None) Where mypropis dynamically generated?
- eru 14y agoWhat do you mean by refactoring a single line?
- hakaaaaak 14y agoIDea Go plugin. No refactoring available yet: http://plugins.intellij.net/plugin?pluginId=5047 http://plugins.intellij.net/plugin?pluginId=5047 Vim plugin. No refactoring available yet: http://go-lang.cat-v.org/text-editors/vim/ http://go-lang.cat-v.org/text-editors/vim/ Eclipse plugin. No refactoring available yet: http://code.google.com/p/goclipse/ http://code.google.com/p/goclipse/ Others (afaik- no refactoring available yet): http://go-lang.cat-v.org/text-editors/ http://go-lang.cat-v.org/text-editors/
- 6ren 14y agoTo be fair, you can do this in java by adding to Header and MIMEHeader "implements emailHeader". Structuring typing seems simpler. Are there any downsides? (apart from two types having an identical method signature by coincidence)
- LeafStorm 14y ago> 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.
- bslatkin 14y agoExactly
- alangpierce 14y agoOne 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.
- skrebbel 14y agoI 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?
- Djehngo 14y agoI 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.
- mahmud 14y agoFolks, 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.
- adam-a 14y agoI 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.
- Uchikoma 14y agoI wished for years for Java to determine "implements interface" by method checking not the way it does it currently. And while Scala has "structural typing" I'd also wish it would implement it the way Go does not with explicit methods.