(no title)
implying | 3 years ago
However, the issue this brings up about structs / types not explicitly declaring which interfaces they implement is a real and unaddressed problem, especially in large codebases. The only tool that I'm aware of that finds implementations is GoLand, at steep JetBrains prices.
Figuring out what type an API is asking for should not require reading every line of code in the package, and slows down every developer of large Go projects
voidfunc|3 years ago
Over three years that's like $150-$200 total and it will save you so many headaches. But that's a steep price? Are you kidding? Why do developers hate tools that cost money when they save them time and allow them to do more?
kstenerud|3 years ago
A language that depends too much on IDE integration for usability is a real problem, because now you have tool fragmentation as everyone goes different routes with varying levels of success to fix the deficiencies in your language. In the end you end up rolling your own tools as I have done, which is the absolute WORST of all worlds.
Go was supposed to be simple, but all it succeeded in doing is shifting the complexity elsewhere and calling mission accomplished. When you're designing a language, it's VERY important to understand the difference between the emergent complexity of the domain, and the inherent complexity of your design. The latter can be fixed, the former can only be managed - in ways that are already well researched (or just swept under the rug, as go has done).
Too much magic and too much "clever" re-purposing of existing paradigms (file names, capitalization, implicit contracts, etc) makes for an infuriatingly bad design.
srer|3 years ago
I like working with Free and Open software much more than proprietary software. I think it's important for society, and I have more fun that way too!
Also the payoff for me has been very good, I can learn emacs once and enjoy using it for the rest of my life for all significant written language tasks on a computer.
Perhaps I could be a little more efficient if I were using a jetbrains IDE, but then I wouldn't like what I was doing as much. Enjoying what I do, even if it may look slightly contrived to others, is important in me achieving results at work.
faitswulff|3 years ago
xigoi|3 years ago
implying|3 years ago
bmitc|3 years ago
dehrmann|3 years ago
beebmam|3 years ago
But I'm not sure any IDE is worth $90/year when VS Code is free. The extensions for VS Code are next-level, especially the SSH extension. No other IDE comes remotely close to how well that extension works for its use case.
AtlasBarfed|3 years ago
sanderjd|3 years ago
prmoustache|3 years ago
richardsondrew|3 years ago
You can do this with a line of code below the struct definition, something like:
The compiler will also generate helpful errors if the struct doesn't implement the interface.Not requiring struct definition is a great feature in golang. I'm able to add an interface to a struct defined in another library to inject a different implementation for unit tests.
thiht|3 years ago
mseepgood|3 years ago
No, it's not. It's one of the best features, and I wish every language did this. At least TypeScript does it, too.
sam0x17|3 years ago
gabereiser|3 years ago
skybrian|3 years ago
When would you want to look for all implementations of an interface? Is this something like an abstract syntax tree?
grey-area|3 years ago
I’ve developed large Go codebases and never had this problem so your last sentence is false. In addition this is not an issue other go developers I’ve spoken to have ever worried or talked about.
serial_dev|3 years ago
Isn't it a feature? You can have a "writer" as long as it can "write", and then use that writer anywhere where a function expects a writer?
richardwhiuk|3 years ago
sudo_chmod777|3 years ago
So are you trying to find implemented interfaces or interfaces' implementors?
Former: In Vim I can use `:GoImplements`, which internally calls `guru` I guess.
Latter: `gopls` supports this.
I agree it's still a pain that one can not tell directly from code what interfaces a struct implements tho.
thegeekpirate|3 years ago
Beltalowda|3 years ago
Alan Donovan's guru tool could do this, but it kind of broke with modules and it was never updated and deprecated in favour of gopls. I don't know if gopls added this yet (I never really found a use for it).
I don't think it's very hard to write a tool for this though; parsing Go code is fairly easy and the stdlib provides a decent API for it. I think you could have a functional tool in a day if you wanted to, although without any caching it might be a little bit slow on larger code bases.
BreakfastB0b|3 years ago
zbobet2012|3 years ago
Firstly You can literally just use one of the dozens of go lsps or code tools to search for API invocations to find what structs are passed/called into it. More importantly if you need to know you've written bad code. The entire point of an interface is that you SHOULDN'T need to know the underlying type. If you do you've violated the entire point. Just pass concrete ones. I've written Go for years and never had a problem with this, even in large open source projects like Kuberenetes.
Secondly, the criticism about flipping return values order/meaning isn't a criticism of interface being structurally typed (https://en.wikipedia.org/wiki/Structural_type_system). If you return int, int and the second int "should be even", you should have defined a type "Even" and returned int, Even*. Systems which are structurally typed can demonstrate functional extensionality and (https://github.com/FStarLang/FStar/wiki/SMT-Equality-and-Ext...) and check whether you've flipped the arguments, which would be a more valid criticism (but such checks are expensive and conflict with compile time requirements). Also Java has the same problem, if you define two interfaces with the same method signature and a single class implements both you can't disambiguate.
Thirdly, the structural typing has a huge advantage, namely looser coupling and more tightly defined interfaces. If you follow the "accept interfaces return structs" go idiom, you'll see why. An open source library that does so leaves their returned structs open to be used by consumer code, that itself uses interfaces, without modification required. This means most go code has small, tightly defined interfaces, where every function on the interface is invoked in the relevant function.
For example if you have a library with this definition:
type Baz struct {}
func (b Baz) Foo(){} func (b Baz) Bar(){}
I can use Baz in my code like so:
type Fooer interface { Foo() }
func DoSomething(f Fooer) { }
And use the underlying library, while being decoupled from it, without having to modify it.
Fourthly: You can explicitly say a type implements an interface...
* A good study: https://blog.boot.dev/golang/golang-interfaces/
* In Idris we would do:
even : Nat -> Bool even Z = True even (S k) = odd k where odd Z = False odd (S k) = even k
int -> even doubler a = 2 * a
X6S1x6Okd1st|3 years ago
https://go.dev/play/p/VCcrSXT59w0
benhoyt|3 years ago
raxxorraxor|3 years ago
To be fair, most APIs need documentation and code is just plainly not enough. At least if we are talking about specialist interfaces that aren't just another web framework.
saturn_vk|3 years ago