
From Node.js to Go - francesca
http://bowery.io/posts/Nodejs-to-Golang-Bowery/
======
wiremine
I'e been writing my first production-sized Go app over the last few months,
and really enjoy it. Some observations:

\- The standard library is solid, and I was surprised how well-rounded and
mature the third-party library support it. Coming from a Python/Ruby
background, that was nice to see.

\- I totally agree with the comments on this thread about dependency
management. Godep [1] is nice, but it would be great to see a canonical dep
management tool for go.

\- The tooling for Go is excellent: More languages need something like "go
fmt".

\- In general the document is solid, but I've found the usability of the
generated docs to be poor. You think they could bribe a few Google designers
to spend some time fixing that...

\- I've noticed a lot of Rust lovers commenting about how great Rust's type
system is. It probably is, but I haven't run into any problems with Go's type
system. I've found it to be practical and easy to use. The only issue is
parsing JSON when you're not marshalling it to struct. They need to fix that
(although there are some nice third-party tools to make it easier).

\- Go is a minimal language and has been called boring. [2] I don't claim to
be an expert yet, but I don't think I've reached this level of productivity
with a language this quickly before.

[1] [https://github.com/tools/godep](https://github.com/tools/godep)

[2] [http://stevebate.silvrback.com/go-is-
boring](http://stevebate.silvrback.com/go-is-boring)

~~~
TheCoelacanth
> I've noticed a lot of Rust lovers commenting about how great Rust's type
> system is. It probably is, but I haven't run into any problems with Go's
> type system. I've found it to be practical and easy to use.

Go doesn't have generics. To someone coming from a language like Rust, saying
that your type system doesn't have generics is like saying your car doesn't
have wheels. It's just considered non-negotiable.

~~~
chimeracoder
> saying that your type system doesn't have generics is like saying your car
> doesn't have wheels.

To overburden an analogy, it'd be more like complaining that your _tank_
doesn't have wheels[0], or your hovercraft. Go takes a different approach to
the same problem (in this analogy, getting from point A to point B).

But really, this is a rather tired flamewar that gets beaten to death
literally every time a post about Go makes the front page, and there's really
nothing more that can be said about it. Either program in idiomatic Go, which
means using the language as it's designed (ie, without generics, at least in
its current form), or don't, but it's very tiresome to see this argument
rehashed again and again.

[0]
[https://en.wikipedia.org/wiki/Continuous_track#mediaviewer/F...](https://en.wikipedia.org/wiki/Continuous_track#mediaviewer/File:Caterpillar_track_shingle.JPG)

~~~
Touche
> Go takes a different approach to the same problem (in this analogy, getting
> from point A to point B).

Go doesn't take any approach to writing generic code at all.

~~~
MichaelGG
That's the really disappointing part. I've read the thread where the designers
talk about implementing generics, and they basically say that every language's
implementation of generics sucks, and since they can't come up with a design
that's perfect (no codegen duplication, but still all the perf of
specialization), they're just gonna punt.

And then the code I've seen is littered with "interface {}".

That's a pretty big thing to give up, and I don't get the point. Something
like F# gives you high level features (and green threads if you want) with
fair perf, and Rust gives you a fair amount of language with C perf.

~~~
Sphax
I think littered might be a bit strong. I'm writing a service in Go, and have
yet to use interface{}. However, you might have to use it more when writing
libraries.

------
sshillo
This is just another generic Go vs Node post. Do we really need another post
telling us about Go's concurrency/built-in features/compile benefits.

This post sadly doesn't really go into much details that bowery.io is trying
to solve, how Go fits that and why Node was so bad.

A basic crud webapp would probably be better suited towards node and it's
larger list of libraries supporting that kind of stuff.

On the other hand, building you own messaging queue or doing heavy
mathematical processing might be better suited for Go.

~~~
falcolas
Fwiw, I have been doing a lot of crud work in Gonthe past few months, and
haven't found it particularly burdensome. I have to write my own SQL and map
it back to structs, but I consider that a good thing. I might have to write
about some lessons learned.

~~~
kochthesecond
Please do. I come from java, and am currently finding Go a bit cumbersome to
work with. No Exceptions, lots of nil checks and a poorer ide makes it quite a
bit of work. I also find testing a bit harder to do, but it's probably because
I'm in a javian mindset.

------
nawitus
>In Go, you can define different files for different operating systems that
implement functionality depending on the operating system.

That sounds like it's actually very difficult to support multiple operating
systems. As a developer I never, ever want to write any OS-specific code.
Sure, that's sometimes required, but saying that the solution is to have
multiple files, each for a single OS, doesn't sound good. It's a lot better to
abstract the OS away. Node.js does this quite well. Seemingly a lot better
than Go.

Besides, Node.js doesn't need to be compiled for each system. This alone makes
Node.js better for writing code for multiple operating systems.

>Go is a compiled language so distributing applications for use on multiple
platforms is just easier.

I disagree. You need to compile to code for every single platform, making code
distribution costly. With Node.js you can simply distribute the code as it is
and it probably works in any platform. (The probability is as high as it is
for Go assuming no extra work for a new platform). Sure, each platform needs
to have Node.js, but Node.js is supported in most platforms.

~~~
billsimpson
> _I never, ever want to write any OS-specific code_

With Go, you never, ever have to write any OS-specific code. From a _single
source_ , you can build executables compiled for different operating systems.

In any case, you're right that it can be nice to simply "run" a JavaScript
application directly from its source code without worrying about compilation.

> _You need to compile to code for every single platform, making code
> distribution costly. With Node.js you can simply distribute the code as it
> is and it probably works in any platform._

You're missing the point about distribution. Let's say you write a non-trivial
command line application, and want to distribute it to your clients. With Go,
you can distribute your program as a self-contained executable file. Yes, you
may generate a few versions (Windows, OS X, etc.) depending on the needs of
your clients, but the cost is a few seconds of compile time, and a few seconds
posting links to the Windows, OS X, etc. executables. The cost is negligible.

Compare that to Node. How are you going to distribute your Node app to
clients? Is every client going to install Node on their personal computer?
Will they be able to figure out NPM? Yes, it's easy, but they'll mess it up
anyway. What happens when the network has a hiccup and npm doesn't download
your dependencies correctly, or they try to upgrade your dependencies and
everything breaks?

If you plan on distributing your Node code, you're pretty much limited to
distributing it to other Node developers. That's not going to work for
everybody.

~~~
nawitus
>With Go, you never, ever have to write any OS-specific code.

Okay. The article claimed otherwise: "In Go, you can define different files
for different operating systems that implement functionality depending on the
operating system."

>Yes, you may generate a few versions (Windows, OS X, etc.) depending on the
needs of your clients, but the cost is a few seconds of compile time, and a
few seconds posting links to the Windows, OS X, etc. executables.

Except when the developer only compiles for Windows and Linux, but someone
wants to run the code on Mac os X.

>Will they be able to figure out NPM? Yes, it's easy, but they'll mess it up
anyway.

You don't need NPM. You can fetch the dependencies and include that with the
installer. There's a downside to that, though, which is binary-packages with
npm.

~~~
curun1r
> > With Go, you never, ever have to write any OS-specific code.

> Okay. The article claimed otherwise: "In Go, you can define different files
> for different operating systems that implement functionality depending on
> the operating system."

Both the article and the poster you're replying to are correct. You almost
never _have to_ write OS-specific code, but you _can_ write it if you feel
there's a benefit to it. Much like Node doesn't make you write C++ code but
allows you to do it when you feel it's necessary. The article's main point
was, I'm assuming, alluding to Go's build tags which are much more elegant
than the traditional pre-processor directives used in the C/++ world. They
give you a powerful expression language for targeting specific runtime
environments that lets you separate out your OS-specific code in a very clean
way.

When it comes to distributing an application, there's another advantage that
Go has over Node. One of the common ways that people are distributing server
applications these days is as Docker images. It solves the problem of users
needing to understand npm quite nicely for a Node application, but makes the
distributable artifact significantly larger since it includes the bulk of an
OS alongside the application code. With Go's ability to create a statically-
linked binaries, you can build your Docker images "FROM scratch" and images
can be as small as 2.5m.

------
balls187
> Go is a compiled language so distributing applications for use on multiple
> platforms is just easier.

How is this a true statement? Ease of distribution isn't a function of a
language's runtime environment (native vs interpreter).

~~~
mrcwinn
Sure it's a true statement. Even if you have to compile to different targets
(and you do), that's much simpler than implementing shared dependencies on
those different targets. When you deploy a binary with no external
dependencies, you can (generally) set it and forget it.

It's not to say there aren't meaningful differences across targets you need to
account for, but it is "just easier" in my experience.

~~~
balls187
So, it's not a function of compiled vs interpreted. It's about a single binary
vs shared resources.

So while you can't get a single binary with an interpreted language (you need
the shared runtime), however you can also get shared libs using a compiled
language.

I've found doing cross platform development using NodeJS significantly easier
than using C++ (of course I had to use compilers that didn't default to IEEE
764).

So old.

~~~
laumars
Minor nit pick, but theses days "interpreted" languages are also compiled.
What we are really taking about is AOT vs JIT (though even here, there are AOT
compiled languages that still require a supporting run time environment
installed, such as Java)

~~~
yellowapple
Java's a bit of a special/odd case, since it's AOT-compiled into a bytecode
that is then JIT-compiled into native instructions.

~~~
laumars
Not that unusual these days. CPython supports a similar intermediate binary
(.pyo) and .NET does the same too, albeit the bytecode is shipped inside a PE.

~~~
steveklabnik
And you can't even get that from the language itself. While MRI (last I
checked) doesn't support an intermediate file of its bytecode format, Rubinius
does (.rbc), for example.

------
eknkc
For me the single biggest disadvantage of Go against Node.JS is the lack of a
decent dependency management solution. NPM is awesome and Go doesn't even have
a "meh" answer to that.

~~~
mcmillion
NPM is only awesome until you need to do something with it on Windows.

~~~
u84six
What kind of problems are you having with it? I'm using npm on Windows and
it's working out great! I'm actually using it as my build/task runner rather
than using bloated grunt or gulp. It's easy to configure and read. I run my
linter, unit test, jscs, and bundler all configured in package.json.

I also install git bash and conemu to have bash on Windows which makes things
much better. I don't use windows console.

~~~
nawitus
My experience is that Npm "kinda works" on Windows. There are mysterious race-
conditions and annoying bugs. And I'm not even talking about npm being
technically completely incompatible with Windows due to the 256 character path
limitation.

------
enahs-sf
Go does lack quite a bit of the web pizzazz you'd find in rails, but I learned
a lot more by writing web things in go than I did in rails because so much
less of the magic is hidden away from you.

~~~
mrcwinn
Go, unlike Rails, is not a web/MVC framework. It's a systems language, which
is even still separate and unique from Ruby, a dynamic language. I agree
you'll certainly learn more from Go than you would from Rails, but it's
helpful to be aware they're very different.

Apart from my own opinion of Rails (I'll pass, thanks), it's also worth
considering that Go, again a systems language, may not always be appropriate
for typical web development. That's not a rule by any means. Just pick the
right tool for the job.

~~~
kxo
> systems

Here we go.

~~~
yellowapple
_rimshot_

------
je42
For testing frameworks, standard library tasks, workflow: he author prefers
less choice and more standardisation, hence Go > Node.js.

Which I find very disappointing. One thing that I learned, if some
standardization happen and you have to use it, it will cause you pain
eventually.

Obviously, there is honey-moon period and a clear path what to do if you only
got "one" standard, but the author will eventually there is no free-lunch. The
standard will be insufficient for some his usecases and then what....

Node.js out of the box embraces multiple solutions - I know this can be
overwhelming, but it gets better over time not worse. When you know, the
trade-offs between the different choices, you feel empowered to pick the best
tool / lib for the job.

~~~
skygazer
I have to agree with your sentiment -- certain types of simplicity, though
attractive, can be a misleading double edged sword.

I once let a team split in two for a week to separately build the same product
using two competing UI frameworks, before our final decision. The simpler,
more opinionated framework won, hands down at the end of one week, being far
more productive with the least effort. But, over subsequent years, we found
the framework far too restrictive, requiring convoluted solutions when
problems strayed from the straight and narrow, leaving our code base littered
with painful hacks.

------
drikerf
Go is definitely promising but the last time I checked the problem with web
development with Go was that there is no mature libraries for User
authentication etc(Please correct me if I'm wrong). This makes going with Node
or something like Rails more tempting.

~~~
voidlogic
>no mature libraries for User authentication

"User authentication" can mean 1,000 different things, maybe if you clarify
your use case, people can suggest solutions.

~~~
kawliga
> "User authentication" can mean 1,000 different things

you mean like 4 different things... and even those have common components

------
gsastry
I wish a language with advanced types like Haskell or OCaml would have the
same tooling and ease of distribution around it that Go does. I haven't built
anything in Haskell/ML in a while, so if anyone has any updates on this please
chime in.

~~~
jallmann
OCaml is usually statically compiled with ocamlopt, so distribution is pretty
easy. As long as build/deploy platforms match, then you're good to go. Shared
libraries only come into the picture for unusual cases, eg FFI.

OCaml tooling has also gotten a lot better over the past few years, mainly
because of OPAM. The library count has exploded, and the language still gets
regular point-releases with improvements designed to aid tooling, such as
extension points.

~~~
djur
The last serious project I tried to do with OCaml (maybe 4 months ago) was
impeded by a ton of dependency problems (this library in OPAM says it depends
on this other library, but it doesn't compile because the latter has changed;
this dependency won't build in OCaml version .X but another one won't build in
.X-1) and ecosystem sparseness (two partially-complete, years-old libraries to
do the same thing, etc.). I was eventually stopped in my tracks by an
impressively opaque camlp4 error.

(My favorite example is when in #ocaml I asked what testing tools people used;
the most positive answer was along the lines of "there's OUnit, but I don't
know anything about it".)

There seems to be three awkwardly coexisting OCaml communities: the old
academic crowd, the Jane Street people, and a crowd of clueless newbies like
myself. It's a really great language, but the ecosystem is going through some
growing pains right now.

------
izolate
So is this is a growing sentiment? Recall that TJ famously left Node.js in
favor of Go.

I find Node downright amazing for web development. npm has everything you
could ask for. And the whole community takes the unix philosophy and runs with
it. Also love that there's no single best way to create something, you as the
architect, gets to decide.

And io.js/ecma6 makes node even more appealing.

~~~
u84six
From what I've heard, TJ is working with Go because Joyent wasn't putting
enough effort into releasing features for node and he also got tired of
JavaScript callbacks. I think node will see some love very soon, and I know
there are plenty of ways to deal with callback hell. That's just one guy's
feeling. I really love working with node. But definitely looking forward some
new features.

~~~
tjholowaychuk
There are lots of reasons! I'd encourage people to try something new (Go,
Rust, Scala, whatever), it's easy to ignore Node's shortcomings sometimes.
Community was a big one for me, the "unixy" nature of node+npm is no good when
the module quality is pretty poor and the names are completely nonsensical,
your app just becomes an abstract blob of code that makes no sense. Go's
stdlib is pretty rock solid, nothing in Node comes close IMO.

~~~
izolate
Having just spent more time at work this week creating PR for bugs in npm
modules, instead of doing actual work... I'm starting to agree.

But honestly I think that's just par for the course for any substantially
popular language. I don't think Go (or any other language) is inherently
immune to this.

~~~
tjholowaychuk
For sure, there are lots of skillful people working on node as well, I just
think the Go team has a lot more experience and it shows.

------
jonpress
I disagree with the concurrency part. Node.js has excellent built-in IPC
support through the process and child_process objects.

Since Node.js is JavaScript, you can't possibly argue that Go code is more
'portable' than Node.js. For one, JavaScript can run on more machines than any
other language.

Go will not run in the browser because most browser vendors will not let that
happen. On the other hand, JavaScript is already universally accepted by
everyone and it's everywhere - You can run JS in the browser, natively on
mobile devices, on the server, on set-top-boxes, on robots/IoT devices and
just about everywhere you can imagine. Anybody can implement and modify their
own JavaScript engine to suit their specific needs.

No need to worry about protocols - Since JSON is a subset of JavaScript, you
can seamlessly pass objects between the client and the server and no need to
context switch between programming styles when going between client and
server.

People who don't like JavaScript mostly feel that way because they don't
understand it well enough (it's a lot more expressive and powerful than people
imagine). I have programmed in many different languages - C/C++, C#, Java,
ActionScript 3, Python, AVR Assembly (ATMEL ATMEGA8-16PU microcontrollers and
family) and a few others but I feel that no other language has the
expressiveness and elegance of JS.

Before I got into Node.js, I considered myself 'language agnostic' because I
often switched between languages because no one language could do everything I
needed. I no longer consider myself an agnostic - In fact, I feel quite
comfortable saying that C/C++ and JavaScript are the only two languages worth
knowing.

In reality, you can't be 'fluent' in that many languages because fluency
requires constant practice - It makes sense to settle on fewer languages -
Mastering a language/tool allows you to focus on what's really important -
Logic and structure.

------
htilford
They left out the most obvious reason for them to switch. Their business is
based on docker, coreOS etc . . . aka the Go ecosystem. In that context
developing Go expertise just makes business sense regardless of technical
merits.

------
20kleagues
It is frustrating to see how many Go vs Node posts are happening here. I have
been implementing a bluetooth LE module in Go, and due to lack of some robust
libraries, had to go back to Node. This is primarily a question of maturity,
but I also realised that my use-case didn't really need the thing which Go is
most useful for - namely really really good concurrency primitives. I am quite
sceptical about Node's future because of that forking fiasco, but at this
point in time, both Node and Go provide enough distinct functionality that
both will be used for a long time.

------
akhilcacharya
I'm primarily a mobile dev, so the biggest impediment to me adopting Go over
Node is the fact that converting and manipulating my data models to send as
JSON documents is considerably harder on Go - there's no Go equivalent to Gson
yet, nor will there likely ever be due to the nature of the language.

~~~
thezelus
Did you get a chance to look into encoding/json package[1]? I come from Java
background and have extensively used Gson in projects, I found encoding/json
at par with Gson. You can find more examples here[2].

Would you mind if I ask what did you find lacking in Go's json package when
compared to Gson?

[1]
[http://golang.org/pkg/encoding/json/](http://golang.org/pkg/encoding/json/)
[2] [http://www.attilaolah.eu/2013/11/29/json-decoding-in-
go/](http://www.attilaolah.eu/2013/11/29/json-decoding-in-go/)

~~~
swah
That's exactly what he is talking about. In a dynamic language, you just parse
the JSON and access the resulting object. In Go, you need to have a matching
record or use the interface type and implement a decoder.

~~~
thezelus
Oh, apologies. I thought he is talking about Gson[1], and hence the comment.

1\. [https://code.google.com/p/google-gson/](https://code.google.com/p/google-
gson/)

------
u84six
I'm having a hard time enjoying Go. It just reminds me a little too much of
Java, and I programmed in that language for way too long. After I finished my
test program, I uninstalled the toolkit from my system. Right now, I feel that
there's no perfect language for me. I do love JavaScript, but there are some
things I wish they'd fix. And it takes browser makers way too long to support
the latest features. Been messing around with Erlang. Kind of an interesting
language.

~~~
billsimpson
Maybe you don't like programming? Or you did once, but you've grown bored with
it now that it's not as challenging?

In my opinion, a programming language is good if it enables the programmer to
move from a concept to correct and maintainable implementation with minimal
friction. I don't expect a programming language to entertain me.

The burden is then on me to find projects that I believe in and will enjoy
implementing. This is, of course, easier said then done.

~~~
u84six
No, I actually do like programming. And I agree with you that there's more to
choosing a language than having fun with it. I've had to make that decision
for 2 decades. :) But my idea of fun is when I find a language that does a lot
with less code, easy to apply patterns, doesn't have a lot of boilerplate,
doesn't take a lot of tooling, simple, sleek, and allows any style of
programming (e.g. oop, functional, procedural). Like I said, I've tried Go and
it just didn't feel like that. It felt like, well, Java. The language I used
to build apps in the 90s.

~~~
gcv
Any modern Lisp gets you there. The three leading dialects, namely Common
Lisp, Racket, and Clojure, are all excellent. Each makes different trade-offs
in what it offers. As a former Java programmer, you will probably like
Clojure's near-perfect Java interop and excellent performance. Racket is
probably the best batteries-included language and environment available today.
Common Lisp is a bit grandfatherly, but it's the kind of grandfather who
teaches you to fly his aerobatics plane. Its condition system, in particular,
should be required study to anyone who purports to design languages and
runtimes.

I read up and played with Rust earlier this week. It's also excellent, and
while it's too young and has been too volatile for libraries to solidify, that
will change in the next few months. The tooling (as far as Emacs modes and the
dependency/build system, Cargo, are concerned) looks solid. Performance is
already decent, and has the potential to eventually match C. To be honest,
Rust feels like what Go would have been had its authors understood Lisp and
Haskell.

------
emehrkay
"but he didn’t learn his lesson there"

This set me up for a negative article about Go, but, like other Go-related
materials, it makes me want to use it. I should use it.

~~~
angersock
"Something must be done. This is something. Ergo, we must do it."

Why should you use it? What problems does it solve for you?

------
oscargrouch
I for one hail our Go overlords, because that way it will mean less Python,
Ruby and Javascript code for serious stuff like backends.. Given the language
will please this crowd.

Theres a lot of good stuff, created by good people, in those languages and
while the solutions are great, the fact that they are in those languages, make
them unfit for a lot of cases.

~~~
pswenson
how is this a useful comment?

------
timClicks
It's interesting the switch was prompted very few things that are JS vs Go,
perhaps concurrency. The main factors were tooling related, enabling stable
workflows and easy deployment.

------
rmetzler
One thing I hate about JS and the thing I love about Golang: the error
handling. I love that there is only one way to do it in Go.

ok, More actually. Some APIs return ok instead of err.

------
jcoffland
Why on earth would a line editor need platform specific code? Sounds like a
case of that's-a-cool-feature-let's-use-it!!!

------
gankgu
Golang only 2x ruby at net/http level and same as ruby at web framework level
?

[https://news.ycombinator.com/item?id=8964255](https://news.ycombinator.com/item?id=8964255)

~~~
grey-area
On render speed, if you're trying to serialize json 1 million times a second,
the benchmark you linked might have some relevance, if not, then you're being
misled by looking at benchmarks like that, which measure an app doing not very
much millions of times a second, so basically they're stressing the routing
path and the json serialisation speed. This is unlikely to be a problem you
ever encounter and if you did you'd just rip out the bits you don't need for
that path - use static routing, cache json etc, and your speed would be
massively improved.

Speed is not the only concern, or even the biggest concern, for most web apps,
the constraints nowadays are typically in something like this order:

\- Memory \- CPU \- Bandwidth \- Database \- Render speed

Clearly that doesn't hold true for all sites, but for most the order is
something like that because with caching you can obviate any render speed
concerns very easily. On memory and CPU usage, golang completely trounces a
solution like Rails (I say this having built similar sites in both) - it's
better by a factor of 10, which means you can run a pretty big site with very
spartan resources.

The largest obstacles to go replacing languages like ruby as a tool for web
apps is more that the libraries at present are not available for everything
you might want to do (user auth, sophisticated templating, csrf, fragment
caching, form helpers, orms and query builders etc), but that situation is
steadily improving, and the standard library is pretty excellent as far as it
goes.

