Earlier quoted context omitted.
fn main() { let x = 1; let x = "foo"; } Does this make rust not strongly typed? Here's a Rust program with no types in the source code. It seems the issue you're objecting to is that python doesn't differentiate variable declaration from assignment (The fact we need let twice in this code is a result of Rust doing this). Which is a fair thing to complain about (and why Python had the "nonlocal" and "global" keywords)…
That's not an identical translation, the identical Rust would be fn main() { let mut x = 1; x = "foo"; } which indeed fails to compile with a type error. (That being said there is a conflation of static/dynamic and weak/strong going on in this thread, as there always is in these kinds of discussions.)
I Want Off Mr. Golang's Wild Ride
371–380 of 508 posts
Re: I Want Off Mr. Golang's Wild Ride
#372Earlier quoted context omitted.
This. I like, and agree, with the conclusion, and wish more people would get to it: > Over and over, Go is a victim of its own mantra - “simplicity”. (...) > It constantly lies about how complicated real-world systems are, and optimize for the 90% case, ignoring correctness. > This fake “simplicity” runs deep in the Go ecosystem. I've always liked simplicity and on my own design, I tend to go for abstraction; trying…
A post about fixing Date in JavaScript got me thinking about why it took so long for languages to get good date/time APIs. I think it's because it took so long to accept that date and time really is complicated. If you sit down and work it out carefully, you end up with Joda-Time (more or less - not in all the details, but in the set of abstractions). If you balk at that and make something simpler, you make a subtly…
Re: I Want Off Mr. Golang's Wild Ride
#373Earlier quoted context omitted.
No, because anyone can use `unsafe` in Rust. GP’s point was that Go can use the feature internally but no end-user can.
That sounds more like a legal argument than an engineering one. I mean, who cares what the mechanisms are and what the precise rules and enforcement mechanisms are? The point is there are complicated features that are OK in some contexts but not others, that this varies between problems and between languages, and that some parties make different decisions on how to make use of them even when implementing software for…
Re: I Want Off Mr. Golang's Wild Ride
#374The 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.
It’s a pretty recent language to the production ecosystem. Is it any different than Java or Python 20 years ago? How much of this is “wrong” given the relativeness of wrong when it comes to what is effectively how to organize a syntax construct hierarchy? You can find the same ranting all over about C, Python, etc Oh look computer people got an opinion on the organization of computer stuff. Shock, awe
Re: I Want Off Mr. Golang's Wild Ride
#375Here's an example of why Go's simplicity is complicated: Say I want to take a uuid.UUID [1] and use it as my id type for some database structs. At first, I just use naked UUIDs as the struct field types, but as my project grows, I find that it would be nice to give them all unique types to both avoid mixups and to make all my query functions clearer as to which id they are using. type DogId uuid.UUID type CatId uuid.…
Re: I Want Off Mr. Golang's Wild Ride
#376Earlier quoted context omitted.
The author of Joda-Time actually thinks that even Joda-Time didn't get it quite right, and believes the java.time libraries in Java 8 and above (aka JSR-310[1]) are better than Joda-Time: https://blog.joda.org/2009/11/why-jsr-310-isn-joda-time_4941... It turns out that abstractions for time are really hard to get right. [1] https://jcp.org/en/jsr/detail?id=310
Date & Time need to be baked into the operating system so it only has to be gotten right once, and then every programming system benefits.
Re: I Want Off Mr. Golang's Wild Ride
#377Earlier quoted context omitted.
That said… I feel that Rust’s use of WTF-8 for OsString on Windows has resulted in some really nasty problems, especially since OsString doesn’t expose any useful methods for string manipulation. As far as I can tell, Rust’s approach fails to hide any of the complexity, and then adds the additional complexity of a new encoding and conversions on top. I can see that there’s some end goal of being able to work with OsS…
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.
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".
Re: I Want Off Mr. Golang's Wild Ride
#378Earlier quoted context omitted.
Agreed, the author’s main argument is summarized nicely at the end, and it’s a good one: > It constantly takes power away from its users, reserving it for itself. > It constantly lies about how complicated real-world systems are, and optimize for the 90% case, ignoring correctness. > It is a minefield of subtle gotchas that have very real implications - everything looks simple on the surface, but nothing is. “Our use…
That's indicative of a serious attitude problem - I am so smart and can handle the power but you can't. Contrast this with C where everybody is on equal footing. Thanks for posting. This tells me everything I need to know to not get on Mr. Golang's Wild Ride.
I don't think we've seen the likes of this since PHP.
Re: I Want Off Mr. Golang's Wild Ride
#379Earlier quoted context omitted.
That's an issue of scoping, not capturing. The x in the lambda isn't scoped to the lambda, it's scoped to the surrounding environment. So the x closes not over the lambda but the outer scope. So it's as expected given shadowing. Edit: Since I'm getting throttled: No, I'm saying that scoping rules are different in python and rust. In Rust (and cpp) there's the concept of scopes/closures as a first class feature. This…
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…
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 main() {
let x = vec![0,1,2]
x.push(3) // fails since x isn't mutable
}
There's no clear direct related concept here by default. If we're allowed to use pytype, you get this: def main():
x: Sequence[int] = [1,2,3] # Sequences aren't mutable
x.push(3) # fails since x isn't mutable
Cool, so mutable and immutable values are possible in both langs. What about refs? Well we went through that one, if you pass a mutable ref to a function in rust, you can modify the ref in ways that just aren't possible in python: fn main() {
println!("Hello, world!");
let mut x: i32 = 3;
modifies(&mut x);
println!("{}", x);
}
fn modifies(x: &mut i32) {
*x = 5;
}
There's nothing analogous to this in python. Everything is always passed as a mutable "value"[1], nothing is passed as a ref.Cool so that's mutable variables and mutable references. That leaves this weird scoping issue. In rust (and in cpp) there's lots of scopes. Any set of braces creates a new scope, and so shadowing can happen across scopes. Lambda capture/closure happens over the scope. A given scope binds a name to a value, or a set of names to their values.
Python's a bit different, only new names are created in the scope. If a name isn't accessible in the given scope, the name is pulled from parent scopes etc.
So for the capturing behavior you want, there's weird nonlocal stuff that needs to be done, or you can explicitly make an additional scope, which removes the wonky behavior. If the name were really mutable, you'd be able to change what x referred to in the enclosing scope, which you can't.
tl;dr: This isn't mutable names, its python's (admittedly abnormal) scoping rules.
[1]: Unless you add in mypy or whatnot, where the typechecker will prevent you from modifying something that is non-mutable, but unlike in rust this isn't done with mutability as a first class citizen, its just that some interfaces expose mutating methods (`append`) and some don't. You can pass a list to a function that expects a list or a sequence, and the first case is mutable, while the second isn't.
Re: I Want Off Mr. Golang's Wild Ride
#380Earlier quoted context omitted.
I agree that the standard library database tooling is really clumsy in a lot of cases, but it's the library implementation at fault, not Go itself. Notably, contrary to your last sentence, you aren't troubling yourself with "weird Go semantics", you're troubling yourself with the semantics of the database stdlib.
Is there a database library that uses reflection that properly descends into type aliases? Probably not, because it isn't always what you want. It's still fundamentally caused by Go's shitty design choices. encoding/json is at fault as well, which is also in the stdlib and a flagship library (basically part of the language - the maintainers wouldn't even extend its struct tag parsing to allow for required fields it's…
The database package uses a type assertions to find the methods, not reflection.
Go types have one level of underlying type, not multiple levels as you seem to be assuming. Go is simplistic compared to other languages in this regard.
A type definition defines a new type using the underlying type of some other type.
I can understand the complaint that Go does not have the aliasing feature that you want, but the database/sql and encoding/json packages work exactly as expected given Go's simple model.