Live data from Hacker News

Half a decade with Go

blog.golang.org

241–250 of 257 posts

Re: Half a decade with Go

#241

Earlier quoted context omitted.

Here's a (very contrived) example of what I think you mean. Here's a container interface. It has a sort() method, which sorts the elements of the container. Here's a different container interface. It's got a method that tells you what kind of concrete container you have, so you can understand how expensive actions like insert and sort are going to be. But the author was from England, and so called that method "sort".…

Right, thank you! Traditional (but even more contrived) examples include "draw" and "fire" doing unexpected things when applied to a gun as opposed to an image or an employee.

ok, ok. I think I'm understanding. Let me propose a middle ground.

First, you really have to split this up into two distinct cases.

The most powerful/useful is when you create an interface in your package for a structure in a different package. It's been years since I've done .NET or Java, but I remember frequently cursing a library developer (often someone at Microsoft or Sun) for exposing a concrete type instead of an interface. In this case, I don't see any downside. Creating a:

type Render interface { Draw() }

And then using my (or someone else's) Gun structure, is no different than using the Gun structure directly and expecting it to render itself to the screen rather than come out of its holster. The interface buys you the level of indirection, but whether you use the interface or the concrete type, it's up to you to know WTF Draw() does.

This first approach is well explained at [1]

In the second case, where a library expects an interface, I agree there's a risk:

// 3rd party package package fastRender

type Drawable interface { Draw() }

func Render(d Drawable) { ... }

// my code: fastRender.Render(new(Gun))

I've lost some degree or type checking. Since my Gun's Draw doesn't explicitly implement fastRender.Drawable, maybe I'm trying to fit a square peg into a round hole. There's nothing the compiler can do to help either.

It sounds a bit like an academic concern to me. Is this something that's actually bitten people in the ass? How is it different than any method that takes primitives? I can pass a []byte of a bitmap to a Music player's Play(data []byte) method...

[1] https://medium.com/@rakyll/interface-pollution-in-go-7d58bcc...

Re: Half a decade with Go

#242
post #233
post #226

Earlier quoted context omitted.

> I bet I can find 10 succeeding that use ruby or node for everyone that uses Erlang. But that's not the question, is it? There are a lot of companies succeeding with ruby or node, but also a lot of companies failing with them. I'll bet the strike rate is better for Erlang companies.

Il bet that the choice of language has no impact on success.

What about whitespace? Do you think choosing it or brainfuck has an impact on success?

Re: Half a decade with Go

#243
post #241

Earlier quoted context omitted.

Right, thank you! Traditional (but even more contrived) examples include "draw" and "fire" doing unexpected things when applied to a gun as opposed to an image or an employee.

ok, ok. I think I'm understanding. Let me propose a middle ground. First, you really have to split this up into two distinct cases. The most powerful/useful is when you create an interface in your package for a structure in a different package. It's been years since I've done .NET or Java, but I remember frequently cursing a library developer (often someone at Microsoft or Sun) for exposing a concrete type instead of…

Note that I'm not arguing for Java. Haskell typeclasses covers both of these use cases (you can make a new type an instance of an existing typeclass, or existing types instances of a new typeclass, without touching any exsisting code) but requires someone to look at it and say "This actually implements the contract that interface assumes." They can be wrong about that, of course, but I think making it explicit helps.

There's also a subtle third case - I import two libraries. One of them defines Drawable, the other has something that looks like it implements Drawable. But it's just happened upon the same signature, and makes different assumptions. Maybe it even says it implements Drawable - but a different Drawable defined in a third library.

As I've said all along, I don't know how often these things are hit in practice. I think so far go development has been comparatively centralized, and so it might be seen less often than it would if it were used everywhere, but that might still be rare enough to not be a problem.

Re: Half a decade with Go

#244
post #214

Earlier quoted context omitted.

Typeclasses aren't structural typing, they are nominative typing, as typing is controlled by explicit declaration of relations between types and typeclasses, not inferred from structural properties.

Sure they are: (forall a. X a => a) is a supertype of (forall a. (X a, Y a) => a).

I stand corrected.

Re: Half a decade with Go

#245
post #241

Earlier quoted context omitted.

ok, ok. I think I'm understanding. Let me propose a middle ground. First, you really have to split this up into two distinct cases. The most powerful/useful is when you create an interface in your package for a structure in a different package. It's been years since I've done .NET or Java, but I remember frequently cursing a library developer (often someone at Microsoft or Sun) for exposing a concrete type instead of…

Note that I'm not arguing for Java. Haskell typeclasses covers both of these use cases (you can make a new type an instance of an existing typeclass, or existing types instances of a new typeclass, without touching any exsisting code) but requires someone to look at it and say "This actually implements the contract that interface assumes." They can be wrong about that, of course, but I think making it explicit helps.…

thanks

Re: Half a decade with Go

#246
post #180
post #168

Earlier quoted context omitted.

Like what? The standard library is no more special, other than where it resides in the filesystem. You can write C and assembly code as well and link it to your Go code. And I'm not talking about cgo, I mean [568][ac], the Plan 9 C compiler and assembler that come with Go.

I was thinking most obviously of generics. The go standard library is full of generic collections, but you're not allowed to use generics in your own code.

It looks like free pascal has generics: http://www.freepascal.org/docs-html/ref/refch8.html#refse46....

But to your larger point, doesn't any non-programmable programming language exhibit the same weakness to some extent?

Re: Half a decade with Go

#247
post #233

Earlier quoted context omitted.

Il bet that the choice of language has no impact on success.

What about whitespace? Do you think choosing it or brainfuck has an impact on success?

Not relevant. I'm sure there are bad choices, but the difference between Go and Haskell is probably negligible or in Go's favor.

Re: Half a decade with Go

#248

Earlier quoted context omitted.

With all the cases were Go pushes you to use interface{} that's the case in Go a lot of the time too. If it had Generics that would be another thing.

With all the cases were Go pushes you to use interface{} that's the case in Go a lot of the time too. However, you can wrap an interface{} using container (for example), with type-specific input and output functions, getting back compile-time type-checking. Yes, it is not optimal, and yes, you're still paying the price for type assertions. If it had Generics that would be another thing. I would like to see a good sol…

I would like to see a ho-hum solution for this that's on par with what's offered on other languages.

I say that because the Go designers, despite having designed a quite mediocre language, suddenly when it comes to generics the want the perfect no-compromises solution or nothing.

Re: Half a decade with Go

#249
post #247

Earlier quoted context omitted.

What about whitespace? Do you think choosing it or brainfuck has an impact on success?

Not relevant. I'm sure there are bad choices, but the difference between Go and Haskell is probably negligible or in Go's favor.

So you think Go is a better language because companies that use Go are more likely to be successful because... Go is a better language? That's just circular reasoning. Do you have any numbers or experience here?

(In my limited experience I've seen a 100% success rate for companies that use Haskell and a 0% success rate for companies that use Go, though as you can imagine I don't have a statistically valid sample size)

Re: Half a decade with Go

#250
post #27

Earlier quoted context omitted.

I get the impression some of the folks in the Golang crowd are "Blub" programmers [1]. It's not so much a matter of simplicity and trade-offs as it is a matter of "I don't need things I don't know about", which isn't a good argument to use Golang. [1] http://www.paulgraham.com/avg.html

I feel like you haven't met a lot of Go programmers in that case. The programmers I have met who use Go or are interested in it are often genuinely good programmers. Of course there are "crowd" followers in any language as popular in Go but Go is not a "Blub" language nor does it attract Blub programmers. Do I as a Go programmer sometimes wish that Go had feature X. Of course I do! I want that feature when I want tha…

Actually, to be a little more constructive about this: I'd be really interested to hear from anyone who's used Go after doing a serious project in any of Haskell, Scala, F# or OCaml. All the Go advocacy I read seems to ignore that this language segment exists, and all the Go programmers I speak to seem to take a very "blub" position on features like pattern matching, ADTs, and the various things I'd summarize as "good type systems". So it would be great to hear from someone who's used these things seriously, understands their advantages, but still thinks Go is making the correct tradeoff.
Post reply on HN