News for hackers. Stuff that matters.
Re:Portable Cloud Programming with Go Cloud by spraak on Tuesday July 24, 2018 @12:21PM (#17602475)
Maybe it's a biased and distorted perception that I have, but Go seems to be the most consistent and unsurprising language I've used, and I mean this positively. I haven't written any Go for over a year since my current job mostly uses Node, but I feel immediately comfortable jumping in to the examples in this blog post. I don't think that I'm explaining what I mean very well, but it's something I don't think is so true for Node/JS and other languages I've used.
Re:Portable Cloud Programming with Go Cloud by sbjs on Tuesday July 24, 2018 @12:40PM (#17602695)
Meh, everyone has a preferred type of language they find least surprising. To many Ruby is the least surprising, and Matz used "principle of [his] least surprise" as a guiding principle when designing it, but many other people find it enigmatic and confusing. Some people find Haskell the least surprising and most consistent, others say Java is. Every language has caveats and inconsistencies, even Go. Like how Go has generics, but only for two or three built-in types. It seems to be more about the person trying out the language than the language itself.
Re:Portable Cloud Programming with Go Cloud by stcredzero on Tuesday July 24, 2018 @12:53PM (#17602811)
Minimalism helps. Ruby has one kind of minimalism, but fails at minimalism in some other ways. The same with Go. People who like Haskell like the kind of reasoning it facilitates. People who like Java want a managed version of C++'s "good parts."

A lot of it has to do with expectations. Going beyond the principle of least surprise, there's also a principle of "no dismay." Go is like the dependable old Corolla. It sets modest expectations, and it delivers a high degree of utility very consistently, and if you're ever let down, it's very rare. C++ can cause you utter dismay due to rather subtle slip-ups. I've only seen this level of dismay in Golang around subtle resource release issues around prepared statements.

Re:Portable Cloud Programming with Go Cloud by sbjs on Tuesday July 24, 2018 @12:46PM (#17602755)
The article has two examples of how I already find Go to be inconsistent and/or surprising:

    w, err := b.NewWriter(ctx, "gopher.png", nil)
    ...
    _, err = w.Write(data)
    ...
    if err := w.Close(); err != nil
Why is := used on the first line but = used on the second line, and then := used again on the third line? I get that you use := when introducing a new variable, and = when just assigning, the third line is not really introducing a new variable, since err is still in scope... or is it?

Not to mention, what is the last argument `nil` supposed to represent? In most high quality Node.js libraries, functions/constructors will take an optional options object so you can omit it, or pass an object like { timeout: 300 } to it.

Re:Portable Cloud Programming with Go Cloud by ssambros on Tuesday July 24, 2018 @01:32PM (#17603217)
Third line ':=' is not required, you can reuse globally scoped 'err' with '=' as well; unless you want to preserve the current value of global 'err' for future use (which would be confusing).
Re:Portable Cloud Programming with Go Cloud by skj on Tuesday July 24, 2018 @12:57PM (#17602868)
The third line has a new err inside the if statement's scope.

It's equivalent to

    { // begin new scope here
      err := w.Close()
      if err != nil {
        foo
      } else {
        bar
      }
    }
Re:Portable Cloud Programming with Go Cloud by elithrar on Tuesday July 24, 2018 @12:56PM (#17602858)
> the third line is not really introducing a new variable, since err is still in scope... or is it?

The "if" block creates a new scope.

Re:Portable Cloud Programming with Go Cloud by ironjunkie on Tuesday July 24, 2018 @02:20PM (#17603668)
agreed that the := that can be used when one new var is introduced but not the others is extremely confusing.

I also hate the inconsistent behavior when you check multiple errors in a row, the first one will get := but not the second one (if you don't put those in a if statement, which I never do). But now if for some reason, you remove the first := statement, the code will error on the second one, that needs to be changed from = to :=

Re:Portable Cloud Programming with Go Cloud by sjellis on Wednesday July 25, 2018 @02:03AM (#17607166)
> It seems to be more about the person trying out the language than the language itself.

This is true, but Go does have a clean and mostly familiar syntax, by design: you can mostly follow along with a piece of Go code even if you haven't learned the language.

I think that what the OP is pointing at is a related issue: readability. This is explicitly a high-priority design goal for Go: lots of things in the language are designed so that developers can easily read and understand the code in the projects that they work on, and that memory use is never hidden.

Re:Portable Cloud Programming with Go Cloud by stouset on Wednesday July 25, 2018 @01:29PM (#17611077)
On the flip side, I personally find go extremely difficult to read.

First, repetitive error handling makes it overly tedious to actually get a quick intuition for what a function is doing. With Rust as a comparison, it’s extremely easy to see what the happy path is trying to accomplish without having the downsides of arbitrary and unexpected exceptions. Go is inarguably worse here.

Second, the inability to express higher-level concepts (due to, yes, lack of genetics) seems like it forces every function to deal with the nitty-gritty details of whatever it’s trying to accomplish, rather than being able to express ideas at a higher level and deal with the specifics in smaller code units. Yes, you don’t get “surprising” behavior, but the cost of this is that you’re forced to keep both the high level goals and the low level details in your head simultaneously, which I find to be a massive hindrance.

As sort of a side effect of both of these, there ends up being a ton of repetitive boilerplate. This actually hides bugs since it’s easy to miss minor differences between overly similar blocks of code dealing with errors or looping. As an example, languages like Rust and Ruby that have proper functional-style iterator methods prevent so many bugs through their inclusion it’s absolutely baffling to me how someone would opt to design a language today without such things.

Re:Portable Cloud Programming with Go Cloud by stcredzero on Tuesday July 24, 2018 @12:34PM (#17602617)
The problem with inconsistencies and surprises in languages, is that these are often the basis of conundrums that are more expensive to detect, figure out, and fix by a factor of 10X or more. I say this with appreciation and without irony: It turns out that "Blub" is actually a good thing, so long as it's done right.

All languages are going to suck, somewhere. The trick is to actually optimize a language for the difficult, expensive parts of development. Many languages seemingly optimize for writing things from scratch slickly. They're "blog example optimized." Instead, languages should be optimized for debugging, reading code, and deployment.

The fact that Go is not afraid of boilerplate is often actually a good thing. I've had to debug C++ in the confluence of 2 templates, such that there was no source code to display in the debugger. I don't expect to have this problem in Go, ever.

Re:Portable Cloud Programming with Go Cloud by nine_k on Tuesday July 24, 2018 @01:50PM (#17603396)
There's a fine balance here.

"You can't pay people enough to carefully debug boring boilerplate code. I've tried." (Yaron Minsky of Jane Street)

While C++ goes to one extreme, not having certain expressive means (whatever they may be) has a price, and for certain kinds of problems, this price may be high.

This returns to the idea I very much agree with: "The trick is to actually optimize a language for the difficult, expensive parts of development." The catch is that difficult parts are also problem area-dependent. Go definitely found a sweet spot for certain kinds of problems, though.

Re:Portable Cloud Programming with Go Cloud by stcredzero on Tuesday July 24, 2018 @02:08PM (#17603547)
"You can't pay people enough to carefully debug boring boilerplate code. I've tried." (Yaron Minsky of Jane Street)

There's boilerplate, and then there's boilerplate. If boilerplate is just a formality, with clean, competently designed underlying concepts, then it should be fine. Someone smart will build a code generator for that part of the project, you have your type safe-whatever and the project goes on its way. On the other hand, if your code base is just numb-nuts and people are just cut & pasting lava-flow code all over the place and rampantly putting business logic into ORM routines, then yes, that's going to impact hiring.

not having certain expressive means (whatever they may be) has a price, and for certain kinds of problems, this price may be high

This is also true. Even fairly innocuous boilerplate can build up to the point where refactoring can become tedious. There is no utopia, only constantly changing cost/benefit tradeoffs.

Re:Portable Cloud Programming with Go Cloud by pjmlp on Tuesday July 24, 2018 @02:04PM (#17603511)
Go is what Java 1.0 should have been.

Question is, how it will move beyond that, if ever.

Re:Portable Cloud Programming with Go Cloud by nine_k on Tuesday July 24, 2018 @03:00PM (#17603946)
Go the language now is indeed very similar to Java pre-1.5, but with a better OOP story, and a much better concurrency story.

I still think that JVM + JIT is hugely important, though. Now it's importance is somehow diminished by presence of LLVM, but 20 and even 10 years ago the situation with native compilation was different. (I know that the canonical Go compiler does not use LLVM.)

Re:Portable Cloud Programming with Go Cloud by pjmlp on Tuesday July 24, 2018 @03:58PM (#17604404)
Oberon, Eiffel and Common Lisp already had VM/JIT + AOT.

When Java came around, latest Oberon variant was Active Oberon (Active Objects are similar to goroutines), then we had Eiffel and Modula-3 as well.

Hence why I say it should have been Java 1.0.

Re:Portable Cloud Programming with Go Cloud by merb on Tuesday July 24, 2018 @03:26PM (#17604162)
and a much smaller heap.
Re:Portable Cloud Programming with Go Cloud by funny_falcon on Wednesday July 25, 2018 @07:57AM (#17608567)
Ironically, java 1.0 had green threads.
Re:Portable Cloud Programming with Go Cloud by untog on Tuesday July 24, 2018 @03:01PM (#17603952)
Go is certainly very easy to reckon with. But I was surprised at how little O cared for it when I tried it, given the hype I'd heard. The two things that immediately jumped out at me were error handling and generics. I understand both were deliberate choices but I'm still surprised they were made - I've been working with Swift a lot lately and it just feels like it makes so much more sense to me.

I do love how opinionated Go is, though. Every language should have a gofmt equivalent.

Re:Portable Cloud Programming with Go Cloud by cloverich on Tuesday July 24, 2018 @05:46PM (#17605223)
I feel like a caveman typing out error handling code in go, but on the other hand (even as a beginner in Go) I _never_ run into unexpected conditions. There's tradeoffs of course but every time I find myself thinking about what kinds of error conditions may be happening in my Node code (where I spend most of my time), and whether I covered them all... i think I'd trade.
Re:Portable Cloud Programming with Go Cloud by marcus_holmes on Tuesday July 24, 2018 @09:49PM (#17606364)
this. I'm writing a system in Go and Vue at the moment, and while there is a certain tedium to writing "if err != nil { " for the thousandth time, I'm happy that if an error occurs somewhere it's not going to get silently passed up the stack until it pops up somewhere totally out of context.
Re:Portable Cloud Programming with Go Cloud by herval on Wednesday July 25, 2018 @01:19AM (#17607057)
I keep shooting myself in the foot _the same way_, all the time - and it's incredibly easy to do so:

- not knowing if "Foo" being returned is a struct or an interface, so you're not sure if you should "if foo != nil" (it could not be nil if it's a struct)

- channels freezing (specially unbuffered ones). I still can't figure out how to debug those well.

- (the most common of all) spawning goroutines on a for loop, and all of them closuring over the same value (instead of one per item on the loop)

it's a surprising amount of sharp edges, for such a tiny language...

Re:Portable Cloud Programming with Go Cloud by gant on Wednesday July 25, 2018 @06:47AM (#17608269)
1. Get IDE support. There is no convention of adding a suffix like "Interface", and I personally am very happy with this. C# ISomething naming conventions have annoyed me quite a bit.

2. Always limit the scope of your channels. I like using unidirectional channels with structs that have more unidirectional channels. (For instance, a chan of workRequest{workData, returnChan} where return chan only receives responses for this request and is closed when no values are left)

3. I think you've been treated to well by JS closures, always hand over arguments you're going to use in the goroutine, this also allows the CG to clean up the stack of the function that started the closure goroutine.

Re:Portable Cloud Programming with Go Cloud by herval on Wednesday July 25, 2018 @10:28AM (#17609498)
1. Naming conventions don’t solve syntax warts. Modern languages solve this as part of their null safety (eg optional monads or the ? on kotlin and swift)

2. Yes, I know how to “properly” do it. Does not eliminate human error.

3. Closures in any other language, afaik. I rarely code in Js, fyi

Re:Portable Cloud Programming with Go Cloud by gant on Wednesday July 25, 2018 @03:37PM (#17612123)
Regarding 1, I (and seemingly everyone else writing libraries) usually return (value, error) and treat a nil value as error. We have quite a bit of old code at work that might segfault because it wasn't done like this.

Most of our Kubernetes code looks something like this

    _, err := clientInterface.Update(object)
    if err != nil {
      if machinery_errors.IsNotFound(err) {
        //handle nil case
      } else
        // handle unexpected case
      }
    }
Re:Portable Cloud Programming with Go Cloud by symlock on Tuesday July 24, 2018 @04:10PM (#17604493)
Yes, gofmt is a wonderful since so many other languages can have very different way of writing code leading to harder-than-necessary digestion of new libs or projects.
Re:Portable Cloud Programming with Go Cloud by pkaye on Tuesday July 24, 2018 @12:26PM (#17602542)
Our company uses Go. Most people who join have no experience in Go yet usually they can get comfortable with the language in 1-2 weeks to start contributing. I know nothing about Node/JS but I'm sure that takes much longer?
Re:Portable Cloud Programming with Go Cloud by stcredzero on Tuesday July 24, 2018 @04:32PM (#17604660)
Most people who join have no experience in Go yet usually they can get comfortable with the language in 1-2 weeks to start contributing.

A lot of what makes anything hard to learn are the non-obvious gotchas. The design philosophy of golang is aimed at avoiding the non-obvious gotchas and the creep-up-on-you-at-scale gotchas.

Re:Portable Cloud Programming with Go Cloud by solipsism on Tuesday July 24, 2018 @06:50PM (#17605566)
Except channels. If you use channels it's non-obvious gotchas galore.
Re:Portable Cloud Programming with Go Cloud by stcredzero on Tuesday July 24, 2018 @06:56PM (#17605598)
Concurrency is hard. Channels make it somewhat easier. Basically, see if you can do concurrency with only synchronous code.
Re:Portable Cloud Programming with Go Cloud by solipsism on Tuesday July 24, 2018 @07:09PM (#17605651)
Concurrency is hard and channels make it somewhat easier. Agreed. That's not relevant to the fact that the use of channels in Go is full of gotchas.
Re:Portable Cloud Programming with Go Cloud by stcredzero on Tuesday July 24, 2018 @07:31PM (#17605766)
That's relevant to the fact that concurrency is full of gotchas. I also used Go to write an MMO all by myself. I think channels are great!
Re:Portable Cloud Programming with Go Cloud by eudoxus on Tuesday July 24, 2018 @07:38PM (#17605804)
I think his point was that concurrency is riddled with gotchas regardless, and channels reduce them, but not remove them.
Re:Portable Cloud Programming with Go Cloud by stcredzero on Thursday July 26, 2018 @12:16PM (#17618606)
People completely misread my comment about doing concurrency with only synchronous code. Basically, channels let you do concurrency with only synchronous code as in Node JS, but without using callbacks.
Re:Portable Cloud Programming with Go Cloud by aphexairlines on Wednesday July 25, 2018 @03:20AM (#17607447)
1-2 weeks is standard for all languages though. A week or less is how long it usually takes people at work to pick up Objective C and contribute to iOS development, or pick up Scala and contribute to service development.
Re:Portable Cloud Programming with Go Cloud by nostalgeek on Tuesday July 24, 2018 @02:01PM (#17603492)
> but I'm sure that takes much longer?

Your people can pick up go reflect package or go routines/channels and co in 1-2 weeks and start contributing? impressive... most people can pick up for loops, if,switch statements, variable and function declaration in a week in any language as well...

In fact, a lot of non programmers use JS regularly to write scripts in the browser. I imagine your people know how to program before hand... So what do you think takes longer to learn? mastering go threading model or being able to add interactivity to the DOM?

Re:Portable Cloud Programming with Go Cloud by pkaye on Tuesday July 24, 2018 @03:29PM (#17604181)
> So what do you think takes longer to learn? mastering go threading model or being able to add interactivity to the DOM?

For me, the go threading model is easier. I just can't stand DOM and web programming in general. Currently working on a problem doing some computation across dozens of cores on multiple servers and go makes it a lot easier to spawn the 1000 goroutines and coordinate between them. I guess everyone has different interests and perhaps it is similar for those we hire.

Re:Portable Cloud Programming with Go Cloud by nostalgeek on Thursday July 26, 2018 @06:17AM (#17616312)
> For me, the go threading model is easier. I just can't stand DOM and web programming in general.

Because you didn't take the time to learn the DOM, that's all. I doubt learning a simple composite API made of dumb nodes is more difficult than writing thread safe programs in Go. I'm not talking about tastes or interests, I'm talking about ease of learning.

Go isn't 'easy to pick up'. For loops, if statements and co are basic, and they are in all languages, that's my point. There is nothing particularly easy with Go.

Re:Portable Cloud Programming with Go Cloud by golangnews on Tuesday July 24, 2018 @02:43PM (#17603827)
go reflect is not commonly used, goroutines are pretty simple to pick up. I have used several large codebases with zero use of reflection. The point of go is it restricts you to 25 keywords (the basics that you sneer at above) so senior people can't get fancy and produce an impenetrable mess/marvel that beginners will take months to orient themselves in.

It is definitely easier to write well than js IMO, and harder to make a big ball of mud in.

Re:Portable Cloud Programming with Go Cloud by outworlder on Tuesday July 24, 2018 @02:59PM (#17603941)
It is so consistent and unsurprising to the point of being boring. Which is a quality I have never thought I would appreciate, but if I am at work I do. It's very utilitarian.

I'll take Scheme for a spin if I am doing something for fun.

EDIT: %s/bored/boring/g

Re:Portable Cloud Programming with Go Cloud by pmontra on Tuesday July 24, 2018 @12:48PM (#17602768)
For me the big surprise is that we still have languages where we have to write things like

  func setupBucket(ctx context.Context) (*blob.Bucket, error) {
      sess, err := session.NewSession(&aws.Config{
          Region: aws.String("us-east-2"),
      })
full of ( ) { } * and & as if we were still in the 80s. So Go is a very surprising language, but this is highly subjective. No hard feelings.
Re:Portable Cloud Programming with Go Cloud by robbrit on Tuesday July 24, 2018 @01:21PM (#17603107)
You're right, it is dependent on your perspective. Go is intended to be unsurprising to developers who want to just be able to look at code and have a good idea of what it does. Punctuation is very useful to get rid of ambiguity.

Contrast this with a language like Ruby which tries very hard to make punctuation optional, and often ends up with ambiguous cases where you aren't 100% certain how the interpreter will parse some code and so you end up throwing in all the punctuation anyway.

Re:Portable Cloud Programming with Go Cloud by tapirl on Tuesday July 24, 2018 @01:03PM (#17602931)
Most popular languages are full of (). Most popular languages are full of {}, except python. All C family languages are full of *.

I can't see any surprises here.

Re:Portable Cloud Programming with Go Cloud by didip on Tuesday July 24, 2018 @12:52PM (#17602803)
For a statically typed language, the number of sigils Go have is surprisingly low.
Re:Portable Cloud Programming with Go Cloud by notdang on Tuesday July 24, 2018 @01:47PM (#17603370)
I prefer it like this instead of relying on indentation
Re:Portable Cloud Programming with Go Cloud by paulddraper on Tuesday July 24, 2018 @12:44PM (#17602737)
> unsurprising language

---

This is a valid Go program.

    import "fmt";

    func main() {
        fmt.Println("Hello world")
    }
This is an invalid Go program.

    import "fmt";

    func main() {
        // fmt.Println("Hello world")
    }
Surprising.

---

Creating typed general-use data structures is impossible.

Surprising.

Re:Portable Cloud Programming with Go Cloud by tree_of_item on Tuesday July 24, 2018 @12:47PM (#17602758)
Nope, you have to use imports. It's a little annoying but not "surprising" since the language shoves it in your face right away.
Re:Portable Cloud Programming with Go Cloud by paulddraper on Tuesday July 24, 2018 @12:50PM (#17602786)
You're correct. I was in no way surprised by this language feature, and neither were any of my coworkers.

Go is a thoroughly "unsurprising" language.

Re:Portable Cloud Programming with Go Cloud by erik_seaberg on Tuesday July 24, 2018 @03:41PM (#17604262)
A fatal error that prevents deployment is a lot more surprising than a warning.
Re:Portable Cloud Programming with Go Cloud by bschwindHN on Tuesday July 24, 2018 @08:35PM (#17606064)
You shouldn't even be at the point of attempting a deploy if your code doesn't compile.
Re:Portable Cloud Programming with Go Cloud by 0xdeadbeefbabe on Tuesday July 24, 2018 @01:18PM (#17603085)
Rave about porting cat to go and we'll restore your karma.
Re:Portable Cloud Programming with Go Cloud by paulddraper on Tuesday July 24, 2018 @01:30PM (#17603198)
Maybe I should also blog about how I was able to keep the size increase under 50x.
Re:Portable Cloud Programming with Go Cloud by tapirl on Tuesday July 24, 2018 @01:05PM (#17602944)
neither of your example is a valid Go program.
Re:Portable Cloud Programming with Go Cloud by paulddraper on Tuesday July 24, 2018 @01:29PM (#17603185)
Ha, fair enough ;) Fixed
Re:Portable Cloud Programming with Go Cloud by sagichmal on Tuesday July 24, 2018 @11:19PM (#17606689)
They are both still non-compilable.