Live data from Hacker News

I Want Off Mr. Golang's Wild Ride

fasterthanli.me

391–400 of 508 posts

Re: I Want Off Mr. Golang's Wild Ride

#391
post #156

If somehow we had a way of checking Golang's source and submit our desired changes...

I seriously hate this argument. Go and have a look at the issue the golang is discussing currently. Do you seriously think that everything can be fixed by a simple request? Most of the time it wouldn't fit with the way Golang is going. It's not a critique of some bugs in Golang source code but the mentality and flow surrounding changes. Do you except the author that submitted change overhauling the whole way Golang h…

Obviously what I mentioned is just an oversimplification. I expect that when some particular piece of software (open source in this case) is causing major trouble to a big chunk of its users, they get together to fix it.

In the particular case of this user, some of the problems are are really related so I can imagine that if they were widespread it would´ve been taken care of.

I am sorry for using sarcasm to take a detour from my real point and I was just making some light-hearted fun about op's problem.

Re: I Want Off Mr. Golang's Wild Ride

#392
post #190

Earlier quoted context omitted.

And the other one is the tendency for Go's design to say "exceptions are allowed for me but not for thee". When I worked at Google I used other languages by some of the same authors and they showed the same design philosophy. Make things with an enforced simplicity, and where there were more special use cases that the language designer needed, they created escape hatches for themselves but not the language users.

And the other one is the tendency for Go's design to say "exceptions are allowed for me but not for thee". Yes. Exceptions are kind of a pain, but the workarounds for not having them are worse. Passing back "result" types tends to lose the details of the problem before they are handled. Rust is on, what, their third error handling framework? Exceptions have a bad reputation because C++ and Java botched them. You need…

GP wasn't referring to those types of exceptions. They were referring to the golang authors making escape hatches for themselves which aren't available to end users.

Re: I Want Off Mr. Golang's Wild Ride

#393
post #377

Earlier quoted context omitted.

Rust still doesn't get this right. If I'm calling an NFS library, say, on Windows I need to use UNIX paths. Rust needs WindowsString and UnixString on every platform, with OsString as a synonym for whichever is most useful locally.

In that case... You wouldn't be using the rust file system libraries though, right? It seems like the simplest definition of an OsString is "the type used to interact with the OS file system API as implemented in rust".

Rust has a policy of keeping the standard library minimal and this is completely reasonable. But sometimes they overdo it. In this case it's nuts that I need to implement my own UnixString because the standard library doesn't expose it, and when I run on Linux I have two incompatible versions of the same thing.

Another example: I wrote a command line app which takes a hostname/ip address plus an optional port number after a colon. And the whole thing's async using tokio. The way the hostname/IP address parsing is structured in tokio and the standard library meant I had to reimplement all of it to add the port number. This all feels like more effort than it should be.

Re: I Want Off Mr. Golang's Wild Ride

#394

Earlier quoted context omitted.

No, Python is not strongly typed by any serious definition of the concept.

Isn't the existence of TypeError and the various things you're not allowed to do implicitly (eg: 1 + "a", something Javascript will happily let you do) a definition of strongly typed?

Javascript has type errors too, and Java will let you 'add' a string to an integer, so it's more nuanced than that...

Javascript:

    > null.bob()
    
    TypeError: Cannot read property 'bob' of null

    > 4 >>> Symbol("four")
    
    TypeError: Cannot convert a Symbol value to a number

    > BigInt(null)
    
    TypeError: Cannot convert null to a BigInt

    > Object.create(false)
   
    TypeError: Object prototype may only be an Object or null: false
Java:

    int anInteger = 10;
    String s = anInteger + "Hello";

Re: I Want Off Mr. Golang's Wild Ride

#395
post #377

Earlier quoted context omitted.

In that case... You wouldn't be using the rust file system libraries though, right? It seems like the simplest definition of an OsString is "the type used to interact with the OS file system API as implemented in rust".

Rust has a policy of keeping the standard library minimal and this is completely reasonable. But sometimes they overdo it. In this case it's nuts that I need to implement my own UnixString because the standard library doesn't expose it, and when I run on Linux I have two incompatible versions of the same thing. Another example: I wrote a command line app which takes a hostname/ip address plus an optional port number…

[deleted]

Re: I Want Off Mr. Golang's Wild Ride

#396
post #44
post #22

The author spent a lot of time dwelling on Window's filesystems, at which point many of the readers got bored and started commenting. There are actually a couple of excellent points in here, the majority of which relate to Go's tendency to just be silently completely wrong in its behaviors from time to time, and is absolutely packed with hidden gotchas.

The problem is... and a lot of people aren't going to like this, including the original author... a lot of those particular gotchas are there for a reason. The author overestimates how much of them are intrinsic to the language, in my opinion. This is a cross-platform file interface, and we've had those for years. What we tend to discover is that if you do write something precisely correct on each platform, you lose…

>It's not the kind of library that Go wants as its standard library. It's a perfectly sensible sort of library. It just isn't what is desired in the standard library. "What is desirable in the standard library" is a very exclusive list.

This sounds like a reasonable argument if your language is, say, Julia, or something like Lua, where in the first case you probably don't write code that needs to do a lot of work at the OS/network/hardware level, i.e. systems programming, and in the second case, the language has a good built in FFI that lets you drop down into C or a similar language to do systems programming. Python, Clojure and Ruby fit more-or-less into the second case. C simply forces you to do all of the work yourself.

But Go's FFI (cgo) is a constant source of consternation, and while Go's authors admit it might not be suitable for "the largest" codebases, the hostility of Go to good FFI makes it more uncomfortable to use in practice. The official viewpoint is something to the effect of "most people shouldn't need cgo". The result has been a proliferation of libraries that attempt to do systems programming in Go, which includes in particular the "monotime" debacle highlighted by the author.

Remember: this blog post highlighted this weirdness in a real library used to solve a real problem. The idea that Go isn't meant to be used for that is belied by the fact that many, many people do try to use Go for that.

So yes, if Go had a more "difficult" file library, it would be less consistent with the "simplicity" idea used to advertise the language, but it might be more consistent with the way that Go is used in practice.

Re: I Want Off Mr. Golang's Wild Ride

#397
post #190

Earlier quoted context omitted.

And the other one is the tendency for Go's design to say "exceptions are allowed for me but not for thee". When I worked at Google I used other languages by some of the same authors and they showed the same design philosophy. Make things with an enforced simplicity, and where there were more special use cases that the language designer needed, they created escape hatches for themselves but not the language users.

And the other one is the tendency for Go's design to say "exceptions are allowed for me but not for thee". Yes. Exceptions are kind of a pain, but the workarounds for not having them are worse. Passing back "result" types tends to lose the details of the problem before they are handled. Rust is on, what, their third error handling framework? Exceptions have a bad reputation because C++ and Java botched them. You need…

btilly really walked into that one[0], but they meant "exceptions to the rules of the language", not "un-/anti-structured stack and/or control-flow fuckery". Most famously the lack of generics, except for anything the standard library wanted to use generics for.

0: "special cases are allowed for me but not for thee" would have been better but, y'know, hindsight.

Re: I Want Off Mr. Golang's Wild Ride

#398
post #292

Earlier quoted context omitted.

It's not surprising that other pieces of golang have incredibly broken assumptions, I know this particular one was discovered independently by many people: https://github.com/golang/go/blob/71ab9fa312f8266379dbb358b9... https://marcan.st/2017/12/debugging-an-evil-go-runtime-bug/

I don't think this example justifies the expression "incredibly broken assumptions", I would rather call it an "incredible corner case"...

Making assumptions about the stack frame size of third-party code is incredibly broken. You have no way to make any guarantees about it and primitives like alloca mean you can't even be sure the stack size will be the same across multiple calls.

Re: I Want Off Mr. Golang's Wild Ride

#399
post #319

Earlier quoted context omitted.

Setting aside any terminology for a second, consider this rust program: fn main() { let x = 1; let capture = || x; let x = 2; println!("{}", capture()); println!("{}", x) } This will print 1 and then 2, whereas python would print 2 and 2. Hence, you can see that the formulation "let mut" is equivalent to python, not "let" followed by "let". Here's the rust program that prints 2 and 2: fn main() { let mut x = 1; let p…

Actually hmm, I may want to take back my earlier comment. There are multiple things at play. There's scoping (where rust will copy across scope boundaries for non-ref types, which allows closing over something as in your first example above). Then there's mutable refs and mutable variables, which as hope-striker mentioned I was confusing, possibly because I was using ints in my example. If instead we used a vec: fn m…

Python's scope & mutability rules are idiosyncratic, but that's a distraction from what's going on here.

Let's go back to steveklabnik's ancestor comment:

"That's not an identical translation, the identical Rust would be:"

    fn main() {
       let mut x = 1;
       x = "foo";
    }
He was saying the identical Rust would not be:

    fn main() {
       let x = 1;
       let x = "foo";
    }
These are being compared to the following Python:

    x = 1
    x = "foo"
So consider these slightly enhanced versions of the fundamental question posed above.

Python:

  def mystery_py():
    x = 1
    capture = lambda: x
    x = 2
    return x * capture()
Rust:

  fn mystery_a() -> i32 {
     let x = 1;
     let ptr = &x as *const i32;
     let capture = || unsafe{ *ptr };
     let x = 2;
     return x * capture();
  }
  
  fn mystery_b() -> i32 {
    let mut x = 1;
    let ptr = &x as *const i32;
    let capture = || unsafe{ *ptr };
    x = 2;
    return x * capture();
  }

If you compare return values, you will find that mystery_py() returns the same as mystery_b().

So! I think you must agree that steveklabnik was right -- the rust code that is equivalent to the python code is the "let mut" variant. (Because surely you would not argue code that returns a different value is equivalent?!)

So now the question is, why?

Rather than answer, I will trollishly pose 2.5 more questions:

What would an implementation of mystery_a and mystery_b look like in scheme?

Would it be possible to author mystery_b in scheme if your "!" key was broken? (How about in some other purely functional language?)

Re: I Want Off Mr. Golang's Wild Ride

#400
post #22

The author spent a lot of time dwelling on Window's filesystems, at which point many of the readers got bored and started commenting. There are actually a couple of excellent points in here, the majority of which relate to Go's tendency to just be silently completely wrong in its behaviors from time to time, and is absolutely packed with hidden gotchas.

Not disagreeing. While some readers got bored (understood), others got more interested at the detail to which this was being taken and enjoying the care of discussion.

I’ve never programmed in Go from a vague sense of these issues. Hey, it confirms my uninformed biases!

Post reply on HN