Four days of Go
evanmiller.org
evanmiller.org
I think this is why some people dislike Go. The Go authors have made a decision about the language and are sticking to it. I get the impression that they are doing this because they believe they are 'right'. That makes some people uncomfortable because we programmers like to discuss everything, and argue, and it's hard to come up against people who have what is close to 'faith' in their own beliefs.
In this telling, the story of Go is really a tale of revenge, not just against slow builds, but against all kinds of sloppy programming. Which in my opinion is too bad, because I myself am a sloppy programmer.
This really does seem to be the approach I see with the Go digest mailing list. What I don't understand though is the ease of importing a library, say from Github. Interesting that the language from the author is all about how rigid and unforgiving Go is, yet "some guys" libraries can just be thrown into the mix in your program, and Go has no issues with this.
Given this background and the Go designers focus on Google's internal needs, it's perhaps not surprising that you can import code from github .... but not specify which version you want. (unless that is now fixed?)
The alternative is of course supporting dozens or hundreds of copies of a library and every possible commit hash of said library. I contracted at a python shop that had 81 versions of a single library in use all pinned at different versions. The reason I know this is that I had the great joy of dealing with upgrading all of them after a critical hole was not only discovered (the company knew about it for some time, but just didn't want to bother updating all those apps) but exploited... repeatedly.
> it's perhaps not surprising that you can import code from github .... but not specify which version you want. (unless that is now fixed?)
If by "fixed" you mean there are dozens of solutions to pin versions -- then yes. If you mean baked into the go tool, then no.
"One version per org" means "upgrades are harder, but patches are easier and you don't need to deal with different quirks of different versions at the same time and you don't get problems using 2 components that need 2 different versions of some other thing in one process etc."
"Latest version, always" means you have no way to even build the latest version of your thing that was tested and is known to compile and work. Kinda sucks, I think.
Does it mean the community isn't a priority? this vertical relationship between the Go team and the community could doom the language as fast as it was made popular, that's my opinion.That's a real issue.
Or arrogance and incompetence. It's been said many times. Go team should spend at least one day with Gilad Bracha...
But I guess it's easy to be critical of other peoples output when you're an anonymous internet user yourself.
> when you're an anonymous internet user
It is easy to be honest, yes.
But I can tell you in my experience that this type of forceful "everything is a error, no warnings" and "it is done this way (formatting for instance)" are a breath of fresh air. Having dealt with team members that barely know how to program and think a compiler spitting out an executable means it's ready (what warnings? why do those matter, it compiled), Go makes coordinating with them a lot easier. It forces them to be more correct before an executable is created. It doesn't make them better, but at least the rest of the team can work with what they create until they do get better.
Also, the simplicity of the language sure helps everybody (regardless of skill) get up to speed quickly. People that know what they're doing may hate there isn't some special feature they love (generics, etc) in the language, but working with a team of varied skill is so much easier this way.
In before "but adding generics does not make team projects harder, look at language ..."
Agreed. Go lacks many things, but the "zen" of Go is wonderful feature most people aren't aware of, or under appreciate.
I wouldn't use Go for everything, but I wouldn't dismiss it because it doesn't have a favorite language feature.
It's funny that you use the word "Zen" - about two years ago, I gave a talk about Go to the New York Python Meetup about why I switched to Go[0], and the punchline was that Go fits the Zen of Python[1] better than Python does[2].
[0] Before anyone gets upset - they asked me to speak, and they were genuinely happy with the presentation. It's not like I went in there to troll with a talk on "This is why your language sucks"!
[1] https://www.python.org/dev/peps/pep-0020/
[2] If anyone's interested, these were the slides: https://s3.amazonaws.com/golangweekly/go_for_pythonistas.pdf
What I like about strongly opinionated languages in general is that most of the strong opinions are around trivial features of the languages relative to the complexity of a decently interesting programming problem.
Features like formatting, no unused imports, etc.
These are typically areas in a project where Parkinson's Law of Triviality rears its ugly head in project planning meetings. Everyone feels the need to bloviate about 2 vs 4 indents, tabs vs spaces, or which lint flags to enable/disable.
Hell, with go get always grabbing the master branch, it even implicitly requires projects to keep their master branch 'green' so it doesn't break projects that depend on it. A very neat way to eliminate a whole set of "Which branching model should we use?" arguments.
Arguably, that also explains its success.
for i in range(10):
if i % 2 == 0:
print('hello')
and I paste `print('world')` after that, there are at least three possibilities of the proper indentation of the line. It can match with `print('hello')`, or with `if`, or even with `for`.That's because Python encodes block information solely using whitespace. So, if the indentation changes, the actual meaning of the code also changes! In fact, that's why it is called "significant". You cannot automate it, just like you cannot automate writing code.
If I want to move a whole block in one level, I select the block, then press control-C and '>'.
That's what I mean.
To me, regardless of the number of the key strokes needed, it's still a manual indentation that bothers me more or less while coding.
edit
More to your point, though. I would never choose a language for a project because it is strongly opinionated on such things. However, when choices lead to an opinionated language I find the feature a positive rather than negative edition....even if I find a particular decision annoying at first.
Making the compiler super strict about it seems like a good way to make quick changes awkward. Especially when there isn't a strong debugger you often end up commenting bits of code out or adding "return true" type statements half way down functions, and it's annoying when the compiler refuses to let you do it. This is one of the things that bugs me about javac - if it detects dead code in a function it refuses to compile. Maybe I'm weird but in my work this has caught legitimate dead code exactly zero times, but has triggered false positives due to transient debugging changes eleventy bazillion times. Luckily javac is dumb and you can trick it by just writing the code as "if (true) return;"
I have no idea why this would be a core part of any language.
It is illegal for a package to import itself, directly or indirectly, or to directly import a package without referring to any of its exported identifiers.
I'm saying that the tooling that helps manage import paths in the way you want is not part of Go-the-language.
The language restriction against unused imports certainly is.
I personally think these should be configurables turned on by default so you kind of push the new comer to write good code and build better habits but there should be an option to disable it, make it hard to find but it should be there, especially for the people like OP and other small over-the-weekend projects.
It was in one of the numerous Go talks/videos/presentations where I think it was Ken Thompson who said that he could walk around the Google cafeteria and hear Python programmers arguing all day long of how white space should work, and in Go, those discussions just don't happen. It's done. It's been decided. Move on.
It really struck a chord with me. It's amazing how smart people, given enough free time, will argue non-stop about the most irrelevant, insane things and stop themselves from being productive.
I disagree with you here. First, just because people are arguing about irrelevant insane things doesn't necessarily mean they're not productive. Second, I love those trivial arguments because at the end of "lunch" I've taken a break from the more involved thought, floated up to lighter stuff for a while, had some fun, and can now easily get back to the tasks at hand.
Your (and many other people's) insistence on dismissing discussion regarding generics as some kind of a joke is anti-intellectual. You're rejecting valid criticism of your arguments on the basis that the critic's argument is unworthy of attention for some reason external to the discussion at hand.
I agree that pro-generics arguments are usually boring, and at least 90% of what they say has been heard before. But the same can be said of Go evangelism, like your comment; they are no less worthy. Please don't deliberately shut down discussion.
Then people bring Rust, which has only had a stable grammar for last couple months and a standard library nowhere near Gos. Would it be wise to complain that the Rust stdlib doesn't contain a HTTP server implementation?
In practice Rust doesn't make breaking changes anymore. (It hasn't since beta, and in a month or so 1.0 will be declared officially stable and it will become forbidden to make them.)
And yes, if not having an HTTP server implementation in the stdlib seems like it makes your project difficult, that's a perfectly reasonable criticism of Rust.
(Though one I suspect will get resolved much more quickly and cleanly than issues like generics in Go.)
It's pretty easy. You just add this line to your Cargo.toml:
hyper = "0.3.14"
And the next time you build, Cargo handles everything. You can now use hyper like any other library that's included with Rust, no biggie.This is one reason we've chosen minimalism for the standard library: It's really easy to use external libraries, and once things land in the standard library, they often don't improve much. The versions become tied to the compiler versions, contributors now need to build the entire compiler rather than just working on a single library, and everything else. We've already seen three distinct major HTTP implementations happen, had we put rust-http right in the standard library, we'd have frozen something the author has already deprecated!
Choosing non-minimalism has advantages too: in this scenario, you need to know that hyper is currently the best library, for example. Engineering is all about trade-offs.
(Solely chiming in on the HTTP in Rust thing here. I found the part of the article about the Gopher... lacking, and it distracted me from the rest of the author's points.)
What a wonderful sentence about a simple, but often forgotten truth!
Rust has language stability (in practice right now, and officially once we hit 1.0 in a month), so we in fact do guarantee this.
> Maintainers of third-party library can write "Farewell Rust" blogpost and all projects, based on that library will be in trouble.
Languages can do that too, in which case the entire language and its ecosystem is in trouble. Anything can be abandoned. The crucial thing is that if a piece of infrastructure is in the standard library, then it's much harder and slower to iterate on it. HTTP is a fast-moving standard (see HTTP 2, for example), and so it's very important to be able to iterate quickly to support new features.
> And as http is a very important thing for web-programs, it's much better to see support of http in std lib.
I disagree. Web applications need HTTP, but many applications aren't Web applications. As a example on the far opposite end of the spectrum, your OS kernel doesn't have an HTTP stack in it (unless you happen to be running something like khttpd), and Rust is designed to be usable for OS kernels. Large standalone standard libraries reduce flexibility, and Rust is designed to be flexible.
(Yes, I know that's completely tangential to the point you're making.)
Languages can abandon own std lib? Keep away from such languages.
> HTTP is a fast-moving standard (see HTTP 2, for example), and so it's very important to be able to iterate quickly to support new features.
Golang doing it just fine, so Rust can too.
> I disagree. Web applications need HTTP, but many applications aren't Web applications.
I'm talking exactly about web applications, not about all applications. And if web applications is not the field of Rust - let us know about it. Right now is not obvious and even web frameworks exist in Rust.
Not abandon their stdlib. Be abandoned. There is nothing more preventing developers of the compiler/vm from abandoning their efforts than the developers of a library. It would make little sense for developers of the language to abandon just the stdlib, as it is part of the language.
I'm talking exactly about web applications, not about all applications. And if web applications is not the field of Rust - let us know about it. Right now is not obvious and even web frameworks exist in Rust.
Rust is a fine language for web applications, but it's not designed specifically for them. The languages with huge stdlibs date from a time when accessing libraries was much harder than it is today. The internet, as well as package management, was young when Python and Java were born. Now that it's easy to download packages, and we have reasonably passable tools for doing so, there's no need for heavy standard libraries.
Go is specially designed for running on servers and performing network tasks. So it makes sense that it would have a stdlib with rich networking support, including http.
Node was designed as a frontend to libuv, to make nonblocking IO easier to use. The most visible domain where nonblocking IO is extremely useful is in making web applications, AND the fact that it's javascript makes it even better suited to web. So Node has http support baked in.
Rust is meant to exist in the same space as C++. It can be used for anything. OS kernels to text editors to web applications. There is nothing in particular that ties it to any of these domains. It has the option of putting support for all of these in the standard library, which would make it hard to maintain. Every time one part of the stdlib needs to change, the language needs a minor version bump, or there's a delay before anyone can use the new libraries. Not a big deal when you only have one or two domain specific components in the stdlib, but a problem when you have twelve.
If the stdlib supported only some specific domains, it would give people from other domains the impression that they're second class, and drive them away. Not cool.
So rust goes for a minimal stdlib.
In second part of your comment you comparing stdlib and external libs as they are equally reliable, but my point is exactly about difference in this aspect. I agree stdlib shouldn't be swiss knife, but I disagree it shouldn't have nothing except minimal set to serve language constructions. Go was designed as C++ also, not only for networking. And it has image module, not only http (for example). I see how fast and successfully Go evolving, I think Rust is better and that's why I think it's the area where Rust can take better idea from Go.
HTTP clients are not something I would want in a standard library to be honest. Since there are so many different ways to implement them. And not all work for all use cases. It's not the same as StringUtils or ArrayUtils.
I don't use Go so I don't really care about their generics or lack thereof. What I found ... odd ... is how the Go team has apparently said they can't go generics because there's no good way to implement them. Seems like a strange thing to say when many languages are happily using them.
Lot's of languages have generics, but they have trade-offs, so they aren't free, even if they can implement them using existing generics implementations. Picking what they're willing to sacrifice can be hard, even if it's something like slower compile times.
Anything backwards compatible has to be in Go 2 or later, because generics are hard to make backwards compatible, we'll have to wait.
People don't want generics for the sake of it, they want type safety.
It seems Russ Cox and Rob Pike are either anti-generics or in the you-dont-really-need-them camp, but Ian Thompson and Brad Fitzpatrick have seemed very open to the idea - what they can't, however, agree on, is exactly how to implement them so that they make sense in Go. That's it.
If you or anyone out there manages to produce a proposal of how they should work/look like and even a fork of Go implementing the idea, it will be taken seriously, at least by some core Go members.
I have a feeling that generics are coming. And I have a feeling they'll be very Go-like - an external tool with code generation, not special syntax. Just my 2 cents.
The Go team may find a brilliant way to accomplish this, but I think the only viable way left is, as you said, using code generation. Either C++-way, which is a special syntax but still a form of code generation, or an external tool. But neither of them is elegant, because you cannot fully utilize the convenience that the type system give. These might be the concerns that the Go team has.
So far, nobody has been able to show all 4 of these requirements, so nothing has been done.
But when/if someone does, I expect it to be taken very seriously.
You can dock a couple of points for pointers being allowed to be nil. You may want to give half-a-point back for the fact that a nil pointer can actually be a valid implementation of an object, and I actually use this quite a bit. But nil maps can be accidentally unpleasant.
You can pass a pointer over a goroutine channel. That's my main issue with them, beside the fact that we should be past this needless complication of our code. Again, they're unnecessary and encourage bad code.
Anything can create unreadable code, but mostly it's bad programmers writing unreadable code, not the syntax they use.
This paralyzing fear of goto is really out of date. I work on a Perl code base with dozens of other programmers of varying levels of skill across man-centuries of programming the vast bulk of which has basically had no code review. I've seen enormous quantities of bad code and had a hand in cleaning up a lot of it. I've seen confusing object hierarchies, bunches of confusing functions calling each other with essentially untyped parameters, all of them "fixing up" each other's parameters (mostly "correctly"...), functions a mile long with nothing but the occasional incorrect comment, reams of dead code kept around "just in case", and a huge variety of other bad code practices. And you know what I have literally not seen once? An abuse of goto. Nor do I see it in the open source I crack open, nor anything else I read.
Even if someone pops up and claims they see goto abuse "all the time", I'd challenge them to go find the source for them, and I bet they find it was just one person doing all of them in their code base. People do not abuse goto anymore, because if anything, they've been beaten so thoroughly into compliance with "goto is bad!" that the problem they have with it is not using it when they should. I don't fear that putting goto into a language will suddenly produce tons of code where entire programs are just one big function with tons of gotos in it, because I observe that it doesn't happen, and observation of facts trumps any theory about how the facts "could" be something else, because the facts are the facts.
As for passing pointers, yes, it can be dangerous. So far I've had no trouble with it because I'm always also passing ownership, but you do have to know what you are doing. I used to pine for Rust's feature set, but then, I observe that it turns Go into a completely different language, so now I prefer a world in which they are both available.
https://github.com/guzzle/guzzle/pull/965 https://github.com/igorw/retry/issues/3
Goto's are seldom used by bad programmers anyway - most of them wouldn't even be aware of them. They generally exist in languages as a niche feature used be experienced developers for those rare situations where a goto results in cleaner code. You definitely don't see Go developers sprawling goto's everywhere just because it exists.
> You can pass a pointer over a goroutine channel. That's my main issue with them, beside the fact that we should be past this needless complication of our code. Again, they're unnecessary and encourage bad code.
Erm, sorry. You've lost me now. I'll grant you that pointers require a little extra mental overhead, but they're most definitely necessary when you're writing code that either needs to be sensitive to memory usage, or performance.
As for pointers "encouraging bad code", I'm not even going to dignify that remark with a proper response.
.....yeah.
I've seen too many internal codebases where "goto" was used so horrifically I want that feature to die in a fire just to prevent such malignancy in the future.
Golang only hasn't reached that stage because its young enough there isn't heavy maintenance work over a 10+ year period yet.
That's the old wives tale about gotos. Mostly repeated by freshment that heard gotos are bad, don't understand fully when and why they are bad, and repeat it as cargo cult gospel.
> Their solution was not to engage and educate those programmers to change their habits.
I wish the blog author good luck in educating masses of programmers, even smart ones :)
In my experience, Go is a tool thats really good for a certain set of programming tasks and like all other languages really bad or annoyingly painful for others.
For me, Go is my number one tool for creating command line apps now. I get immediate cross-platform cli tools with zero headache. Its also a really nice fit for lower level networking/distributed applications where you are working with byte protocols (things like mozillas heka, or docker, proxy servers, chat clients, etc), the networking server-side stuff where you would probably have used C++/Java.
My recommendation would be, if you work a lot on this kind of software seriously start using Go, you will love it and think everyone is crazy for hating on Go.
The problem is I think lots of people are trying to use Go for stuff it is not designed for and where, compared to the alternatives, it is a rather bad fit. For instance Go is zero fun for: Compiler Programming (Haskell/C++ have way better tooling), Games (libs are one thing but Go cannot compete with C++ perf here), Desktop GUI apps (Just use QT), Mobile Apps, and Web Programming (take your pick of python,ruby,js,clojure,php - your life will be much easier), Hardware/Low Level Systems programming (Obviously you can't use a GCed lang here).
I haven't found another area where I really like programming in Go besides CLI and networking I mentioned above. It could have another sweet spot I've missed...
Some people say to prototype in a dynamically-typed language and then switch to a static language later. Dynamic typing might save keystrokes, but typecasting and type-checking do require lots of typing, and who cares that much about a few hundred extra keystrokes anyway?
Some people say to create whole, large apps in dynamically-typed languages, but those people clearly haven't tried modifying or debugging code bases in those languages that weren't created with utmost discipline and 100% test coverage.
So with 10 years of web programming experience, I'd emphatically argue that masochism is not using static typing.
I have warm, happy dreams of a future where there's a great alternative to the dynamic/weak web languages of today. There are already some great entrants, but nothing has reached the massive popularity of existing languages yet.
(Edited for clarity)
json parsing in Go uses reflection, which not only means it is slow, but if your input is not consistent (like say.. a log file with 20 different possible formats), it can be quite painful and very verbose.
* http://erickt.github.io/blog/2014/11/03/performance/ and http://erickt.github.io/blog/2014/11/11/benchmarks/
* https://github.com/ugorji/go-codec-bench
* https://github.com/golang/go/issues/5683
In my own testing it was faster (even with ffjson) to pre-clean my data in cpython or pypy, and then emit some intermediary format (like capnproto) for the go code to consume. I was parsing huge files full of lots of non-uniform json with many formats.
For most use cases though, the fact that json is "slow" is probably not a huge factor, as network IO or something else is likely the gating factor. For those uncommon cases though, I wish the native json lib in Go was faster.
Anyway, you could always use a highly-optimized JSON parser written in C[1], so it shouldn't be a deal-breaker for anyone interested in Go.
I am currently using the massive PHP + Node.js ecosystem for most of the application and Go for the critical communication parts.
My current company's web API is built using Django, which may come as a surprise since we also do realtime stuff, but that's the benefit of mixing the best tools for each job.
It's nice to know that I am not crazy in questioning its viability in that area.
> Words in names that are initialisms or acronyms (e.g. "URL" or "NATO") have a consistent case. For example, "URL" should appear as "URL" or "url" (as in "urlPony", or "URLPony"), never as "Url". Here's an example: ServeHTTP not ServeHttp.
> This rule also applies to "ID" when it is short for "identifier," so write "appID" instead of "appId".
> Code generated by the protocol buffer compiler is exempt from this rule. Human-written code is held to a higher standard than machine-written code.
To enforce this in the linter they literally define a list of initialisms[1].
[1]: https://github.com/golang/go/wiki/CodeReviewComments#initial... [2]: https://github.com/golang/lint/blob/master/lint.go#L695
I doubt that, for the sake of truth and not just to argue with you. Most programmers do not want to argue or discuss things. Most programmers leverage knowledge and understanding to make the computer do interesting things. Some find go more understandable and useful than others.
There was no option to even be flexible about this, for example, by programming one way and then using gofmt before committing code, because you will literally have an incorrect program if you put the opening brace on the next line due to automatic semicolons placed at the end of lines.
And so ended my 15 minutes of playing with Go.
As usage of gofmt is idiomatic Go, simply using the superset goimports handles all of this for you.
Sure, any language has tools to reformat code for you in some magic ways - but what makes Go special is that it takes this kind of tooling seriously enough by making it standard right out-of-the-box and right when initiating new users to the language (notice the [Format] button on the first slide of the official Go tutorial http://tour.golang.org/welcome/1 ).
https://github.com/bradfitz/goimports
http://michaelwhatcott.com/gosublime-goimports/
Nevertheless, this new article from Evan is a marvel, a must-read, as usual.
This is the sort of thing we should see more of on HN IMO.
1) The artistic approach which is very flexible and requires creative thinking and deep understanding of the essence of computing. However, you can easily shoot yourself with it. Languages of this type are for code guru, knights and hackers.
2) The engineering approach which has rigid rules for efficiency and social cooperation. It is less error-prone but tend to suppress diversity and discovery. Golang belongs to this category. To me, the core Go authors are more of engineers than artists :)
I use Go for work and simple command-line tools for myself. It is also great for cooperation in well defined scenarios, e.g., Web back-end service. When it comes to creative works, I'd rather avoid it.
I thought the same thing. They are like the anti-Larry Wall.
Note: Said without any bias towards either Go or Perl.
Also, I'm not a language lawyer, and this was a joke, so I'm not replying to any comments about Go not being "purely" or "strictly" strongly typed or whatever.
http://jugad2.blogspot.in/2015/04/interview-linux-journal-wi...
Go is crazy boring. You type things. You hit return. You type the next thing. Error not nil? Type more.
There's something very sequential, linear, methodical about it all. I suppose in part it's gofmt. It may also be a byproduct of any strongly typed language, but unlike many of those languages, Go feels simple and reasonable.
I actually think this is how programming serious applications should be. A little boring. Nothing too fancy or cute. No refactors to fit some new great abstraction pattern.
Not to wax nostalgic — in fact, I can't, because I wasn't even born — it reminds me of paper tape in old computers. The card gets punched, it feeds in, and the computer considers and executes your instructions. We're still doing that, really. Programming should be simpler. Sometimes I think we go out of our way to make it more complicated because we are experienced and bored. :)
This captures my sentiments and experiences with the language perfectly.
The point about Go being too pedantic and thus hindering exploration is something I've felt too. Some of that pain was mitigated by the Sublime Text Go plugin that has shortcuts to add/remove imports.
I would recommend using Python or possibly Clojure to experiment with and then translate the code to a language that will help you catch bugs (Ada/a functional one) when you know exactly how the problem is solved.
> It is possible, however, that the Go team has developed a set of secret signifiers to distinguish these constructions in everyday conversation and not told me about them.
or
> At first I wrote my methods on the values, which seemed like the normal, American thing to do.
Someone posted yesterday about how to pronounce hexadecimal numbers. It's funny because somedoby, somewhere has a lexicon for describing the different overloaded loop types. sidenone: i find overloading cheap or sort of a cheat. I understand it in the content of typed languages, but in something like JavaScript or PHP it fucking sucks.
Two tips about the pain points regarding unused imports and variables:
The program goimports is an extended version of gofmt that will automatically add and remove imports. Bind it to a keystroke of your editor of choice, and the imports situation becomes painless.
For unused variables, you can do "_ = someVar" to stop it from being flagged as unused. Still a bit of a pain, but much easier than commenting and uncommenting things all the time.
Catching unused variables is pretty essential, it's easy to shoot yourself in the foot by redeclaring a variable with := inside a block.
>> which means you have to need separate storage for the actual RaceCar and GetawayCar values, either on the stack with a temporary variable or on the heap with calls to new
Maybe I miss his point here, but in Go it's totally valid to just create a new *GetawayCar with &GetawayCar{} in any scope. You can return that pointer from your current method. It's not necessary to explicitly put your GetawayCar on the heap with new(), Go will decide for you with escape analysis.
In order to do evil things like convert raw bytes to floats,
I chose to use the “unsafe” package
FWIW you don't need unsafe to do that. encoding/binary + http://golang.org/pkg/math/#Float64frombits will do the job just fine.- How not to sort by average ranking (http://www.evanmiller.org/how-not-to-sort-by-average-rating....) is a recommended read on coursera's recommender systems course.
- Rank Hotness With Newton's Law of Cooling (http://www.evanmiller.org/rank-hotness-with-newtons-law-of-c...)
This was really funny!
I thought the same, so I built a stats library[1] of my own. It also only works on float64's at the moment.
I love writing like this, where you got that pen doesn't matter one bit, yet it turns the drab of a tech blog into an enjoyable story to read.
Sure, they will still bite me in that individual test file if the situation arises. It keeps the problem out of the "real" code, however so I don't get it when building. In this way I get to maintain a creative space to test out various apis and do my "print to console" testing, while also keeping my primary code base Go-Clean™.
It's also funny to see errors solved automagically by tools instead of manually by the developer; there used to be a time where IDEs where voluntarily avoided because they did too many magic things to your code and to your project, and true hackers should be able to work with only a text editor and the compiler. I fear go may be headed back to IDE-land if it starts relying too much on tools (we have goimports today, the go generate command is to be used for code mangling before compiling ...)
I think that it's kinda the opposite: rather than one monolithic IDE, it's lots of little pieces working together. Pretty much what one would expect from the guys who brought us Plan 9 and Go…
The article itself is a great read. I love hearing interesting and honest commentary about the language. But I wonder if comments like "for reasons that appear to be political, does not have integer Min and integer Max functions" are appropriate. Later the author mentions "I get a similar sense of refusal-to-engage — the authors are communicative, to be sure, but in a didactic way." If the go community (or the programming community at large) truly has the sense that the go authors are unwilling to engage with the users of the language, then that's a big problem. However, are these sort of off the cuff comments the right way to start a discussion about it? At the very least, I wish that the author would provide specific evidence for these claims. I'm sure that there is some justification for them, but what the author is telling us is his inference, and I would appreciate an opportunity to read the source material and decide for myself. FWIW I have been programming in go for 2.5 years and made a few trips to the go-nuts mailing list. I don't share the author's impression, but I also haven't read every thread on the mailing list.
That's far from the worst of it, of course. I have read comments calling the go authors arrogant, ignorant, or conceited. If you insist on criticizing the go authors, I would hope that you could at least keep it professional and provide a link to some comment/literature to back up your criticism.
I welcome criticism of go, or of any topic for that matter. I just want to avoid unfair characterization and irrelevant ad hominem comments. Am I being too defensive or do other people share this concern?
Well it is a persons' opinion. There are some facts, some humor, some personal opinions. I am not sure the author planned on being on the front page of HN. I don't think he submitted his own article. It is up to the readers to put things in the appropriate "bins" so to speak -- "This is good advice", "I don't like this part", "This is just a personal attack" and so on. Sometimes the same article can contain a variety of things.
Love it!
This is criticism of go I haven't heard before.
However, I learned that Go is a language conceived for Programming in the Large, and I found out (once again, thanks Java) that I don't like languages for Programming in the Large.
But if I liked that sort of thing it'd probably be one of my first choices.
Not so fast. That library is only available for OS X and FreeBSD.
return (data.name !== '' ?: 'New Data')
or Python style: return (data.name if data.name else 'New Data')
vs: if (data.name != '') {
return data.name
} else {
return 'New Data'
}
The former being much more concise, so that you can display (and grok, perhaps) a single function in 3 or 4 lines, vs the Go style, which can result in extremely long functions (long because they do a few things, and require error checks before and after each one, and so on, rather than being long for actually doing a lot).The single line version implies at the beginning that all the line does is return. The longer version requires you to read the whole paragraph to figure out what it does.
The difference ends up being between a 5 line function, which does 5 simple things, and a 20 line function that does 5 simple things.
In my previous example, it was 1 line which returned either the name, or 'New Name', or else 5 lines to do the same.
In the end, not a big deal. A matter of taste, rather than judgement, I feel.
kinda mimics c in that way.
> if (data.name != "") {
> return data.name
> } else {
> return "New Data"
> }
Not exactly... if data.name != "" {
return data.name
}
return "New Data"
And consider the likely context... func name(ref int64) string {
data, ok := get(ref)
if !ok {
return "No Data"
}
if !data.valid {
return "Invalid Data"
}
if data.name == "" {
return "New Data"
}
return data.name
}
Straightforward and unambiguous. package main
import "fmt"
func main(){
fmt.Println(name(28))
}
type T struct{name string; valid bool}
func get(ref int64) (T, bool) {
return T{"abc", true}, false
}
func name(ref int64) string {
switch data, ok := get(ref); true {
case !ok:
return "No Data"
case !data.valid:
return "Invalid Data"
case data.name == "":
return "New Data"
default:
return data.name
}
} return (isblue ? "Blue" : "Red");(pickfunc? func1: func2)(pickarg? arg1: arg2);
Works great!
The ternary operator usually appears in imperative languages (or should I say, languages which are not expression-oriented) where the if-then-else construct statement is NOT an expression, and possibly has side-effects. Therefore, you need an alternative construct that really is an expression and evaluates to something.
The syntax itself is irrelevant. If you can say the following in your favorite language:
x = if (condition) { something } else { something else }
then you don't need a "ternary operator".The concept is simple. The syntax can be terse, but it doesn't have to be. Modestly capable Excel users take advantage of something just like it.
The only time I've ever seen it become difficult is when either the conditional or result expressions get hairy or depend on undescriptive variable names. And when that's the case, well, you're going to have the same problem with the expressions in your if/else, albeit spread out over a few more lines by convention (which one could do with a ternary expression just as well).
I'm at the point where I suspect complaints about the ternary operator are a cargo cult repetition thing, and the developers who are scared of it are scared because they were either taught by someone else to be scared, or they're suffering from a confirmation bias problem where they notice confusing conditionals more when they're associated with the operator.
It's definitely possibly to write obfuscated ridiculous code without the ternary operator -- but I think that's part of the whole "go-lang mentality".
Would I leave unused declarations in production code? No.
Do I have a problem with a compiler that doesn't let me test code with a function call commented out without also commenting out all the other variables/functions that are now unused as a result? Yes.
> I'm at the point where I suspect complaints about the ternary operator are a cargo cult repetition thing, and the developers who are scared of it are scared because they were either taught by someone else to be scared, or they're suffering from a confirmation bias problem where they notice confusing conditionals more when they're associated with the operator.
I definitely don't think Rob Pike and Ken Thompson are getting confused -- it's more like they took a utilitarian view of the situation and decided - if the average code-base is made better or easier to read by this change, then it's worth it.
The over-all result is a language that appears to be easy to pick up and productive at least for those who use it - but it's hardly exciting or fun to code in.
Simple ternaries can be useful in trading off the unreadability of verbosity for the unreadability of compactness. Real Programmers should know how and when to use them. But nested ternary expressions are basically trolling...
> I get the same feeling about the Go language. It feels like it is designed by an obsessive personality — obsessed with build times in particular, but also having an obsession with detail, someone who rarely makes mistakes when writing code, who generally will not run code until it appears to be complete and correct.
WTF? Not only is it insulting, it's ignorant. Considering some of the other comments here regarding how "excellent" this article is, it clearly doesn't concern many when casual insults are allowed.
No no, let's applaud someone for making casual, racist-like remarks without even questioning it. If this is considered quality, we should be ashamed.
As a father of two autistic children, I do.
> and I don't find his comments offensive.
He's equating look to a disorder. It's like saying "Black man dressed 'street clothes' must be dangerous."
It seems like you're reading a negative connotation into the "autistic" label that isn't present in the article. Calling the gopher "unsettling" is the biggest insult I can find in what he wrote.
The author could have used plenty of other adjectives but had to use a medical condition.
I didn't bother to read the rest of the article even if it supposed to be entertaining. I didnt feel like sifting through other offensive comments (seems there may not have been others) so I skipped it.
Also seems oddly tone deaf given how common ASD seems to be among techies and their immediate family.