What Go Might Be Like With Generics
play.golang.org
play.golang.org
Surely that's the best argument?
As pathetic as it is, "syntax bad" is probably the best argument.
Typically, generics are implemented using either code generation (causing code bloat) or type erasure (which requires boxing the type). They're not satisfied with either.
There is a comprehensive doc by Russ Cox that explains in detail: https://docs.google.com/document/d/1bMwCey-gmqZVTpRax-ESeVuZ...
Compare:
map f [1, 2, 3]
map g [1.0, 2.0, 3.0]
Versus: integer_map f [1, 2, 3]
double_map g [1.0, 2.0, 3.0]
In both cases, you wind up with specialized versions of map (one for Integers and one for Doubles). The benefit of the generic version is that the programmer must only implement map once, and the compiler handles specializing it for various types. Without generics, the programmer has to write the specialized version for every type he needs the function for. This creates more tedium for the programmer, and does not reduce bloat in any way.Caveat lector: Though my examples above are written in Haskell, I don't have enough knowledge of GHC internals to know whether it performs specialization this way. Nonetheless, it could be a reasonable approach for Go.
Yes, generics will increase compile times. I seriously doubt it will increase compile times by an integer multiple, and most people probably won't even notice.
I'm not entirely sure what's going on that is causing the instruction cache to be underutilized, but it seems to me that the only way to avoid it is to also avoid abstraction in general. As usual, there's a tradeoff between performance and maintainability -- that's nothing new. Pick the appropriate abstractions for your use case.
Russ Cox is wrong in this case because his sample consists of one language: C++. Go is not C++, so it's a mistake to assume it will suffer from the same problems.
To get an idea of how generics could be reasonably implemented, take the Clay programming language as an example: http://claylabs.com/clay/
I have had the exact opposite experience with the Go community. In particular, I've found community hubs like #go-nuts and the mailing list to be professional at worst and friendly at best, and always helpful.
some of the pretentious designs of Go itself.
How can a design be pretentious? Either you favor the design or you don't, but calling it pretentious is simply projecting your own emotions onto the language.
This is an example of how Go as a language is pretentious. It's way is the best way, even when no one else does it that way. The community becomes pretentious whenever you draw criticism against these core choices (note this mostly comes from #go-nuts, I haven't spent a lot of time on the mailing list). I like to believe that I can engage in well-reasoned discourse about these things, and I don't think I have seen the same degree of defensiveness and close-mindedness you might see from most other communities.
If you really have an issue with some of the very opinionated ideas that come to a large degree bundled with Go, that is fair. That is great even! It probably isn't a good fit for you. Which is fine, there are hundreds of other programming languages that work for you, most are the wild west.
For certain people (like myself) the sanity of Go is striking -- each decision is made for unremarkable and straightforward defensible reasons... a lot of them are community driven over personal preference... it is better for the herd (think: herd immunity) if everyone uses one style and everyone uses one layout... etc. It isn't about being "right" or "needed" by every person, it is about being consistent so you can move from project to project and focus on learning the code, not layout or style, just what the code does.
Go was designed from inside Google, with large teams in mind with many projects.
I think many people put too little value on communal norms, they have substantial value and are worth the adaption time. When in Windows C++ -- follow the conventions, when in Linux C -- again, follow the conventions -- and when in Go -- do that same. Fighting the dominant style for established platforms and languages is a mostly pointless, exhausting and sometimes debilitating task generally only done by those too inexperienced to realize how ridiculous it is. Team leads more experienced tend to just choose whatever is the dominate style / layout (preferably per-written up) for that platform/language realizing the benefits for getting ease of reading, consistency, hiring, firing, flexible labor (consultants) and most importantly not having absolutely worthless debates about style and layout.
Well, opinionated doesn't mean much quality wise. Either you have the right opinions or the wrong ones. If you have the wrong opinions on something AND are opinionated about it, then you're stupid.
This is not a bad thing -- but it does mean that when a language chooses to ship "opinionated" tools as the default supporting toolset, users gain from the 'convention over code' as rails would call it - you run go build and the tool does the math -- but accomplishing source-tree validation across arbitrary maintainers trees is less trivial than "package-path == path" -- so if you name your code "com.foo.baz.bar", you'll be hurt by its opinions.
That said - if you want to learn the toolchain, 6c/6g/6l (and its 5/8 counterparts) will act like the simplest gcc tools - so long as the benefit you gain from manual definition outweighs the cost, you still win without "go build".
I'm not aware of any projects that break the mold. Almost everyone that writes Go perceives the benefits of the `go` tool to be greater than the cons.
In another comment, I suggested using symlinks. I do it. Is there a reason why that doesn't work for you?
-- HN has eaten my asterisks, sed {asterisk} appropriately.
(locate your {5,6,8}{c,l,g} per your go install, or use 'go tool' if you want to go half-way in, I'll use go tool '6' (amd64) for reference).
go tool 6g {asterisk}.go
if you're linking to a final binary:
go tool 6l -o outname {asterisk}.6
Then run ./outname
I'm eliding over linking and includes, but if you run 'go tool 6l -help', you'll find all your expected 'include' and 'link' directory type parameters.
...
All of that aside, I've found it rare that I actively link go code to languages outside of C, and even then, only rarely do I need to share the C subset outside of the 'go' repo. So I'd step back for a second before you go down this road and ask _why_ it must conform. I assume you have a reason -- and if you have a reason and want go as well, exploring the nitty-gritty of 'go tool' is going to be a must. I found it easier to conform with go in a different repository - that may not be an option for you.
Symlinks solves this for me.
> This could easily be avoided by letting me set enviornment variables that would relocate some of these folders (especially bin and pkg) to different places.
AFAIK, `GOBIN` will allow you to relocate `bin`. I'm not aware of any such env var for `pkg`.
> This is an example of how Go as a language is pretentious.
It's not pretension. It's following a philosophy that prefers convention over configuration.[1]
That has not been my experience reading go-nuts. Almost any language improvement idea, however valid, is met with snark and you-re-doing-it-wrong answers. And there have been many, and from quite serious developers over the years.
because it doesn't look like it's solving anything, it feels positively ugly, and there's no way we'll every shut those people up no matter how hard we try. there's no generics solution that will do that.
thankfully go's authors don't usually favour the internet's opinion on these matters, or we'd be dealing with something even uglier now.
Gosh that word has lost all meaning at this point.
We'll see how the language evolves, but I can't see them coming for a "long" time.
The idea that all languages have to cater to all people is silly. Generics are ALWAYS a trade-off. None is hard for developers, C++ style is terrible for compile (tons of code-gen, macro crap, duplication, de-duplication stages), and Java style (box-box-box-box) is slow at runtime.
The misunderstanding that generics are free and there lack of inclusion was an oversight rather than a choice is misguided. The Go team aren't fresh faced neophytes, they move with purpose.
Additionally -- if you want lots of features, there are LOTS of ways great languages for you! Leave the small, crazy cadre of people who don't mind C, think Lua is awesome and think Go is great to their (own) devices, we will be OK.
I'm glad Rob Pike and Co. don't give a rats a about such opinions.
It seems to me that there are two disjoint sets of people: those who write Go regularly, and those who complain about generics in Go.
Of course, you can interpret this either way you wish!
1) Perhaps those latter people would like Go despite its lack of generics if they only bothered to get familiar with idiomatic Go.
2) Perhaps the lack of generics is precisely what prevents them from writing Go on a daily basis.
But as someone who actually does write Go on a daily basis, and has for a year and a half, I can honestly say that I've only ever missed them a handful of times. And I say this as a functional programmer who is used to being able to call "map" everywhere.
In fact, if I had to prioritize the things that I wish I could change about Go, generics would not be in the top three - not even in the top five[0]. They're just really something that I don't miss anymore.
[0] I could tell you what they are, but that'd be making it too easy - give Go a shot, long enough to realize you really don't need generics as much as you think you do, and then you'll probably have a good idea of the good, bad, and ugly when it comes to Go.
Like you, I've bumped up against areas where some form of generics beyond structural subtyping would have helped me solve a problem more elegantly. But it's never been a huge issue.
I think the primary reason why I'm drawn to Go is that I perceive it to be incredibly simple (like, Lua simple). Not just the language design, but the entire ecosystem---from idioms to tooling.
I tried to write nice idiomatic Go code. And I'm usually pretty good at adapting my brain to strange languages—I've positively enjoyed Haskell, constraint programming in Mozart, distributed functional programming in Elixir, and quite a few other strange things. (To be fair, I never did get comfortable in Prolog.)
And try as I might, every time I write a couple thousand lines of Go, I walk away in frustration. I love so much about the language, but my actual code keeps disappearing under the weight of error handlers, and stupid little iteration/transformation functions that I have to write over and over again thanks to the lack of generics. (Sometimes I get lucky, and an interface fits well.)
This means that every time I wander down a wrong path (and it's possible to wander down quite a few when messing with OCR algorithms), I end up having to tear up more code than I'd like. It's not fun.
Every time I say this, Go programmers say something like, give Go a shot, long enough to realize you really don't need generics as much as you think you do. But after three serious attempts, it's clear that the programs in my head were never meant to be implemented in Go. Which is too bad: It's a nice language in so many ways.
I am curious about specifically where you got bound up -- and how we managed to via ignorance or blind luck avoid these rough patches. Additionally, I am not 100% sure I understand why you refactor cycle is so brutal. That generally is one of the things I enjoy about Go, lightspeed refactor / dev / test cycles.
Good thing no one is asking you to use Go, Haskell is always around (and Elixir, I guess... I am too used to Erlang syntax, Elixir feels like an ill fitting glove) and we need lots of great languages -- and they SHOULD feel different and some shouldn't be a great fit for you.
It isn't the most elegant, not even close. It isn't the most succinct, not even in the running. It isn't the most flexible -- people would mock you for claiming it is. It isn't interesting in the least, remarkably unremarkable as they say.
But when it comes to just simply getting shit done, and quickly understanding and being able to work in other peoples code, it is second to none. It just doesn't get in your way, and out of the box it gives you simple syntax, great tools and easy deploys.
I've read various articles including (but not limited to) tutorials, made a point of exploring a few open source projects and I've written a few thousand lines of Go. I enjoy writing Go, but I have a hard time so far figuring out if what I write is idiomatic.
Short of that, read the source of some standard library packages. They are quite approachable.
By reading the source code of the standard library. It's directly linked from the API documentation.