Live data from Hacker News

Learning Go by porting a medium-sized web back end from Python

benhoyt.com

161–170 of 207 posts

Re: Learning Go by porting a medium-sized web back end from Python

#161

I can agree with most of the article, but for some it looks like we have not been using the same language ecosystem at all. Go really feels opinionated around the wrong things, in order to claim "simplicity" as a feature: - No generics just mean you're going to be handing interface{} all the way in your stack, it makes things more complex and less readable for no reason (and less safe) - error handling which is essen…

Your criticism would have been a lot better if you had pointed to an alternative.

Re: Learning Go by porting a medium-sized web back end from Python

#162

Earlier quoted context omitted.

>Writing in a fast compiled language is not premature optimization. If the fast compiled language is equally expressive and equally fast to write then no. Those things are rarely (if ever) the case, though. It's certainly not true in this case. Go appears to be about 30% less expressive.

Another way to look at it is that Go expresses additional things that you can't express with Python.

In Go it's impossible to make for...range support user-defined types, and you have to write out every loop the hard way (and rewrite any loop that was using a builtin type). In Python you just define __iter__. That's what's meant by expressive, you can write what you mean instead of having to explain yet again how it should be implemented.

Re: Learning Go by porting a medium-sized web back end from Python

#163

Earlier quoted context omitted.

Chances are, if you are using mocks in Go, you are doing it wrong. Functions should take interfaces (not interface{}, but interfaces that list methods) and return structs. In your tests, you create a fake that meets the interface and pass that to your function under test. If you have to test file io or DB interaction, you can either do the adapter pattern or, as I prefer, just actually use the filesystem and DB but w…

What's the difference here between a "fake" and a "mock"?

Might be splitting hairs. There are fakes, mocks, and stubs. Generally, mocks assert, stubs do not. Some folks define both stubs and mocks as fakes. This does not fit perfectly for Go. The "fake" in Go is just a struct that matches an interface but is purely for testing. It allows for dependency injection where you pass a fake designed for your test. It can have its own properties and helper methods, but the key thing is that it matches your interface. You don't make assertions against the fake like you would a mock. You assert against responses from your functions under test.

Example:

  >  type Bar interface{
  >     Walk() (int, error)
  >  }
  >  
  >  func Visit(b Bar) (string, error) { ... some code ...}
In the production code, you call Visit with some struct that matches the interface (has a Walk method). In tests, you create a new struct like fakeBar that also matches the interface. You can have your fakeBar return any string or error you like and you can verify that Walk behaves the way you need it to.

Hope that helps.

Re: Learning Go by porting a medium-sized web back end from Python

#164

I can agree with most of the article, but for some it looks like we have not been using the same language ecosystem at all. Go really feels opinionated around the wrong things, in order to claim "simplicity" as a feature: - No generics just mean you're going to be handing interface{} all the way in your stack, it makes things more complex and less readable for no reason (and less safe) - error handling which is essen…

Your criticism would have been a lot better if you had pointed to an alternative.

(Not the OP)

That's the problem, I see the following often suggested instead of Go:

Java - maybe if you use Spring Boot you can get around some of the boilerplate, but there is a ton of baggage in the ecosystem.

Clojure - This is really popular where I work but LISP + Java Ecosystem turn a lot of people off. Also, some people really want static typing (maybe Spec is good enough?)

Node/TypeScript - terrible concurrency, good for throwing something together that works rather quickly, good for cutting corners. Terrible memory, cpu profiling. As a professional node developer in the day job I could go on and on, but at least the type system is better than Go (too bad the concurrency story is so abysmal)

Elixir - not popular, but at least it's on BEAM VM and has lots of libraries. Not statically typed (yes you can use dialyzer). Never done anything with it, but apparently deployment is a pain.

I personally write JavaScript mostly because its ubiquity. It's good enough, until it's not.

Re: Learning Go by porting a medium-sized web back end from Python

#165
post #23

I can agree with most of the article, but for some it looks like we have not been using the same language ecosystem at all. Go really feels opinionated around the wrong things, in order to claim "simplicity" as a feature: - No generics just mean you're going to be handing interface{} all the way in your stack, it makes things more complex and less readable for no reason (and less safe) - error handling which is essen…

>- No generics just mean you're going to be handing interface{} all the way in your stack, it makes things more complex and less readable for no reason (and less safe) Depends on what you do. I've written a good chunk of go code and interface{} is the rare exception rather than the rule, usually employed where a user might supply arbitrary types (ie a unmarshaljson like function) But if you do a website or webapp, 99…

> But if you do a website or webapp, 99% of your code is not using interface{} in it's methods.

How do you deal with the lack of sets and trees? I believe those two data structures are frequently almost indispensable - even in the most boring mostly-CRUD web projects. And it's either type assertions on {}interfaces or go-generate based specialized implementations. Both feel odd to me. (Am I missing something?)

Re: Learning Go by porting a medium-sized web back end from Python

#166
post #39

What I've noticed, and personally experienced, about these porting projects is that they're generally a premature optimization but are a great way to learn a new language. The gains from a port are largely intrinsic in nature, residing with the programmers. However, systems and operations largely carry on just fine with the original language chosen. Only one story comes to mind where a programmer had a legitimate pro…

I ported a Groovy/Grails app to Java/SpringMVC once.

My technical motivations were more about moving away from Hibernate. Arguably there were plenty of reasons for leaving it as it was, though -- if I had known enough to be able to solve certain data access complexities back then, Grails was in many ways a better fit for the problem. The experience in a (more-or-less) functional language wouldn't have hurt any either.

The business motivation was simple: Java/SpringMVC programmers are (or were then) far more plentiful, so adding/replacing tech resources was made much simpler.

Re: Learning Go by porting a medium-sized web back end from Python

#167

Earlier quoted context omitted.

I feel like this is true for any language though. Once you write a well designed, well tested, and feature complete piece of software, you can deploy it and forget about it unless the server it's running on breaks. Go isn't special in that regard, unless there's something that makes Go easier to write, test, or deploy, which might be the case, but you haven't supported that.

Any language that compiles to a static binary, sure.

Even if not. Depending on your paranoia, lockfiles or containers or bazel solve that problem.

Re: Learning Go by porting a medium-sized web back end from Python

#168
post #107

I can agree with most of the article, but for some it looks like we have not been using the same language ecosystem at all. Go really feels opinionated around the wrong things, in order to claim "simplicity" as a feature: - No generics just mean you're going to be handing interface{} all the way in your stack, it makes things more complex and less readable for no reason (and less safe) - error handling which is essen…

Context: I've been programming in Go full-time for the last 2 years and come from a Python and C# background. > No Generics The lack of generics was something I was hung up on, too, but TBH I haven't found myself reaching for them for a while now. > Error handling This is not a problem for me, either. I can easily handle different `error` types and if I want to provide more context I pull in github.com/pkg/errors > g…

> The lack of generics was something I was hung up on, too, but TBH I haven't found myself reaching for them for a while now.

I mean, if you lose an arm you probably stop trying to pick stuff up with your missing hand after a while too, doesn't mean it's not better to have two arms.

Re: Learning Go by porting a medium-sized web back end from Python

#169

Earlier quoted context omitted.

I feel like this is true for any language though. Once you write a well designed, well tested, and feature complete piece of software, you can deploy it and forget about it unless the server it's running on breaks. Go isn't special in that regard, unless there's something that makes Go easier to write, test, or deploy, which might be the case, but you haven't supported that.

Our team was able to develop/deploy about 20 Microservices in Go in the past year or so which is really awesome. I can say this after having worked with several other languages.

how much of this would you attribute to the stdlib and popular libraries, vs the language itself?

Re: Learning Go by porting a medium-sized web back end from Python

#170

I can agree with most of the article, but for some it looks like we have not been using the same language ecosystem at all. Go really feels opinionated around the wrong things, in order to claim "simplicity" as a feature: - No generics just mean you're going to be handing interface{} all the way in your stack, it makes things more complex and less readable for no reason (and less safe) - error handling which is essen…

Wait a second... Go doesn't have generics, only has string-based error handling, and has poor dependency management? This is literally the first time I have heard these complaints. I can't believe no one else has ever complained about this in the comments of every article ever submitted about Go.
Post reply on HN