Live data from Hacker News

Go Replaces Interface{} with 'Any'

github.com

401–410 of 481 posts

Re: Go Replaces Interface{} with 'Any'

#402
post #325

Earlier quoted context omitted.

Why don't you list the languages that you have used? Otherwise there isn't really any new information. For example for, having done Java, Scala, Python, Groovy, Haskell, Typescript and a couple others, Go reads extremely horrible. It feels as bad as enterprisey Java to me.

I’ve used all those languages. It’s far easier to make sense of a non trivial go code base I’ve never seen before than any of those.

It's far easier for you. It definitely isn't for me or in general. Thank you for answering the list of languages though. Makes me wonder what the concrete points are for, since I really have a different opinion. Maybe our minds just work very different; :)

Re: Go Replaces Interface{} with 'Any'

#403

Earlier quoted context omitted.

Why don't you list the languages that you have used? Otherwise there isn't really any new information. For example for, having done Java, Scala, Python, Groovy, Haskell, Typescript and a couple others, Go reads extremely horrible. It feels as bad as enterprisey Java to me.

I've used all of those and more and spent a decade deep in the purely functional Scala/Haskell camp. Diving into a moderate or large Go code base is always far easier for me even though I've used Go much less than the others. Before I even knew Go I would often look at various algorithms in Go just because it was so easy to understand exactly what was happening.

For algorithms, this might indeed be different. Not only are algorithms usually small and very focussed snippets, the emphasis is on performance and hence mutability, language primitives and shortcuts are common.

I can definitely see that languages like python or go beat pure functional languages in that regard.

For business logic and glue code (which in my field is the vast amount of code) I think it is the opposite though.

Re: Go Replaces Interface{} with 'Any'

#404

Earlier quoted context omitted.

Why don't you list the languages that you have used? Otherwise there isn't really any new information. For example for, having done Java, Scala, Python, Groovy, Haskell, Typescript and a couple others, Go reads extremely horrible. It feels as bad as enterprisey Java to me.

The readability of Go is intrinsically linked to the error handling in Go. If the spec started accepting "clever" rules to do with auto-magic return / assignment of error values instead of explicit handling, then the cognitive load of code review increases. If every error path is explicit, then the review becomes simple and self-explanatory (at least when it comes to error handling).

By that logic, assembly would be the most simple and self-explanatory language. I'm not sure if these two attributes are sufficient to determine how readable/productive a language is in the large.

Re: Go Replaces Interface{} with 'Any'

#405
post #393
post #192

Earlier quoted context omitted.

Nitpick, but I like to point out that Java’s exceptions are themselves a Result type/analog with them. You can unwrap it by a try catch, and can choose to rethrow it with minimal syntax. It even has a plus, it will auto-attach a stacktrace to the error case.

Not so much a nitpick because with checked exceptions your method signature can declare multiple types of exception whereas Result generalizes your specific exceptions to Throwable, which you can't pattern match with the compiler being able to enforce exhaustiveness. So to achieve the same exhaustiveness as a method like User createUser() throws IOException, BusinessException you would need both a Result-like constru…

checked exceptions don't integrate very well with streams and reactive pipelines, to the point that basically all of then end up being wrapped and rethrown as unchecked

methods that declare checked exception can throw RuntimeException(s) so exhaustiveness cannot be totally enforced anyway

Re: Go Replaces Interface{} with 'Any'

#406
post #62
post #32

This is fantastic. It'll make Go feel much less weird. eg from the diff: []interface{}{1, 2.0, "hi"} -> []any{1, 2.0, "hi"} Now that Go is going to have generics, all we need is sugar syntax for early return on error -- like more modern languages such as Rust and Zig have -- and Go may finally be pleasant to program in!

It's definitely more streamlined, but my concern would be that newcomers might not understand that it's just an alias. Learning Go really reframed my concept of what an interface is, and I thought that using an empty interface to represent "any type" was kind of ingenious, and helps reinforce its ethos. An empty interface can represent any type because every type inherently implements an interface with no methods. An…

I'm an experienced programmer whos just learning go now and I never made the connection that interface{} meant 'an interface with no methods'. I've always thought 'interface{}' was the clearest wart on the language. Languages shouldn't be about teaching me things, they are just a tool. Keyboard input goes in, computer instructions come out. any is easier to read, more intuitive in its meaning and takes less keyboard input.

Re: Go Replaces Interface{} with 'Any'

#407
post #39

Earlier quoted context omitted.

In semantic versioning, going from 1.X to 2.X is only indicated when there are incompatible API changes. Adding generics doesn’t break compatibility with preexisting Go code, so it’s unnecessary to increment the major version.

Sure, but semantic versioning really is the wrong kind of versioning to use for a language. The major version should represent major language changes, not whether its a breaking change or not, semantic versioning isn't somehow magically a "good" way to version. It's useful for libraries / dependencies where you are dealing with many different libraries and just want to know you can upgrade without having to deal with…

> Sure, but semantic versioning really is the wrong kind of versioning to use for a language. The major version should represent major language changes, not whether its a breaking change or not

Major language changes almost implies breaking changes, like Python 2 to 3 was major changes that break things everything from how modules were changed, where they were, and some syntactic and fundamental changes as well.

Re: Go Replaces Interface{} with 'Any'

#408

Earlier quoted context omitted.

This is equivalent to: let x = match may_fail_who_knows() { Ok(y) => Ok(another_computation_which_can_fail(use_value(x))), Err(e) => with_some_error_handling_that_can_rescue( some_error_processing(e)), }; match x { Ok(y) => y, _ => a_default_value, } It's a bit more verbose than using the combinators, but someone coming across it for the first time will understand it immediately because there's less to remember to un…

> This is equivalent to You just had to write the concrete types (Ok and Err) out. What if these types are changed later on, e.g. to "Some(...)" and "None" or "Ok" and "ManyErrs(...)"? As you said, it is easier to understand. Because it less abstract. This can be a good thing, but as well be a bad thing - but one thing is sure: while it does the same in the concrete case, the code is not "equivalent" when it comes to…

> the code is not "equivalent" when it comes to refactoring and certain changes.

Yes, there are a very specific and limited set of changes you could make to the types here and not have to change this code. You can't replace `Result` with `Option` because of `map_err`. You could replace `Result` with something else that is very `Result`y, but your flexibility would be very limited if you didn't want to change the signatures of `with_some_error_handling_that_can_rescue` or `some_error_processing`.

I'm sure it's possible to contrive an example where this would help, but I don't believe that it would be that much of a help very often in practice. I think it's just a bit more monady and people who take the time to learn monads then want to apply that wherever they can.

I'm not saying that the combinators should never be used, but that each additional one you use increases the cognitive burden of reading your code. So the question becomes: which of the combinators are worth it.

I would argue that `.map_err()` is useful as it compliments the `?` operator. Hopefully with (and often without) `try!` blocks many of the other ones can go away. In particular I think that language constructs are almost always better than `.and_then()`.

Re: Go Replaces Interface{} with 'Any'

#409
post #330

Earlier quoted context omitted.

> I don't agree. I usually don't care so much when a particular feature was introduced into a language I care very much when a feature was introduced into a language, because maintaining compatibility with earlier versions of the language determines what features may be used. If I'm working on a library that needs to be compatible with C++03, then that means avoiding smart pointers and rvalues. If I'm working on a li…

> In order to determine it for X > Y (new code on old compiler), you need to know when features were introduced. I think this is a deliberate reduction of dimensionality. Go says that you don't need to worry (for long) about this case, because the toolchain must be updated regularly - and promises that it will be as pain free as possible. This simplifies for the Go team, for library authors, and library users in most…

> Not saying this tradeoff is for everyone, and I've never used C++ professionally so I'm probably ignorant. But are you saying it's common with production projects that use a compiler from 2003 or earlier? What's the use case?

Let's start with the fact that newer doesn't mean better. With already deployed compiler you have tested it and know that it works good enough (code it generates, bugs you have workarounds for, etc). Where with new compiler you are on step one. You must do work again.

Or vendors just support particular version they have patched.

Or you are scared of GPL3.

Re: Go Replaces Interface{} with 'Any'

#410
post #39

Earlier quoted context omitted.

In semantic versioning, going from 1.X to 2.X is only indicated when there are incompatible API changes. Adding generics doesn’t break compatibility with preexisting Go code, so it’s unnecessary to increment the major version.

Sure, but semantic versioning really is the wrong kind of versioning to use for a language. The major version should represent major language changes, not whether its a breaking change or not, semantic versioning isn't somehow magically a "good" way to version. It's useful for libraries / dependencies where you are dealing with many different libraries and just want to know you can upgrade without having to deal with…

Ruby introduces new language features all the time in minor versions while maintaining backward compatibility. I can pretty much upgrade a minor Ruby version to get access to new language features without worrying about breaking anything.
Post reply on HN