Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

As a reliability engineer I disagree. It's nice to know that your code has few antipatterns in it by design. "Blunt knives" is a really bad way to think about it. You have plenty of very sharp knife, and they are easy to use and have clearly defined scope and purpose.

A knife that's sharp and unweildly makes me nervous even in the hands of an expert. Keep unweildly constructions out of go!



> It's nice to know that your code has few antipatterns in it by design.

But does making the language incredibly simplistic really do this?

The way I see it some devs will have more antipatterns than other devs - and this will be the case even if you make the language as simplistic as possible. The solution here is not to make the language simpler, but to rather look at why people are using anti-patterns.

> "Blunt knives" is a really bad way to think about it.

Is it? Most of these things result in having to write more code and does not really prevent you from doing something stupid. I'm not even sure it reduces the surface area of all possible stupid things in a meaningful way.

> Keep unweildly constructions out of go!

What makes a construct unweildly?


"Most of these things result in having to write more code and does not really prevent you from doing something stupid."

I see this accusation a lot, but it does not manifest in my code after years of usage (and, yes, I know Haskell and am pretty good with it, so it is not a lack of knowledge of the possibilities).

If you write Go in Go, it's a pretty good language for production code. It doesn't give you all the goodies, but it's got some stuff of its own that's pretty cool, like it's baby structural typing (I think it is still massively underestimated how useful this is in practice over languages that require you to declare conformance to an interface, this has major second- and third-order consequences to code bases), the syntactic ease of composition, and the select statement (channels on their own, meh, but put them in a select statement and they're very nice). On the whole I'd say it's usually a bit less slick than Python but noticeably more pleasant to work with than Java.

If you, on the other hand, want to write Haskell in Go, or C++ in Go, or Javascript in Go, you're in for a bad time. Certainly from this angle Go is a nightmare. It's not a good idea in any language, but it's fatal in Go.

(I'll also say it's hard to put a finger on all the details why, but it's a really easy language to refactor in. I've been handed 5,000-ish lines of "sorta OK code" from various code bases in Perl, Python, Go, and Java in my job, and of the four, Go is by far the easiest to go into and brush it up to a higher quality level.)


I'll also say it's hard to put a finger on all the details why, but it's a really easy language to refactor in

I'd be interested in some data on exactly what refactoring operations are most common in your practice. Back in the Smalltalk Refactoring Browser heyday, "Extract Method" was by far the most common operation. I'm not so sure that's going to be the case for golang. My situation might be idiosyncratic, but I find myself thinking, I did this with a struct, but this really should have been an Interface!


In these particular bits of code, the "brushing up" I'm referring to is removing global variables and init functions (or local equivalents) and putting them into structs with New functions (in Go, local equivalents in the other languages), adding the local equivalent of dependency injection (even with the framework the code was using, most difficult in Java) and making it so development test code was not directly hitting production infrastructure with that (!). Mostly I wasn't doing "extract method" types of refactoring in these particular cases.

Go isn't necessarily the easiest in any particular category, but it probably wins globally. Python is the easiest to refactor some code without making any modifications to some code that uses it, with all of its magic methods and such, but if you keep doing that to a given code base, after a few rounds of that you get into the sorts of situations where you really have no idea what "a.b = c.d(e.f, f.g())" is really doing. On the other hand, you end up missing that stuff when you're trying to refactor the Perl, which is nowhere near as good at that stuff. Java's the worst one, and I have to admit I ended up giving up even trying to clean it up; even with IDE support it takes a lot more cognitive effort than Go, the changes run deeper and spread farther, and in the end, you only end up with as much as you would have gotten with Go, not anything particularly better.

It's funny; on the one hand I'm all about how the cognitive affordances of programming languages produce different results, on the other hand, when it really comes down to it, an awful lot of code is written in a way that means those affordances don't even matter because it's just too darned easy to assume the entire rest of your infrastructure is up and it's OK to bring in production resources because they're there and they're going to work... and what can your language really do about that? Who cares if that code is written with mutable or immutable variables? We lost at a much deeper level than that.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: