Re: [dev] Let's talk about Go, baby

From: Ciprian Dorin Craciun <>
Date: Sun, 27 Jan 2019 08:56:12 +0200

On Sun, Jan 27, 2019 at 3:57 AM Anselm Garbe <> wrote:
> I
> wouldn't recommend the cgo approach at all ;) I came to that
> conclusion almost 10 years ago already, when some people started
> writing WMs with Xlib in Go (cgo'ed xlib.go or whatever it was called
> at the time) and realized that it sucks.

Indeed, CGO is not a "simple" solution. I too once had to write a
LevelDB interface to Go, and it wasn't a pleasant experience... On
the other side Rust's solution is a little bit simpler in this regard,
and as a bonus, it already includes a library `libc` which exposes
everything the native C library has to offer, therefore calling a
`libc` function is hassle free.

However to the date, except Rust's approach, I can't say I've seen any
language that handles nicely the C interfacing, most solutions
resembling Java JNI's as you've mentioned.

And still on this topic, has anyone programmed in Erlang, and wanted
to interact with the OS? I ask because they have two ways, one the
JNI way, and another very UNIX-y in nature: just write a C program
(or whatever) and communicate with it over stdin/stdout. (I know that
the second way isn't rocket science, but its used by default in a lot
of places, which I can't say for any other programming language out

> > On the other hand comparing the two languages (as in syntax and
> > features) is not enough; one has to look at their ecosystem, better
> > said the tooling, documentation, and third-party libraries (and
> > dependency management tooling).
> Yeah and these ecosystems are actually something I pretty much
> dislike, specifically in Go as well. It really feels like a autocratic
> environment. I really prefer how 'free', diverse and lean the C
> ecosystem is. Only ecosystem is probably which compiler and which
> target you wanna use. Some people might be inclined with Rusts or Go's
> readymade environments, but it feels too much like a JDK to me (sorry
> for the comparison).

My issue with C-s ecosystem, which contains only the compiler and
linker, is how people manage library dependencies? Sure you install
these libraries via the package manager (hoping that the same library
version, or compatible) is available in other distributions / OS's,
however how does one handle:
* libraries that aren't available in the package manager? (many
projects just embed these libraries;)
* how to deploy such applications when on the target one doesn't have
`root` rights and the application requires some library which isn't
installed? (I remember writing wrapper scripts which
`LD_LIBRARY_PATH`, or patching the executable to use `$ORIGIN/lib`;)

> > * Go's approach (until lately) was, how to put it, "non-existent";
> > you would have a `src` folder where you've let `go get` checkout your
> > dependencies at whatever version their `master` branch was at, hoping
> > for the "best"; **there is no concept of version** (therefore there
> > are a lot of competing "vendoring" tools;)
> > * Rust's on the other hand went the Java / NPM / Ruby / Python way in
> > providing a centralized repository, explicit versions, explicit
> > dependencies, etc.;
> Go's approach does give you the freedom to invent version handling on
> your side. I kind of prefer that there is no centralized or
> recommended straightjacket for versioning or dependency management.
> At leat I personally would probably dislike how it is mandated and
> prefer my own way.

But here is the issue: have you found a working solution for this
version handling in Go? I'm still yet to find such a solution. In my
case whenever I start a new Go project, I spend about 1-2 hours
copy-pasting some wrapper scripts that allow me to have my `sources`
folder, but then "reconstruct" the mandated `/pkg` folder structure...

Go sure doesn't provide a straight-jacket for dependency handling, but
it surely does provide one for your project structure...

Therefore I would say in today's environment having a dependency
manager is a must, and I would say that:
* (to date) Go has a very primitive dependency manager which only
identifies the required libraries and checks-out their master branch
hoping for the best; (they are working for something better;)
* Python has `pip`, `virtualenv` and one has to cobbler them together;
 however when the requirements are installed you don't have an
automatic way to get exactly which libraries are installed, and most
importantly at which version, so that your co-workers have exactly the
same development environment; (they are too working on this;)
* Ruby / NodeJS (npm) / Rust have a very complex dependency system
which have both optional dependencies, development only dependencies,
the "dependency version lock file" (which solves the previously
mentioned item with Python);
* Java has Maven which, besides the dependency management, is really a
`make` replacement;

Therefore, given how "suckless"-less many libraries are -- in fact
many are just plain crazy, for example in the NodeJS world if one uses
a large framework, one can easily end-up with 1k dependent libraries
-- having a dependency manager is a must.

> > (For example in Go, I'm yet to find a good way to fork a library,
> > patch it, publish it under my own GitHub account, and still be able to
> > use it without changing all the imports to the "forked" location...)
> Hmm, I don't really get what the problem is here. Just maintain all
> dependencies you rely on on your side and good is.

And then how do you distribute your tool to others? Sure it works for
personal projects that don't ever see the "light of the internet"?

In my case I had to resort to `git-submodules` and give some bash
snippets so one can create its own `/pkg` environment. (As opposed to
the simple `go get mytool`.)

> Never rely on
> dependencies maintained by someone else. How would you prevent those
> dependencies to start behaving 'funny' at some point, if you don't
> maintain them?

In Ruby / NPM / Rust each library tries to follow semantic versioning
(which mandates that backward incompatible changes must change the
major version), and your package manager writes down in a "lock file"
what version of each library you've actually been using. Thus you at
least get repeatable builds.

Moreover in Rust's case, the source code of the dependent libraries
are taken from a centralized repository, where one can't even change
an already published version. Therefore if your tool had successfully
built two years ago, it would certainly build now.

Then you upgrade your dependencies carefully so not to break anything.
It's the same as curating your own forks of those dependencies.

> At least in my stali experiment I came to the conclusion, that this is
> the only way to do things right. You have to maintain *all*
> dependencies in your side, otherwise something will break sooner than
> later.

Or see the above. :)
It's a whole other world. :)

> > > Besides this it's the hipster environment of Rust that is putting me
> > > off.
> I don't mean the modern look of the web page. I derive my judgement
> from people I know who are pretty strong Rust zealots and I'd say
> those I came across fit very well into the hipster category of things.
> It might also be because Rust ist certainly pretty new in PL terms,
> and hipsters are usually attracted by if something is new it must be
> good.

But this is true of every language / tool / OS out there. I have
encountered Java "zealots", Ruby "zealots", Python "zealots", and on
the internet many Go "zealots", but then this doesn't make a language

On the other hand the some ecosystems might be called "hipster-ish"
due to the way the community is organized and the "look-and-feel" of
the libraries written; however at the moment I would say all
programming languages look "hipster" by this definition. :)

> > use-cases of this community. However I am yet to find a large
> > "enterprise-ish" / user-interacting system written in C / Go / Rust;
> > and in fact at the moment if I were to start a large "enterprise-ish"
> > project (especially of the "book-keeping" kind) I would choose Java
> > without a regret...
> Well, define enterprise-ish ;)

An accounting software, an electronic medical records system, an
internet banking system, airplane ticketing systems, the stuff that
big business pay money for. :)

I understand that these are badly-designed, badly-written,
poorly-secured, etc., however they "keep the world spinning"... :)

> If you mean mediocre software that
> contains many bugs, poorly performs and features a big complexity that
> could've been done in much more easy and straightforward ways by using
> C, then I agree. I didn't come across any Java software in my life,
> that had equal behaviour in terms of stability, reliability and
> maintainability than almost any decent C program that we use in our
> system.

I beg to differ... I had the opportunity to look inside OpenSSH's or
Bash code in order to "patch" some idea in. And to this day I still
cry when I think about what I saw in there...

Now I don't say this is OpenSSH's or Bash's developers fault, as they
are complex systems with a lot of "legacy". But it does prove the
point that just having a program written in C is not a silver bullet.

> > Moreover, last week I've played with HHVM (Facebook's PHP execution
> > environment), and I would say that in this configuration (i.e. HHVM as
> > the "PHP execution environment") and with simple PHP code (without
> > frameworks which try to mimic Ruby's Rails) the result could be quite
> > "suckless" and UNIX-y in nature.
> I don't know that one. I do know React a bit and can say, that
> generally speaking the Facebook engineers seem to be saner in many
> aspects than most Google engineers. Not sure why that is though.

I can't believe that I agree with your statement about the sanity of
Facebook engineers... :)

> > BTW, does one know of a "suckless" CGI HTTP server? (Perhaps written
> > in Go?) :)
> I once added cgi support to quark, but the work of recent years
> removed this. CGI has not many fans these days -- I still like it for
> simple stuff.

Then I must share with you these two nice tools, written in Go (I've
never used them, but when I will have the need I'll certainly do):

Received on Sun Jan 27 2019 - 07:56:12 CET

This archive was generated by hypermail 2.3.0 : Sun Jan 27 2019 - 08:00:08 CET