Hacker News new | past | comments | ask | show | jobs | submit login
Go Is a Shop-built Jig (2014) (robnapier.net)
103 points by m1245 on May 26, 2018 | hide | past | favorite | 76 comments



I've always felt this is one of the better characterizations of Go. Great programming tool. Not an especially great programming language. A lot of the time, more than we acknowledge in PL slapfights, that's what you really want. And, sometimes, being in an efficient but limited language allows you to focus better on your problem domain, which can be useful creatively.


On Go-the-language, I agree. It takes a few things from PL design that have widely been shown to be helpful and packages them up in a simple language that C/Java programmers can use to be productive in an hour or so.

The implementation is a different story. It was really goofy to implement a new compiler backend, garbage collector, scheduler, calling conventions, and hey, why not make have the standard library make syscalls directly, what could possibly go wrong? The result has been the last several years has largely been spent reimplementing solved problems (basic compiler optimizations, a GC which is competitive with JVMs from 15 years ago, etc) rather than actually evolving the language.

In short, I wish they'd stuck with their "just do a few things well" philosophy in both language design and implementation.


The compiler backend, till the Go rewrite, had been in production use for ~15 years or so from the top of my head, it's just neither GCC, nor the new hotness LLVM.

Calling convention TBQH is something that often has to be custom in a language outside of interop bits, otherwise you are forced to deal with various C-style brammage. Unfortunately most OSes don't have language-independent interop calling conventions (Windows has COM, VMS has, iirc, SDL, the rest pretty much has nothing), so even if technically there's some official document practically you get stuck with peculiarities of a specific compiler and its relationship with C standard library. Syscalls are about the only safe interface on most unices and the reason why you can make self-standing Go programs that don't bring glibc garbage and random and unexpected shared library dependencies, something that is quite a reason for the following Go gets on container based platforms.


One of Go's features is fast compilation, which wouldn't have been the case if it used LLVM.

> a GC which is competitive with JVMs from 15 years ago

I don't know where you got this impression, but it's absolutely wrong. Go's garbage collector is excellent. It has sub-millisecond pauses [1] (for multi-gig heaps), and it mostly runs in parallel to the application.

You might be referring to Go's old GC, which was dropped when the current was introduced. [2]

[1] https://groups.google.com/forum/?fromgroups#!topic/golang-de...

[2] https://blog.golang.org/go15gc


Go has never been a single implementation language. It had a GCC backend since the start.

GC (Go Compiler) has very peculiar characteristics: for one thing, it's written in Go itself. Another important thing is that it's very fast. That was an objective since the beginning of the Go project.

Finally, comparison with Java GC (garbage collection) are quite nonsense as Go has a very different allocation pattern than Java software.


I would call your comment a better characterization of that "better characterization" :) Says it shorter, and gels with some of what I have experienced, specifically the last sentence. That even works if are you in a less limited language but consciously do not use some of the more advanced features, because you know you don't need them for some work at hand.


I cannot really put my finger on it, but Go is basically perfectly compatible with the way my brain works. Its semantics so far have not surprised me, and I only have to look up the language specification very, very rarely. Most of the time (like 90+ %), I can just let my intuition guide me. Of course, Go has its share of problems, but that one huge advantage dwarfs those problems entirely.


That, plus the lack of magic.

I can always understand what a Go program is doing because of the simple semantics and lack of magic. It's an underrated benefit to be able to browse the source code of a dependency and grok it easily, first time.


Maybe it's because I've gotten better over the last year, but since I swapped from Java/python/c++ to a Go project, I've reduced my "find the answer on Stack Overflow" time by at least 75%.


The error handling in Go seems verbose:

    if err = logit(FrobulatingMessage); err != nil {
      return err
    }

    if err = f.cleanupOldest(); err != nil {
      return err
    }
There's an advantage, though. You can easily insert code for an error case. You might add, if cleanupOldest fails, something like

    logError("cleanupOldest failed unexpectedly while cleaning up chain")
if that's an unlikely but possible event that needs to be investigated. Big operational shops do that. It's hard to stick debug code in the middle of an expression.


The equivalent in rust, for a fair comparison:

Before:

    frobulate(message)?;
After:

    frobulate(message).map_err(|e| {
      error!("error happened: {}", e);
      e
    })?;
    // or, more like the go one
    if let Err(e) = frobulate(message) {
       error!("error: {}", e);
       return Err(e);
    }
It's really not that different in the debug case than go, but the normal case is less painful to deal with.


> I would rather spend my time writing generic, elegant functions that help developers think deeply and correctly about their programs. Like Alex, falling back on for-loops and mutable state makes me feel like a bad programmer. But there is a certain tension between all that and shipping things today.

(Emph. mine)

It hits the nail on the head: there's a certain tension between speed and correctness. For some, there's never enough time to do the right thing, but always (inevitably) enough time to keep fixing a wrong thing.

There are also diminishing returns of typing imperative code fast top to bottom, but having to deal with constant boilerplate and manually checking things that a machine could check, were the language more expressive.

Somebody called Go "systems PHP"; I think it's very fitting.


Ehhh I dunno about the PHP thing. I can see what you mean, but there’s a certain negative implication to it which isn’t accurate. PHP is bad because it’s inconsistent and doesn’t really have a coherent design. You can tell that it evolves by having things bolted on to it, and there’s all sorts of weird dark corners. Go really isn’t like that at all.


I disagree that Go isn't like that at all. On that contrary, that's exactly how I'd describe it. It's the jankiest language after PHP.

I think people coming to Go are coming from at least 3-4 different angles and it dictates their judgment.

There's people coming from languages that aren't statically type checked, from javascript to python. They like doing systems programming and having real concurrency. They like the plain style. They don't notice how weak Go's type system and abstraction faculties are, because it's already better than nothing.

There's people coming from C, who really like some things like easy concurrency, easy compiling, a package manager, and automatic pointer de-referencing, and (where applicable) GC.

There's people coming from C++ who will like the return to simplicity, but also hate it.

There's people coming from JVM and .NET who are just going to dislike almost everything about the language ergonomics of Go. You can get an actor model library and write those languages almost exactly like Go if you want to (without the bad syntax) but nobody does, because it's worse.

From my perspective, I wish people would stop complaining about Go's lack of generics. It's really an understatement. The real problem is Go basically doesn't have a type system.


I came from Java and don’t really miss anything most of the time. What you get out of the simplicity of the libraries and raw productivity more than makes up for the lack of OO features (which are abused and misused more often than not in static languages anyways). I don’t need an actor model, and I don’t miss Futures or RxJava stuff either. Channels and goroutines are plenty good enough for the vast majority of use cases. If the type system is really so bad that it basically doesn’t exist, I must be a godlike programmer to rarely have my Go code do something I don’t expect. The end product has always been stable, easy to read, and easy to debug in my experience.

Perhaps if we were to rebuild the ecosystems of each platform today things would look differently, but Java has so much baggage and shitty library APIs that it’s almost as if everything were written to abstract ideas with no regard for the human programmer using the final product. Even if your assertion that Go is the jankiest language after PHP aid correct, it basically doesn’t matter because it’s ecosystem is much more pleasant to work with than Java’s.


> The real problem is Go basically doesn't have a type system.

I don’t understand what “basically” means in this context. If you mean to say that Go’s type system isn’t formally sound, I think it would be better to argue that than to argue that it essentially has “no type system”. That strikes me as a very weird thing to say in general.


Go has plenty of weird, inconsistent dark corners. To name one off the top of my head, indexing a value in a nil map returns a zero value, while indexing a value in a nil slice panics.


>PHP is bad because it’s inconsistent and doesn’t really have a coherent design.

Same for Go. Built-in special case generic behavior -- but only for specially blessed types, and many other things besides:

https://medium.com/@tucnak/why-go-is-a-poorly-designed-langu...


I do not think an equivalence class of "incoherent languages" that includes Go and PHP is a reasonable place to argue from.


Comparing to PHP, I mostly mean the mindset: the no-frills, "just code it in a few hours" approach. Solving the problem with the minimum care of any abstraction. It works pretty well for simple scripts.

The problem is, of course, that the scope grows, and with it, the need for more powerful tools. Go does not have C's macros (phew), but has nothing else either, so people end up writing code generators.


Ahh okay, I get it. This is pretty accurate. I do think they arrived to that from different places though. PHP being more about getting shit done and iterating quickly, and Go having the opinion that the wrong abstraction is worse than no abstraction at all. In Go’s case, it’s more of a reaction against the overuse of abstraction and GoF patterns in C++/Java/C# IMO.


I disagree that PHP does not have a consistent design. Since PHP 7 they have been intentionally removing all old PHP warts and pushing the language to real consistency. They even have an RFC process now for proposing new features from the community so they can be more responsive.

It’s not statically typed like Go but it’s far from inconsistent IMO


https://eev.ee/blog/2012/04/09/php-a-fractal-of-bad-design/

> Unlike (literally!) every other language with a similar operator, ?: is left associative. So this:

  $arg = 'T';
  $vehicle = ( ( $arg == 'B' ) ? 'bus' :
               ( $arg == 'A' ) ? 'airplane' :
               ( $arg == 'T' ) ? 'train' :
               ( $arg == 'C' ) ? 'car' :
               ( $arg == 'H' ) ? 'horse' :
               'feet' );
  echo $vehicle;
> prints horse.

In what world is this sane language design?!


I do PHP a lot and it is extremely inconsistent. Even PHP7. Like half of standard library uses _ and other half does without them (var_dump(), phpinfo(), gettype(), get_class()). Half uses to other half 2 (deg2rad(), strtotime()). So many bugs because of comparsion and operators doing wierd stuff.

PHP is mad. I think they have to keep it for legacy reasons.

Don't get me wrong i think the way php handles requests is useful for the small websites i create and i would probably not use any other language for that. But PHP is THE dirtiest most inconsistent language that people actually use.


Perhaps I have a little bit of a knee jerk reaction. I've gotten a new job where I have to do php development pretty heavy, and I haven't done it since I was 19 when I was interning at my first programming job and I absolutely hated it. Back then php 5.5 I think was the latest version and it just felt incredibly impossible to get anywhere with it. It wasn't long after that I moved to Python. I only recently got a different job all these years later where I am doing it again but PHP 7 is just so much better. 7.2 in particular even though its a point release has even done a lot to improve it.

So I feel like there is this level of people who look at people who have to do PHP and actually enjoy it (and I have to say I am enjoying it, warts and all. Drupal is OK but where it really shines is https://laravel.com ) like we aren't 'real' programmers unless we somehow know its a terrible language and are only doing it because we have to.

I really like it.

With that said, if I'm being completely honest here, there are parts of the PHP community that just down right drive me nuts. There are a lot of scammy companies out there trying to sell PHP solutions that are such garbage. Its like JavaScript. PHP does have a low barrier to entry (but a high bar to being good at wielding it, much like JS. You could probably make this argument for a lot of web tech in general) that all kinds of people use it and really feels like it sullies the language quite a bit and some of the community around it.

Alas however, much like everyone hating jQuery without ever actually explaining themselves or what is the technical aspects of jQuery that make it so undesirable, PHP occupies the same space: everyone loves to hate it, it seems.


I feel confused. Are you really saying that your justification for PHP having a consistent design is that, on its seventh major version, twenty years into its lifetime, an effort has been started to attempt to establish consistency by removing some old features, and adopting a community RFC process, or am I misunderstanding your claim here?


I’ve written production code in Go professionally every day for two years. None of the language design complaints in these thinkpieces are a real problem. You learn the idioms and it works out.

Go’s showstopper problem is dependency management. Fighting with Glide costs at least 30% of my time and every moment of it is excruciating. My organization started migrating to Dep just as Google announced its decision to have the Go community continue thrashing around on the issue even longer.

My advice: do not even begin to engage with the details of the langauge. That’s a waste of time. Understand that dependency management is horrifically broken and that Google considers it reasonable to thrash between experimental half-baked solutions forever. However much you may hate Java, Maven terminates with a correct output in less than an hour, which is more than I can say for anything in the Go ecosystem.


I love Go, I really do. But there are some issues that should be fixed (maybe in 2.0).

I'm not so sure if we really need full-scale generics like in Java or Rust, but the interface system (which is the Go solution for the Generics use-cases) certainly needs some improvements. For example, when you write a container lib which expects an empty interface as input you constantly have to cast the type while using the lib. The result is code which looks awful when you use the container and horrible when you look at the container implementation.

Next, using slices of interfaces is just another bad joke [1]. there might be technical reasons for the current state, but I am sure there are ways to solve those issues.

One thing I am not quite sure about the way Go handles bindings methods to interfaces. Currently, that is not supported and the practical way to do it anyway is to embed the interface into a struct and bind the methods to that struct, but that feels more like a hack than anything else.

Another thing that keeps bugging me is the requirement for map keys to be comparable while that is just some internal property which some types have and others don't. For example, functions are not comparable and therefore you can't use them as map keys. Finding out about such stuff really sucks when functions are considered first-class citizens.

That said, I have to add that I enjoy a lot of the positive sides of Go and while I wish those issue will be fixed someday, I will gladly continue to use it even with those issues.

[1]: https://github.com/golang/go/wiki/InterfaceSlice


I don't understand: what do you mean with binding methods to interfaces?

Interfaces just represent a bunch of functions that an object must provide (and you can call when you "mask" the object behind the interface).


Well, normally you bind functions to types like:

  func (m myType) calcRandom() int {
    return m.nine
  }
But there are some situations when it would be useful to be able also bind functions to interfaces (e.g. some of them are similar to use-cases for abstract classes in OOP):

  func (i myInterface) calcRandom() int {
    return i.Nine()
  }
While I would consider it a clean language design to be able to do that too, it brings some additional complexity and as we know Golang doesn't like complexity.

As I said, I am not completely sure of the consequences such a change would bring with it and if it would enable bad practices. So I would not push too hard for that one, but some of the other issues I mentioned are issues of which I am pretty sure that they should be fixed.


um.. I think you've confused the interface and the implementation.

Interfaces are not the same thing as classes, and bringing anything from OOP to them will almost certainly result in Bad Things.


This article contains a dead link in the third paragraph marked as "bugs the lead language designer". Here is an archive.org link from the same time period: https://web.archive.org/web/20140822173033/http://gophercon....


Though to continue with the analogy, you don't want your entire workshop to consist of ad-hoc tools that kinda-sorta work for narrow purposes. You want your basics to be solid, well-designed, and applicable generally - so that you're not already having to account for their individual exceptions and shortcomings when you layer your hacky jigs on top.

I feel like there's a physical workshop analog of how (Lisp) macros get you one and only one additional layer of abstraction. I've made an impromptu "table saw" by fastening an upside-down circular saw to a piece of plywood, but it certainly wasn't a basis for doing anything greater and I had to be real deliberate about plugging that thing in.


So again, in the end, Go turned out to be a language for solving real problems rather than a language filled with beautiful tools, and so you build real solutions rather than finding excuses to use your beautiful tools. Don’t try to make Go what it isn’t. If you’re trying to solve abstract CS problems in their most generalized forms, then you may find it frustrating. But if you’re trying to solve specific, practical problems in the forms professional developers typically encounter, Go is quite nice.

This is a straw man argument. How many people who complain about Go -- or evaluate it for a project, drop it and move on -- start out solving non-real problems?


This is exactly what I feel when using Go. Love the way I can really focus on solving real problem rather than trivial (but important things like styling and formatting). About generic, when I thought need it, I always able to find simpler design using composition.


>About generic, when I thought need it, I always able to find simpler design using composition.

How exactly would composition help you e.g. make a general purpose reusable math library for different kinds of numeric types?


I think the implicit argument is that “a general purpose reusable math library for different kinds of numeric types” is not a real problem.

A real problem is, “I need to draw this triangle”, and using math.Cos w/ float64s works just fine.


And yet it's a problem anybody who makes any kind of library that should work with > 1 types, faces...

Not just math and scientific libraries. Even a simple reusable data structure. And fact it's so commonly needed for this, that Go's slices and maps would have been useless unless Go's designers have not cheated and used genericity for themselves...

And let's not get into reusable abstractions for behavior -- like a library that encapsulates the 5-10 more common uses for channels and goroutines (span N goroutines and wait for all to collect the results, span N and use first result, and so on).


You could say my usecase is on different scope than that. But I still on the against side of the generic. It will add (for me unnecessary) complexity to the language.

Cmiiw even when have generic in place, we still need to write the code for each type right? Just the interface is the same. (this argument sounds silly actually, just want to say that)


About generic, when I thought need it, I always able to find simpler design using composition.

This doesn't seem like it can be broadly true, though. Have you never needed containers besides Map and Array?


You're right it couldn't be true on all the cases In my use case map and array are generally enough.


In Swift, what's wrong with writing the imperative version to start with, then switching to the monadic version as there's time to polish, or as the function logic evolves to a point where other styles are clearly preferable?


Nothing at all. His point is just that there's cognitive burden associated with making those kinds of decisions in Swift, and there isn't in Go, because you don't have those options. All things considered, he prefers Swift. But he's productive in Go as well.

I've had similar experiences. I find that for some problems --- not all of them --- I can drill in quicker in Go, because the problem is all I can really think about; there isn't enough elbow room in the language to really spread out and work on the task of making things elegant.

At my last company, I found that writing an emulator in Go was super straightforward, and I think Go made that task easier than a "better" language like Clojure or Swift would have. But in addition to an emulator, we also wrote a compiler, and writing a compiler and SSA optimizer in Go was fairly unpleasant. Not prohibitively so, but enough that I noticed it.


I think it’s kind of akin to the premature optimization people do when they think they have ‘big data’, but really don’t.

If you’re really doing heavy list processing, transforming complex data structures, etc., then you’re probably going to miss map, reduce, and friends. But for most real world problems, the code is faster to write, faster to run, and easier to understand with a few dumb loops.

It’s always tempting to do things the clever way, but Go made me realize how rarely it’s actually beneficial.


For compilers and optimizers, people have said pattern matching support in the language is very beneficial. I bet there are other tasks where something like algebraic data types and pattern matching would make the code much simpler, and it's not really hard for the language to implement.


The issue here can become, that there's more than one way to do that translation. Monadic operators and the underlying types are all broadly similar but not the same. It's a little like the situation in JS with promises, though with promises the convergence has been pretty rapid and one can basically ignore that the underlying implementations are different.


The title of this submission reads like a No True Scotsman fallacy.


I think this is from 2014?

Anyway, it hardly seems fair to give yourself choices (by introducing that “LlamaKit” library) and then criticizing Swift because there’s different ways to approach the problem.

(And I wonder if LlamaKit does anything besides obfuscate code? Hopefully I’m just missing some context.)


He's not criticizing Swift. He's a Swift programmer who prefers working in Swift to working in Go.


it impossible to not roll my eyes when i read such a title.


Flagged for changing the blog post subject to clickbait.


> Very cross-platform out of the box. Not “sort-of cross-platform as long as it’s unix” like C/C++

Wut? Firstly, no it's not. I have to drop into MinGW just to interface with native libs statically. Many languages don't do this. Secondly, C++ is very at home on Windows. Not a very good FFI story for something that is very cross-platform that it only binds w/ C libs with only one Unix compiler (gcc). It's like you got the phrasing exactly backwards and need to switch Go and C/C++.

> Go feels under-engineered because it only solves real problems.

Until I list the ones it doesn't. Or are they not "real"?

You know what? I'm not reading these things anymore. We know the type...supposedly senior devs writing a bunch of words about one language over another, cherry picking specific things for both to fit the narrative. I feel like this is how Michael Moore would write blog posts comparing languages. Sorry to hop on this article like this, saw it a couple of days ago with the Java/Kotlin blog post too and I'm seeing it every so often. And I like Go and Java. I'm afraid I just don't see these language opinions as that valuable anymore since I write in them all myself and know better.

Edit: In retrospect, probably a bit harsh. But I'd prefer the journalistic lang X does this but not this approach over the op-ed.


I'm an old C++ programmer who's had the pleasure of doing an XP codebase and I would pick Go any day of the week over the early-aughts C++ I remember working in --- but I concede this may have gotten better since then.

While I don't think he was trying to say Go solves every real problem (rather, just that the subset of problems Go solves are all practical and not theoretical), it would be constructive if you could take the time to list the problems you think Go is bad at solving, and why.

I'll probably agree, but I may also learn something, and I'll definitely learn more about where you're coming from.


As someone who uses Go daily and enjoys it a lot, there's definitely an inflection point in many areas where Go's lack of abstraction becomes a pain point.

One application I work on is a real-time query engine. Queries are parsed into ASTs, then reorganized into a higher-level graph reminiscent of relational algebra, then run through optimization stages, etc. Go is terrible at this in pretty much exactly the same way C is. Clearly, good software has been written in C that face the same challenges; PostgreSQL comes to mind, but I've read the PostgreSQL code, and while it's clean, I don't find it that readable or nice. Those guys work with C's limitations, of course, and that's fine.

One specific example here is matching structures. I look at Haskell and Scala with envy, because you can do things like this (pseudocode!):

    match expr {
      Or(p, And(q, r)) => And(Or(p, q), Or(p, r))
    }
Similarly, writing graph-traversal (walking and transformation) logic in Go is painful. Go doesn't have sum types, so you have to dick around with interfaces (which weren't meant for this) and write big table-driven tests to ensure that all your matching cases is exhaustive.

There's a lot of boilerplate, and there are times where I've been tempted to write code generators that use small DSLs that let me express everything in a higher-level way. But I've not taken that step yet.

If I'd started this particular project today, the choice would have been Rust or C++. This applies to future project that smell like something that'd need this kind of expressiveness.

Another area where Go disappoints is how surprisingly hard it is to write good concurrent programs that need to distribute work and handle errors in a resilient manner. Your actual logic — the meat of your program — quickly becomes obscured by error handling, ErrGroups, channel orchestration, inelegant wrapper structs, managing the lifecycle of resources (sockets and files and what not) and, ugh, contexts. Context is like a virus that morphs code into refactoring monsters every time you start weaving it through your application. I get Erlang envy when I need to do even the simplest thing, like coordinate the concurrent importing of chunks of data that is distributed to a dynamically growing/shrinking pool of worker goroutines. With all the bragging about modern CSP, Go provides nothing that can compete with Erlang supervisors, which is mightily strange for a (relatively speaking) new language supposedly invented for writing resilient networked systems.


While I would choose Go too, my specific complaint was about saying that Go is very cross platform and C/C++ are only sort of in a Unix way. Not only do I think Go has cross-platform issues wrt Cgo and that they only support gcc (but hopefully changing [0]), but that it is incorrect to say C/C++ is "sort-of cross-platform as long as it's unix". Those types of statements turn me off the article. So I stopped reading after that and the "real problems" statement.

I'm not sure it has much value to list places where Go may not solve the problem because we all know the limitations of our languages/platforms/runtimes. Among places Go is not the best: low-level embedded software, very performance critical software, software static correctness is more important than maintainability, etc. It's like saying Rust solves all real problems. While I guess mostly true, it doesn't mean too much to me. In general, I'm just finding these posts have little value to me anymore.

0 - https://github.com/golang/go/issues/20982


This is just disagreeing on definitions. You're assuming a particular definition of "cross-platform" and I think what they mean is that pure Go (using its standard library) is very portable. It's great if the standard library does what you need.


A portable stdlib does not a portable language make.


While I agree with most of your comment, I think you've misinterpreted the intent here:

> Until I list the ones it doesn't. Or are they not "real"?

My reading of the original post is asserting that there is a specific set of problems that Go is designed to solve well, and that it's avoided providing functionality not related to those specific problems. The entire comparison is to a "shop-made jig", which explicitly solves only a specific subset of all problems you might encounter in woodworking, but is not at all a general-purpose tool.

This definitely fits with my experience with Go. If you want to build something that only needs concrete data types, channels, HTTP, and a database connection, and want to bang it out fast and move on, Go works well in this niche, because that's precisely the set of "real problems" that it was designed to solve.

I do not consider Go a general-purpose programming language. I would not use Go for ambitious large-scale projects. If I were putting together an engineering team to write a small network service, with junior developers, Go would be at the top of my list.


I admit I may have taken the "solves real problems" too literally and did not read the rest to understand it.


These kinds of nuances can be a bit subtle; I hope I managed to come across as polite correction instead of attack. :)


The fun thing is that Go on unix is not the native Go environment, and it shows in several places, including treatment of import paths of all things (the whole GOPATH thing).

It shows even more in the fact that it originated, and afaik is still partially compatible, with a C compiler that is completely alien to both GCC and MSVC worlds. In essence, Cgo is a hack even on GCC.

Windows treatment of C and C++ as "just yet another language" is very alien, however, to the devs who come from unix world, and many basic things are not handled corrently by them or even planned for :(


Go is cross-platform out of the box.

The problem is that you can integrate other languages like C which often don't come with cross platform compilers. So any Go program which depends in some way on C is not cross platform anymore (as long as you don't have a cross platform C compiler).

To be honest I don't know how to solve that issue. On the one hand I really like the easy cross platform capabilities of the Go compiler, on the other hand I don't want to sacrifice language interoperability for cross platform builds.

I wonder how someone who has C/C++ experience thinks of Go as not being a cross platform language.


> To be honest I don't know how to solve that issue

Support more compilers (e.g. clang, msvc). It can be more work than it's worth, sure and I understand the issues there, but jumping through hoops per platform (e.g. can't use a popular lib like https://github.com/mattn/go-sqlite3 on Windows without a MinGW gcc installation) is worth noting when touting the cross platform ease of use. Langs like Rust were lucky to compile to the same IR as a cross-platform C compiler.

> I wonder how someone who has C/C++ experience thinks of Go as not being a cross platform language.

I don't think that and definitely never would. I said it has issues, namely in the Cgo department. And I said that the other statement about C/C++ only being Unixy was wrong.

I definitely like Go and its cross-platform ability and hope I didn't give the impression that I don't.


> Langs like Rust were lucky to compile to the same IR as a cross-platform C compiler.

Even then, it was a lot of work to be compatible with MSVC. Alex Crichton spent years on it. Not to mention the dozens of man-years of work that folks from Google put into getting it all to work on the clang/LLVM side.


Okay I might have interpreted your words a bit too harsh and I have to admit that especially in the case of sqlite I am disappointed too that there is no easy way to built cross platform builds for projects which use it ;-)


What's the big deal with using mingw?


MinGW doesn't integrate as well with the predominant workflows (toolchains, linking, debugging, etc.) Most Windows desktop apps are compiled using MSVC, so this is important for many people.

Just to name one issue of many, MSVC uses Microsoft's PDB format for debugging instead of GCC's DWARF.


Besides what has also been mentioned, sometimes it breaks and reasonably so since so its not the most targeted environment. For example, lots of people had to downgrade packages on MinGW recently for a bit before fixed, see https://github.com/rust-lang/rust/issues/47048


See, this is why I don't blog. Something hits the top of HN and you go from "guy writing about tech for fun" to "supposedly senior dev" faster than you can blink.


Meh, people like me shouldn't be able to make you feel bad about what you write. I would recommend ignoring me or disagreeing with me the way I have with the author. Otherwise, this would be the reason why I don't comment on HN. My comment hits the top and someone complains faster than you can blink.


It feels even less cross-platform when you have a team mate who uses x/sys/unix and you're on a mac, which may be expected, but your first quote seems to miss such situations. (The quote itself, not your comment on it - [edit for calrity]).


> When writing the Swift function, I found myself spending a lot of time thinking about how to write it. Should I use >>== or .flatMap()? Should I use my custom Result here at all, or should I stick to standard Swift and return NSError?, or maybe Bool with an NSErrorPtr? This was my first time using Result<Void>, and I started asking myself if I should create a typealias for that and maybe a helper function for the slightly strange looking success(()). The var bothered me. It always feels like a hack in FP, like you’re not smart enough to do it right. I wrote a different version that didn’t have a var. That duplicated self.cleanup in two places. So I started working on a new function that would let me include the conditional in the functional composition. I made and re-made a lot of choices.

This has basically been the entirety of my experience with Scala. Having too many options - including just writing Java without semicolons - is ultimately not great for my own productivity.


Edit: I had used a quote from the blog post as the title, but updated it to match the blog post as I realised it was a mistake.

The original title was: "Go feels under-engineered because it only solves real problems".


Go might be nice and all, but I could probably never in good conscience use it seriously, for one simple reason: It’s dominated by Google. It was started by Google, and all of its core development (I assume) is done by Google people, with Google’s blessing. It’s even named for the company, making the ownership transparent and obvious to all.

With something like C, C++, Lisp, Python or the like, you know that even if some large company abandons it, it probably won’t even make the headlines, since it won’t matter much for the rest of the users of the language – it has a large enough user base that the language will be fine.

But what if the controlling company decided to abandon Dart, Swift, C#, Go, etc.? It would kill the language in an instant. Or if they decided to simply take the language in a new direction more suited to the company but contrary to the wishes of its global user base? I can’t work under those conditions, and neither should anyone else accept to do so.

To clarify: If, say, at least two thirds majority of the development of the language was no longer done by a controlling company (and if the supposedly non-affiliated developers were not also all incidentally employed by the same company), and, in the case of Go, the name was changed, I would probably not have a problem with using any of the aforementioned languages.

P.S.

Rust is a slightly special case, since it’s dominated not by a company, but by the Mozilla Foundation, making it slightly more dependable than an arbitrary company.


>Go might be nice and all, but I could probably never in good conscience use it seriously, for one simple reason: It’s dominated by Google. It was started by Google, and all of its core development (I assume) is done by Google people, with Google’s blessing.

I don't think Google is particularly the problem here. Go has lots of people working on and with it from outside Google.

The problem is that the core team is very resistant to any kind of outside ideas (while not being always brilliant with their ideas to compensate) -- and the community has fossilised to those loving the same ideas as well. It encourages a groupthink that's not there in other languages.

Contrast with e.g. Swift, which while run by Apple, has a great community participation story (to the point to going into too much bikeshedding).


A significant part of it is that there's a disconnect between a bunch of the core team, and the rest of the world, because even said fossilized group of the community often has no idea about certain Go fundamentals (like that significant portion of the runtime is copy-paste rewrite of certain C libraries, libs that even were part of the runtime before the rewrite, and that Go is verily not unix/posix native language).




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: