I think this is similar to what people think about the type system in Haskell or the borrow checker in Rust. With every higher level language comes new things to learn and obey.
I want to mix C++11/14 into that also. Now that the typesystem is used by the standard library to describe resource ownership in code whole categories of errors can be found at compile time. If you are new this it can seem like you are fighting the compiler, but once you learn that the compiler just won't let you make certain kinds of mistakes you get access to every level of abstraction with C++11/14 and Rust. You can code in terms of passing database bindings betweens threads in threadpools or you can twiddle individual bits in specific registers and everything in between.
I don't know Go well, but it seems really limited. You can't write certain classes of bugs, but you also can't write many design patterns.
Whether or not I choose Go is almost always comes down to whether I want to solve a problem quickly and with decent performance/readability/etc or if I want to take a lot longer for a solution that is more aesthetically pleasing or with a smaller risk of error.
I'm sure lots of people will argue that their language is faster to develop in, but apart from toy programs or those requiring libraries unavailable in Go, this has never been my experience. In particular, even after two years with Rust, I still have trouble reasoning around memory management, lifetimes, how to pass around functions, how to do anything asynchronously, etc. Go isn't perfect for anything, but it strikes a good balance for the kind of work I tend to do.
YMMV.
That was my experience, too. Vaguely interesting in a couple of ways, but definitely a bondage and discipline language and nowhere near compelling enough to make me want to put up with that.
This is true in every text-based programming language. s/compile/execute/ for interpreted or repl-based languages.
My favorite was the Comair christmas failure back in 2004 or 2005. I tried googling the root cause, but I think it was an Integer overflow in the 16 bit integer they used for storing the flight number. The system was designed in the mid 80s and 65535 flights was an insane amount, but but when the software failed on Christmas it interupted more than 1,100 flights.
No one disagreed with this comment and it is one of the least controversial thing I have said on HN. I think I have a downvote fairy, someone who just downvotes everything I say. If so, why bother? If I don't have one then when you downvoted me, why didn't you respond?
Go hijacks control flow and makes it more difficult to reason about how your code will be compiled and executed. At least that is true in my personal experience.
https://gobyexample.com/channel-buffering
As far as my understanding is concerned, channels are a way for goroutines to pass data between one another, correct? Yet in this particular case, the channel `messages` is operating in the same manner as a generator or array. So, am I creating goroutines by passing messages to the channel or am I just using the channel as a simple buffer?
This example helps as well: https://gobyexample.com/channel-directions
Am I implicitly creating goroutines by using channels or am I simply creating a buffer?
Sorry I don't have any of my own code to share as I deleted all of my Go practice stuff.
The flow of data through channels can be confusing until the concept becomes familiar, but the behavior is well-defined, so the behavior is as easy or difficult to predict as of any program of the given complexity.
Pid ! {self(), 42}
And in the process identified by Pid, to receive the message: receive
{From, Data} when is_pid(From) ->
handle_data(From, Data)
end
And beyond that, the process identified by Pid can be running on a physically separate host system - it's transparent.Too bad we can't use Erlang for systems programming, but you can't have everything!
A channel is just a thread-safe queue. An unbuffered channel blocks until something else receives the sent value. A buffered channel allows n sends until it blocks. Using a channel will never create a new goroutine, its just a way send data. You can use a select statment to wait on sending or reciving from multiple channels or to send or get without being blocked by a full or empty channel.
In C you could put together a RW mutex, condition and a linked list or array and have the same thing pretty much.... If you want to create a goroutine you need to invoke "go X".
Out of curiosity, do you know C/C++ or Java?
Will Nim be as versatile and solid as Go in the future? Hard to predict but i would say no. You need a solid financial backing and certain amount of adoption where people actually write software that makes them money.
Agreed, that's why I don't use it for anything super important yet. Nim is approaching a 1.0 release soon. Go has a similar problem in that it is maintained almost entirely by Google who has a history of dropping projects without warning.
> Go is more versatile and at the same time more mature than anything out there.
This is objectively incorrect. In fact, Go aims precisely to be non-versatile for the sake of simplicity. That is why Go does not have generics for instance.
> It is a different design and it excels in what it does (considering all tradeoffs now)
I don't think it's design is all that different. It looks like a stripped down version of C and it's definitely not the first PL focused on concurrency.
> Will Nim be as versatile and solid as Go in the future?
Nim is already leagues above Go in the versatility(I assume you mean flexibility?) department. As far Nim being as "solid" as Go, I'm not entirely sure what you mean. If you're asking about stability, I believe that Nim can reach a similar level of stability as Go, yes.
> You need a solid financial backing and certain amount of adoption where people actually write software that makes them money.
I agree with this. However, it's not always a quick process. The only reason Go is as popular as it is is because of Google's size and reputation(edited). Every programmer on Earth heard of Go within a few days of it's official release. Nim is taking a slow roll approach. Look at Python. It took almost 15 years before it started getting really popular.
All that said, I didn't come into this thread to argue about Go vs Nim. I've been accused of shilling Nim in the past. I'm sorry that I like talking about PLs I enjoy using.
The reasons Go doesn't (yet) have generics are practical rather than philosophical. And well-documented.
I also don't believe Google's marketing budget contributed much if anything to supporting Go. The _reputation_ of Google and the Go authors was far more important. (Personally, when I saw people like Brad Fitzpatrick try Go and rave about it making programming fun again, I decided to try it.)
You can happily accuse me of shilling Go if you like :-)
> The reasons Go doesn't (yet) have generics are practical rather than philosophical. And well-documented.
Can you give an example? I guess I fail to understand why a statically typed language would choose to forgo all of the advantages generics provide. Does it have something to do with Goroutines?
> I also don't believe Google's marketing budget contributed much if anything to supporting Go.
I didn't necessarily mean their marketing budget. I should probably edit that. I meant that anything they do is news.
Like I said, the objections are practical, not philosophical:
They published four past design docs for generics in Go that simply didn't pass technical muster (https://github.com/golang/proposal/blob/master/design/15292-...)
Also, rsc stated he plans to understand generics better in 2017: https://research.swtch.com/go2017#generics
Also, bradfitz said recently on the GoTimeFM podcast that doing Generics and Go2 together makes sense.
> I didn't necessarily mean their marketing budget. I should probably edit that. I meant that anything they do is news.
I feel like the comments from others about Dart give the lie to this one. Go is fantastically, dramatically, massively more popular than Dart, which is also from Google.
Russ Cox and Rob Pike keep repeating this mantra, but I don't buy it. No, I don't believe they object the idea of generics itself. And yes, generics pose practical complexities and a plethora of issues that have to be resolved.
But so does every other language feature. The features you choose to add reflect your philosophical values and priorities.
Go chose to bake some hitherto very niche features that could have been as libraries into the language. Channels in particular, are a language construct only because Go doesn't allow operator overloading and generics for user types. But channels get them, because channels are demonstratively important for Rob Pike[1].
There's nothing wrong with that of course, but that's a philosophical decision. Why channels can avoid the vagaries of interface{} boxing, but not sets, linked lists or queues?
The reality is that every modern statically typed language except Go has generics, and they all implemented them very well. The ML languages and Ada were already doing it in the 80s, and OCaml and Eiffel managed to combine generics and polymorphism back in the 90s.
It seems to me that when originally designing Go, Pike, Griesemer and Thompson just didn't think generics are worthwhile enough for the effort it takes to properly research them.
When Go was started, its authors mostly looked to languages which implemented generics later in their lifecycle (namely Java and C++) and their implementations suffered from problems due to other, rather obvious, design defects: https://research.swtch.com/generic
I'm happy to see that this attitude is changing, and other languages are looked at.
> It seems to me that when originally designing Go, Pike, Griesemer and Thompson just didn't think generics are worthwhile enough for the effort it takes to properly research them.
Are you arguing that it's easy, and they just haven't done it? Or are you arguing that it wasn't important enough at first, and so the implementation developed in directions that preclude straightforward implementations now? I can believe the latter, but after reading the multiple, detailed proposals from Ian Lance Taylor, I don't believe the former.
I think Google put lot of marketing budget for Dart. But I don't see it ever comes in discussion regarding popularity or lack of it.
It is fine a lot of people do not like Go but claiming its popular just because of Google seems baseless.
It is fair to say that without those names attached I would have likely passed it by. Google is boring, but those three names, for me at least, I had to take a look.
Let's see if Flutter and Fuschia teams manage to push adoption for Dart.
> Google & adoption
I think it helped get around the initial cycle of drawing in the curious. An argument counter to claims regarding the importance of the people involved would point out Plan9 etc. that are hardly widely known, much less adopted.
In sum, I think the role of Google in one becoming a Go programmer depends entirely on when it happened. Today, of course Go has its own brand name. 8 years ago, it was Google that eased the debutante phase of the language.
This doesn't seem like a very credible statement on the face of it. Is Go more mature and more versatile than Python? Than Java? Than...Scala? Go does seem to share a lot of use cases (and limitations) with Java; and it would be hard to call it more mature.
It was the same for Linux, Python, Ruby. Being community-driven can be a bug or a feature.
> Go is more versatile
Nim has macros, templates, overloading and compiles to C, JS, Objective-C. Runs on more architectures than Go including arduino microcontrollers.
> mature than anything out there
Go is not more mature than C, C++, Java, Python, Perl...
> You need a solid financial backing
See Linux, Python, Ruby... many projects had no big company or funding behind them.
Pardon me and no offense, but it sounds like you are hitting the 'statically typed language' boundary.. all of the others you mention are fairly loose and dynamic. Go & C, not so much. It sounds like your use of C has been library code, which presumably is more 'data processing' oriented and so doesn't require much structure or control of process/runtime/etc.. which is where you will run into this stuff on the c side..
This is why I moved from c/c++ into dynamic languages to start with.. that said, as I grow more sophisticated and can 'deal' with the typing/lower 'machine' level control, the more I can understand other tools.. even C++! ..
i mention this because each layer of abstraction is there for a reason.. best to view with a fresh pair of eyes imho
You are supposed to "compile on save".
You know, it's interesting. I've been programming with Python for about 6 years now. I've also picked up Javascript, SQL, bash, and PHP along the way. I'm always gaining a little bit of C knowledge here and there when writing C extensions for my Python applications. I'm a fairly experienced programmer at this point. To the point:
I tried picking up Go one day because I was hearing so much about how it could replace Python as network glue code with better performance and reliable concurrency. I can't really validate or invalidate those claims. That said, I found Go to be sort of difficult. The syntax is really simple. Compiling is really simple. Concurrency is even simple. However, need to do something in a different way than Go decides is correct? Well, you can't. It won't even compile. The difficulty in Go is in learning about what the compiler thinks is OK. I don't really like that. You don't really know if your code will work until you compile. Basically, I just think Go isn't really flexible enough for modern programming. I find that Nim can do Go's job better than Go can for my use cases anyways.