I'm going to risk being labeled an ~incompetent dev~ or whatever but learning golang was seriously a breath of fresh air compared to literally any language I have ever tried to grok before.
Everything felt like it was there on purpose. It always seemed like there was a "proper" way to achieve something. Being told to use this opinionated formatter was like removing a 40kg bag after a bush walk. You never have to worry about if you're writing Go "the right way", because it's extensively documented what that way is.
Generics is an awesome feature, writing C# is my day job so sometimes I miss it, but I have full faith in the designers when they say it will be in the language in a "Go appropriate way". The last thing I personally want to see is Go being handed over to the community to be designed by committee.
I completely agree. When I first started writing Go (coming from Python/C#) I complained an awful lot about what felt like pointless hamstringing of functionality. Go is a simple language, and you don't get many toys. It also feels very verbose at times, and forces you to think a lot about doing things which seem automatic in other languages.
However, as time went on, I noticed a few trends. Firstly, forcing me to think more revealed that what I had thought was automatic was more automagic - Go forces you to take responsibility for what your code does to a far greater extent than other more convenient languages, albeit not to the extent that C/Rust does. Secondly, I noticed that code written in Go tends to do what I expect it to pretty much all the time (with the occasional except of async stuff). Sitting down and writing a program in Go often results in something that actually works the first time it runs, and has far fewer runtime surprises.
As painful as it is to do numerical computation in Go sometimes, I have a very high level of confidence that I can look at a program, deduce with some accuracy its runtime memory usage & footprint, multithread it easily, and reason (successfully) about possible runtime failure modes and behaviour. This is something I find difficult if not borderline impossible to do in Python, especially utilising the standard '10 layers deep' stack of numerical computing libraries.
Interesting, that I saw a similar pattern like "at first I complained, but as time went on I found some benefits" quite a lot.
It can be that your learn a language better, became more comfortable with the way it must be used: say, stopped writing code in Elixir the way your used to write in Python.
But the other thing is that it's in our human nature that we tend to look for something positive in bad situations we exposed to for a long.
Say like, PHP was a fractal of shit, but when you use it for a long you will notice that it will make you more aware of what functions to use and how not to fall into some undocumented craphole, be more responsible, and do not take it for granted that some function would work flawlessly. The obvious benefit from the shitty situation.
That's like the idea of planting a bamboo plant, then jumping over it every day. It's a nice idea, but you won't ever be able to jump over a two story house. Instead, you'll eventually catch your foot and tumble. Likewise with the minefield. The result, is that you'll eventually step on a mine. At best, you can use a simulated minefield as an exercise, then use mine detection equipment and proceed with caution.
My enjoyment using any given language always tends to grow as I get more productive with it, even if I have a more general dislike for the language itself.
Making computers do things is fun (usually)! The programming language is (almost) immaterial - depending on the task at hand of course.
Despite myself, I've even found myself enjoying JS in the few times I had no choice to avoid it. shudder
That part about JS is pretty much the story of my career - I started out completely hating JS, was forced to use it enough to get more familiar with it, and eventually eventually started enjoying it to the point that it's now the primary language I write.
(I still hate it occasionally, but there's a lot more joy these days.)
The initial turning point was probably around the first release of jQuery...
[Javascript isn't actually that bad of a language. It really is about 90% of Scheme plus prototype inheritance, which takes some getting used to but ... eh, it's as good as any other option. The problem was that it was one of the battlefields between Microsoft and Netscape and has some really hideous scars in the landscape.]
I did not write this. My fingers did not type it. Nothing to see here. Move along. I'm a hedge.
Well, the basic parts are not that great. Plus, it has almost nothing of Scheme (nothing more than e.g. Python has of Lisp), that's just an old wives tale. It just has closures and that's it. Scheme is a Lisp, whereas Javascript isn't [1]. Not sure what Brendan had in mind when he was inspired by Scheme, but the end product is nothing like it.
Coercion rules are crazily bad. No integer type is stupid. Prototypal inheritance nobody much cared for (where nobody = very few). An empty array is not falsy. And several other stupid decisions besides.
The only reason it wasn't that bad, is that it wasn't big enough to be bad. It was just a handful of features plus a tiny (and bad) standard library (some math, some string stuff, etc). Everything else people had to build on top (and usually the did it badly).
This. Plus folks are always comparing to their previous experience, which is likely to still be a subjective and also hard to compare at all too. It's like apples (Go) vs oranges (C#) vs broccoli (Python).
Mostly machine learning for distributed sensor networks (ie: smart meters). Deal with lots of time-series data, state space modelling, some recurrent neural nets (etc). Our shop has a 'golang only' thing going, which means that I end up having to reimplement algorithms in go sometimes from scratch.
nice area, I would be interested to learn more into this type of problems. Recently, I became for interested in power electronics / smart grids / energy, and looking for the ways to get in touch with people working on such problems, learn more and join any company on these domains.
It depends on what you want to do as this industry is HUGE. Do you care about metering and working at the solar panel or wind farm level? Or maybe on the actual energy markets that commit and dispatch all generation in a region? Or maybe the vendors that write the software for those markets? Or you could work for the utilities or IPPs that own the generators...or the state public service commission that control state plans. There is also FERC and NERC. There are companies that sell energy storage systems...the list goes on and on.
I saw on the Adacore website a success story for another company that sells smart metering products, so it is nice to see all the work in this space. There are plenty of major vendors as well with smart meter products and the accompanying software.
What company do you work for by the way if you can say?
I agree, the greatest thing about Go is all the stuff it left out. Which is still annoying sometimes coming from more expressive languages (no exceptions! no generics!) But thanks to the simplicity and the common format standard it is so easy to read and understand. If I want to know about an edge case of a library function, I just dig through the code in my IDE until I have the answer. In most other languages I'll hesitate to do that, either because it's hard to read the code, or hard to access it.
I rarely have to think much about how to write the code itself, just about the actual problem that I'm solving. Once I know where I'm going, there's really only one way to write the code for it. Reviewing and using a co-workers code is also a breath of fresh air.
I think languages fall on a spectrum with regards to both typing and expressiveness, and it's not good to be on either end (e.g. PHP vs Scala or C vs C++) the designers of Go were very disciplined in walking that line and struck a great balance. I'd hate to see that undone by turning it over to a committee which results in a million compromises that turn a language into a Swiss army knife of features. It needs that strong guiding hand and the discipline to say no most of the time. Go has become my favorite language, I just wish I get to use it more in my work.
I rarely have to think much about how to write the code itself, just about the actual problem that I'm solving.
Bingo. This is also what the designers of Smalltalk, Ruby, and Python were trying to achieve. This is the opposite of C++, where I find that I'm thinking about the how all the time. (And at least 25% of the "agile" process time is spent on this activity in explicit reviews.)
> The last thing I personally want to see is Go being handed over to the community to be designed by committee.
I'm thankful for exactly that. Go is developed by Bell Labs people, the same people who bought us C, Unix and Plan 9 (Ken, Pike, RSC, et al). They took the time to think through all their decisions, the impacts of said decisions, along with keeping things as simple as possible. Basically, doing things right the first time and not bolting on features willy-nilly simply because the community wants them.
> Go is developed by Bell Labs people, the same people who bought us C, Unix and Plan 9 (Ken, Pike, RSC, et al).
Exactly and it comes in line with other research languages, namely Newsqueak and Limbo, both relying on channels for concurrency. I hope their other work will also find their way into every day usage though.
My experience is the same. I spent a couple of weeks playing with Go and had such an easy time with it. I can go back into the code I wrote and understand exactly what's going on. I can't say that about most languages I tried. I can even make sense of other people's code in large, complicated Golang codebases despite having little development experience.
This probably scares people whose livelihood depends on managing complexity in other languages. If anyone can get up to speed quick, anyone can potentially make the program that eliminates the need for that complexity.
I don't know that Google had this in mind while developing Golang, but they stand to benefit from commoditizing development. This is fine for someone like me who has zero interest in it as a career but does use a lot of scripts and plugins for creative work. Right now it's $10+ every time I want to do something with music/video/art where free or included stuff doesn't work or doesn't exist. If every DAW, video editing suite, and art/graphic design program had a scripting language as easy to use as Golang, I would never need to pay for add-ons.
The markets would still exist, but they wouldn't be as lucrative. Pricing would go from value to commodity.
> The last thing I personally want to see is Go being handed over to the community to be designed by committee.
There is a point about diversity to be made here. Different design models will each have their strengths and weaknesses, and the design spaces each opens up are not going to be fully explored if one model prevails. So I'm glad there's a language like golang with a coherent centrally-planned vision behind it in existence. It's also good to see more community-driven models get to do their thing. We'll see over time how each develops and what problems they best solve. It does seem to me to be a 'let 100 flowers bloom' type situation.
A bit of a bland centrist view perhaps, but with systems as complex as programming languages and their associated libraries, ecosystems and pragmatics, it's really hard to know what works. Best to experiment.
> Being told to use this opinionated formatter was like removing a 40kg bag after a bush walk.
I think the gofmt approach is becoming an unofficial standard. In the JS world 'prettier' has taken off and I think most languages now have a community anointed formatter (and new languages are likely to have an official one).
Strongly agree. Go feels great to write. I hesitate when designing a new project in C++ because I need to figure out the right / clever way to implement something. Go feels a lot more straight forward where I can just write it in the one way it's designed to allow. It gets me writing code a lot faster than other languages.
My experience is different. Believe it or not the type checker is actually inferior to Python + mypy. For example it is possible for variable to be nil, even when it is not a reference.
Types, it has int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64 and also float32 and float64.
If you use anything besides int, int64 or float64 you will just have a lot of fun casting.
math.max() and math.min() only work on float64, you can easily use it with different types, and actually it is discouraged to use it with integers. So you need to roll your own if you want to work with integers. But ok, it is math so when you do math apparently you should work on floats because that's what scientists do, but then why it doesn't work with float32? You actually have to cast like
result := float32(math.max(float64(left), float64(right))
If you want to convert a string to an integer, you have nice strconv.ParseInt() where you can specify among other things a bitSize, great, but the resulting type is still int64, you will need to cast it. What about other types, using them is a nightmare, if they were not supposed to be used why not just have int and float type?
If you try to implement a data structure that stores objects, you either have to duplicate the code, use interface {} (looks like that's most common, but then you no longer get help from a type checker) or use generator (this seems best to me, but it is just automation of the first approach).
I don't understand why Go is getting so much good opinions, it is not an enjoyable language to program. The supposed killer feature which were go routines and channels are kind of meh and nothing that you couldn't replicate in other languages. Seems like people like its simplicity, does that mean the other languages are overwhelming?
It's okay, I like elixir's take on things more and I question how suitable Go is for maintainability of large projects. But it's okay. It will improve as more developer tools and language features come online.
I personally don't see Go and Elixir's primary domains as being equal, or one a superset of the other. So there's some argument to be made about the region where they overlap, but for something inherently based around fault-tolerance and distribution, seems to me that code written to run on the BEAM will be smaller and clearer and therefore more maintainable.
If I'm interested in building low latency and highly available web services it seems to me that both Go and Elixir are reasonable choices. How are they not the same primary domain?
But in any case, Elixir allows a lot more clever code. In my experience working on legacy software, clever code in a dynamic language is error prone and hard to refactor and maintain. Static typing can help, though, I've found this especially true in functional languages where you have a super smart developer do something clever that's hard to understand 5 years later.
Because it is standard, in these discussions, for someone to quote Rob Pike to say that golang was designed for the lowest common denominator of developers.
Personally, I like go a lot for writing services and console applications.
A common HN trope is that Go doesn't have enough features (Generics usually) and gets in the way of '10x'/'competent' programmers expressing their genius - unlike Haskell (or some other advanced language for advanced minds)
What are the advantages of having a committee involved in the design of Go? In the case of C++, based on the threads that I read on HN, I see people being unhappy about the decisions taken by its committee.
A slice isn't an array. A slice is a view into an array.
You don't look through a window in your house into the backyard, and plant a tree in the backyard by fiddling with the window. It's the same with arrays and slices in Go.
If you want to insert an item into a slice, insert it into the array (by copying to a new array and adding your new element to it while copying), then creating a new slice which includes your addition.
edit: (adding for clarity) In a lot of programming languages, whether they use slices or not, arrays are of a fixed size and must be copied to a new array if you want to add elements. Some languages have some syntax that makes it feel like you are modifying an array in-place, while doing the copy to a new array behind the scenes.
> edit: (adding for clarity) In a lot of programming languages, whether they use slices or not, arrays are of a fixed size and must be copied to a new array if you want to add elements. Some languages have some syntax that makes it feel like you are modifying an array in-place, while doing the copy to a new array behind the scenes.
It's that or some magic with larger-than-needed arrays that automatically grow by a bunch extra every time they hit their boundary to make appends faster, while blowing up memory use and making append performance unpredictable.
Lots of (especially) scripting language hide this behind automagic and you see tons of append-in-a-loop where it's not really necessary, as a result.
[EDIT] had insert two places I intended append. Me need coffee.
Yep, you're right, that's the transparently resizeable array thing, and it's exactly how Java's ArrayList class gives the feel of a resizeable array while it actually manages fixed-size backing arrays for you. That's why I linked the source to that class. :)
This is absolutely not best practice. It's perfectly idiomatic to insert an item into a slice (without the copy shenanigans you describe). The slice will manage the copy if necessary.
That's fine as long as you don't mind if the underlying array is modified. As the parent points out, a slice is a view into an array and there could be other views into the same array.
.... that's really it. Will it have the same backing array as it did before you did append? Maybe, maybe not. Should you care? Absolutely not, and if you do, you're probably doing something wrong.
Everything felt like it was there on purpose. It always seemed like there was a "proper" way to achieve something. Being told to use this opinionated formatter was like removing a 40kg bag after a bush walk. You never have to worry about if you're writing Go "the right way", because it's extensively documented what that way is.
Generics is an awesome feature, writing C# is my day job so sometimes I miss it, but I have full faith in the designers when they say it will be in the language in a "Go appropriate way". The last thing I personally want to see is Go being handed over to the community to be designed by committee.