You Don't Like Go Because You Are Small


  • BINNED

    I think this is satire, but I'm not 100% sure.

    Filed under: Poe's Law

    Paging @ben_lubar 🚎 .


  • I survived the hour long Uno hand

    ...blocked by the work filter...wow


  • BINNED

    So your job is TRWTF?


  • BINNED

    @antiquarian said:

    So your job is TRWTF?

    It has effective Go protection. It's AWESOME!


  • ♿ (Parody)

    Heh...I liked this comment:

    Too bad you got flagkilled on HN. Not that I would have commented there though because I'm hellbanned and slowbanned.

    Sadly, that just makes it more difficult to decide if this was serious or not.


  • I survived the hour long Uno hand

    Good thing I have a cellphone, that was funny XD



  • Apparently the author thinks && does something other than short-circuiting boolean logical AND, because x && x.foo doesn't make sense. And if you have a method named foo defined on a boolean type that returns a boolean type, x && x.foo() works, unlike C++ where that's not even a thing you can do.

    If I wanted to write a function that did this: std::cout << max(b(),c())

    I don't have to write this:

    t1 := b()
    if t2 := c(); t1 < t2 {
        t1 = t2
    } 
    fmt.Print( t1 )
    

    I can do this instead:

    fmt.Print(max(b(), c()))
    

    Where max is a function defined in exactly the same way it is in C++. In fact, there is a function named Max in the standard library.

    Why should the compiler go to all the trouble of validating an interface implementation when you, the programmer, can do it manually?

    This doesn't make any sense at all. The compiler checks every conversion, including implicit interface conversions. How is this:

    type MyWriter struct {
        // some fields
    }
    // a bunch of methods
    
    //later:
    functionThatTakesAWriter(new(MyWriter))
    

    harder than this?

    class MyWriter : public Writer {
        // some fields
    
        // a bunch of methods
    };
    
    //later:
    functionThatTakesAWriter(new MyWriter());
    

    And if you really need to implement an interface that you never use, you can just define a nameless variable, like so:

    var _ Writer = new(MyWriter)
    

    It gets optimized out at compile time, but it does get type checked.

    With Go's interfaces, you can make a third-party type implement the same interface as your mock version, even if the third-party type doesn't come with a matching interface. You can't do that in C++.



  • @ben_lubar said:

    Where max is a function defined in exactly the same way it is in C++

    Can you say max("a", "b")?

    I am not a Go programmer, but my understanding is it doesn't have the ability to have generic functions like that.... and if so, then it's emphatically not defined the same was as in C++.

    (I ask in part because if there is actually a reasonable way to do something C++-like on this front and I have a misconception, I'd love to hear about it.)



  • func max(a, b string) string {
    	if a > b {
    		return a
    	}
    	return b
    }
    


  • But do you have to write that function for each type? If I next want max(complex.New(1,2), complex.New(2,3)) do I then have to go and write that same thing yet again?

    Edit: in retrospect, complex numbers aren't a good example, as the "maximum" isn't well-defined.



  • Yes, you would have to write the function again, but how many times have you written a program that computes the maximum of two things without doing anything else for multiple data types?

    Anyway, you couldn't even write a function for that one because there is no order in complex numbers.

    a := complex(1, 2)
    b := complex(2, 3)
    fmt.Println(a < b)
    

    invalid operation: a < b (operator < not defined on complex128)



  • @ben_lubar said:

    Yes, you would have to write the function again, but how many times have you written a program that computes the maximum of two things without doing anything else for multiple data types?

    What about sort? In C++ I can write a sort function that will work for any orderable type. (I edited in a caveat about complex ordering not being well defined just as your posted showed up for me.) Same problem arises there.

    Go sort of gets around it in that case, but it's (IMO) awkward; it puts the responsibility of how to compare items onto the container when they should be on the element. (Of course, you also "can't" write a generic container class, so maybe this is more of an ideological objection.)

    I've programmed in C and in pre-1.5 Java, and the lack of the ability to write generic containers in both of those languages I view as an enormous impediment. It makes me very very skeptical about Go, which is why I'm sort of hammering on this. I've read a little and not been very convinced... not that I have the opportunity to use Go at work or do much programming on my own anyway.



  • type ByAge []Person
    
    func (a ByAge) Len() int           { return len(a) }
    func (a ByAge) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
    func (a ByAge) Less(i, j int) bool { return a[i].Age < a[j].Age }
    

  • Banned

    @ben_lubar said:

    Apparently the author thinks && does something other than short-circuiting boolean logical AND, because x && x.foo doesn't make sense.

    It does make sense if x has overloaded operator bool or operator&&.

    @ben_lubar said:

    And if you have a method named foo defined on a boolean type that returns a boolean type, x && x.foo() works, unlike C++ where that's not even a thing you can do.

    Honestly, who would ever want to write methods on bool ⁉

    @ben_lubar said:

    var _ Writer = new(MyWriter)

    That's one terrible hack. Almost as terrible as std::enable_if.



  • Why would you want to compare complex numbers? They don't have a order compatible with its field structure (the reals are the only complete ordered field, and C is a complete field).



  • @Captain said:

    Why would you want to compare complex numbers? They don't have a order compatible with its field structure (the reals are the only complete ordered field, and C is a complete field).
    Wow, if only I had edited my post a couple minutes after making it (and well before your reply) to say

    Edit: in retrospect, complex numbers aren't a good example, as the "maximum" isn't well-defined.
    It's too bad I didn't do that. ;-)


  • Here's the C++ version:



  • Really? It takes zero code to sort an array of an arbitrary type by an arbitrary field? Tell me more about your magical mind-reading compiler.



  • @ben_lubar said:

    Really? It takes zero code to sort an array of an arbitrary type by an arbitrary field? Tell me more about your magical mind-reading compiler.
    I'm cheating slightly... but only slightly. You would "have to" have a < operator available for the types of interest, e.g. bool operator<(Person const & other) const { return age < other.age; } as somewhat an analogue to Less. You'll need an operator= (somewhat an analogue to Swap) -- but more often than not, you won't need to define it explicitly. Even if you do, you probably need it in other cases than for sorting anyway. An analogue to Len is entirely unneeded.

    The reason I assert it's only slightly cheating is that operator<, like =, is useful in other contexts. I can define it once and it's available for sorting, for max, and any other place that you might want to compare two Persons. Because Less is associated with ByAge instead of Person, the same is not true for your code. max can't use that Less to get the maximum of two Persons and you'll have to write a different comparison function there. That's why I said what I said: if you have an operator< available for other purposes, there's nothing additional to do in order to sort in C++. If you have < available for other purposes in Go, you still need to define Less.

    And to nip a response in the bud: it's not like you get additional flexibility. For example, in Go you could define a ByName type and give it a different less function. But in C++, you'd just define another analogue to Less. You still don't need Swap or Len.


  • BINNED

    A couple of interesting comments from the reddit post:

    http://www.reddit.com/r/programming/comments/2w9mg5/you_dont_like_googles_go_because_you_are_small/coozcaw

    I work at Google. An AWFUL lot of us don't like Go.

    Does Go have neat things that C++ doesn't? Yes. And all of those things are at least 15 years old, and were first implemented (better) somewhere else. Mostly in OCaml.

    http://www.reddit.com/r/programming/comments/2w9mg5/you_dont_like_googles_go_because_you_are_small/copbu1n

    I also work at Google, and yes I have been unreasonably forced to use Go. In internal discussions, the tone of Go team is actually not much different than this blog post.



  •   t1 := b()
      if t2 := c(); t1 &lt; t2 {
        t1 = t2
      } 
      fmt.Print( t1 )
    

    How does that not break the most common denominator for if semantics across the languages. The condition is multi-statement with the first statement being assignment. How do I know what is being evaluated? Or is this like a condensed using

    using (t1  = b()) {
    using (t2 = c()) { if (t1 < t2) t1 = t2 } fmt.Print(t1) } }
    

    I mean, at that point, why not just use an anonymous method?

    fmt.Print([b(),c()](int t1, int t2){ if (t1 < t2) { t1 = t2 } return t1 })
    

  • Java Dev

    @xaade said:

    How does that not break the most common denominator for if semantics across the languages. The condition is multi-statement with the first statement being assignment. How do I know what is being evaluated? Or is this like a condensed using

    Bash allows multiple statements between if and then as well, with the return value of the last being the one used for the if. I don't think I've ever seen it used.



  • @PleegWat said:

    Bash allows multiple statements... the return value of the last being used

    Holy hell. That's scary as fuc*


  • Banned

    Well, even plain C allows this.

    t1 = b();
    if (t2 = c(), t1 < t2) t1 = t2;
    printf("%c", t1);
    

    And C++ even lets you overload the comma.





  • @antiquarian said:

    Filed under: Poe's Law

    100% certain this satire.

    @ben_lubar said:

    Apparently...

    Apparently, someone is rankled.



  • @Gaska said:

    And C++ even lets you overload the comma.

    C++ lets you do many many things... operator&& anyone?



  • So, the guy is ranting about a new language that doesn't have a built in set of libraries for Mathematics and other stuff. Meh!

    He could rant about what Go solves that not any other language has. Let's see:

    • Concurrency: no
    • Syntax: no
    • Multiplatform: no
    • Null pointers: no
    • GC/Memory Handling: no
    • New paradigm: no
    • Ease of deployment: no
    • Easy DB integration: no

    So again, why? I really think Go is the sort of thing that comes out of the "20% policy" of Google that got too far. Like Dart, anyone remember Dart? That's right.



  • @Eldelshell said:

    Like Dart, anyone remember Dart?

    Isn't that the Javascript replacement that shipped with an Eclipse-based IDE?



  • IDK, the first time I heard about Dart was in 2010 or something and was a guy asking me if we should write a new project in CoffeeScript or Dart and I was like :wtf: you were hired as a JavaScript developer.



  • The one thing I feel that I can take away from this article is: Go doesn't have macros.

    What a shame. Everyone knows that all decent languages (Lisp, C++, Scheme, Rust) have macros.



  • @Eldelshell said:

    Concurrency: no
    Syntax: no
    Multiplatform: no
    Null pointers: no
    GC/Memory Handling: no
    New paradigm: no
    Ease of deployment: no
    Easy DB integration: no

    Isn't this why we make languages extendable.... with libraries.
    I mean, what's going to beat that. A new language with every possible feature baked in?



  • With all due respect, you didn't get the point. I was trying to reflect that Go doesn't have anything new or bright or excels on anything in particular like C, C#, Python, Java, JavaScript or many others do in their particular cases.



  • Oh I got the point.

    I'm "extending" your point.

    My point is that we always assume we have something really awesome because it has x new feature baked in.

    Well, unless that means better performance, or better semantics/syntax, it doesn't actually give us any benefit over having a robust extendable language.

    And, oh look, we already have that, like 15 times over.

    So, you're going to have to do something really profound to convince me you are justified in reinventing the wheel.

    All Go has seemed to have done is just shift the syntax around.

    Guess what, I can do that in C++, without forcing people to use my new pattern.

    Hell, you can mimic other languages with macros in C++ if you so deem fit.

    #DEFINE IF if(
    #DEFINE THEN ) {
    #DEFINE ENDIF }
    


  • @xaade said:

    All Go has seemed to have done is just shift the syntax around.

    Plus removed features and flexibility.

    Apparently they do something clever w.r.t. concurrency with their cgoroutines, but that's about it. (And I'm not too sure how it differs from what e.g. Erlang does -- but I've not looked at either in depth.)


  • BINNED

    @tar said:

    Apparently, someone is rankled.

    @ben_lubar not getting the joke is arguably the best part of this thread.

    @Eldelshell said:

    So, the guy is ranting about a new language that doesn't have a built in set of libraries for Mathematics and other stuff. Meh!

    He could rant about what Go solves that not any other language has. Let's see:

    Relevant:

    http://what.thedailywtf.com/t/poll-do-we-really-need-more-programming-languages/1453



  • @antiquarian said:

    @ben_lubar not getting the joke is arguably the best part of this thread.

    ❤



  • Don't put words in my post. I didn't say we don't need more/better languages. For example, I like the ideas behind Rust and Erlang because they're trying to solve real problems.
    Go is just Google's language. If it wasn't because of that no one would talk/rant about it.


  • BINNED

    @Eldelshell said:

    Don't put words in my post. I didn't say we don't need more/better languages.

    I didn't say you did. I'm the one saying we don't need more languages. We may[1] need better languages, but that's seldom what happens when someone makes a new language.

    [1] My opinion is that Ada is more than sufficient to cover system programming and real-time applications, and Haskell for everything else, or at least Haskell would be if its language and library designers would stop making breaking changes. Or if you absolutely must have dynamic typing, there's Python and the Lisp family (including Clojure).

    @Eldelshell said:

    Go is just Google's language. If it wasn't because of that no one would talk/rant about it use it at all.

    FTFY



  • OK... Carry on.



  • @xaade said:

    Hell, you can mimic other languages with macros in C++ if you so deem fit.

    #DEFINE IF if(
    #DEFINE THEN ) {
    #DEFINE ENDIF }

    Oh my Jesus fuck, I'm starting to think you're actually serious on that one.



  • @Maciejasjmj said:

    Oh my Jesus, fuck, I'm starting to think you're actually serious on that one.

    Watch your commas, please. 😃

    There are coding games that attempt to do this. It's all fun and games until it ends up in someone's production.



  • @xaade said:

    There are coding games that attempt to do this. It's all fun and games until it ends up in someone's production.

    I think we've seen this particular antipattern documented in the wild a couple times around here.



  • If your argument against Go is "we already have a turing-complete language", then why do we already have more than one turing-complete language in the first place?

    It's because they have different purposes. Go has garbage collection and CSP-style concurrency. C++ has reference counters and whatever-c-style-concurrency-is-called concurrency.



  • @ben_lubar said:

    var _ Writer = new(MyWriter)

    It gets optimized out at compile time, but it does get type checked.

    It would be nice to have a better way to say that, though.

    @Eldelshell said:

    He could rant about what Go solves that not any other language has.

    @Eldelshell said:

    I was trying to reflect that Go doesn't have anything new or bright

    “Go is not meant to innovate programming theory. It’s meant to innovate programming practice.”

    —Samuel Tesla, whoever that fuck is, sure isn't Nikola

    @tar said:

    The one thing I feel that I can take away from this article is: Go doesn't have macros.

    What a shame. Everyone knows that all decent languages (Lisp, C++, Scheme, Rust) have macros.

    With go generate, you can commit your post-macro code to source control.



  • @xaade said:

    Well, unless that means better performance, or better semantics/syntax, it doesn't actually give us any benefit over having a robust extendable language.

    @cvi said:

    Apparently they do something clever w.r.t. concurrency with their cgoroutines, but that's about it.

    The whole reason that channels and goroutines are not a library is the select statement. Mr. Rob Pike actually says that.

    You can't implement a control structure in a library.

    Usage example:

    func fanInStr(ch1, ch2 <-chan string) <-chan string {
        chR := make(chan string)
        go func() {
            var s string
            for {
                select {
                case s = <-ch1:
                    fallthrough
                case s = <-ch2:
                    chR <- s
                }
            }
        }()
        return chR
    }
    

    Note also that goroutines are garbage collected along with channels.

    (yes, fallthrough and select are keywords)


    Note also that other concurrency primitives, such as mutexes and thread joins, are implemented in a library because they can be.



  • Which, IMO, is good. But it's also the only place where Go "innovates"(*). And even there Go isn't unique, but Erlang does something rather similar with receive and ->.

    Also with good meta-programming support (better than C++, perhaps something like metalua) you could implement control structures outside of the core language.

    (*) That I've heard about.



  • @Samuel Tesla said:

    “Go is not meant to innovate programming theory. It’s meant to innovate programming practice.”

    Go is a special-purpose programming language. Like any other programming language, you can use it to write general-purpose programs, but you may be "punished" for doing so:

    • Static linking (nb: this works well when you "move the code where the data is")

    • No method overloading

    • Etc

    Basically, they like to tell people that they're Doing It Wrong™. Which does cause some pain. For example, I can't keep my code in my ~/projects directory without doing symlink magic.



  • ... which begs the question why anybody would want to use it (voluntarily).



  • Because their program's use-case matches with the language well?

    Now, with "managers forcing people to use Go", I am reluctant to say that that was justified.

    But I liked being able to sprinkle time.Sleep() in my bot code.


Log in to reply