1. 26
    Was Go's Try Proposal a False Flag? go doxsey.net
  1. 35

    …and following Betteridge’s law of headlines, even the author says the answer is no (albeit in the footnote at the end of the article, behind a door with a sign saying “beware of the leopard”).

    1. 6

      Well that is the Headline Answer Department.

      1. 1

        Is this really an example of Betteridge’s law? The author paints a picture for us, one that might or might not be true. It’s not a simple “no” answer.

        1. 5

          😈 I don’t actually believe it was a false flag…


          1. 0

            But my point is that the article doesn’t conclude that the answer is no, unlike typical Betteridge’s law examples. Rather, it presents a good argument for the opposite (even if the author admits that he doesn’t believe it).

            You can’t summarize the article with “no”, and you can’t change the title to “Go’s Try Proposal Wasn’t a False Flag”, making this not an example of Betteridge’s law, in my eyes.

            1. 6

              You’re right, this is all reverse psychology. The author is actually playing 10 dimensional chess with our minds. Betteridge’s law doesn’t apply in the cases where you thought that think that you thought but you didn’t think that you thought but instead was made to think that you had thought that you think so. It all makes sense now.

              1. 1

                the cases where you thought that think that you think

      2. 13

        except… that’s not what a false flag is…

        A false flag operation is flying/painting/wearing someone else’s flag with intent to deceive an adversary about who is engaging in the operation for some strategic purpose. (Usually to keep the enemy off their guard or avoid political blame.) The who is important. The Go team neither raised nor withdrew the propsal while pretending to be someone else.

        What TFA describes is merely ulterior motive.

        Further, and I have zero horses in this game since I don’t know Go, the propsal review committee dude stated pretty well why the proposal was being declined: communication and collaboration around the proposal sucked and it was either solving a problem that a lot of people didn’t believe was actually a real problem, or it didn’t solve the problem well enough, I can’t tell. Hard to see how that’s a bad thing. First rule of language improvements should always be, first do no harm. Far better to miss a potentially useful feature than to have to deal with the consequences of a poorly executed one for decades after.

        1. 4

          At this point, I think the meaning of “false flag” has faded so much that almost no one bat an eye when reading the article.

          Further, it’s not just a proposal with an ulterior motive; the proposal in itself was false and untruthful (if we accept the theory).

        2. 9

          Disclaimer: I work at Google (on an unrelated product team)

          It was not a false flag. I feel upset reading this. Articles like this don’t help me talk to others as a developer working at a corporation, they just make me want to shut up so I don’t get quoted like Russ.

          1. 4

            I’m sorry that the article came across this way. It was not my intention to malign the good work of Russ or the rest of the Go team. I think they do good work and I’m a big fan of Go (I even wrote a book about it). In fact I think they usually make better decisions than the community. Vgo was just better than dep, which has only become more apparent the more I’ve used it. I think its great that he was able to make the tough call and do what he did, despite the social ramifications. Go would’ve been worse off if he hadn’t.

            I quoted Russ because it was illustrative of an issue in the Go community about trust and ownership. It’s not any individual’s fault, and I actually think the issue is a bit overblown. The Go team has nearly impossible demands placed upon them and I think they do a good job of managing – far better than I could in a similar circumstance. Nevertheless, even if not wholly deserved, the issue is a real one, and this latest issue with the try proposal really strained the community. Had it gone through I suspect there may have been long-time developers who would’ve given up on the language, or at least pulled back from future involvement, distraught from a project that seemed to have taken a very different turn from what they signed up for. Is that fair? Probably not. But the tension was real regardless.

            The article was meant in jest. Of course the proposal wasn’t a false flag. I suppose the last comment may not have made that clear.

            I think the objective outcome here is great. I don’t think try would’ve been a good addition to the language. Like a lot of Go developers it didn’t strike me as particularly go-like, and it left a lot of us scratching our heads. So for things to pan out the way they did was a surprisingly good outcome, so good that you wonder if it wasn’t planned.

            Happy accidents do exist, but I wanted to just be a bit playful with an absurd conspiracy theory. I see now how this could be misinterpreted due to sloppy writing. The fault is entirely my own and I apologize.

            1. 5

              Oh, I’m sorry for my emotional reaction :/ Thanks so much for the explanation, I get where you’re coming from now.

              I think I’m too attached emotionally and shouldn’t comment on these discussions. They’re 100% important conversations to have. Lobsters has made me think a lot about corporate teams working on public technology, their relationship with the community and the risks that dissonance between company goals and community goals can pose – I absolutely want to read more and think more about it.

              1. 1

                I am afraid especially the final disclaimer may be much too tiny, both in font size and in length/depth. Even seeing it, I still absolutely didn’t grasp what you really meant by it, until I read your comment above. In other words, I’d say it isn’t counter-balancing the initial part of the article well enough; to me, it even seems half-hearted enough, that I took it more like a “I don’t really mean it, hee hee, right? wink, wink, nudge, nudge, or do I? ;D”

                Please remember the old truth, that on the Internet, it’s not possible for the reader to know if the writer is sarcastic, or if they really mean it, while the reader is often convinced they know the answer. It’s unfortunate, but I’ve seen it introduce problems much too many times. To the extent that I’ve even seen it used as an explicit and effective trolling tactic, to seed conflict in a community.

                1. 0

                  Vgo was just better than dep, which has only become more apparent the more I’ve used it. I think its great that he was able to make the tough call and do what he did, despite the social ramifications.

                  So true. I’ve been thinking this during the whole drama. Happy to read it here.

                  Had it gone through I suspect there may have been long-time developers who would’ve given up on the language

                  This goes both ways. I agree that maybe try was not right choice, but I could consider giving up on the language if nothing is done about error handling verbosity.

                  PS: Nice and funny article by the way ;-)

                2. 1

                  If this ever happens to you, then hopefully the take away is to apply the feedback of your peers so that they can help you think about your actions instead of inspiring you to never communicate again. The initial problem that stemmed this now paranoid group of Rust fans was a lack of communication from Russ, so not communicating is the actual problem which caused the issue in the first place.

                  There’s also always the option of not working for big evil corporations. :)

                3. 13

                  If Go 2.0 will get generics, as this piece asserts, why not have sum types as well, and then use said generics to implement a monadic error handling scheme?

                  1. 3

                    Rust has generics and sum types, and error handling was verbose until the introduction of the try! macro, and eventually the ? operator. The issue try was trying to solve is about control flow, and this can be solved only with macros, a new built-in function or a new keyword.

                    1. 2

                      Sum types have been proposed before. Here is a Reddit thread that discusses some of the difficulties involved in adding them.

                    2. 13

                      I think it was a big mistake not accepting the try proposal. I was actually thinking to myself, man, Go is catching up to Zig’s error handling abilities, this is closing the gap. But now I’m raising an eyebrow and wondering what they’re thinking. The reasoning for closing the proposal seems to be “we didn’t explain it well enough”. That’s kinda odd.

                      1. 4

                        I was also surprised and also kinda pity this decision, from a practical point of view of a professional Go developer.

                        That said, I think I do kinda see some arguments that I think could be what made them pause.

                        Or at least personally to me, I think the thing that made me the most uneasy about this proposal, was that it basically encouraged a significantly different approach to error handling than what was “officially” considered idiomatic in Go beforehand. Notably, if your code was written in the “idiomatic way”, you wouldn’t really be able to change it to anything better with try. And what I mean by “idiomatic” here, is adding some extra info/context to the error message, and maybe also doing some extra logic in the “if err” block. As opposed to a trivial if err != nil { return err }, which is not considered officially idiomatic in Go - though quite commonly found in real life code (esp. with helper libs like log15.v2 etc.).

                        This is a somewhat subtle thing, and I’m not sure if I managed to explain it well enough (I can try giving more examples if you’d like, maybe in priv if you prefer). I’m not even 100% sure if that’s their actual main reason, but personally to me, that was the one thing that made me feel not 100% good about this proposal from the beginning. And kinda helps me rationalize the rejection, although from short-sighted immediate perspective I’d much prefer to have the try.

                        1. 3

                          Thanks for this explanation! This made a lot more sense to me than the official explanation on the issue tracker.

                          As a counter-argument (not to you but for the proposal in general) try allows the language to automatically add context to an error as it bubbles up the stack. For example, it could add the source file, line, column, function name where the try occurred. Once the error reaches a point where the application reports the error or decides to panic because of it, the resulting data attached to the error explains exactly what the developer needs to know about what happened.

                          In Zig this is called error return tracing and I’m getting really positive feedback about it.

                          1. 3

                            Yep, you’re technically not wrong (regarding the counter-argument). The thing is, stack traces are somewhat controversial in the Go community.

                            I mean, it’s technically easy to attach a stack trace to an error in Go when it’s created, if that’s what you want (my last employer’s codebase works that way). If you mentally take a step back however, there are some interesting issues with stack traces, and especially if you try to use only stack traces when dumping error messages:

                            • stack traces are tightly coupled to a specific version of a codebase; a very next commit may make line numbers in your stack trace invalid/misleading; thus, you must track the codebase of a binary very well; as a corollary, stack traces mean little when analyzed in isolation, without source code.
                            • pure stack traces will still lack context that may be important at intermediate steps/levels of the stack (e.g. values of some local variables that may help when debugging, or may otherwise shed more light on what was the meaning of the call in a particular frame).
                            • also, stack traces tend to be noisy, making it somewhat tedious to find actually important information in them.
                            • stack traces are arguably developer friendly, but not very end-user friendly.

                            In contrast, an error message “officially” seen as “idiomatic” by the Go “fathers” could look kinda like below, when emitted from a program (with no formal stack trace):

                            error: backup of /home/akavel to /mnt/pendrive failed: cannot write /mnt/pendrive/foo/bar: device not ready

                            With some care, such an error message can be short, informative, give some potentially important extra context (e.g. the /home/akavel path as the source of the backup), be time-proof, self-contained, arguably more end-user friendly, and still usually make it possible to trace a concrete call stack in the codebase that emitted the error (though with some extra work compared to raw stack traces).

                            I don’t claim they are perfect, or that they are strictly better than stack traces. But I do understand their advantages and find this dilemma quite interesting and challenging (no clear winner to me). Also, it’s worth to note that this area is now kinda being further explored by the Go 2 proposals, esp. the “error values” one, with regards to how the ergonomy here could be maybe further improved, both for error message writers and readers.

                            1. 2

                              That’s a fair point about different versions of code with regards to stack traces.

                              And I do like your example quite a bit. That really is an amazingly helpful error message, both to end users and to developers. If Zig had the ability to do hidden allocations like Go does I would be all over this.

                              Even without that though, maybe there is a way… perhaps with something like this proposal.

                              1. 3

                                If you haven’t yet, please try and take a look at what is explored in the relevant Go 2 design draft (https://go.googlesource.com/proposal/+/master/design/go2draft-error-values-overview.md). Even if you don’t understand the whole context, I think there are some potentially interesting thoughts and considerations there. Please note also this is a very early stage “thought experiment”/exploration, that is not even at a proposal/RFC stage yet (or rather, it is something that could match the “request for comments” phrase if it was treated literally and without historical baggage).

                                As to the Zig proposal you linked, one thing that’s sorely missing for me there in order to fully understand it, is what kind of error messages/traces this could enable. I don’t see any example output there. Would it allow printing extra information as part of Zig’s “error return tracing”? Or let the programmer build error messages like what I’ve shown? I don’t know Zig enough to understand the unstated consequences. So, we’re now in a reversed situation, where previously I explained to you the unstated Go context that you didn’t have, and now it’s me who doesn’t have Zig context ;)

                              2. 2

                                I actually don’t find the ‘idiomatic Go error message’ example very helpful. I see the why the error happened, but what can I do to fix it and where can I do that? These are really the kinds of questions stack traces answer. I don’t find that line numbers shifting over time to be very compelling as an argument against. Stack traces are meant to be used to jump to the exact line numbers where the error travelled through. Typically when you’re debugging, you already know the specific commit you’re debugging–some commit SHA of a deployment. So you would already have that commit checked out and trace the error with accurate line numbers.

                                1. 1

                                  In this particular example case, the answer to your question (what, where) would be something like: “Insert the backup pendrive back into the USB port”. That’s not something one could fix in code in any way, so actually, stack traces are of completely no use here! (Ok, one could maybe make the code ignore the error and go on, but anyway, the message would still have to land in logs.)

                                  Other than that, as I said, the “idiomatic” errors are not perfect, and have disadvantages vs. stack traces, with the main (only?), most important one being how super easy and powerful it is to jump through code when you do have the call stack with line numbers and do know the commit SHA. And please note, that the Go 2 draft designs do try and explore if and how the advantages of both approaches could maybe be fused together.

                              3. 2

                                try allows the language to automatically add context to an error as it bubbles up the stack

                                Nothing in the proposal mentioned anything like this, and if you mean that users could combine try with deferred functions that annotated all errors returned in the function scope the same way, well, (a) that was already possible, and (b) it’s significantly worse than doing individual in-situ annotations, because (i) it physically separates error generating statements from the code that handles them, and (ii) it forces all errors that escape a function to be annotated the same way.

                              4. 1

                                Like you, I’d prefer to have try immediately, but I agree it introduces a style which is not idiomatic.

                              5. 1

                                I also feel like they abandoned the proposal mostly to keep the peace in the community. That said, catch and try fit better in Zig because you have error traces. Go doesn’t have error traces, and this is why people insist on decorating errors, and why they dislike try which only permits to return “naked” errors.

                              6. 12

                                The article sounds like a good explanation of why communities shouldn’t always have final say in language features.

                                1. 12

                                  I think a better way to phrase this is that programmers generally see the language as their adversary. They want to enlarge the space of possible programs to include the one they want to write.

                                  In contrast, for language designers programs are their main adversary. They want to maintain or sometimes shrink the space of possible programs so that bad/invalid programs can’t be expressed.

                                  Inevitably, these groups will clash over this as many proposed features while making some good programs possible also make some bad programs possible as well. The best way forward is to lobby for language features which make both groups happy by showing that a feature doesn’t make it possible to write bad programs. It’s not enough to say it’s unlikely the feature will be abused, you have to show that it’s impossible, since once a feature is added it is very hard to take away without breaking backwards compatibility.

                                  Worse, the more features you add the harder it is to prove it would have some weird interaction with some other part of the language. All of this is largely invisible to users of languages and not said upfront by language designers often enough.

                                  1. 5

                                    Sounds taboo to even think this, but I fully agree. The community is not always right.

                                    1. 1

                                      I agree. Something the community does not have is the comprehensive vision its creators has. This isn’t to say the community opinion is not valid, but rather a solution to an immediate problem simply may not align with the long-term goals. Whether or not this case was a “false flag” (I don’t believe this was the case), its something community members should keep in mind and not get bent out of shape when it feels like the creators are making an executive decision.

                                    2. 5

                                      Like the Go developers have nothing better to do that making up fake proposals…

                                      1. 3

                                        It’s never a false flag.

                                        1. 1

                                          Go’s problem is not that it is (or isn’t) true, their problem is that it sounds pretty plausible to many people’s ears.