←back to thread

131 points apta | 1 comments | | HN request time: 0.217s | source
Show context
ereyes01 ◴[] No.9266715[source]
If I wasn't already a Go programmer, reading this would make me more interested in Go than not.

Simplicity is deceivingly challenging, and quite different from simple-mindedness, which seems to be what the author is accusing Go of being.

Keeping code simple, elegant, and consistent is IMHO one of the most valuable principles a team can adhere to. Simple is not necessarily shorter, as short can often be subtle and sneaky rather than simple. Complex power tools can be fun to the inquiring mind, but the ultimate consumers of your product almost never appreciate how you built it, but almost always appreciate the final outcome.

A wise man once said: “Everyone knows that debugging is twice as hard as writing a program in the first place. So if you're as clever as you can be when you write it, how will you ever debug it?” - Brian Kernighan

replies(2): >>9266740 #>>9271681 #
meowface ◴[] No.9266740[source]
There's also the argument that your chance of writing buggy code increases with each additional line you write.

Highly readable code helps reduce bugs. But if that code is also so simplistic that it necessitates a lot of verbosity, you definitely increase the chance of introducing some stupid bug. Thankfully, as a compiled language, Go can find a decent portion of the silly stupid bugs where in a more expressive language like Python they might go hidden for longer, but it's still a big tradeoff you're making.

replies(2): >>9267290 #>>9267710 #
NateDad ◴[] No.9267290[source]
Go is not significantly more verbose than python except in a couple trivial cases (list comprehensions become a 3 line loop). Across even a moderately sized program, this will most likely not even amount for a statistically significant difference.
replies(2): >>9267691 #>>9268256 #
meowface ◴[] No.9267691[source]
As a professional Python developer and amateur Go dabbler, I very vehemently disagree.

Without access to list/dict/set comprehensions, or libraries like itertools, or a lightweight lambda syntax or something like Ruby's blocks, transformations on collections will always be considerably more tedious and verbose.

Various functions have "bring-your-own-buffer" calling conventions, which will often double or triple the number of lines required for those function calls.

No tuple unpacking, no ability for functional programming (Python's isn't that amazing but with functools and some of the builtins, you can get pretty far), no operators for string formatting or anything but absolute barebones operations.

Combine that with what Go lacks even compared to languages like Java (no inheritance [which is usually an anti-pattern but does decrease verbosity when used properly], no generics, no deep type/class reflection) and it's hard to say that Go isn't a verbose language.

No statically typed language is going to be as terse or expressive as Python can be.

replies(1): >>9275439 #
NateDad ◴[] No.9275439[source]
Can you explain how tuples are significantly different from multiple returns in real programs? You can do

    func foo() (string, int, bool) {
        return "one", 2, true
    }

    func bar(s string, i int, b bool) {}

    bar(foo())
replies(1): >>9279398 #
meowface ◴[] No.9279398[source]
When dealing with function calls, they're roughly the same.

But how about things like:

    g = some_input() # A list with 3 elements
    a, b, c = g
Or in Python 3+:

    lst = [1, 2, 3, 4]
    head, *tail = lst # 1, [2, 3, 4]
    *init, last = lst # [1, 2, 3], 4
    a, *b, c = lst # 1, [2, 3], 4
replies(1): >>9288538 #
1. NateDad ◴[] No.9288538[source]
You can do that in go with just a few more characters:

    g := some_input() // A list with 3 elements
    a, b, c := g[0], g[1], g[2]
I'll grant you, having to specify the indices is slightly more verbose, but it's also a lot more clear... because what happens when g has more or less than 3 elements? In Go it's clear, more is ok, less will get you a panic.

    lst := []int{1, 2, 3, 4}
    head, tail := lst[0], lst[1:]
    init, last := lst[:len(lst)-1], lst[len(lst)-1]
    a, b, c := lst[0], lst[1:3], lst[4]
Again, I don't think the magic unpacking is really helping that much... doing it the same way you'd do anything else in Go is slightly more verbose, but it's also not some new syntax you have to figure out either.