Live data from Hacker News

Half a decade with Go

blog.golang.org

211–220 of 257 posts

Re: Half a decade with Go

#211
post #96

Go has a rather specific purpose. It's intended for writing server-side web systems that will run fast and scale well. Since that's what Google does to make money, that makes sense. The available libraries reflect this - good support for dealing with many network connections at once, no GUI support. It's not suitable for writing an OS, hard real time, highly generic libraries, or GUI programs. Within its niche, it's…

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 function that takes a rawarg and an error and returns your type and an error

- In the implementation of your 2nd function, if err != nil, return it directly

This way, as a library user you can just chain your calls without the tedious if err != nil (it will be taken care of in the library).

This might not scale to huge programs, but there certainly is a way to reuse this idea.

[1] https://github.com/garyburd/redigo/blob/master/redis/reply.g...

Re: Half a decade with Go

#212
post #16
post #12

Earlier quoted context omitted.

What do you think is worthwhile about Go? I agree that the tooling is nice, but beyond that, there is nothing interesting to me. Goroutines aren't interesting; languages like Erlang and Haskell got green threads right many years before Go was on the scene.

You should ponder why Erlang or Haskell achieved a fraction of Go's adoption despite being on the market 20+ years longer. Some people see languages as a bag of features (immutability! generic programming! laziness! operator overloading! algebraic types! hindley-miller type inference! pattern matching! exceptions! manual memory management!). See http://yager.io/programming/go.html for an example of that line of think…

> You should ponder why Erlang or Haskell achieved a fraction of Go's adoption despite being on the market 20+ years longer.

Because Google.

In longer form, because Google is big and Go is well-enough-adapted for problems Google has (there may or may not be better solutions, and there may be some NIH factor going on in Google favoring it, but its at least good enough), and because the fact that Google is big and behind Go, that gets it lots of attention and interest and use even in places where it may not be as well suited as alternatives or what it is replacing.

Re: Half a decade with Go

#213
post #128

Earlier quoted context omitted.

Go seems to be an iteration of Rob Pike's previous languages, Limbo and Newsqueak - perhaps with a sprinkling of other ideas, but not much. Rust on the other hand has been a far more ambitious project, with very lofty goals. This has meant that the Rust team has needed to do a huge amount of experimentation and iteration, culminating in the tight set of core semantics that you see in the language today. It's not been…

Rob Pike's keynote at GopherCon 2014 does a great walkthrough of the evolution of the design of the language, where ideas were borrowed from and why: https://www.youtube.com/watch?v=VoS7DsT1rdM

Oh nice, I'll check it out. It's always good to see where things come from.

Re: Half a decade with Go

#214
post #196

Earlier quoted context omitted.

Haskell's typeclass provide it.

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

Re: Half a decade with Go

#215
post #165

Earlier quoted context omitted.

Absolutely: do_stuff() -> GetAnswer = fun() -> 42 end, spawn(fun() -> io:format("The answer is ~p\n", [GetAnswer()]) end). Here, GetAnswer is a closure, as is the anonymous function given to spawn() function.

And here is why these functional langauges will never make main stream. I've, been programming for 20+ years and I look at that code and say what the f *k? Ooh, it's the functional stuff. Ok, move on.

Seriously? I mean, Erlang has some gnarly syntax, but this is really basic, and translates directly to anything you'll find in JavaScript, Go, Ruby, Scala, C++, even Java.

Let me take you through it:

    do_stuff() ->
This declares a function do_stuff(). It's exactly like:

    function do_stuff() { ... }
Everything after is the body. Unlike many languages, Erlang uses comma, not semicolons, as statement separators, function bodies end with a "." so a function follows the form:

    do_stuff() -> a, b, c.
Here, a, b and c are statements. The last statement provides the return value. This directly translates to:

    function do_stuff() { a; b; return c; }
Next line defines a variable:

    GetAnswer = fun() -> 42 end,
This just defines a variable which is an anonymous, inline function, sometimes called a closure or a lambda (all three are technically correct). In Erlang, anonymous functions end with "end", not ".". This is equivalent to JavaScript:

    var GetAnswer = function() { return 42; };
The next line is therefore easy to understand, as it uses the same inline function syntax; it calls spawn() with this function as an argument. So it's this:

    spawn(...)
The argument is this function:

    fun() -> io:format("The answer is ~p\n", [GetAnswer()]) end
JavaScript version:

    function() { return io.format(
      "The answer is ~p\n", [GetAnswer()]); }
(Of course, JS doesn't have spawn() or io.format(); this is just syntax.)

Complete version:

    function do_stuff() {
      var GetAnswer = function() { return 42; };     
      spawn(function() {
        io.format("The answer is ~p\n", [GetAnswer()]); });
    }
In some ways, the JavaScript version is actually gnarlier. Look at all those braces and semicolons.

The thing is, the syntax we found nice is usually nice because it's familiar. Many languages could seem like an incomprehensible mess if you're used to C-style brace syntax. But that's purely a question of familiarity. If you don't know what all the bits and pieces mean, you're going to be alienated by it. A developer who has grown up on COBOL and Forth will not find JavaScript syntax familiar any more than you find Erlang syntax familiar.

I suggest stepping out of your comfortable protective shell and trying it out. It's not rocket science. After 30-60 minutes reading this book you'll no longer find it alien, I bet:

http://learnyousomeerlang.com

Re: Half a decade with Go

#216
post #20
post #17

You still need a Makefile if you use things like godep, or their new `go generate` stuff. They have a long way to go on tooling; however, getting to say that is a luxury, due to just how "right" golang has been for systems work. Golang has been amazing to work with, and has just been stupidly productive. I miss debugging (gdb) and generic compile tools like tup, but that's about it!

I saw a debugger[0] posted on the go-nuts mailing list today[1]. It's fairly simple at this point, but it works. [0] https://github.com/derekparker/delve [1] https://groups.google.com/forum/#!topic/golang-nuts/bmsFE3dQ...

Thank you for mentioning it. With the last version of liteIde (refactoring, jump-to, usages, info about a anything...) the only thing that I missed was a debugger. I Hope that the project gains traction.

Re: Half a decade with Go

#217
post #137
post #126

Earlier quoted context omitted.

If languages like Haskell and Erlang gave a competitive advantage, wouldn't we see companies which used them succeeding over those that don't? Maybe Go is fitting into the cultures that succeed, and if that's the case, well it's the better choice, right?

> If languages like Haskell and Erlang gave a competitive advantage, wouldn't we see companies which used them succeeding over those that don't? We are. WhatsApp generated a flurry of interest around Erlang. Heroku uses it. I'm sure there are more examples. Google is at this point already a large corporation and probably already in decline (IMO). The tools they use are optimized for interchangeability of mediocre pro…

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.

Re: Half a decade with Go

#218

Earlier quoted context omitted.

I NEED to work Go into one of my projects, but dammit I love Python so much. it is a warm and safe and comfortable cocoon. :)

Then you need to scale and your library isn't actually built in C... or only runs on 2.x (or 3.x) and the cocoon seals up and you can't escape... you scream but no one can hear you... you look for help, desperately clawing at cython, numpy, jython, pypy and C extensions -- they all require you to leave your cocoon far behind... you struggle and break free... suddenly you are exposed to the big wide world outside of y…

hahah well I am very comfortable with C and other languages, but I love python for it's versatility and ease of use! It has some very expressive one liners that are surprisingly coherent for being one liners.

Re: Half a decade with Go

#219
post #186

Earlier quoted context omitted.

The very point of an interface is to decouple the caller from all the implementation specifically because it will work differently between implementation. If you expect two classes to implement it the same way, you an abstract base, not an interface. Close is a particularly good example. One need only look at C#'s IDisposable to see that it does, in fact, work well. A mock might noop it, another class might close an…

It's not just "people who use it poorly". The point of an interface is to abstract over some details while guaranteeing others. If I am unaware of an interface, I don't know to avoid the names used in that interface, and I don't know to abide by the invariants assumed in that interface. That seems like it will bite people who've done nothing wrong. If I am providing a library, I can't possibly be aware of every inter…

If I am unaware of an interface, I don't know to avoid the names used in that interface, and I don't know to abide by the invariants assumed in that interface. That seems like it will bite people who've done nothing wrong. If I am providing a library, I can't possibly be aware of every interface anyone might define in code that uses it. I've no clue how frequently this will occur, in practice.

That's not a problem with Go's module system. If someone is using your library, and wants to use your interface in a particular package, that's fine. If they want to use another library, with another interface of the same name in another package, that's also fine.

If they want to use both libraries in the same client package, they'll have to locally rename one or both of the imports.

Re: Half a decade with Go

#220

Earlier quoted context omitted.

It's not just "people who use it poorly". The point of an interface is to abstract over some details while guaranteeing others. If I am unaware of an interface, I don't know to avoid the names used in that interface, and I don't know to abide by the invariants assumed in that interface. That seems like it will bite people who've done nothing wrong. If I am providing a library, I can't possibly be aware of every inter…

If I am unaware of an interface, I don't know to avoid the names used in that interface, and I don't know to abide by the invariants assumed in that interface. That seems like it will bite people who've done nothing wrong. If I am providing a library, I can't possibly be aware of every interface anyone might define in code that uses it. I've no clue how frequently this will occur, in practice. That's not a problem wi…

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).
Post reply on HN