
Learning Go by porting a medium-sized web back end from Python - benhoyt
http://benhoyt.com/writings/learning-go/
======
4c2383f5c88e911
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 essentially string-based, in 2017? Give me a type
system, please

\- gofmt is a good idea (just like clang-format or yapf), and having it is
great, but the maintainers specifically refuse to add simple features, saying
"running it in an automated process is not supported", despite all github
projects already having it in their automated CI suite

\- go test is good, but in the end it is found lacking

\- dep, well, if you don't mind dumping the code for all your deps in the
source tree, it's probably ok, but it solves a deficiency that the language
should not even have (see next point)

\- stability: the language itself is fine on that, but the ecosystem really
isn't. The fact that they don't even have the package management quality of
python (which I find awful already) is baffling. I don't even know how they
could think "yeah, github-importing is a good idea, let's do it". Go is eight
years old tomorrow and you still have to rely on third-party tooling to do
proper imports that don't burn your house.

~~~
brudgers
The opinions expressed in Go are solely those of Google about the productivity
of Google programmers. Nothing else is driving design. It is by Google
employees for Google employees. Making it widely available and open source is
a strategy for extracting value in the form of bug reports and patches and
Google friendly upgrades from a world wide community for the price of a few
conference talks and some sticker swag.

That Go solves some problems for programmers outside Google is a side effect
of being a general purpose programming language. It is not a primary business
goal except in so far as it raises Google's bottom line, creates a hiring
pipeline, and keeps its employee moral off the floor.

~~~
mhd
I think if you're replacing "Google" with "those Bell Labs guys", you're
closer to the truth. A lot of the design decisions are quite familiar if you
look at the past work of e.g. Rob Pike.

It's not necessarily all about peak efficiency for specific enterprise
applications.

------
Dowwie
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_ problem
using a high-level language and solved it with a lower-level language, and
that was Armin Roacher, who solved a significant performance issue using Rust:
[https://blog.sentry.io/2016/10/19/fixing-python-
performance-...](https://blog.sentry.io/2016/10/19/fixing-python-performance-
with-rust.html)

Can you think of other stories? Please, share.

I encourage all to be more skeptical about potential gains and realistic about
who is actually gaining.

~~~
hasenj
Writing in a fast compiled language is not premature optimization.

Premature optimization would be something that makes the code more complicated
and more difficult to follow but produce better performance.

Writing the same code in a fast compiled language is just the default thing
that you should be doing when you are not doing premature optimization.

Writing in a slow interpreted language is more like premature "deoptimization"
(if that's a word).

~~~
didibus
I don't follow this logic. Why not use C all the time by default then?

~~~
AnimalMuppet
Let's say that C produces 100% of the performance available. How much does Go
produce? Maybe 90%? How much does Python, say, produce? 25%? So going from
Python to a compiled language produces a huge gain, and going from Go to C
produces a little bit more.

But why not get all the gain? Well, sure, _if performance is the only thing
you care about_. But it usually isn't. You might also care about networking,
or multithreading. Would I rather write that code in C, or in Go? Is it enough
better in Go to be worth that last 10% of performance? Arguably, yes.

When someone says "X matters", it doesn't mean that they are saying "X is the
_only_ thing that matters". It is not correct to conclude that they should,
for consistency, be saying "turn the X knob as far as you can". Instead,
interpret it as saying "given your other constraints, look for a sweet spot
where X is somewhat toward this end of its range."

~~~
didibus
Yes, that's my point. It is premature optimization, because you do not have a
use case for such performance. Instead you might want Python's extensive
numerical libraries, or you enjoy its quick prototyping capacities. The same
way that you do not always go for C, and sometimes prefer Go, because of non
performance related requirements.

That's why saying a compiled performant language should be default is not
logic I understand. Default should be whatever you need for your requirements.
If you don't need anything special, just go with what you already know well.

~~~
AnimalMuppet
Fine, but if that's your point, _don 't_ say "Why not use C all the time by
default then?" Actually make that point, rather than leaving us all guessing
as to what your point is, and more important, _why_ it's your point.

And, as I said, "Why not use C all the time by default then?" does not
actually follow as the logical endpoint of the argument that your trying to
answer, so making that your response really doesn't contribute much to the
advancement of the conversation.

------
trumpeta
Recently I have had the opportunity to write a microservice in Go. It was a
very refreshing experience switching from Scala. Go is a lot faster to compile
and runs with a far smaller footprint. The channels are nice. On the other
hand the testing feels wrong because its so annoying to do mocks. And don't
even get me started on the dependency management.

Overall Go feels to me like some version compiled PHP with better concurrency
support.

~~~
oblio
I really wish that there was a language which had these features:

\- simple (so not Scala, Haskell, Perl 6, etc.; no Rust either, unfortunately)

\- clean (nice syntax, preferably Python inspired, but consistent)

\- modern (generics, some functional features, string interpolation, etc.)

\- decent concurrency/parallelism story

\- good IDE, preferably supported by the core dev team

\- compilation to a (possibly static) native binary

\- decently big ecosystem

\- and a big enough community of contributors or commercial backing from at
least 1 stable entity

\- also preferably didn't have a lot of historical baggage

From what I gather C# might actually be close to this, 2-3 years from now, if
the .Net Core transition happens smoothly and the OSS community adopts it...
Who knows, maybe even Kotlin 2019 or so?

~~~
beagle3
Nim has everything nailed down except the ecosystem/commercial backing; It
does have some of those, but not to the extent that I would blindly tell you
they are there.

It's as fun as writing Python (with a similar syntax), but it has essentially
all the goodies you want from Lisp when you need them, runs as fast as equally
optimized C, produces standalone native binaries, _or_ standalone JavaScript
if that's your thing.

~~~
reacharavindh
Cheers to Nim. I'm learning it in my spare time for fun. However, I will not
consider using it for anything more than toy projects until it hits 1.0.
Hopefully soon.

~~~
narimiran
> _I will not consider using it for anything more than toy projects until it
> hits 1.0. Hopefully soon._

It should happen soon (TM), but from what I understand it will be just another
version, just this time renamed to 1.0 - this basically means you could start
using it more seriously even now.

~~~
reacharavindh
Yeah. I understand that it will be just another version with not that many
changes. Nim as it currently already feels stable and solid. But, I believe
v1.0 release will carry a commitment to not introduce breaking changes at
least for reasonable period of time after.

------
reacharavindh
I'm at the same spot myself, trying to learn Go by building a simple web app.
Your article was a refreshing read to me.

One extra thing that is the major motivation for me to go to Go is the ability
to deploy as a single God damn binary and not deal with dependancies and pip.
pip and counting on OS repositories may be the right thing to do, but it is
just too cumbersome. I have an air gapped setup at work, and there is no easy
way for me to deploy Python applications - because all projects just say pip
instal this and pip install that. It would make my life so much easier
building something on my laptop, scp the binary to servers and expect them to
"just work".

~~~
proto-n
Coming from a data science background, don't anaconda and environment
description files [1] solve this problem with python? Not even sudo is needed
to install anaconda and setup / clone environments, also it can manage python
versions independently from the system's python.

[1] [https://conda.io/docs/user-guide/tasks/manage-
environments.h...](https://conda.io/docs/user-guide/tasks/manage-
environments.html#building-identical-conda-environments)

~~~
reacharavindh
Thanks for your comment.

I have just started using Conda locally to learn before taking it to work. I'm
a new sysadmin and my predecessor maintained a restricted list of python
packages on all cluster systems like a dictator. I don't want to be one.

Does conda cloning the environment mean I can just copy the project directory
to another server and expect my program to run without it looking for the
packages on the internet?

~~~
proto-n
No, the intended way of cloning works by exporting the exact specifications to
a text file and re-creating the environment from the text file.

If you use packages from conda channels (which are repositories of packages),
then it should work flawlessly. Usually basically everything is available from
either the official channel (anaconda) or some community channel (like conda-
forge). At least in the data-science domain. I'm not really familiar with the
python web-development scene, so not sure about that.

Edit: actually once I had to copy an environment from one machine to another
(because of connection problems), and I seem to recall that worked too, but I
don't think this method is officially supported.

~~~
oblio
> No, the intended way of cloning works by exporting the exact specifications
> to a text file and re-creating the environment from the text file.

Snatching defeat from the jaws of victory :)

But I'm not sure who to believe, the other reply to the parent comment says
that copying things around is actually possible.

~~~
proto-n
Well, as my edit says, I've had success with installing anaconda on an other
machine and copying the environment folder to the proper place inside the
installation, but AFAIK that's not an officially supported way of doing it.

------
pjmlp
> compiles very fast (for a statically-typed language).

Like Turbo Pascal 4.0 in 1987 or Modula-2 in 1978, as two possible examples.
:)

------
bischofs
I am doing some python to go conversions for some performance gains in parts
of my stack - I really like it so far because of how they brought some of the
perks of languages like python into a compiled language. One thing I really
miss though is ipdb.

The Delve debugger still doesn't let you run functions and I miss all the
autocomplete fun with ipdb. I hope they can make go a little more friendly to
debugging in general.

------
crdoconnor
>However, it was only 1900 lines of Go (about 50% more than the 1300 lines of
Python).

>However, I’d seriously consider using Go for larger projects (static typing
makes refactoring easier)

Assuming a fully tested codebase and a relatively sane runtime type system,
I'd _much_ , _much_ rather maintain the shorter codebase than the statically
typed one.

Having less code makes refactoring easier.

~~~
boomlinde
Assuming a fully tested codebase, there is an overhead in writing and
maintaining unit tests that has to be considered as well, and using a static
type system obviates a whole category of them. You move the type specification
out of tests and manual documentation directly into the code where you'll find
out at compile time what you did wrong. Not at run-time, or during testing
because you diligently wrote a test that considered the case.

I agree that brevity sometimes aids refactoring, but there are many parameters
that have to be weighed in, and often I find that the benefit of static typing
outweigh whatever ignoring the type or checking it at run-time might offer.

~~~
crdoconnor
>Assuming a fully tested codebase, there is an overhead in writing and
maintaining unit tests that has to be considered as well, and using a static
type system obviates a whole category of them.

I've not found this to be true, and tests that do type checking are a waste of
time in any language.

Bugs that are caught by static type systems are almost always caught by a
combination of behavior tests and a sprinkling of sanity/type checks on border
code (e.g. a module's publicly facing API).

>you'll find out at compile time what you did wrong

In a fully tested code base that is regularly tested the distinction between
compile time and runtime does not matter a lot.

By contrast n code bases in _dire_ need of tests (which is more common than
generally assumed), the distinction is absolutely vital.

------
oblio
I'm not sure about Javascript, but why do you have to have two APIs when you
have async? At least in C# you write the async version of the API and that's
it.

Then you go asyncStuff.Request on it, and it blocks. There are some quirks but
I remember that it worked all right.

------
jpcarmona
I really liked to read the article. You gave your opinion and didn't try to
sound that this was the way, it was clear that it was YOUR opinion. Thanks for
it.

