
Why I switched from Ruby to Go - poissonpie
http://codegangsta.io/blog/2013/07/21/creating-cli-applications-in-go/
======
kitsune_
I'm looking forward to all the "Why I switched from Go to XXX" posts in three
years.

Same thing will probably happen to node.js pretty soon. It has already been
happening to MongoDB for quite some time.

Go is currently in its hype phase.

Some people seem to make a living by writing post-mortems.

Why does everything always have to be the latest and greatest thing on earth?

Can't we just institutionalize the hype cycle? Like fashion, minus the
seasons? One big show every year where everyone can compare their dicks and
then let's shut up about it until next year?

~~~
TheHydroImpulse
While there was some hype about Node, it didn't turn out to be a fad. The
ecosystem is thriving and not slowing down anytime soon, especially with 0.12
and then 1.0 coming quite soon.

While I tried getting into Go, and initially didn't like it but wanted to like
it. Seems like the more I read about it, the more I get into it, the less I
like it. Which kinda sucks, Go seems like a powerful platform.

~~~
octo_t
people said/saying the same thing about ruby/RoR too.

"While there was some hype about Rails, it didn't turn out to be a fad. The
ecosystem is thriving and not slowing down anytime soon, especially with Ruby
2.0 and then Rails 4.0 coming quite soon."

is a thing someone could have easily said on this site in January 2013.

~~~
rpedela
Yeah, but Node.js actually has a valid use-case: code that needs to be non-
blocking. Most of the time, you want web servers to behave that way. Yes you
can do that in other languages/frameworks, but Node.js is the only one with an
ecosystem where most modules are also non-blocking by default. If you look at
the languages/frameworks that have survived their initial hype, it is almost
always ones where there is a use-case that the language/framework uniquely
solves well.

C/C++: Easier than most of the other low-level languages. Used when
performance and/or memory management are critical: kernel, database, embedded
system, etc.

BASH: Dammit, I just need a script that executes five commands in a row!

PYTHON: A scripting language that properly handles gigantic numbers and
seamlessly integrates with R. The scientists love it!

And the list goes on. Of course those languages have other use cases, but the
point is that they all have at least one use case that they are the best at.
However only time will tell if Node.js ends up being the non-blocking
scripting language or something else will take its place.

~~~
asdasf
What you think is node's strength is its weakness. Having to write event-
driven code is terrible. Just as the world is finally waking up and moving to
actually caring about concurrency like erlang and haskell have forever, node
is a throwback to the error prone and convoluted event loops of C. Go is far
better for the very use case you think node excels at.

~~~
rpedela
Like I said, only time will tell if Node.js is THE non-blocking scripting
language/framework. Still too early in hype mode to know for sure. At the
moment it is and it has the momentum. Doesn't mean Go won't take its place at
some point in the future assuming it really is better at the non-blocking use
case. Or Go could just be another language in a long line of languages that go
nowhere. We shall see.

No matter the mechanism, event-driven programming is here to stay. All UIs
must be event-driven unless you enjoy pissing users off. Games must be event-
driven. Web servers should usually be event-driven for similar reasons.
Callbacks are just the most basic way to achieve that when you have an event
that won't finish processing for awhile like a DB call.

I certainly understand the desire to not use callbacks since I also loathe
them. But they are also much easier to understand than something that looks
synchronous but actually isn't. But there are a lot of people who have tried
and are still trying now to rid us of the need for callbacks but still allow
for async. I certainly hope they prevail, but, historically speaking, I am not
optimistic.

~~~
TheHydroImpulse
I don't know if Node will win for THE non-blocking platform award, but it's
coming close to THE non-blocking web platform.

I think Go (and heck even Clojure with it's added core.async model) would be
better at winning the first award. They are much more general and can be used
freely. Node is basically limited to web and web servers (including tcp
servers here).

I think Node is turning onto generator mode. Now that generators hit V8 (and
Node under a flag), it's much easier to write async code (even easier than
callbacks) yet you write in a synchronous style. That'll definitely improve
the concurrency model.

------
adrianoconnor
The title of the post is "On Distributing Command Line Applications: Why I
Switched From Ruby to Go", which changes the sentiment somewhat. The guy who
wrote the post is clearly happy to choose the right tool for the job. The
sensational title here looks silly.

Anywaay Go looks like a good solution for what he's doing. I tried
distributing a Ruby-based app years ago (maybe around 2008 or 2009) with a
pre-compiled version of Ruby for Windows bundled as part of my programme. The
Nullsoft installer package I wrote took ages to write all of those .rb files
(that make up the standard lib). It sort of worked OK, but the project didn't
go anywhere -- that was probably lucky -- it'd have been a nightmare to
maintain.

------
joaomsa
One approach I've seen for portable Ruby apps is to use JRuby. You gain the
ability to package your code as a standalone, compiled java app for
distribution. From that it becomes as simple as running 'java -jar app.jar' or
use a similar transparent stub executable.

Granted now you've just punted the problem of Ruby version to JVM version
(which I've found to be less of a hassle) but at least took care of the
nightmarish management of gem dependencies without something like bundler.

~~~
mcdougle
Wow that's cool. I didn't even know that existed!

~~~
jacques_chester
JRuby is an impressive piece of kit. Look at TorqueBox for a sequel.

------
evilduck
As a Ruby guy, one thing off putting to me is that what appears to be
"idiomatic Go" involves naming things as tersely as possible. Most Go code I
look at has maybe-usefully named types or interfaces and then they usually go
and assign them to something utterly meaningless like 't', 'vt' and so on.

Go's official docs and standard libraries seem to reinforce this style choice,
and most 3rd party code follows this general C++ style inspiration too. I know
I can do what I like in code that I would write, but it seems like I'd be
swimming against the current.

~~~
asdasf
>involves naming things as tersely as possible.

No it doesn't. It involves naming things appropriately. If you have a 4 line
function that does something with a string, that string argument _should_ be
named "s". You aren't making it clearer by giving it a longer name. The length
of a variable name is proportional to its scope.

~~~
evilduck
I disagree.

's' has no meaning by itself, which means that you have to read all of the
context surrounding 's' into your short term memory just to gain any
understanding of the single line you may be interested in. That's slow and
more work than necessary most of the time.

Also, naming things is a habit and a style. Short variable naming leaks out of
4 line methods into any 40 and 400 line methods you may eventually write, and
it leaks into the ABIs/APIs of your application. I've rarely seen any code
that would use 's' appropriately in a 4 line method that wouldn't hesitate to
use it everywhere else inappropriately.

~~~
jff
Oh come the fuck on. At least to anyone who's written a C program, using "s"
for a string argument is absolutely clear. Read the man pages for pretty much
every goddamn string function in the standard library; strlen, strcmp,
whatever, they call name them either "s" or "s1", "s2" if there are multiple
strings.

Maybe we should do strlen(const char* theStringThatIsBeingMeasured), that's a
lot clearer. Maybe we should expand char to character, and strlen to
stringlength, because it might not be clear enough.

~~~
evilduck
Why are you guys stuck on 's' definitely being a string? It could just as
easily be a struct or anything else imaginable, in which case, you're back to
not knowing anything about it from the name 's' without going to look it up.

You can contrive simple examples about basic data types all you want, the
simple cases and built in types are precisely where it's not a problem. Go
read the src for Go's Unicode package as an example, you get 60 line methods
with stuff like 't1' used all over the place and the value of t1 is assigned
pages away from where it's actually used.

~~~
asdasf
>Why are you guys stuck on 's' definitely being a string?

Because that is the example I used.

>It could just as easily be a struct or anything else imaginable, in which
case, you're back to not knowing anything about it from the name 's' without
going to look it up.

If there were more information that could be conveyed, then it wouldn't be
named "s". That is the entire point.

------
16s
This is the same reason I re-wrote a lot of my Python code in C++ many years
ago. Distributing one self-contained, statically linked executable just works
and even the most clueless user can download and run it.

But I _still_ use a lot of Python and I'm sure this guy still uses a lot of
Ruby. Everything has its place.

~~~
Touche
I feel the same way, but I'm not willing to go to an inelegant language to
achieve it. So I write cli applications in Lua with a thin C wrapper.

~~~
16s
"Inelegant" is really a matter of opinion.

~~~
Touche
Of course, I speak only for myself.

------
h2s
Couldn't agree more. I made the mistake of using Ruby to build a CLI
application too, and distribution is a massive hassle. At the moment I'm still
at the awkward stage of distribution via Rubygems which the article advises
strongly against, and I'd add "Gem startup time cripples your performance" to
the article's point about Rubygems being difficult for non-Rubyists.

~~~
FooBarWidget
So why don't you distribute your Ruby app without using RubyGems?

Look, I've never been able to understand the people who think RubyGems is a
good distribution mechanism for end users either. But switching to another
language altogether seems to throwing out the baby with the bathwater. You can
just create a Debian package or something that depends on Ruby. That's exactly
what we do with Phusion Passenger.

Have gem dependencies? Vendor them. Not that hard.

But if you have gem dependencies that contain native extensions that aren't
distributed by the OS... well then switching to Go starts to make sense.

~~~
mcdougle
That's assuming everyone's using Ubuntu (or some other Debian-based OS)...

He actually did mention that in the post, though -- packaging Ruby into the
installer -- and mentioned how difficult it is. I've never tried it myself,
but I imagine it's pretty tough if, for example, you're distributing to
Windows as well (although who uses CLI apps in Windows anymore...?)

~~~
pjmlp
Lots of us.

Many configurations are done via command line tools actually, more so since
PowerShell exists.

------
masklinn
So... wouldn't _any_ language which allows building statically linked
executable be suitable for TFA's issue[0]? Or even just a more reliable
version of py2app or py2exe-style bundling?

[0] Ada, OCaml, Haskell, Rust, ATS if you're really perverted?

~~~
humanrebar
Rust isn't stable enough for anything but alpha-level applications at the
moment. But you're right that the blog author should elaborate on why he chose
Go over all of the other compiled languages (and even dynamic languages with
nice standalone packaging solutions).

~~~
lloeki
Although not mentioned in the article I'd venture to say language design
choices squarely aimed at solving distribution woes, like:

\- static linking _only_ (unless you 1. use cgo and 2. dynamically link
against a native lib)

\- trivial cross compiling (but no cgo)

------
vidarh
I love Ruby, and use it a lot, but I have to agree with him about
distribution. It's one of the reasons I am slowly plodding along on my ruby
compiler (though at my current rate it's still a couple of years away from
being useful) - I want static executables.

If I wanted to distribute a Ruby app to non-Rubyists today, I'd likely end up
packaging up the Ruby interpreter of my choice and all dependencies in a
single archive rather than trust a sane environment on the users machine.

And that obviously limits the type of situations you'd want to use it
substantially. For my part it's not really an issue, because of what I'm using
it for, though.

------
eliot_sykes
tl;dr: Distributing command line apps is awkward when they are written in
Ruby, so you're better off using Go. The author has created a library to help
write CLI apps in Go [1] and gives an example of how to use it.

[1] [https://github.com/codegangsta/cli](https://github.com/codegangsta/cli)

------
dodyg
This is why enterprise tends to be very conservative and stick to one or two
platforms for decades. It's stupid to throw away your investments when your
tech du jour ran out of its time.

~~~
trailfox
I write all my web apps on Cobol, with formal specifications for every piece
of code. This Java/.NET/javascript/Rails/Python thing is just a fad. Everyone
will come round back to Cobol, wait and see. Mark my words...

~~~
voyou
And how right you were to stick with COBOL; even the Ruby community are re-
inventing it now: [http://cukes.info/](http://cukes.info/)

~~~
tonyplee
If it is not running in PDP11/Commondo64, I ain't using it.

------
shortlived
How come no mention of rb2exe and things of that nature? Are they not viable
options? (Haven't used ruby in years but when I did above mentioned solution
was the way to go)

~~~
vidarh
They may be viable options if you happen to use the right platform.

------
solarexplorer
Previous discussion:
[https://news.ycombinator.com/item?id=6083231](https://news.ycombinator.com/item?id=6083231)

------
vorbote
Hmm... There is a basic misuse of terms here. The author uses the term
"distributing applications" but he is actually talking about _application
deployment_. Oh well, language evolves and most of the times becomes murkier.

But I do agree. There is a in inherent higher barrier of entry when you force
your users to install third-party libraries or even your deliverable from an
outside ("fourth-party"?) distribution source. Be it ruby gems, CPAN, Pypy,
cabal, whatever.

~~~
nakkiel
I was also expecting to see a program running on multiple computers at some
point until I realised the article is actually not news-worthy.

------
code_scrapping
If we put aside the ego-bashing and dick-measuring, the good side of hyping-
out a technology would be to find it's limitations.

So, the articles will slowly turn from "why X is great" to "I don't want to
move to X because...", but the meta-message is that you get a survey of tool
usage.

Always look on a bright side of hype, tu-dum, tu-dum-tu-dum-tu-dum.

------
steeve
Speaking of distribution, cross compilation on Go is really, really easy and
awesome.

And for those who want to do cross compilation _with CGO_, it's definitely
possible and I put a little tutorial to do it:
[https://gist.github.com/steeve/6905542](https://gist.github.com/steeve/6905542)

------
camus2
live by the hype , die by the hype. That and the fact that the ruby/rails
community is full of egocentric hipsters that like to take a shot at each
other,other languages, and say "f*ck" too often...

The problem is now these hipsters are moving to nodejs so that community has
exactly the same problem too.

Go community,while little, is more like python's, mature,respectful(most of
the time),that's important on the long run,to build a community around
positive and cosntructive thinking.

NodeJS will burn itself like rails if it goes on that way.

~~~
gfodor
This is a fun little narrative that's been constructed here, but I fail to see
how it has anything to do with the ruby ecosystem I see from here, which is
full of highly maintained, mature libraries at this point.

------
caiob
def hype_switch from_lang, to_lang 'Why I switched from #{from_lang} to
#{to_lang}." end

------
voodoomagicman
does anyone know what the library he is using is in the example ruby code?

------
finishingmove
Code Gangsta (certified) !!!

Fuck. Yeah.

