Why do people keep on saying that? Would people say javascript is for the pragmatic crowd because jsfiddle exists ? no
Go is a badly designed language period. the type system forces devs to write runtime type assertions which should be the job of the compiler thanks to parametric types, if go designers knew one or 2 things about types. The fact that Go dismisses 30+ years of type theory isn't pragmatism. It's ignorance.
Nobody would call PHP pragmatic yet even PHP is more expressive.
I had the same opinion as you until I started some code with it.
The true is that I had never been so productive writing code. The friction from what is in your head and the code is almost 0.
It is true that I ended writing a few functions that were there only because the lack of generics, the type system and other stuff being "built-in". But at the end, I think it was an order of magnitude less often than I was expecting it to. I was wrong.
Your comment is interesting, it has made me want to look at the language, so thanks.
But I think that the "friction from what is in your head to code" probably betrays that you weren't settled in a previous language? I only say this because I have zero friction writing C++, and have to think mildly backwards when it comes to C# or Java, and definitely Objective-C. Even PHP is like simplified C++ to me, so I write everything like it is a dumbed-down dialect of C++.
I suppose it is just what some people find comfortable.
> But I think that the "friction from what is in your head to code" probably betrays that you weren't settled in a previous language?
I had the same feeling as the user you're answering to. And I have used quite a bunch of languages I've been quite productive with (C, C++, PHP, Python, Java, Ada), but I've never felt with these languages as little "friction" as with Go.
I mean, that language is so dumb that you don't have to think about the right way to do stuff. It's obvious. Boring, sometimes verbose, but obvious. It doesn't stand in the way between me and the problem.
I was following Rust very entusiastically. But at some point the language was getting itself in the way of the problem I was solving.
I am not only talking about the strict compile checks. I am talking about that extra thinking in the ten ways you can design it and how it should be done in "proper" Rust.
And the friction is not only in the language, but also in the standard library. A language that comes with XML/json marshal/unmarshal plus a quite decent http client/server framework covers most of what I need to do.
I am sure if Rust had included in the standard package http/xml/json it would be far more popular. I understand the voices that say "It does not belong there", "the language is not targeted at that". Fine. But then I found myself having not much user for the language, even if I loved the idea/theory behind it, plus that I could not get comfortable thinking in it.
* Transforming a collection means doing boring for loops instead of one-liners.
* interfaces/duck typing is great. But hey, []interface{} does not fit into interface{}.
* Structs with fields are encouraged, but there is no uniform Uniform access principle and that sucks.
* etc
But definitely, my own "science" confirms that it turned to be out less of a problem (for my own usage) compared to better languages with more friction.
[I'm a Rust user, and not particularly fond of Go, but...]
Not having great static typing doesn't make it not pragmatic.
Given Go's purpose, it is extremely pragmatic.
One of the reasons Google uses Go is because their employees are often fresh out of college and might not be familiar with the depths of type systems.
If you look at most professional Java/C++ code (starting to see this with Rust too), the features of the language are used to their full extent to create really convoluted APIs (to an outsider not familiar with the language). So, to work on it, one must first become familiar with the intricacies of these languages (this is not as easy as picking up a book, you need experience), and then with how the language is used in context, which is another time consuming thing.
Instead, go trades off some higher level features for compilation speed and ease of learning.
After programming in Go for a week I was able to pick up any Go code -- ranging from the standard library to various other applications, and know what was going on. I cannot say the same about Java or C++ or Rust; generics/templates/virtual/friend/advanced typesystem gymnastics all are used to great extents in the code for a standard library or some large application. one may be able to use the language for your own stuff after a week of learning and hacking, but one will need much more time before they're well suited to contribute significantly to existing codebases.
A course I took recently was taught by a PL aficionado. He knew Rust, Nim, and Go, along with many older languages. Go, Rust, and Erlang, among others, would have worked beautifully for the project topic (concurrent stuff). He made everyone write in Go because he wanted a uniform language for project evaluation, and because Go is something students could reasonably pick up in a week without constraints on their background.
=========================
At the same time, the Go community is pretty awesome. There is a "go way" of doing things, and while it is pretty rigid, that doesn't make it not pragmatic. From my (admittedly limited) discussions with them, they do seem to think practically/pragmatically. There are good reasons for wanting to use Go. These folks know those boundaries, and think practically within them.
Though there might be much to say about the different implementations of generics, I've found them to be easy to understand and use in languages. No type theory required. That has been more like "Oh, so that's the name for that thing/aspect, neat".
If I don't have a problem with that, those coveted master race Google developers should have absolutely no problem with it.
It's not that generics are hard to grok, it's that they get used in a hard to grok way. Wrapping your head around such things gets more and more hard as the app complexity grows.
The base point is that languages like Go let you think of the program at runtime, only. Types are a runtime concept, everything is a runtime concept. Structuring APIs to use compile time safety requires a whole other kind of thinking, one which they may not expect to be uniformly available.
Ultimately it's a choice of whether or not you want to the programmer to think of data and flow (runtime), or metadata (types, compile time). Once you're used to both the difference is blurred. For newbies, the concept of using compile time safety can be daunting.
Right, don't have to think about compile time. Instead they sometimes have to think about post-compile time[1], i.e. code generation. Now you don't have to think about those weird bracketed capital letters. Just take care to check where you have comments[2] that happens to include directives to some external tool.
With how Go programming seems to work for some people, I can perfectly well imagine a system with commands that do code generation as a hook for other commands, or by 'listening to the file system' for changes in certain files. That could get out of hand pretty easily. And yeah, one can say "anything can be taken too far". Just like you said about generics. The difference might between having well-encapsulated and behaving mechanisms that does most of what you normally would need. As opposed to a "simple" system that just pushes the problem to another level, in more ad-hoc ways.
[1] I honestly don't know if the code generation typically is pre-, post-compile or a mix of those two. It's too complex for me.
[2] I thought single-line comments was supposed to be a safe haven...
Not everyone uses codegen or other tools. You can write generic-ish code in Go which is just runtime checked via vtable pointers (interface objects).
And of course, the loss of static checking means that one has to write more tests for mundane things. But again, designing tests requires "runtime thinking", designing statically checked APIs requires "compiletime thinking".
Well, variance can be hard for many to grock. The combination of generics, mutation, and subtyping is problematic, complicating nice feature like type inference. I can see why Pike and company left it out, though I think it's quite feasible to fix their problems.
Why do people keep on saying that? Would people say javascript is for the pragmatic crowd because jsfiddle exists ? no
Go is a badly designed language period. the type system forces devs to write runtime type assertions which should be the job of the compiler thanks to parametric types, if go designers knew one or 2 things about types. The fact that Go dismisses 30+ years of type theory isn't pragmatism. It's ignorance.
Nobody would call PHP pragmatic yet even PHP is more expressive.