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

From: Anselm Garbe <garbeam_AT_gmail.com>
Date: Sat, 26 Jan 2019 17:56:20 -0800

Hi Ciprian,

On Sat, 26 Jan 2019 at 13:35, Ciprian Dorin Craciun
<ciprian.craciun_AT_gmail.com> wrote:
> * I would skip C if it doesn't require too much OS-related
> interaction; in fact if I do need OS interaction, Rust is a better
> alternative than Go, due to Go's goroutine runtime which, as a
> previous poster noticed, doesn't play nice with the standard C
> library;

When considering Go, it surely is a bad idea to incorporate any libc
bypass. Either plain Go and using its own syscall abstraction inside
or sticking to plain C altogether ;) If someone uses libpng or
whatever from inside a Go program, the devil will be drumming. 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.

The only comparison to cgo I have personal experience with is JNI --
it suffers almost the same issues, but has the advantage that the JVM
is hooked ontop of C's runtime and syscall implementation, so there
are no surprises by running into concurreny problem due to independent
syscall abstractions in the same process concurring with each other.

> 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).

> * 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.

> (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. 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?

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.

> And lastly there is a hidden pitfall with Go, which Rust solves it
> "better", in the case of high-performance use-cases: heap-based
> allocation of what "seems" to be a stack-based allocation (especially
> in the case of buffers).
>
> Go's compiler tries its best to use stack-based allocation, however it
> throws the towel whenever it encounters a interface. For example say
> you want to implement a simple tool that computes the
> cryptographic-hash for the input stream. You'll just use the `Hash`
> interface, declare a buffer of "enough" size, and loop through
> read-hash. Unfortunately because we use the `Hash` interface Go's
> compiler can't keep the buffer on stack, but instead it allocates it
> on the heap. However one allocation is not that bad, unless you've
> decided to declare the buffer inside the loop (just before the read),
> instead of outside the loop; in the former case you'll end up with as
> many allocations as there are iterations... In Rust on the other
> hand, being explicit about allocation, you don't have to "hunt" for
> such places in your code.

Interesting example. This is why I like C more than golang, because I
know exactly what happens. I can't hide the fact by some implicit
language features how something is allocated and where.

> > Besides this it's the hipster environment of Rust that is putting me
> > off.
> I am truly curious what contributes to this "hipster" perception?
> (I myself find that the old web site was "better" than the current
> "color-fest" site... However if you look past that I find it quite
> "serious looking", or at least as "serious" as Go's ecosystem...)

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.

> Sometimes I would say that perhaps in Go there is too much "Bell Labs"
> heritage... (For example the `Dial` function name... What's wrong
> with `Connect`?)

Heh, I suspect that dial is more a Plan 9 influence, I think they used
connect() earlier even at Bell Labs in UNIX, but I might be wrong.

> I do acknowledge that sometimes "functional pipelines" seem more
> closely to badly written Perl code; however I do miss (in Go) the
> ability to `v.map(|x| x*2)`...

This is something I really dislike, whenever I come across this
map/reduce or filter paradigms in 'modern' programming I could cry. I
kind of find it totally counter-intuitive, but call me old fashioned.

> Thus my bottom line about the two would be: I like them both (perhaps
> Rust a little bit more), but each has it's own use-cases which don't
> overlap much.

Fair enough.

> 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 ;) 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 only hear excuses in the enterprise world about why some
Java crap doesn't work. But I almost never see some JVM process that
has had an uptime for > a couple of weeks.

> 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.

> 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.

Best regards,
Anselm
Received on Sun Jan 27 2019 - 02:56:20 CET

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