News for hackers. Stuff that matters.
Re:Go Creeping In by DiabloD3 on Tuesday June 18, 2019 @06:12AM (#20211301)
I just don't think Go has a place in new code. I know Googlers (who shall remain unnamed to protect the innocent, and politics at that company can kill your career) who joined the Go fandom because its their company's language, their department was C++ or Google-flavored Java heavy (arguably, a Java style worse than 'normal' Java or Android's dialect), and it was their only way out...

However, when they were exposed to Rust, a lot of them converted to Rust, and now write Rust for Google on internal apps that need performance but safety, especially during concurrency. Others were exposed to Kotlin (especially due to the Android guys), and are championing that as a replacement for Google-flavored Java inside the company, since the JVM is also very sane when it comes to large scale safety during concurrency.

So yeah, if I was writing brand new highly concurrent coroutines-like code, I'd skip Go and Goroutines, and go straight to Kotlin and Akka (not written in Kotlin, but very natural to use with Kotlin), since I end up with the power of the JVM, the elegance of Kotlin's syntax, and the Erlang Actors brought by Akka.

And for those who have never used Erlang, learn it once, write something highly concurrent in it, and you'll learn to distaste almost every other language's faulty concurrency idioms almost immediately. Without the Erlang actors model, you're not going to be writing fault tolerant concurrent systems; just like "all languages converge until they become LISP", all concurrency systems converge until they become an Erlang actor model.

Re:Go Creeping In by the_duke on Tuesday June 18, 2019 @06:35AM (#20211462)
I'm personally not a big fan of Go due to the weak type system, with lack of generics as the main offender. And as a result, the ubiquitous `interface{}` pattern, stringly typed annotations, ...

BUT Go offers simplicity, incredibly easy concurrency, decent performance, a good standard library for networking/http services, very quick compile times and a stricter type system than many other languages like Python/PHP.

For many teams, especially coming from more dynamic languages, Go fills a sweet spot of performance, concurrency, type safety and ease of use.

I love Rust, but it is much more complex, boilerplate heavy, adds more friction, is harder to learn, and concurrency is much harder to get right, even with the upcoming async/await feature. Not to mention the immature ecosystem, that will still need years of catching up to achieve parity with Go.

Kotlin is also a great language, but has it's own downsides. You need to learn and understand Java (due to the many Java dependencies that you will pull in), there often will be a mismatch between Java libraries and idiomatic Kotlin code, concurrency is harder than in Go, and the JVM is a much more complex beast then the minimally tunable Go runtime.

Go definitely has a place, even though it often wouldn't be my own first choice.

Re:Go Creeping In by enneff on Tuesday June 18, 2019 @07:36AM (#20211866)
> the ubiquitous `interface{}` pattern

I’m totally biased because I’ve worked on and with go for a decade, including reviewing all sorts of Go we write at Google, but I just don’t get this criticism. It’s just not something I see in the code bases I work on. I admit that I may be working on different kinds of programs to what some others do, and I don’t want to deny anyone their legitimate experiences, but my personal experience has been that this is rarely a thing, if ever.

Re:Go Creeping In by the_duke on Tuesday June 18, 2019 @07:56AM (#20212018)
It can be found in many libraries in the ecosystem, and is common enough in the standard library.

The lack of generics just severely restricts the expressiveness of the type system.

I think the best way to work around this is use of code generation, which is a great tool for internal, controlled environments, but very cumbersome for open source libraries.

Re:Go Creeping In by enneff on Tuesday June 18, 2019 @08:16AM (#20212180)
I don’t see much, if any, generated Go code at Google. Not to say that it doesn’t happen but it’s not on my radar.
Re:Go Creeping In by zigara on Tuesday June 18, 2019 @08:30AM (#20212272)
Re:Go Creeping In by pjmlp on Tuesday June 18, 2019 @09:40AM (#20212841)
Kubernetes makes heavy use of generated code, as workaround for lack of generics.

They even gave a FOSDEM talk about this, with a very interesting title.

https://fosdem.org/2019/schedule/event/kubernetesclusterfuck...

Re:Go Creeping In by dnautics on Tuesday June 18, 2019 @10:16AM (#20213214)
Aren't http or grpc apis autogenerated? You'd be crazy not to use a generator for those.
Re:Go Creeping In by happythought on Tuesday June 18, 2019 @10:55AM (#20213749)
I don’t have the experience you do, but I feel like it comes up a lot when working with dictionaries and json.
Re:Go Creeping In by samnardoni on Tuesday June 18, 2019 @08:34AM (#20212296)
sync.Map?
Re:Go Creeping In by natefinch on Tuesday June 18, 2019 @09:25AM (#20212683)
I've worked on a million line Go code base and a dozen open source projects and many typical backend services, and interface{} is actually quite rare outside of something like json serialization or string printing - i.e. fmt.Printf(msg string, args ...interface{})

I almost never see code that application developers write using it, and usually if someone is writing that code, it's wrong, and I help them figure out how to avoid it.

Usually you can avoid it by using closures or interfaces.

Re:Go Creeping In by hombre_fatal on Tuesday June 18, 2019 @10:58AM (#20213804)
Just depends on the person. Some people like to copy and paste 50 times, some people use interface{}.
Re:Go Creeping In by natefinch on Tuesday June 18, 2019 @01:54PM (#20216086)
Functions are a thing. Interfaces are a thing. I have literally never, in 6 years of full time go development, just copied and pasted code for the purpose of making it work with a different type. Nor has anyone I have worked with in that time (to my knowledge). I have seen two or three libraries written that use interface{}, but these are by far the exception.
Re:Go Creeping In by sacado2 on Friday June 21, 2019 @04:57AM (#20240962)
Just depends on your application domain. I never copy/pasted code and could count the number of times I wrote `interface{}` on a single hand.
Re:Go Creeping In by darkr on Tuesday June 18, 2019 @07:58AM (#20212038)
> the ubiquitous `interface{}` pattern

Ubiquitous where? It's the equivalent of `Any` in Scala (and other similar strongly typed languages with unified type hierarchy) and should be strongly discouraged in production code.

Re:Go Creeping In by ben0x539 on Tuesday June 18, 2019 @08:20AM (#20212204)
Standard library APIs like context.Context's WithValue/Value, sync's Map/Value/Pool, stuff like the sort or container/heap packages. Some of them are obvious "really wanted generics, but wasn't important enough to get the special built-in treatment" cases, some aren't.

Most logging libraries I've seen follow the pattern from fmt.Println etc to accept arbitrary `interface{}` values to be logged instead of actually using some Stringer or Formatter interface in their actual method signatures.

Re:Go Creeping In by saturn_vk on Tuesday June 18, 2019 @09:43AM (#20212875)
Context's WithValue will be an interface even if go supported generics. It stores anything, not values of a specified type. Same with fmt
Re:Go Creeping In by ben0x539 on Tuesday June 18, 2019 @10:24AM (#20213345)
Yeah, that's what I meant with "some aren't", I was mostly listing stuff to support the idea that `interface{}` itself is ubiquitous and not some super-niche edge case that never shows up in real code.
Re:Go Creeping In by kpcyrd on Tuesday June 18, 2019 @07:03AM (#20211642)
async/await is async io, this is something js is known for since it doesn't actually require parallelism.

Getting concurrency _with_ parallelism right is a lot easier in rust than it is in go. You need to write thread safe code in both of them, but you get zero support from your compiler in go.

Re:Go Creeping In by the_duke on Tuesday June 18, 2019 @08:02AM (#20212069)
Rust prevents data races with the `Send` and `Sync` markers, but that's a long way from making concurrency and parallelism easy.

In Go, as long as you are not sharing data, you don't really have to care about whether something is concurrent or parallel, the runtime takes care of it for you. You just use goroutines, IO transparently happens on a dedicated threadpool, CPU heavy tasks are spread out over the available cores.

As long as you restrict sharing to sending owned data over channels, you are mostly in the clear. Of course sometimes performance concerns etc mandate more traditional tools (atomics, mutexes, etc) and there the compiler won't help you anymore, but I'd argue that is the exception in Go rather than the norm.

You can often solve problems with a actor-system inspired design. (learning Erlang/Elixir will probably make you a better Go developer!)

In Rust, you still have to care a lot about what you do. Things like tokio::fs can handle file system IO for you, but you need to ensure that code you are calling does no synchronous IO. Also, CPU heavy workloads should be offloaded to a dedicated CPU thread pool, since the tokio runtime is not intended for juggling CPU intensive tasks in addition to the async IO. This is fine for Rust, a language that wants to give you insight and control, but it is still much more demanding of the developer.

Re:Go Creeping In by pcwalton on Tuesday June 18, 2019 @10:02AM (#20213051)
> You just use goroutines, IO transparently happens on a dedicated threadpool, CPU heavy tasks are spread out over the available cores.

In Rust you can do that too! Just use threads. That's what Go does: it just uses threads.

Async I/O is there if you need better performance than what Rust—or Go—can provide. If you don't need that performance, then don't use async I/O.

Re:Go Creeping In by foldr on Tuesday June 18, 2019 @10:48AM (#20213660)
Go uses async IO under the hood (for network IO at least). The exposed API is blocking, but the underlying implementation uses async IO and transparently schedules Goroutines across different OS threads.

As you know, Rust doesn't currently have stable support for a similarly high-level interface to async IO. See e.g. the following reddit thread from 3 months ago:

https://www.reddit.com/r/rust/comments/ausuld/what_is_the_cu...

Re:Go Creeping In by pcwalton on Tuesday June 18, 2019 @10:57AM (#20213788)
Using async I/O in userspace to implement the sync I/O interface of goroutines is equivalent to what the kernel does to implement sync I/O for normal threads.
Re:Go Creeping In by the_duke on Tuesday June 18, 2019 @11:13AM (#20213983)
Sure, technically there is little difference, but my point was is is much easier to use for the developer. The complexity is hidden from you and the choices are largely already made by the runtime.

Sure, modern Linux handles 10k threads just fine, but where Go shines are middle-level network services or microservices where you can easily have 10+ additional tasks for each incoming request. Using real threads quickly becomes unfeasible, and also more cumbersome (passing around threadpools, which threadpool do I use for this task?, do I really want to do those two things in parallel and eat up an extra thread? the cancellation issue, ....).

Also in Rust you'd need to rewrite a lot of code when switching from sync to async, and still need to delegate things to a threadpool since not every dependency will be async enabled.

When the ecosystem stabilizes Rust will be a great choice for the lower stack libraries and servers, where the performance matters. But for many projects the increased complexity, for moderate performance gains, would be a hard sell.

Re:Go Creeping In by pcwalton on Tuesday June 18, 2019 @11:46AM (#20214368)
Do many Go programs really have 100,000 goroutines simultaneously? I'm certain that's quite rare.
Re:Go Creeping In by stickupkid on Tuesday June 18, 2019 @01:08PM (#20215405)
Working as part of Juju project, I can tell you for certain that the answer here is yes, very much so.
Re:Go Creeping In by pcwalton on Tuesday June 18, 2019 @03:48PM (#20217605)
If you have over 100,000 threads, then you are at the point of scalability where you probably want more than what Go can provide. Async I/O would likely be better for your use case, because even 2kB of stack per thread is 195MB just from thread stacks.
Re:Go Creeping In by saturn_vk on Tuesday June 18, 2019 @01:03PM (#20215328)
Well, even if you do not do any parallel work for each request in your service, each request in itself is a goroutine. So depending on the load of that service, you might reach such numbers, and more.
Re:Go Creeping In by foldr on Tuesday June 18, 2019 @11:05AM (#20213873)
Kind of, but with the difference that Goroutines are lighter than kernel threads, so you can run more of them.
Re:Go Creeping In by pcwalton on Tuesday June 18, 2019 @11:45AM (#20214351)
Not as much as you'd think. You can run thousands of kernel threads on Linux.
Re:Go Creeping In by foldr on Tuesday June 18, 2019 @12:07PM (#20214621)
https://golang.org/doc/faq#goroutines

"It is practical to create hundreds of thousands of goroutines in the same address space. If goroutines were just threads, system resources would run out at a much smaller number."

More generally, Go is hardly the first language to implement userspace threads backed by OS threads. Erlang famously does this, for example, and so does GHC: https://en.wikibooks.org/wiki/Haskell/Concurrency

In response to your other comment, the whole point of Goroutines is that you can use them pretty freely without (usually) having to worry about how many there are. Let's say you're writing a server, and that handling one of the requests requires completing 10 tasks, each of which can run in parallel. In Go you can just spawn a Goroutine for each of those tasks. But if you were using real OS threads, then that implementation could easily end up spawning more than a few thousand threads, when the server was under significant load.

Re:Go Creeping In by pcwalton on Tuesday June 18, 2019 @03:50PM (#20217633)
That FAQ answer is misleading. Linux supports thousands of threads just fine. If you have hundreds of thousands, you probably want true async I/O instead of having stackful threads at all.

> But if you were using real OS threads, then that implementation could easily end up spawning more than a few thousand threads, when the server was under significant load.

There's no inherent problem with spawning a few thousand threads in Linux.

Re:Go Creeping In by foldr on Tuesday June 18, 2019 @03:59PM (#20217732)
The FAQ is talking about “hundreds of thousands of threads”. It doesn’t make sense to respond by saying that Linux is fine with “a few thousand threads”. Similarly, I was talking about a scenario where a server would end up spawning more than a few thousand threads.

>If you have hundreds of thousands, you probably want true async I/O instead of having stackful threads at all.

This is a completely baseless assertion, and really makes no sense at all. "Async IO" in itself doesn’t even offer a means of exploiting multiple CPU cores. If "async IO" were all that was required, people would be sticking with Node.js for heavy loads.

>even 2kB of stack per thread is 195MB just from thread stacks.

You say this as if 195MB were a large amount of memory for a server to be using! Obviously, if the memory overhead of running 100,000 Goroutines is only 195MB, then memory limitations are not going to prevent you from running 100,000 Goroutines.

Re:Go Creeping In by pcwalton on Tuesday June 18, 2019 @04:06PM (#20217813)
Linux is fine with a few hundred thousand threads too. I didn't mention it because it's significantly suboptimal to run that many OS threads or green threads like goroutines. If your scalability needs are that high, all the other little inefficiencies in Go, such as the lack of compiler optimizations and GC, are likely going to end up dominating more than threading models. We usually talk about high scalability as C10K; C100K is an extreme case.

> "Async IO" in itself doesn’t even offer a means of exploiting multiple CPU cores.

Sure it does. Multithreaded epoll is the standard solution for such things; that's how nginx is multithreaded, for example. Node isn't multithreaded, but that's a Node problem, not an async I/O problem.

> then memory limitations are not going to prevent you from running 100,000 Goroutines.

100,000 Linux kernel threads with 8kB kernel stack + 2kB user stack is only 1GB, which is likewise tractable.

And that 2kB assumes that the goroutine stacks remain small, which is not always the case. They can and will grow based on the dynamic behavior of the program.

Re:Go Creeping In by foldr on Tuesday June 18, 2019 @04:16PM (#20217923)
You point out yourself that Linux kernel threads use more memory. For this and other reasons (e.g. slower context switches) you cannot spawn as many Linux kernel threads as you can spawn Goroutines.

The rest of your comment is just a repeated insistence that "Go doesn't scale" without a shred of evidence in support. You really seem to have some kind of beef with Go that's clouding your judgment in this area.

>Multithreaded epoll is the standard solution for such things

Multithreaded epoll is exactly what Go provides. Rather than having to manage thread pools yourself, the Go runtime does it for you by distributing logical threads of execution over OS threads.

>We usually talk about high scalability as C10K; C100K is an extreme case.

You seem to be assuming one Goroutine per connection. As I said before, a more plausible scenario for 100,000 goroutines is C10K with 10 goroutines per connection.

Re:Go Creeping In by foldr on Tuesday June 18, 2019 @07:29AM (#20211809)
Go provides channels for safe communication between goroutines (which are distributed across multiple threads).
Re:Go Creeping In by twic on Tuesday June 18, 2019 @10:00AM (#20213023)
You can use channels to pass mutable objects, which are then shared between threads. The passing itself may be safe, but the resulting situation isn't.

The Rust compiler won't let you do that.

Re:Go Creeping In by foldr on Tuesday June 18, 2019 @10:45AM (#20213621)
You can mutate objects from multiple threads in Go without using channels.
Re:Go Creeping In by twic on Tuesday June 18, 2019 @11:35AM (#20214243)
The Rust compiler won't let you do that either!
Re:Go Creeping In by foldr on Tuesday June 18, 2019 @04:49PM (#20218253)
I know. I just didn't see why you were bringing channels into it. It's not as if it's some loophole involving channels that's the issue here.
Re:Go Creeping In by 0815test on Tuesday June 18, 2019 @07:23AM (#20211769)
People who think Rust is "complex" and "boilerplate-heavy" have never had to deal with C++, or heck, even Java. (Though I'd guess we would actually find plenty of C++/Java code within Google itself.) The only reason one could fairly give for that sort of statement is that Rust - the language itself, not just the ecosystem! - is still quite far from mature. But it's going to have a great future once some of the "tweaks" that are in the pipeline right now reach stability. Async is one of those of course, but there are more.

Edit: And to be clear, I'm not a Go-hater! In fact, Go comes out-of-the-box with a very nice, high-performance concurrent GC that makes it highly appropriate for some scenarios where Rust would not be a good fit at all.

Re:Go Creeping In by mmargerum on Tuesday June 18, 2019 @09:41AM (#20212853)
I've written 100k+ loc in go and i've had to use interface{} once. I would like a coalesce operator though.
Re:Go Creeping In by neilalexander on Tuesday June 18, 2019 @06:25AM (#20211392)
I would argue that Go's opinionated style is what makes it elegant. It's a programming language for people who are sick of programming languages. It makes clear promises and delivers on exactly those - it belongs in new code for that reason.
Re:Go Creeping In by coldtea on Tuesday June 18, 2019 @08:34AM (#20212293)
>I would argue that Go's opinionated style is what makes it elegant

I'd say Go is opinionatedly inelegant. It is minimal, I'll give you that, but has several non-orthogonal design decisions, smells, etc.

Re:Go Creeping In by tsavola on Tuesday June 18, 2019 @08:57AM (#20212444)
Please elaborate.
Re:Go Creeping In by snarfy on Tuesday June 18, 2019 @09:21AM (#20212648)
This article [1] explains why I'm not a fan.

[1] - https://www.teamten.com/lawrence/writings/why-i-dont-like-go...

Re:Go Creeping In by coldtea on Tuesday June 18, 2019 @01:59PM (#20216185)
Not compile-time checked repetitive error handling (if null != err), duality of panic and error codes, specially blessed constructs (maps, slices, etc being "generic"), lack of expressivity, specially typed map libs, interface{} type safety escape hatch, etc...
Re:Go Creeping In by dnautics on Tuesday June 18, 2019 @10:18AM (#20213240)
If err != nil everywhere is definitely a code smell and poor language design.
Re:Go Creeping In by randomvectors on Tuesday June 18, 2019 @06:39AM (#20211494)
No, being opinionated by itself isn't a good enough reason to belong in new code.
Re:Go Creeping In by neilalexander on Tuesday June 18, 2019 @06:41AM (#20211506)
If you don't believe that making clear promises and delivering on them is, then what would you suggest is a better reason?
Re:Go Creeping In by vageli on Tuesday June 18, 2019 @08:26AM (#20212245)
> If you don't believe that making clear promises and delivering on them is, then what would you suggest is a better reason?

How is "being opinionated" and "making clear promises and delivering on them" equivalent?

Re:Go Creeping In by neilalexander on Tuesday June 18, 2019 @08:30AM (#20212275)
I didn't say they were. They weren't even in the same sentence in my original comment.
Re:Go Creeping In by simiones on Tuesday June 18, 2019 @09:33AM (#20212765)
If the promises you are making are not appealing, even if they are clear and you deliver on them, you can't count that as a reason to use a language in new code.
Re:Go Creeping In by randomvectors on Tuesday June 18, 2019 @07:44AM (#20211931)
You're arguing with a point that I'm not making at all.
Re:Go Creeping In by neilalexander on Tuesday June 18, 2019 @08:03AM (#20212072)
What is your point then? You're being obtuse.
Re:Go Creeping In by lmm on Tuesday June 18, 2019 @06:45AM (#20211523)
Go has been carefully designed to solve the problems of today. But relying on solving those problems at the language level means I have very low confidence that the language can adapt to solve the problems of tomorrow. They have built-in language-level support for concurrency, great - that's always going to be slightly more user friendly than a library-based solution. But what about when the next wave comes along? Are they going to be able to rework the whole language to incorporate whatever 2020's equivalent to the concurrency revolution is? While retaining compatibility with existing code?

I would not want to use Go for any codebase that's expected to last more than a couple of years. I'd put a lot more faith in languages that were able to adapt elegantly to the challenges of concurrency at the library level, without requiring language changes - that suggests those languages will be able to adapt similarly to the next revolution. And my impression is that languages that started with a solid theoretical underpinning, and/or a small core language with as much as possible pushed out into libraries, handled the transition a lot better than languages with the more ad-hoc, practical-problem-first approach to design that Go has.

Re:Go Creeping In by apta on Tuesday June 18, 2019 @09:04AM (#20212494)
I'm with you in general that golang code is very unmaintainable in the long term.

> Go has been carefully designed to solve the problems of today.

I'd even argue it was "carefully designed" to be in the 70's. Other than "goroutines", the language is stuck in that decade. No generics, no expression based syntax, exposing system-dependent "int" type and encouraging its use, badly designed interfaces that can't be used for tagging, badly designed time package, the list is too long to mention here.

Re:Go Creeping In by chewxy on Tuesday June 18, 2019 @09:42AM (#20212865)
My oldest "big" Go project started in 2010. Last commit date was 2013 - https://asciinema.org/a/cJosP51z0oScKPLmVUhyNKUOj

It still runs today. I have Haskell and Python programs that are somewhat smaller from around the same time that no longer run.

More importantly, I can go into my source code and I can still understand it. I can't say the same for the Haskell and Python programs.

I wonder which is more maintainable in the long term.

Re:Go Creeping In by apta on Tuesday June 18, 2019 @11:14AM (#20213998)
I didn't mention Haskell or Python. I'm not really familiar with Haskell, and I definitely wouldn't use Python, or any dynamically typed language for any project spanning more than a couple of files.

You can find old C programs that compile and run fine now, so I don't really see the point of your argument.

Re:Go Creeping In by lmm on Tuesday June 18, 2019 @12:06PM (#20214602)
Smaller in the problems they solve, or just smaller in code? I wouldn't expect Python codebases to last well (no type safety and the language evolves quite aggressively), but I'm surprised you'd have Haskell that now didn't run (assuming you could reproduce the original build/dependency environment - Haskell package management was a mess until very recently) - can you give any details about what kind of thing goes wrong?
Re:Go Creeping In by chewxy on Tuesday June 18, 2019 @11:33PM (#20220591)
There are several factors as to why the Haskell program no longer worked - first is that I'm a crappy Haskell programmer. A lot of the things I thought I was doing ended up being NOT what I want upon reflection many years later (it was a game that was essentially a spreadsheet in disguise). Second, the ecosystem has changed a lot in the intervening years. Thus, nothing worked. I recently rewrote the game just to keep up my Haskell skills because I don't really write much on a day-to-day basis
Re:Go Creeping In by jerf on Tuesday June 18, 2019 @09:42AM (#20212862)
And yet, people are solving problems in it, often quite well.

I say this as one who has basically mastered Haskell, so it's not like I'm not aware of all these things: Fans of all these complicated abstractions really need to take some time and grapple with that fact. It will improve your programming in the more complicated languages as well.

No, seriously. Stop for a moment and think about that. Consider the advanced features as a scientific prediction: "If you do not use these features, you can't have a good program come out the other end." This prediction is falsified by the concrete existence of a lot of good Go programs. This matters. It is something that should be grappled with intellectually, if you are a language fan.

It will bring you to a deeper understanding of all the fancy features. By a deeper understanding, I mean that quite directly, with no attempt to be subtly saying something like "Oh, you'll find they're all useless in the end." That would not be true. They are not even remotely useless. They are incredibly useful. I would even go so far as to say that the development of these complicated sorts of features is legitimately among some of the most simultaneously interesting and useful intellectual work being done in our time, and greatly contributing to our ability to hold our software world together. It's just that the shape of that usefulness is more complicated than a lot of people realize, and a deeper understanding of that complication is very useful for developers.

One of the things that I think really comes out of it is a yet deeper understanding of matching tools to problems. I use a lot of Go, because I write a lot of things that are at a size and complexity where those other language features just aren't that helpful. Yet, there are tasks I could be assigned where I wouldn't dream of using Go, because I know I would need all that fancy stuff to hold the program together. I can easily imagine ways in which my career trajectory would change in the next couple of years and I'd go primarily Rust; I can equally easily imagine ways in which I will stay primarily Go. I can imagine ways in which I'd need to go with some other language. I think a lot of programmers who find these fancy features and fall in love with them end up overestimating the scope of the set of programs where they can be helpful. To give a degenerate example, my six line shell script does not need to be written in the Rust type system. It is not only not helpful, it would be actively harmful. The scope of programs that don't really need those features and where they quite easily become actively harmful is larger than a lot of people think. Especially if you consider them in the context of a heterogeneous team of developers who may not all be in the 5+ years of experience range, or when you may not be able to guarantee that the project is going to stay in those hands.

Re:Go Creeping In by lmm on Tuesday June 18, 2019 @12:18PM (#20214746)
> Consider the advanced features as a scientific prediction: "If you do not use these features, you can't have a good program come out the other end." This prediction is falsified by the concrete existence of a lot of good Go programs.

I'd claim that programs built without those features have a ceiling on how complex a problem they can solve before maintainability collapses under its own weight. Go is popular for microservices, which makes a certain amount of sense (if you believe that microservices are an effective way of doing systems architecture - I don't, but I can see why people would). I've yet to see a Go system that I found genuinely impressive/innovative in terms of the functionality it provided.

> To give a degenerate example, my six line shell script does not need to be written in the Rust type system. It is not only not helpful, it would be actively harmful. The scope of programs that don't really need those features and where they quite easily become actively harmful is larger than a lot of people think.

Disagree. In my experience a significant proportion of production incidents happen because a six line shell script gets modified incorrectly, or does not handle an unexpected condition properly.

I've seen plenty of ineffective solving of business problems in e.g. Haskell, which I think boils down to a failure to appreciate how low the reliability requirements actually are in most businesses (exacerbated because many organisations are dishonest with themselves about such things, even in internal communications). I do think that someone who knows the advanced features but is willing to write "YOLO Haskell" (or similar language) will be more effective at solving business problems and creating value than someone using Go or similar (and at this point I've built my career on the effectiveness of fancier languages, even for 6-line-script-like tasks).

Re:Go Creeping In by jerf on Tuesday June 18, 2019 @01:23PM (#20215626)
"Disagree. In my experience a significant proportion of production incidents happen because a six line shell script gets modified incorrectly, or does not handle an unexpected condition properly."

"My" six-line shell script isn't on production. It's something I wrote to rearrange my mp3 collection, or whatever. Then I deleted it.

My personal threshold for leaving shell is quite low. We may make fun of Perl, but it's really a lot, lot better than shell for any serious task. It's even lower for "production" tasks.

But whipping out the Rust because I want a shell script to increase the brightness of my screen through the /proc file system is massive overkill. I can write the thing in the amount of time it takes you to compile the Rust, and I'm not particularly trying to make fun of Rust here... it's just massive overkill.

Re:Go Creeping In by FreeFull on Tuesday June 18, 2019 @10:27PM (#20220327)
I actually ended up writing a Rust program to change screen brightness through /proc myself. Previously, I used a Python script. Understandably, the Rust program is very significantly faster than Python, and I was surprised by the difference it made for interactive use (changing brightness by a scrolling keybind). For comparison, here are two iterations of the Python code, and the Rust code: https://gist.github.com/FreeFull/1e5873f0b13ec291158176db9d7...
Re:Go Creeping In by lmm on Tuesday June 18, 2019 @06:24PM (#20219068)
> "My" six-line shell script isn't on production. It's something I wrote to rearrange my mp3 collection, or whatever. Then I deleted it.

Which is fine unless it deletes your mp3s, or dumps them all in the same folder, or something. A script inherently has the potential to do a lot of damage, because it can take a lot of actions very quickly. So it's worth being safe even if that means being a little slower.

> But whipping out the Rust because I want a shell script to increase the brightness of my screen through the /proc file system is massive overkill. I can write the thing in the amount of time it takes you to compile the Rust, and I'm not particularly trying to make fun of Rust here...

If your point is that a REPL or shell is a worthwhile feature then I agree with that. But you can have that in a safe language too.

Re:Go Creeping In by apta on Tuesday June 18, 2019 @11:12AM (#20213962)
> Consider the advanced features as a scientific prediction: "If you do not use these features, you can't have a good program come out the other end." This prediction is falsified by the concrete existence of a lot of good Go programs. This matters. It is something that should be grappled with intellectually, if you are a language fan.

I didn't mention anything about fancy features such as the likes of what Haskell and gang bring. I'm referring to much more "basic" things like generics, good error handling, non-nullable by default pointers, and so on. Things that one has come to expect in a modern language (which golang isn't in general).

Having the ability to provide abstractions does not mean must use them to write software, but that they are available when required, and when used correctly, they end up simplifying the overall system architecture. I think the world has moved on from writing abstractions for the sake of writing abstractions, and I agree that it's not the way to go if such code is still being written. But the solution is not to get rid of the ability completely, resulting in a different sort of mess. At least we have tools that make navigating large code bases easier.

I feel it's actually golang people end up reinventing things differently just for the sake of writing things differently. Take the builder pattern for instance. For some reason, golang code I see uses a different, more convoluted pattern of passing an options struct that gets returned in a closure to emulate that. It's a bigger mess to understand, and probably ends up generating more work for the GC since closures keep getting allocated.

Re:Go Creeping In by pjmlp on Tuesday June 18, 2019 @09:43AM (#20212874)
I was also solving problems in Z80 Assembly, once upon a time.
Re:Go Creeping In by jerf on Tuesday June 18, 2019 @09:53AM (#20212967)
The sort of deeper understanding I'm talking about will actually integrate that as a point in a more comprehensive picture, rather than thinking of it as some sort exceptional case. To the extent that you have a model in your head where that point doesn't fit (and, I assume, believe that would somehow challenge the model in my head), I'd say that is also a point to consider and ponder and try to integrate, rather than having it sit outside of the model that only fits a fraction of the code out there, and has places where it actively mismatches existing code bases.
Re:Go Creeping In by saturn_vk on Tuesday June 18, 2019 @01:16PM (#20215519)
I would argue that the select is the more important feature. Goroutines are just lightweight threads, and go isn't the first language to have them.

No generics suck, unfortunately. I don't care that most things aren't expressions, and tbh, I don't know a lot of people that do. System-depdendent int is not a problem for me, but I recognize that it is a problem in some fields. I like how interfaces are designed and used in the language, so I don't share your opinion there. For the time package, the only thing that's badly designed is the American-centric parsing system. Everything else is, for me, ahead of the various package I've used in other languages.

Re:Go Creeping In by apta on Tuesday June 18, 2019 @02:02PM (#20216243)
The fact that duration is basically an int wrapper around nanoseconds, and converting between different units is very awkward are just the beginning. Take a look at Joda time (JVM, which served as the basis of what later was integrated into the standard lib) or Noda time (.NET) to see examples of properly designed time libraries. It's no wonder that golang's badly designed time library caused an outage at cloudflare.
Re:Go Creeping In by dis-sys on Tuesday June 18, 2019 @06:55AM (#20211582)
The codebase of Go itself (which is in Go of course) has been there for multiple "couple of years" already.
Re:Go Creeping In by twic on Tuesday June 18, 2019 @10:02AM (#20213048)
> Are they going to be able to rework the whole language to incorporate whatever 2020's equivalent to the concurrency revolution is?

This is why i'm sad that Rust has baked async/await into the language. Somewhere in the RFCs, it is stated that "async/await is now known to be the right way to do concurrency" or something like that, but to me it is clear that it is at least a decade too soon to say that.

Re:Go Creeping In by kibwen on Tuesday June 18, 2019 @01:55PM (#20216106)
I would be curious if you could find a link for that quote, because Rust has always been of the mind that there is no one correct approach for concurrency, and has good support for channels, threads, work-stealing task pools, etc., all intended to serve different use cases. If there is a line like that somewhere in the RFCs, I would expect it to be in the context of "the design of async/await proposed herein is now known to be the right way to do asynchronous I/O in Rust, given Rust's other design choices and constraints [in contrast to the years of other experiments have been tried, including Go-style green threads]". In particular the long term goal is not to make async/await the end-all be-all, but rather to expose a generalized concept of generators which async/await is then built upon.
Re:Go Creeping In by dboreham on Tuesday June 18, 2019 @10:28AM (#20213389)
It turns out to be hard to do concurrency in a library, if you need both absolute correctness (e.g. works with all system calls) and scale (more threads than the OS native threading will allow).

Afaik only Go and Erlang currently meet (at least my) criteria. No JVM solution currently does.

Re:Go Creeping In by apta on Tuesday June 18, 2019 @11:34AM (#20214227)
You have solutions like Akka, Vertx, and Reactor/RxJava on the JVM. Not to mention that the JVM is getting a green thread (fiber) implementation by means of project Loom.
Re:Go Creeping In by Milner08 on Tuesday June 18, 2019 @06:39AM (#20211488)
"a programming language for people who are sick of programming languages" is nonsense.
Re:Go Creeping In by pdpi on Tuesday June 18, 2019 @07:02AM (#20211630)
Is it nonsense? Makes perfect sense to me. There are programmers who don't get excited about languages as a topic and would rather just get on with it. "People who are sick of programming languages" seems like an apt description for that crowd.

I personally dislike Go, precisely for many of the reasons why those "people who are sick of programming languages" would like it!

Re:Go Creeping In by oddthink on Tuesday June 18, 2019 @09:09AM (#20212534)
I like the phrase, too. I'm on the "sick of programming languages" side, and I like go, for the things I'm using it for: CLIs, simple debug web-servers, calling out to RPC services. (Read a CSV file, run everything through translate / grammar parsing / etc.)

I'm in that age of folks that did pascal in high school, C and Scheme in college, C++ and python in grad school while futzing around with ocaml and common lisp and sather and other fun things. Programming languages are fun.

But, oh, I have so much other stuff to pay attention to. I write C++ a few days a week, which is barely enough to keep move semantics in my head. I also write SQL and analysis docs and internal DSLs and configuration files and python.

At this point, C++ is barely earning its keep, in terms of mental complexity for reward. Go feels a lot nicer, since I can just get in, do my thing, get out, and it'll at least work and give me a compile error if one of the APIs change when I don't look at it for a year.

I'm not about to jump into rust.

So, at least for me, go hits a pretty good sweet spot.

[Edit: I'm not trying to point fingers at rust in particular. It looks fun. If I weren't still working on getting my hobbyist-Haskell better, I'd probably be playing with it. But that would be at home, for fun, not where I have to have the thing in my head for production issues.

It reminds me a bit of the old statement about perl, that it was a fantastic language if you used it every day, but not if you don't. And I don't get to use these things every day any more.]

Re:Go Creeping In by nl on Tuesday June 18, 2019 @08:24AM (#20212232)
Please give me this nonsense. I'm sick of programming languages.
Re:Go Creeping In by 0815test on Tuesday June 18, 2019 @08:30AM (#20212273)
Protip: You can write FORTRAN in any language!
Re:Go Creeping In by TheRealKing on Wednesday June 19, 2019 @04:35PM (#20227069)
Of course, you can (re)write code in any Turing-complete language in any other Turing-complete language.
Re:Go Creeping In by neilalexander on Tuesday June 18, 2019 @06:42AM (#20211508)
Why?
Re:Go Creeping In by gonzo41 on Tuesday June 18, 2019 @07:00AM (#20211618)
Look at Java. Look at Spring and look at all the other junk out there. Every corner you go around you see smart people trying to outsmart each other rather than solve problems. Go makes that harder.
Re:Go Creeping In by gerbilly on Tuesday June 18, 2019 @09:12AM (#20212566)
Spring and Java aren't junk.

I like Go for some things, but when using it I miss many things from Java:

* I can connect to the running JVM and change log levels, and other parameters live.

* I can debug a Java file that has compilation errors in it and fix them as I go in some cases. (In Go you can't even compile a file with an unused import)

* Java libraries and frameworks are mature. Some have been around for decades with all the testing and refinement that implies.

For some applications, like a REST server connecting to a database, why would I use Go and use all it's brand new, limited libraries when I could use dropwizard instead and get an easy to deploy JAR file?

Sure Java has some esoteric features, but you don't have to use them.

If you can't keep your team from being clever in Java, I doubt you'll be able to do so just because they use Go.

I've seen many Go libraries attempt to use introspection and backtick 'annotations' to very confusing and buggy effect.

Re:Go Creeping In by apta on Tuesday June 18, 2019 @11:36AM (#20214254)
Re:Go Creeping In by vips7L on Tuesday June 18, 2019 @08:48AM (#20212385)
Spring boot is fantastic if you havent checked it out.
Re:Go Creeping In by sagichmal on Tuesday June 18, 2019 @08:59AM (#20212458)
Spring Boot is precisely the magical nonsense the GP was complaining about.
Re:Go Creeping In by gerbilly on Tuesday June 18, 2019 @09:13AM (#20212577)
I like Java and Spring, but I don't use Spring boot.

Note that just because the recent tutorials out there mention Spring Boot, doesn't mean you can't wire together a Spring app either through config files or programatically.

Re:Go Creeping In by vips7L on Tuesday June 18, 2019 @09:18AM (#20212612)
In my opinion, its not any more magical than any other framework.

What it is though is something that solves problems and has a great ecosystem, instead of reinventing the wheel.

Re:Go Creeping In by th124567543 on Tuesday June 18, 2019 @07:52AM (#20211987)
Citation needed.

From what I understand there is no Rust being used internally at Google (apart from perhaps individual engineers tinkering with it just for fun).

There is no support for it from the build tools, so anything more than just messing about on your own machine won't work at Google: no libraries, no way to compile it, no way to test it, no way to deploy it, and no way to monitor it.

Re:Go Creeping In by rapsey on Tuesday June 18, 2019 @07:56AM (#20212015)
I do not know about internally, fuschia apparently has major parts written in Rust.
Re:Go Creeping In by lima on Tuesday June 18, 2019 @08:12AM (#20212132)
And Chromium's crosvm. Rust is a perfect fit for that particular task (writing a VMM).

I would be surprised if there was widespread usage of it, though. Rust chose a whole different set of tradeoffs than Go.

Re:Go Creeping In by giaour on Tuesday June 18, 2019 @07:50AM (#20211977)
I would agree that Go is rarely the best choice for particular problem, but I've found it to be a good choice for "enterprise development" for two reasons. It's easily reviewable by others with varying levels of skill and familiarity with the project, and it doesn't have a complicated deployment story.

At work, I've seen Go used primarily in projects that would have previously been written in Python or Ruby.

Re:Go Creeping In by notafrog on Tuesday June 18, 2019 @08:31AM (#20212281)
My biggest issue with navigating Go codebases is that sometimes it's cumbersome to find where a specific type/function is defined, when there are multiple files under the same directory.
Re:Go Creeping In by NateDad on Tuesday June 18, 2019 @09:36AM (#20212794)
A simple text search will find it every time. Since Go code should always be formatted, it's pretty trivial to search for `type HTTPServer` or `func NewServer(` ... even over fairly large codebases this will give few enough hits that you can just search everything most of the time.
Re:Go Creeping In by apta on Tuesday June 18, 2019 @11:40AM (#20214298)
Not to mention trying to figure out which types implement a given interface. You'll get completely unrelated types you don't care about a lot of the time.
Re:Go Creeping In by Lio on Wednesday June 19, 2019 @05:28AM (#20221965)
Would this not be solvable with something like ctags or godef?

(I'm a newbie with Go so I've probably missed something in the problem you're describing).

Re:Go Creeping In by cmonfeat on Tuesday June 18, 2019 @08:53AM (#20212416)
I've had this issue as well and found that it makes using an IDE almost mandatory for large code bases.
Re:Go Creeping In by Thaxll on Tuesday June 18, 2019 @08:09AM (#20212103)
I started working with Kotlin recently, it's bad compare to Go goroutine model, the biggest problem is actually knowing if a function is sync or async, especially when you use other Java lib.

The fact that you need to create your own threads pool to run those koroutine, really it's inferior to the Go runtime that does everything for you ( multiplexing goroutines onto os threads, creating new thread if blocking ect .. ), in Go it just works and it makes sense, in Kotlin you need to do many many things manually and it's much more complex for no apparent reasons.

Re:Go Creeping In by eropple on Tuesday June 18, 2019 @09:14AM (#20212585)
It's more complex because you have more control. If the Go scheduler does something pathological, you're going to be digging a hell of a lot deeper than you need to in Kotlin.

You can just use a shared executor with a growing pool if you don't care.

Re:Go Creeping In by apta on Tuesday June 18, 2019 @11:38AM (#20214274)
Java is getting a fiber (green thread) implementation by means of project Loom. I recommend you check it out. In the mean time, you have other solutions like Vertx, Akka, and Reactor/RxJava.
Re:Go Creeping In by apta on Tuesday June 18, 2019 @08:44AM (#20212361)
> I just don't think Go has a place in new code

This makes a lot of sense. I've seen and worked on code at a large US tech company that is mainly reliant on golang for its services, and let me tell you, it's hideous. It's very verbose, and they end up reinventing everything you have in Java land anyway in a much more verbose and error prone way. You also end up losing on the tremendous monitoring and management capability of the JVM, as well as the extremely mature and diverse ecosystem, with integrations into basically anything you can think of. You want to integrate into an "enterprise" system or infrastructure? ew who'd want to do that? we use golang because it's hip, who cares about about all that money making business?

The funny thing is, there's still no getting away from Java/JVM, and they have a good number of services running on the JVM (particularly security related, and data processing pipeline services).

While the language is "simple" (i.e. underpowered) enough that you can read it, it immediately translates into verbosity and complexity in the code base, with things like helper functions that are basically "map/filter/etc" calls in any sane language taking up 8-10 lines of code scattered everywhere, as opposed to them taking a single line of code as they're supposed to. Not to mention things like JSON handling, validation (non-existent way to do them in a non-error-prone way, unlike annotations or attributes in JVM/.NET), no way of doing compile time DI (unlike e.g. Dagger or micronaut on the JVM), the list goes on.

Java the language is improving with things like switch expressions, records, and value types being added. The JVM itself is getting fibers, and better native integration for high performance work. GraalVM enables compilation to native binaries if needed.

You also have languages like Kotlin to use on the JVM if you don't fancy Java itself.

The only reason golang is being pushed around is hype. It's so underpowered that using it for any moderately complex domain becomes a mess. Even generics if they decide to add them won't fix that.

Re:Go Creeping In by simiones on Tuesday June 18, 2019 @10:30AM (#20213421)
I agree with almost everything you said. However, there is one point where I think you're wrong: the only advantage Go still has over java (as it exists today) is the size of the runtime - you can get a Go container serving an HTTP server in ~10MBs of size and similar amounts of RAM - this is still a far cry from what I've seen Java achieve.

This is not important in many use cases, but if you are planning to run a microservices architecture, this can help a lot with horizontal scaling costs.

Re:Go Creeping In by apta on Tuesday June 18, 2019 @10:58AM (#20213796)
You might want to check out: https://quarkus.io/ or https://micronaut.io/ for that :)
Re:Go Creeping In by simiones on Thursday June 20, 2019 @08:21AM (#20232121)
yes, these are very promising projects, but they are just starting out this year unfortunately. I hope they will prove to be stable and close enough to the OpenJDK as time goes, but I wouldn't bet a new product on them just yet, unfortunately.
Re:Go Creeping In by ajbeach22 on Tuesday June 18, 2019 @09:24AM (#20212672)
> I just don't think Go has a place in new code.

This is a completely blanket statement. Not only are there very large open source projects written in go which your company more than likely already uses (kubernetes, docker, prometheus, influxdb to name a few) there are also case studies of very respectable performance in go:

1 million requests/min http://marcio.io/2015/07/handling-1-million-requests-per-min...

1 million websockets in go: https://www.freecodecamp.org/news/million-websockets-and-go-...

event loops in go: (surpasses redis in their benchmarks) https://github.com/tidwall/evio

I see golang more as a progression for JS or Python developers than Java or JVM based languages, as the concurrency model in golang is closer to to pythons + javascript async. The argument that Java, Kotlin, Erlang developers are less likely to move to Go is probably a valid one, but it is completely baseless to say that "go has no place in new code".

The concurrency model in golang with channels makes more sense to someone more familiar with python/javascript who hasn't been exposed to threading or other concurrency models. If you can understand basic coroutines/channels you get the benefits of golangs concurrency (and even parallelism) without much effort, or code complexity, with an order of magnitude more performance that python or javascript for the same feature set.

The profiling tools in golang are also first class (pprof, trace, ect) With pprof, its easy to see even traces of different coroutines, heap allocations, cumulative allocations, these are even safe to sample on production running services and this is provided by the standard library. There are even built in tools to profile GC. The argument that tooling and monitoring doesn't exist in golang is simply not true.

Re:Go Creeping In by Touche on Tuesday June 18, 2019 @09:05AM (#20212512)
Rust is a programming language for people who like programming languages. Every feature under the sun. Seems like the new Scala in that regard. I'd definitely use it if I was building a web browser or something else where C++ was previously the only option, but I personally don't want Scala 2.0 to build web servers or cli apps. I would rather focus on what I'm building, which is where Go excels.
Re:Go Creeping In by kibwen on Tuesday June 18, 2019 @02:03PM (#20216269)
> Every feature under the sun.

Have you gotten this impression from actually using Rust, or merely from people who themselves have not used Rust? It deliberately omits a ton of ideas from other programming languages (exceptions, classes, data inheritance, monads, and more), and the features it does have are intended to compose well and without a huge amount of mental burden.

Re:Go Creeping In by Touche on Wednesday June 19, 2019 @10:52AM (#20223891)
Yep, it leaves out ideas that are no longer en vogue but has every idea that is currently en vogue. So in 20 years when those ideas are themselves thrown out, it will feel like a language of the 2010s.
Re:Go Creeping In by kybernetikos on Wednesday June 19, 2019 @08:27AM (#20222643)
Rust and Scala are at nearly opposite ends of the spectrum.

Rust forces you to be explicit about nearly everything, Scala is all about allowing you to hide the details in lots of different ways.

Re:Go Creeping In by pjmlp on Tuesday June 18, 2019 @09:42AM (#20212861)
I focus on what I am building with JVM and .NET stacks, while enjoying quite expressive languages.
Re:Go Creeping In by jacquesm on Tuesday June 18, 2019 @07:39AM (#20211898)
> all concurrency systems converge until they become an Erlang actor model

That's absolute gold, and I've seen a very accurate real life representation of that in recent times. Uncanny how many of those wheels we keep re-inventing.

Re:Go Creeping In by 0815test on Tuesday June 18, 2019 @07:48AM (#20211964)
Well, Erlang-like actor model is one basic pattern for achieving safe concurrency. A second one is keeping data read-only so that it can be freely accessed by multiple threads; and a further pattern is serializing access at run time (either using explicit locks, or in special cases with "non-blocking" algorithms and data structures). Rust is pretty unique in being able to comfortably encompass all of these patterns in its concurrency model, while ensuring safety.
Re:Go Creeping In by masklinn on Tuesday June 18, 2019 @08:25AM (#20212241)
> A second one is keeping data read-only so that it can be freely accessed by multiple threads

That's not really a "pattern for achieving safe concurrency". At one point, your concurrent processes need to communicate somehow or they're parallel more than concurrent.

Re:Go Creeping In by gypsyharlot on Tuesday June 18, 2019 @07:29AM (#20211807)
What is your criticism of Go in all of this? That someone at Google prefers Rust? Or that you personally like Kotlin because of "the power of the JVM"?

Getting away from the JVM is one of the reason FOR using Go rather than Kotlin/Scala/Java etc.

Re:Go Creeping In by tptacek on Tuesday June 18, 2019 @07:56AM (#20212016)
This is an extraordinarily unproductive way to start a comment and root a thread.
Re:Go Creeping In by twic on Tuesday June 18, 2019 @10:07AM (#20213094)

  $ curl -s 'https://news.ycombinator.com/item?id=20211301' | egrep -o comhead | wc
       99      99     792
Seems to have been pretty productive to me.
Re:Go Creeping In by fetbaffe on Tuesday June 18, 2019 @06:23AM (#20211382)
Why shouldn’t Go have a place i new code? You talk about Rust, but why does that make Go a bad choice? Is it technical reasons or politics?
Re:Go Creeping In by laumars on Tuesday June 18, 2019 @07:39AM (#20211892)
In my 30+ years of experience writing software in a wide variety of paradigms (never mind imperative languages) I've found most of the arguments for and against Go to amount to little more than tribalism and snobbery[1]

There is no such thing as perfect language and clearly some languages are designed to be better at some scenarios than some other languages...and visa versa. The problem with Go is that it's designed to be a boring language where it's aims are more around language simplicity and API stability. This makes it very easy to play the "death by a thousand paper cuts" game with Go. If you'd believe what you read on HN, nobody would be using it when actually it is a very popular language.

[1] I'm sure that comment will annoy a great many on here but that's my honest observation.

Re:Go Creeping In by gypsyharlot on Tuesday June 18, 2019 @07:55AM (#20212007)
This is exactly my experience.

I've used C (closer to Go than Rust) and I've used C++ (closer to Rust than Go) in previous jobs. My experience is that the C programmers tend to focus on the problem at hand. On C++ teams, people spend a lot of time going to C++ conferences and discussing the idiomatic approach to mundane tasks in their superior language. I imagine we'll see the same thing happen in Go and Rust... different personalities are drawn to the different languages.

I'd rather be going to security, networking and crypto conferences instead of wasting a lot of time on a particular language.

Re:Go Creeping In by majewsky on Tuesday June 18, 2019 @08:21AM (#20212208)
Language-specific conferences are not just a C++ thing, though. There are Java conferences, Ruby conferences, Python conferences, Rust conferences, etc.

The only thing that doesn't exist is a C conference, but that's because C is the least common denominator.

Pretty sure that there are Go conferences.

Re:Go Creeping In by chewxy on Tuesday June 18, 2019 @08:34AM (#20212291)
There are. GopherCons are a thing. Also, here's an ad for the upcoming GopherConAU : https://gophercon.com.au.

CFPs are open until end of June. https://papercall.io/gophercon-au-2019

Re:Go Creeping In by Dylan16807 on Tuesday June 18, 2019 @02:17PM (#20216499)
> I've found most of the arguments for and against Go to amount to little more than tribalism and snobbery[1]

You can say that about any technical option that isn't garbage. That observation doesn't help us learn about Go, and doesn't let us dismiss all the other arguments.

Re:Go Creeping In by laumars on Wednesday June 19, 2019 @04:17AM (#20221649)
The answer to their question (to paraphrase: "why are opinions so polarised on Go?") isn't a technical one. It literally is just people arguing personal preference.

If he or she wants a technical arguments for why they should or shouldn't use Go (which is a subtly different question but results in a significantly different answer) then there is already a wealth of debate on that topic already so there's no new technical perspectives that I - nor anybody else - could actually add.

Re:Go Creeping In by eeZah7Ux on Tuesday June 18, 2019 @08:01AM (#20212057)
Absolutely spot on.
Re:Go Creeping In by neel_k on Tuesday June 18, 2019 @06:45AM (#20211521)
It's taking on a fair amount of risk to use a language that (a) encourages the use of concurrency but (b) is not memory-safe when you do so, especially when writing network-facing code.

Go uses multi-word primitive values, which means assignments are not atomic. Consequently, racing assignment statements can leave objects in weird states that violate type and gc invariants. For example, racing assignments to a value of interface type can give you an object with the wrong dictionary for its data.

The argument for not worrying about this is that this is an unlikely scenario. It's reasonable to think in probabilistic terms when clients are not trying to break the software (eg, in games or office software). However, attackers are not probabilistic: they actively search out vulnerabilities and push on them, so potential vulnerabilities turn into actual vulnerabilities in predictable fashion.

Re:Go Creeping In by foldr on Tuesday June 18, 2019 @07:26AM (#20211789)
Go definitely doesn't encourage code where multiple goroutines directly modify the same values. You're supposed to use channels for communication between goroutines by default.

Rust also lets you write memory unsafe multithreaded code, if you want to.

Re:Go Creeping In by burntsushi on Tuesday June 18, 2019 @07:31AM (#20211826)
> Rust also lets you write memory unsafe multithreaded code, if you want to.

That's a false equivalence. Nobody is criticizing Go for having an `unsafe` package. The criticism is that your Go code can be undefined without using the `unsafe` package. In Rust, you need to use `unsafe` in order to write code that has data races. Otherwise, data races are statically prevented in safe code, unlike in Go.

Re:Go Creeping In by foldr on Tuesday June 18, 2019 @07:37AM (#20211872)
You don’t need to use 'unsafe' yourself in Rust. Any package that you’re using might contain unsafe code that its author believes (rightly or wrongly) to be thread-safe.

The situation with Go is pretty clear. Channels are safe. If you start mutating shared state across different goroutines, then you’re in the same situation you’d be in if you were doing the same thing in C++. Anyone who doesn't understand why that's potentially unsafe wouldn't be ready for Rust in any case.

Re:Go Creeping In by burntsushi on Tuesday June 18, 2019 @07:43AM (#20211918)
> You don’t need to use ‘unsafe’ yourself in Rust. Any package that you’re using might contain unsafe code that its author believes (rightly or wrongly) to be thread-safe.

Sigh. That's true of Go too. Both Rust and Go have `unsafe` labels that give access to dangerous things that can cause UB. Both Rust and Go are susceptible to UB-at-a-distance if library code internally uses `unsafe` incorrectly. The difference is that, in Go, you can write code with data races without using any `unsafe` at all. Nothing will yell at you (unless you exercise the race in a test and run the race detector). Rust does not suffer from this flaw.

I've been writing both Rust and Go since before each had their 1.0 release, and I like both languages. This isn't some back-handed comment about how I think Go is bad because of this. I rarely trip over data race related bugs in Go, but they do happen, so they aren't a huge issue in practice. (And your continued mention of channels is a red herring. Go has mutexes and idiomatic code uses mutexes quite frequently. Channels are not always the right thing to use.) Nevertheless, the comments here comparing Rust and Go are a fairly important mischaracterization of how each language treats memory safety, and it's important therefore to correct that.

Re:Go Creeping In by foldr on Tuesday June 18, 2019 @07:44AM (#20211930)
>Sigh. That's true of Go too.

Yes I know. I'm not sure why you think I'm saying that this is not true of Go.

>The difference is that, in Go, you can write code with data races without using any `unsafe` at all

Again, I know. I addressed this in my previous comment.

Less sighing, more reading!

Re:Go Creeping In by burntsushi on Tuesday June 18, 2019 @07:49AM (#20211971)
Yes, I'm sure you're aware. But the way your comments are written are pretty misleading, so I'm trying to clarify them. If you don't think the clarifications are beneficial to you, then treat them as clarifications for anyone else who is reading.

> Anyone who doesn't understand why that's potentially unsafe wouldn't be ready for Rust in any case.

That's most certainly not true. They might not be ready to write high performance generic data structures from scratch, but application level code in Rust generally has about as much explicit `unsafe` as application level Go code, in my experience. (And writing high performance generic data structures isn't really a thing in Go. Not nearly as much as in Rust anyway.)

Re:Go Creeping In by foldr on Tuesday June 18, 2019 @07:58AM (#20212040)
I don’t think you are clarifying them so much as misreading them.

I'm confused by the second paragraph of your response. My point was that the lack of an explicit 'unsafe' block in Go isn’t that much of an issue, as pretty much everyone knows that Go does not make any memory safety guarantee when accessing shared state from different Goroutines. Anyone who doesn’t know this isn’t ready to get their head around writing multithreaded code in Rust. Rust’s features for doing this are cool, but they require a pretty good understanding of Rust’s complex type and lifetime system.

Re:Go Creeping In by 0815test on Tuesday June 18, 2019 @08:09AM (#20212107)
What a strange argument. "Pretty much everyone knows" that C/C++ aren't memory safe even for sequential code, and that it's incredibly easy to trigger thread-safety bugs in C/C++. But since "pretty much everyone knows", I suppose that makes it OK?

> Anyone who doesn’t know this isn’t ready to get their head around writing multithreaded code in Rust.

Well, if they aren't using `unsafe` in the process (or, to be fair, relying on buggy library code that uses `unsafe` inappropriately), they're not going to introduce memory unsafety via data races - no matter how "ready" they are. You just can't say the same about C/C++. Or even Go.

Re:Go Creeping In by foldr on Tuesday June 18, 2019 @08:24AM (#20212234)
I don’t recommend that people use Go to write complex multithreaded code that accesses shared state. My point is that I doubt many people are doing this while erroneously thinking that their code is guaranteed to be memory safe. In other words, whatever the problems with Go may be in this regard, it’s not primarily the absence of an ‘unsafe’ keyword that’s the issue.
Re:Go Creeping In by vageli on Tuesday June 18, 2019 @08:32AM (#20212285)
> I don’t recommend that people use Go to write complex multithreaded code that accesses shared state. My point is that I doubt many people are doing this while erroneously thinking that their code is guaranteed to be memory safe. In other words, whatever the problems with Go may be in this regard, it’s not primarily the absence of an ‘unsafe’ keyword that’s the issue.

I think the point here is that if the word "unsafe" exists as a language construct, someone is not wrong in assuming anything without that mark is safe. Otherwise, why isn't there a "safe" language construct?

Re:Go Creeping In by foldr on Tuesday June 18, 2019 @09:06AM (#20212513)
That’s true to an extent, but it’s important to bear in mind that you can’t lexically scope memory unsafety. Rust code that doesn’t contain an 'unsafe' block should be safe assuming that all of the libraries it’s built on are safe. But those libraries may well contain 'unsafe' blocks that are (one hopes) carefully written to be memory safe.
Re:Go Creeping In by brodsky on Tuesday June 18, 2019 @07:19AM (#20211740)
Admittedly, my understanding of the problems you describe is superficial at best. But it sounds like you are citing a rather narrow set of requirements (memory safety in network code where protection against exploitation is paramount) as a means to generalize that Go is overall not a good language and should be avoided in new code. I don't think that's fair. As with everything, it may be not suitable for the scope you outlined, but it evidently has its place in a multitude of other uses.
Re:Go Creeping In by sagichmal on Tuesday June 18, 2019 @06:51AM (#20211557)
“Memory safe” has a specific technical definition, and “atomic assignment” isn’t it.
Re:Go Creeping In by burntsushi on Tuesday June 18, 2019 @07:09AM (#20211678)
No, the GP is correct. Data races are undefined behavior, and break memory safety: https://research.swtch.com/gorace
Re:Go Creeping In by pwodhouse on Tuesday June 18, 2019 @09:37AM (#20212800)
Is there a sense in which Russ's claim that "data races are not security problems" is true? It seems to be assuming that data races are impossible to exploit by users (data input), only by programmers.
Re:Go Creeping In by kibwen on Tuesday June 18, 2019 @02:11PM (#20216400)
Presumably because data races are so inconsistently triggered that creating a reliable exploit would be generally infeasible, even with control over user input. However, this unpredictability is also why data races (among other concurrency issues) are some of the most maddening types of bugs to observe, hunt down, and diagnose, which is why eliminating data races is actually a big deal for anyone who's ever wrestled with threads before.
Re:Go Creeping In by 0815test on Tuesday June 18, 2019 @07:13AM (#20211702)
Go is indeed memory-safe for sequential code, but non-atomic assignment can definitely break memory safety in multi-threaded settings - it's effectively a data race.
Re:Go Creeping In by agumonkey on Tuesday June 18, 2019 @06:21AM (#20211366)
So LFE will reign http://lfe.io/

LFeO even ;)

Re:Go Creeping In by brobdingnagians on Tuesday June 18, 2019 @07:56AM (#20212023)
I was curious about learning LFE, but didn't see if it was able to interface with Phoenix (Elixir's web server). Is there any way to use Phoenix from LFE?
Re:Go Creeping In by naikrovek on Tuesday June 18, 2019 @07:34AM (#20211849)
> I just don't think Go has a place in new code.

This is a confusing statement, to me. This implies that go has a place in old code. Or are you saying that Go should not be used at all, because any future use is "new code"?

Re:Go Creeping In by adrianN on Tuesday June 18, 2019 @07:43AM (#20211919)
Rewriting existing, working programs in a different language very rarely makes sense. Avoiding a certain language for greenfield programs is much easier.
Re:Go Creeping In by arvinsim on Tuesday June 18, 2019 @10:25PM (#20220318)
> And for those who have never used Erlang, learn it once, write something highly concurrent in it, and you'll learn to distaste almost every other language's faulty concurrency idioms almost immediately.

Does learning Elixir do the same?

Re:Go Creeping In by EdwardDiego on Tuesday June 18, 2019 @07:32AM (#20211833)
I'm really curious now as to what Google flavoured Java looks like.
Re:Go Creeping In by chewxy on Tuesday June 18, 2019 @08:38AM (#20212322)
They taste like guava
Re:Go Creeping In by vmsp on Tuesday June 18, 2019 @07:10AM (#20211688)
What's "Google-flavored Java"?
Re:Go Creeping In by wikibob on Tuesday June 18, 2019 @07:21AM (#20211747)
Check out the Google Java Style Guide:

https://google.github.io/styleguide/javaguide.html

Re:Go Creeping In by saltyshake on Wednesday June 19, 2019 @12:45AM (#20220859)
Guice, Guice and more Guice.

Some teams switch to Go because they are fed up of writing Google Java instead of real Java.