Live data from Hacker News

Channels Are Not Enough

gist.github.com

151–160 of 224 posts

Re: Channels Are Not Enough

#151
post #11

Go doesn't let you build abstractions - it offers what it does, and if its not enough - tough luck. What I dislike worst is the denial of the Go community and creators, claiming that generics are too complex and that you don't really need them. I dismissed Go not because of its lack of abstraction power, but because its authors and community is incapable of admitting problems when they see them. A similar problem wit…

My understanding is that the Go team says they can't figure out how to make generics work nicely, that's why they haven't added them. Also, type casts don't cause runtime panics. You can use type-based switch/case or check the "ok" return value from the cast to see if it worked.

That's basically what Java said in 1995.

There is a reason why Java completely abandoned that position.

Re: Channels Are Not Enough

#152
post #52

Earlier quoted context omitted.

No, that is not what I was referring to. It is definitely user code complexity that turns us away from generics. People tie themselves in knots with generics all the time. Just look at pretty much any mature C++, Java, Scala, etc codebase.

As somebody using pre-generics Java libraries from time to time, I can say with confidence that generics are not the cause of complexity. Casting from Object is a source of bad type safety and doesn't help with documentation. The complexity you'll find in a mature codebase is a function of the way it is architectured and the complexity inherent to the domain, mostly.

I wish people wouldn't assume there's only two options - Generics or casting from Object/interface{}/void* It's a straw man argument. No experienced Go programmers are trying to say that's a good way to write code. The idea is to restructure your code so that basic data structures and interfaces pick up the majority of your reuse scenarios.

Re: Channels Are Not Enough

#153
post #61
post #11

Go doesn't let you build abstractions - it offers what it does, and if its not enough - tough luck. What I dislike worst is the denial of the Go community and creators, claiming that generics are too complex and that you don't really need them. I dismissed Go not because of its lack of abstraction power, but because its authors and community is incapable of admitting problems when they see them. A similar problem wit…

> A similar problem with CoffeeScript (conflation of declaration and assignment + scope rules) That's an issue you simply cannot fix in CS, you need a new language/fork (not having var/let is at the heart of the language's syntax). I wouldn't compare it with Go's lack of generics.

> I wouldn't compare it with Go's lack of generics.

Why? It feels like forking Go would be the fastest way to get Generics.

But on the other hand, the people who are able to pull that off usually just stay away from Go in the first place.

Re: Channels Are Not Enough

#154

Rather than arguing about generics in Go again, I'd be interested in reading about how experienced Go developers solve the problems posed in this article. (He may be wrong that there's no elegant solution.) Also, if it can't be solved elegantly, perhaps adding merge() and a few other important functions to the language would be good enough? After all, Go already has the magic append() function for slices and we get q…

In my experience solutions generally fall into two camps: 1) Create a "generic" version of the function using reflection / typecasts 2) Create a specific version of the function for your use-case I don't have a ton of experience using channels. My code tends to be very imperative and I add the channel layer at the main application level rather than the library level. So from his example: > func merge[T](cs ... You ca…

You can in Haskell

    min :: Ord a => [a] -> Maybe a
    min = foldl' go Nothing where
      go Nothing a  = Just a
      go a0@(Just m) a 
        | a 
You can in OCaml

    module Min (M : Comparable.S) : sig
        val min : M.t list -> M.t option
      end = struct
        open M
        let go a0 a = match a0 with
            None    -> Some(a)
          | Some(m) -> if a 
Point being that these problems with generics are reasonably solved. There are perhaps other problems, of course. OCaml should at least be a suggestion that compilation speed isn't really one of them.

Re: Channels Are Not Enough

#155

Earlier quoted context omitted.

> but it's unsurprisingly frustrating for people used to more expressive languages Speak for yourself. I know you certainly don't speak for me. I love Go. I love Haskell. I love Rust. There are things in all languages that frustrate me. I can appreciate the particular trade offs made in each language. Believe it or not, I think the language specifications for both Haskell and Go are things of beauty. It's amazing how…

I find your response condescending and hostile, actually. The parent was making a basic generalization; he didn't categorically claim that his statement applied to all people. People de facto speak in the form of opinions, and if we are all to qualify our statements with "...in my opinion" for fear of accidentally making an authorative statement, then HN would become a very unhappy place.

> I find your response condescending and hostile, actually.

Welcome to the Go community.

Re: Channels Are Not Enough

#156
post #32
post #3

Earlier quoted context omitted.

The problem (which the article touches on) is that you have to resort to interface{} to make things reusable since Go doesn't have generics. So you have to pick between using a library (which will handle edge cases better) or compile time type checking.

You don't have to resort to an empty interface, in fact, mrust experiences go programmers cringe when they see anyone using empty interfaces. The fact of the matter that much code can reused without being "generic" and often your code never gets reused. YAGNI and all that.

The point of generic code is not purely that it's easier to re-use. The almost more important fact is that generic code has less information about its inputs and outputs—this leads to a smaller design space and, consequently, an easier time designing the implementation and an easier time avoiding bugs.

Re: Channels Are Not Enough

#157
post #53

Earlier quoted context omitted.

With the right implementation debugging generics wont be hard. It doesn't have to be C++'s version of generics. And I'm not buying the poor programmer understanding argument. Generics aren't that complex, they're just parameterized types. The fact that basic language libraries such as maps and slices cannot be implemented without them speak volumes about how fundamental they are when building abstractions. My point i…

> But I know that fast compilers and runtimes that implement generics exist, so I don't find the whole discussion believable. Are you arguing that an implementation of generics in a programming language is free? (Whether it be performance or implementation complexity.) Because if not, then you admit there are trade offs. If there are trade offs, then it is conceivable that some circumstances (including programmer tas…

> Are you arguing that an implementation of generics in a programming language is free? (Whether it be performance or implementation complexity.)

I am.

Performance: if you replace all generics with interface{}, you get performance that is at better or equal to current Go code.

Implementation complexity: You could add some constraints to generics, for example only interface types can be used as generic parameters, and all uses of variables/methods/functions with generic types need to have generic parameters given. In that case, there's no complexity for code that doesn't use generics. Also, generics could actually be implemented as a preprocessor that would simply insert appropriate casts from/to interface{} at calls to generic methods. Since all variables/functions in Go are declared and have known types, you could of course go further and eliminate most generic parameter annotations.

Re: Channels Are Not Enough

#158

Rather than arguing about generics in Go again, I'd be interested in reading about how experienced Go developers solve the problems posed in this article. (He may be wrong that there's no elegant solution.) Also, if it can't be solved elegantly, perhaps adding merge() and a few other important functions to the language would be good enough? After all, Go already has the magic append() function for slices and we get q…

There's no generalized solution to every generic problem. The "cast to interface{}" is the closest to a linear mapping of generics, but if you're reaching for that all the time, you're doing it wrong. So the only sane answer is, "it depends".

The only use case that I have encountered that is essentially impossible in Go is the "generic data structure". Mind you, that's a bit of a big deal, even if it covered over by "generic" arrays and maps (which, further, does cover over a lot of the cases), but it is also the only case where it is actually a problem. Despite the fact Go is not functional, like, at all, I still find myself using my functional training in minimizing the surface area of an "object" as much as possible incredibly useful when programming in Go. I think if I were only an OO programmer trying to come over to Go I'd have a much harder time of it.

Most of the rest of the time you can solve your problem by asking what the code is really trying to do, pull that up into an interface, and carry on. A substantial portion of the rest of the use case can be covered by providing wrapper objects that compose in another object, probably using an interface as the composition point.

I think in practice, about 80% of the problems that people trying to jam generics into Go are encountering are because they are trying to program C++, Java, or C# in Go. Despite their substantial superficial similarities, Go is not any of them, and idiomatic answers differ substantially. Let me rhetorically underline that... Go really looks like a Java or C# clone if you just read down the bullet points, but there are enough important differences that it's a substantially different experience to program in it. Trying to program Go as C# is only slightly less frustrating than trying to port FP idioms into Go (which is a complete waste of time). The remaining 20% are real problems that Go hasn't got a good answer for beyond duplicating code.

Now. All that said, despite the fact that people not used to idiomatic Go are significantly overstating the problem that is the lack of generics, it is a problem and were I in charge, I'd be trying to work something out on this front. (I actually have a proposal I've probably put about 4 or 5 hours of thought into. In defense of the Go developers, this is a nontrivial problem when you stop just waving the word "generic" around and start trying to seriously create an implementable suggestion, accounting for all the use cases, grammar interactions, semantics, etc.) My best argument is that for a language as mature as Go, this is embarrassing: http://golang.org/pkg/container/ Those are the "generic" containers in the standard library that ship with the language.... all three of them as of this writing, plus array and map. At this point that ought to be significantly richer.

(So, that ought to just about piss everybody off...)

Oh, I ought to add for context that I'm actually pretty fluent in Haskell, and my primary work programming language up to this point have been dynamic languages (Perl, Python, etc). So it's not like I'm not comfortable with generics or incapable of understanding how to use them or anything. If anything, I dare say my openness to other answers and then finding ways to express them in Go may be part of why this doesn't bother me too much. There are other options, most of the time, and they are not generally "compromises", either... they are often perfectly sensible options, or even better options than are available in other languages on a bang/buck basis, such as the trade for making composition very easy and inheritance something fairly difficult.

Re: Channels Are Not Enough

#159
post #102

Earlier quoted context omitted.

It was the community attitude towards generics and code distribution that eventually made me focus on Rust and D. At least those communities embrace modern computing abstractions and code distribution practices.

It's fine that you don't agree with our tastes, but it would be nice if you could stop coming into every Go thread and being condescending about it. Like PostgreSQL and OpenBSD, I've been permanently turned off Rust because I never want to be left at the mercy of a community that invests so much time in harassing and insulting others.

Please tell me where you've been harrassed and insulted by the Postgres community? Sometimes people come into the IRC channel and say something that doesn't make sense and are told it doesn't make sense, and sometimes those people get very upset, but I wouldn't classify that as harrassment. And that's basically the strongest reaction you'll ever get from anyone in the community.

Re: Channels Are Not Enough

#160
post #97
post #94

Earlier quoted context omitted.

I never thought people will actually come up and defend code duplication. It's definitely more than ugliness. The need to fix all the copies when they need to be updated is a bigger problem.

Or the fact that I actually saw someone on the mailing list also implement min() incorrectly due to copy-paste :) > I never thought people will actually come up and defend code duplication. Indeed. Some of the responses by some Go fans really leave me surprised to say the least.

Yeah, the deficiency isn't the most harmful part - its the attitudes that come with defending that deficiency.
Post reply on HN