Live data from Hacker News

Half a decade with Go

blog.golang.org

231–240 of 257 posts

Re: Half a decade with Go

#231
post #199
post #141

Earlier quoted context omitted.

> In my experience, the problem is complexity. Simple languages led to complex code bases. Many of the Enterprise Java sins were caused by the language limitations and developers trying to work around them.

I think the enterprise Java sins were caused by cargo cult programming. Java can actually be pretty nice when wielded by someone who isn't afraid to invent new things.

What leads you to believe the same won't happen to Go?

I have seen this happen in C codebases before Java took the enterprise.

Its own little macro based DSL and pointers that were actually handles for the real data.

Re: Half a decade with Go

#232
post #172
post #135

Earlier quoted context omitted.

Languages without decent compile-time type systems are pg's own blub.

pg writes about macros as the top of the blub ladder whereas you mention compile-time type systems, but I'd say it isn't a ladder but a twin-peaked hill, i.e. strongly-typed lazy functional code (e.g. Haskell) and dynamically-typed variadic homoiconic code (Lisp). They have an "impedance mismatch" such that they don't inter-translate very well, unless they use clunky addons like Template Haskell macros or Typed Cloju…

You're right, but don't assume that there are only two peaks. That's making the same mistake you're arguing against.

Re: Half a decade with Go

#233
post #226
post #217

Earlier quoted context omitted.

You are seeing companies that use those languages suceeding at a higher rate than those that don't? I bet I can find 10 succeeding that use ruby or node for everyone that uses Erlang. We could also look at the open source world. For every riak there are 10 java sucesses of a similar kind. We'd need to do some real statistics but my bet is that we see no benefit from those languages in terms of success of the business…

> 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.

Re: Half a decade with Go

#234
post #231
post #199

Earlier quoted context omitted.

I think the enterprise Java sins were caused by cargo cult programming. Java can actually be pretty nice when wielded by someone who isn't afraid to invent new things.

What leads you to believe the same won't happen to Go? I have seen this happen in C codebases before Java took the enterprise. Its own little macro based DSL and pointers that were actually handles for the real data.

Java's sin is a fetish for over abstraction. Go has a strong cultural emphasis on avoiding unnecessary abstraction.

Re: Half a decade with Go

#235
post #211

Earlier quoted context omitted.

The lack of exceptions forces far too many lines of "if err != nil { return err}", (or worse, a goto) which takes 3 lines of text every time. If I could go back in time, and discuss one thing with the designers, it would be to fix this. I'd rather see some kind of Option type (like in Rust) baked deep into the language. Maybe there would be a scheme where you could use these Option types as regular values. The moment…

> The moment you try to use one of them that is actually an error (trying to pass it as an argument to another function without inspecting it first for example), it causes your current function to return an error. I've seen another way to do it, that works with current Go, in a redis client [1]: - Function 1 returns rawarg, error where rawarg can be anything - You want to transform arg into some type, so you create a…

I'll have to take a look at that. Thanks for the link.

Re: Half a decade with Go

#236

Earlier quoted context omitted.

It's entirely possible that I just don't know enough about go's interfaces. Wasn't it explicitly stated up-thread that you don't need to name the interfaces you support? If that's the case, I don't see how you get around the possibility of a type seeming to support (because of what's defined for it) an interface that it doesn't (because those functions actually do other things - obviously or subtly).

OK, now I understand. It may be possible to muck things up if you've got two different types (from different packages) that have the exact same signatures for all the functions defined in the interfaces. It doesn't seem like a high probability that this would happen on accident, though it might be possible to contrive an example. I'll have to think about that.

Thinking about it in the abstract, it seems to me that the probability goes up as interfaces get smaller/narrower (which apparently is a style that go encourages) and the codebase gets larger (which is go's target environment).

Re: Half a decade with Go

#237
post #234
post #231

Earlier quoted context omitted.

What leads you to believe the same won't happen to Go? I have seen this happen in C codebases before Java took the enterprise. Its own little macro based DSL and pointers that were actually handles for the real data.

Java's sin is a fetish for over abstraction. Go has a strong cultural emphasis on avoiding unnecessary abstraction.

Enterprise architecture is traversal to the languages being used.

Re: Half a decade with Go

#238

Earlier quoted context omitted.

OK, now I understand. It may be possible to muck things up if you've got two different types (from different packages) that have the exact same signatures for all the functions defined in the interfaces. It doesn't seem like a high probability that this would happen on accident, though it might be possible to contrive an example. I'll have to think about that.

Thinking about it in the abstract, it seems to me that the probability goes up as interfaces get smaller/narrower (which apparently is a style that go encourages) and the codebase gets larger (which is go's target environment).

It goes down as method names contain more entropy, too.

Re: Half a decade with Go

#239
post #202
post #133

Earlier quoted context omitted.

Consider e.g. traverse, which is a function you simply can't write in a language without higher-kinded types. Several times I've written half a page of code only to realize "that's just traverse" or "that's just foldMap" or so on. In a less expressive language I would've had to leave that half-page as is. Surely that means the expressiveness results in more readable, less complex code?

Sounds more like boilerplate or redundancy to me than complexity. Things I would call "complex" in a software system are god objects, APIs with too many options, invisible interactions between parts that appear unrelated, and so on.

Fair enough. In that case I'd say expressive languages help, but only indirectly, because they make it possible to keep track of effects and interactions without having to write reams of code.

In a language with lenses, you can delimit where your models are mutated. In a language that lets you treat composable effects in a generic way, you can e.g. split up your variables explicitly with ReaderWriterState, making it clearer which serves which purpose.

The kind of things you might be tempted to use "magic" or global variables for in a lesser language - the "cross-cutting concerns" - you can instead handle in normal code as a generic kind of context. E.g. an audit trail can just be Writer. Or actions that need access to a database session can just be another kind of context. I'm working on such a thing right now (see tpolecat's doobie for a public example of the same kind of thing) - whether a function accesses the database or not is visible right in its type, but it's easy to compose functions that do. The types ripple up, and in the end I'm probably going to do session-creation-in-view - but in a principled way, using the ordinary type system, visible in the code - with Spray, my web route definitions are just another ordinary bit of Scala code (whereas in most languages I would define routes in an external config file, or at best a config object a la Django - adding complexity).

Heck, error handling is a perfectly good example of this. In a less expressive language, the only way around the boilerplate of handling errors where they occur is unchecked exceptions (or effectively-unchecked exceptions, as in "throws Exception"). In a language with good generic context support, the possibility of failure is just another kind of context that we compose with the same generic tools as any other, and the control flow becomes something sensible again.

Re: Half a decade with Go

#240

Earlier quoted context omitted.

Thinking about it in the abstract, it seems to me that the probability goes up as interfaces get smaller/narrower (which apparently is a style that go encourages) and the codebase gets larger (which is go's target environment).

It goes down as method names contain more entropy, too.

True. And yet... for a good method name in an interface, you want it to be as general as the interface could be. You want sort(), not sortVector(), because sorting is much more general than sorting a vector - you could sort a tree, if it can be ordered.

You could include the name of the interface as part of the method name, though. But the downside of that approach is, if another interface wants to re-use the same method, things get awkward...

Post reply on HN