[HN Gopher] Go Replaces Interface{} with 'Any'
       ___________________________________________________________________
        
       Go Replaces Interface{} with 'Any'
        
       Author : brosciencecode
       Score  : 305 points
       Date   : 2021-12-14 20:24 UTC (2 hours ago)
        
 (HTM) web link (github.com)
 (TXT) w3m dump (github.com)
        
       | [deleted]
        
       | rackjack wrote:
       | I'd really like it if Github handled massive commits like this
       | one better. The way they present it is not very pleasant to
       | navigate.
        
       | moth-fuzz wrote:
       | I'm not sure I like this change. I liked interface{} since it
       | just works out naturally from Go's relatively simple type system,
       | and anyone could come to the conclusion without actually being
       | told "use interface{} to represent any possible value" just by
       | having an understanding of that type system. Adding what is
       | simply a type alias, multiple words for the same underlying
       | concept, to me just feels like jargon. I admire Go for its
       | simplicity and clarity and this change gives me anxiety that that
       | will be obfuscated.
        
         | takeda wrote:
         | Isn't Any essentially:
         | 
         | type Any interface{}
         | 
         | ?
        
           | throwaway894345 wrote:
           | I'm pretty sure it's an alias, so: `type any = interface{}`.
           | 
           | `type any interface{}` would declare a new type, while an
           | alias is exactly another name for the same type.
        
           | [deleted]
        
           | erdaniels wrote:
           | It's a type alias so it's                   type any =
           | interface{}
           | 
           | That means they're interchangeable compared to defining a new
           | type.
        
           | Laremere wrote:
           | Close, it's:                   type Any = interface{}
           | 
           | That is, it's an alias and casting is not necessary.
        
         | eadmund wrote:
         | I agree with you right now, but I wonder if I will change my
         | mind after having had some experience using the new generics.
         | Maybe it will feel more natural then?
        
         | xh-dude wrote:
         | I don't think the concern is unreasonable at all but 'any'
         | feels pretty solid as far as I've had the chance to poke
         | around. There's some tensions where I think 'any' is arguably
         | much simpler:
         | 
         | The baseline is that constraints aren't best expressed as
         | interface literals in situ. Unlike exceptional use of
         | 'interface{}', 'any' will be a more naturally invoked
         | constraint.
         | 
         | Also, some of the uses of constraints rely on a unification
         | involving an 'any' term that cancels out. Here, the use of
         | 'interface{}' is not incorrect but maybe indirect.
        
       | arcanon wrote:
       | Ball is in your court now typescript-on-the-serverside ppl!
        
         | tills13 wrote:
         | I didn't realize there was a "war" going on between the two
         | groups.
         | 
         | If there is, I imagine it's not among the type of people who
         | you'd want leading technical decisions at your company.
        
           | friedman23 wrote:
           | There isn't. What I have noticed in the go community is a
           | rabid fandom and belief that golang is the pinnacle of
           | language design when in reality go is a language for people
           | that think memorizing a few syntactical rules is too
           | difficult. People used to rabidly defend the lack of generics
           | for example and look at where we are now.
           | 
           | And before people identify me as a TS fanboy, I'm not, I'm a
           | go hater.
        
         | jamespwilliams wrote:
         | I'm not a typescript person, but to be fair to typescript, its
         | type system is still much more expressive than Go's, even with
         | the generics addition
        
           | [deleted]
        
           | woah wrote:
           | Typescript is stricter and safer while also being less
           | obtrusive than Go
        
             | travisd wrote:
             | This isn't super clearcut. Typescript has lots of footguns
             | and famously says that soundness is _not_ one of their
             | driving factors. There are lots of ways to devolve to
             | accidental implicit any 's (even with the no implicit any
             | strict rule turned on).
             | 
             | Of course, Go makes zero attempt to enforce nullability
             | (nilability?) in its type system... so... win some, lose
             | some I guess.
        
             | Thaxll wrote:
             | Any language based on JS can't be safer than Go. The end
             | result of TS is JS which is a dynamic language.
        
               | jwandborg wrote:
               | The usual end result of Go is machine code, machine code
               | is not safe to the degree you would consider Go to be
               | safe.
        
               | friedman23 wrote:
               | Ok, so if Go compiled to JS it would be a dynamic
               | language?
               | 
               | https://github.com/gopherjs/gopherjs
        
               | fwip wrote:
               | That's absurd. If TS can't be secure because it compiles
               | to an unsafe language (JS), Go can't be secure because it
               | compiles to unsafe assembly.
        
         | carlhjerpe wrote:
         | I don't see how they're competing, TypeScript can still share
         | code between client and serverside, go "can't". They're not
         | exclusive to each other, routing "form submissions" though a ts
         | verification layer and then down to Go makes sense to me if you
         | need the Go performance but want to share things client and
         | server side.
         | 
         | Also, application servers are cheap, persistent, fast and
         | durable storage isn't, these won't be written in TS.
         | 
         | TL;DR: different problem domains, not important
        
       | AtNightWeCode wrote:
       | Like it! Now, can they continue to add more "useless"
       | improvements like while-loops and so on.
        
         | karmanyaahm wrote:
         | https://go.dev/tour/flowcontrol/3
         | 
         | for sum < 1000 { sum += sum }
        
         | jjice wrote:
         | Doesn't 'for' work as 'while' if you only give it a condition
         | in go? I haven't written much, so correct me if I'm wrong.
        
           | AtNightWeCode wrote:
           | Does not Interface{} work as well as Any? I mean, most
           | languages have while-statements cause it is more clear what
           | the intention is.
        
       | jamespwilliams wrote:
       | Loading this commit in safari almost killed my phone
        
         | jeffbee wrote:
         | The Gerrit view of the same commit transfers far less data than
         | the GitHub view. https://go-
         | review.googlesource.com/c/go/+/368254
        
         | saagarjha wrote:
         | Loaded just fine on my iPhone SE. I hope you're not using
         | anything older than that...
        
         | hu3 wrote:
         | Works fine for Firefox on a Pixel 6. Took a couple of seconds
         | to load then smooth (ginormous) scrolling was available.
         | 
         | Same for an old Android phone with outdated Snapdragon 660 I
         | use to test app performance bottlenecks. Except this one took 4
         | secs to load.
        
       | mseepgood wrote:
       | It's a type alias, introduced for generics. By the way, Go 1.18
       | Beta 1 is released (with generics):
       | https://groups.google.com/g/golang-announce/c/eAjK4Oezs_A
        
         | exdsq wrote:
         | How is generics not a big enough change to warrant 2.0?
         | 
         | Edit: I'm impressed generics aren't a breaking change! I
         | thought this changed Interface{} to Any as a breaking change
        
           | preseinger wrote:
           | It's not a breaking change.
        
           | mseepgood wrote:
           | They are backwards compatible and don't break people's code,
           | so it's 1.x.
        
           | philwelch wrote:
           | 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.
        
             | keithnz wrote:
             | 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 breaking changes. For a
             | language? Silliness. Your version is not really telling you
             | the main things you care about.
             | 
             | It's much much more useful to the users to say, 2.0
             | introduced generics, it's distinct. If it's like other
             | languages, generics changes the code people generate a lot,
             | libraries start looking significantly different. It's very
             | distinct, and if that is simply in version 1.18.0 or
             | whatever, that is super bad usability from a language
             | perspective.
        
               | robto wrote:
               | In Java people regularly refer to a particular JDK
               | version as a Java 17 or Java 11, even though they
               | actually refer to versions 1.17 and 1.11,
               | respectively[0]. In Clojure land they just say 1.x, even
               | when large new features are added.
               | 
               | I like this because it emphasizes the community's
               | commitment backwards compatibility, which I greatly
               | value. I've spent a good deal of time writing Javascript,
               | where library developers seem to have very little respect
               | for their users and constantly break backwards
               | compatibility. In ecosystems like that, upgrading fills
               | me with dread. When I see a library on version 4, I have
               | learned to keep looking - if they weren't thoughtful
               | enough about their API design for the first 3 major
               | releases, I shouldn't expect it to be much better going
               | forwards.
               | 
               | For an application, I'm pretty open to version numbers
               | signifying big features - Firefox and Chrome do this, and
               | it's helpful with marketing. But for a programming
               | language? A programming language is a tool, and when
               | upgrading you need to carefully read the changelog
               | anyways. A programming language is no different from a
               | library (in Clojure it literally is a library), and
               | backwards compatibility is /literally/ the main thing I
               | care about. Is my tool going to intrude on /my/ schedule,
               | and force me to make changes /it/ wants instead of being
               | able to spend my time making changes /I/ care about? I
               | want to know that.
               | 
               | [0]This is apparently an awful example as I've just
               | learned that Java is actually doing the major version
               | only thing. It still sort of works because the only
               | reason they can do that is because they Will Not Break
               | Compatiblity.
        
               | linkdd wrote:
               | > In Java people regularly refer to a particular JDK
               | version as a Java 17 or Java 11, even though they
               | actually refer to versions 1.17 and 1.8, respectively.
               | 
               | 17 -> 1.17, 11 -> 1.8, this is bothering me way to much
               | for no good reason.
        
               | danudey wrote:
               | Clarification:
               | 
               | * Java 8 is Java 1.8.0
               | 
               | * Java 11 is Java 11.0.11 (at the moment)
               | 
               | * Java 17 is Java 17.0.1 (at the moment)
               | 
               | SunOS/Solaris is what I use when I want to get nerd-rage
               | mad about minutae: https://en.wikipedia.org/wiki/Oracle_S
               | olaris#Version_history
        
               | post-it wrote:
               | I don't think 11 ever referred to 1.8 generally, but for
               | the longest time the `openjdk-11-*` packages in one of
               | the Ubuntu LTSes (18.04?) actually installed Java 8 for
               | some reason.
        
               | cortesoft wrote:
               | Wait, why wouldn't it matter for a language? I want to
               | know if I can compile my existing project with the new
               | version... isn't that an important thing to know?
        
               | 13415 wrote:
               | It makes no sense to replace a meaningful and helpful
               | criterion - whether it breaks code or not - by some
               | purely subjective assessment of what's a "major change."
               | That just leads to usual version creep, from "Go 2.2" to
               | "Go 3.0", to "Go 4.0", to (inevitable) "Go 10", "Go 11",
               | "Go 11 Pro", "Go 11 Ultimate Edition",...
        
               | pawelmurias wrote:
               | > Can upgrade without having to deal with breaking
               | changes
               | 
               | This is actually very important. If something is a major
               | change or not is pretty subjective.
        
               | lanstin wrote:
               | Not really from my perspective. I want know if there is
               | any reason to not upgrade due to my existing code base
               | breaking. Extra new features I could use are not such a
               | reason. New reserved words are such a reason. If someone
               | is using a new feature, I can just say "make sure you
               | have the newest version, also here's my reason for
               | keeping close to the edge of current versions, so that
               | you amortize the labor of keeping up to date rather than
               | pinning and then having some big migration project in 5
               | years."
        
               | WastingMyTime89 wrote:
               | > The major version should represent major language
               | changes, not whether its a breaking change or not
               | 
               | Why?
               | 
               | Old code still work and unless you are purposefully
               | maintaining an old system you are expected to use the
               | last version anyway. What does it actually change that
               | generics were introduced in version 1.18 rather than 2.0?
               | From now on, Go has generics. As there is no breaking
               | change, it's not like you had to keep using the previous
               | version to opt out.
        
           | bastardoperator wrote:
           | See https://semver.org/ for more details. https://0ver.org/
           | is fairly popular, and I see https://calver.org/ pretty often
           | too.
        
             | ignoramous wrote:
             | _0ver_ is parody, right?
        
               | taywrobel wrote:
               | Yes - https://0ver.org/about.html
               | 
               | "ZeroVer is satire, please do not use it"
        
               | mseepgood wrote:
               | But why is it satire? It makes a lot of sense for
               | projects that don't want to commit to a stable API.
        
               | jonathankoren wrote:
               | Well there's a joke somewhere.
               | 
               | Less has my favorite version numbering system.
               | Sequential.
               | 
               | Latest stable release: Version 598
               | 
               | https://www.greenwoodsoftware.com/less/
        
               | Dylan16807 wrote:
               | "Tell the user nothing" is your favorite system?
               | 
               | Especially, like, what if you release a bugfix for a
               | significantly old version? Do you give it an up-to-date
               | number? Do you not give it a number at all?
               | 
               | (Also I see a 581.2 on that page.)
        
               | meowface wrote:
               | My favorite has become just making the version number the
               | release date.
        
               | ViViDboarder wrote:
               | See CalVer. The date is definitely helpful for something
               | with fairly stable APIs where breaking changes aren't
               | really happening.
               | 
               | Perfect for things like Ubuntu, pytz, and ca-
               | certificates.
               | 
               | Less for something like a library who's API could change
               | and break your implementation.
        
         | egeozcan wrote:
         | AFAICT, its usage is not restricted to generics. It seems to be
         | suggested to use anywhere you would use interface{}.
         | 
         | For the release announcement:
         | https://news.ycombinator.com/item?id=29556646
        
           | mseepgood wrote:
           | Yes, it's not restricted to generics. But the reason the
           | alias was introduced is generics. Because they use interfaces
           | to specify bounds (constraints) for type parameters (bounded
           | polymorphism): [T fmt.Stringer], [T io.Reader], ...
           | 
           | So an unbounded type parameter is [T interface{}], or [T any]
           | when using the shorter alias. It's a type alias / predeclared
           | identifier defined in the universe scope:
           | type any = interface{}
        
             | eweise wrote:
             | Couldn't unbounded just be [T]? Why the extra typing?
        
               | mseepgood wrote:
               | No, that would be a parsing ambiguity with arrays. And
               | the consistency of type parameter lists with normal
               | parameter lists where types are mandatory is an
               | additional benefit.
        
               | handrous wrote:
               | Makes it much less likely someone will accidentally
               | define a type as "any".
        
               | MadcapJake wrote:
               | I am not well-versed in Go, but isn't it because Go
               | supports specifying multiple parameters with the same
               | type by just using a comma. Your suggestion would lead to
               | syntactic ambiguity except when only a single parameter
               | is provided. Additionally one can provide only types when
               | parameter values are not needed and this requires there
               | to be a typename to differentiate between no parameters.
        
       | alkonaut wrote:
       | After generics (coming soon), a proper sum type and then I'll
       | shut up.
        
         | qaq wrote:
         | same :) maybe also relax rules a bit to allow type elision for
         | structs in function calls to get python like keyword args.
         | foo("blah", {option1: true}) would work better than functional
         | options people use now.
        
           | 13415 wrote:
           | I think they should freeze the language for the next 10 years
           | or so.
        
       | maxk42 wrote:
       | So now that go has generics and modules, is there an up-to-date
       | intro for writing cutting-edge Go code for people who are already
       | pretty familiar with the older styles?
        
         | vlunkr wrote:
         | While it's good to get up-to-date, I don't think anyone should
         | go re-write code or radically change their programming style to
         | use generics. There's no need to over-complicate things.
         | Anywhere that you're either copy-pasting a bunch, or using code
         | generation might be a good fit for generics.
        
           | jcadam wrote:
           | Just you try not being up-to-date in a coding interview.
        
             | saagarjha wrote:
             | I've found out that it's possible to be _too_ up-to-date
             | for some coding interviews.
        
               | aliswe wrote:
               | about 10 years ago I had a discussion with an interviewer
               | (he was actually consultant manager) who said "c# and
               | Java are exactly the same in terms of runtime
               | architecture" which I very much disagreed with when
               | speaking strictly, which wasn't appreciated.
        
               | dilyevsky wrote:
               | Lol so true, go a little overboard with fancy language
               | features and people think you're a cowboy coder
        
               | catillac wrote:
               | I was in an interview not long after format strings in
               | Python came out (for example, print(f"Hello, {name}")
               | rather than print("Hello, %s", name)) and the interviewer
               | thought I was confusing languages and features, asserted
               | this fact strongly, and was pretty surprised when it
               | worked, but I think overall I lost points because the
               | interviewer lost face.
               | 
               | C'est la vie.
        
               | vlunkr wrote:
               | As a very casual Python user, I didn't know about that!
               | that's great.
        
         | mseepgood wrote:
         | There is lots of tutorial-style documentation on modules:
         | https://go.dev/doc/#developing-modules
         | 
         | There is also a tutorial on generics:
         | https://go.dev/doc/tutorial/generics
        
           | maxk42 wrote:
           | I tried doing the modules tutorial a while back but had
           | difficulty with the directory structure. At some point I
           | think the "recommended" directory structure became mandatory
           | and I don't think my personal dev environment ever quite
           | lined-up with it. Perhaps I should wait another year then buy
           | a book.
        
             | mseepgood wrote:
             | Modules don't require any particular directory structure,
             | just a go.mod at the root of your project.
        
               | hamburglar wrote:
               | That's "a particular directory structure" that conflicts
               | with many already-existing projects. What if I have a
               | mostly-java project that has a couple bits of go code
               | buried in it that I want to use as modules? Break it up
               | into multiple repos for no good reason? No single tool
               | should be acting like it owns the root directory of my
               | repo.
        
               | mseepgood wrote:
               | The root of the Go project with the go.mod file doesn't
               | have to be the root of the repository.
        
               | hamburglar wrote:
               | Doesn't it? Is this new?
        
               | mseepgood wrote:
               | As far as I know this was always possible since modules
               | were introduced. You just have to prefix the version tags
               | for Go with the subdirectory in the repo:
               | "my/sub/directory/vX.Y.Z"
        
               | hamburglar wrote:
               | I swear it didn't always work this way, but I'm happy to
               | be wrong.
        
       | nkozyra wrote:
       | I like it, interface{} always felt unlike anything else in go
       | other than structs.
        
         | mseepgood wrote:
         | Why does 'interface{}' feel unlike 'interface{String() string}'
         | to you? Just because it doesn't have a method? You know that
         | you can inline non-empty interfaces, too?
         | func foo(x interface{String() string}) string {
         | return x.String()         }
        
           | nkozyra wrote:
           | I think you (and the other reply) are for some reason
           | confusing my complaint as functional rather than purely
           | syntactical.
        
         | throwaway894345 wrote:
         | `interface{}` is just an empty interface, and every type
         | implements `interface{}` because every type has at least zero
         | methods.
        
       | twsted wrote:
       | Right decision, in my opinion. I was hoping this.
        
       | kbd wrote:
       | 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!
        
         | nvarsj wrote:
         | Yes, please, the iferr pattern drives me nuts. While I built a
         | few years of my career on golang, I'm absolutely sick of the
         | language at this point. At least we finally get generics.
        
         | hbn wrote:
         | 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. And that's
         | what Go is all about -- implicitly implementing interfaces.
         | 
         | If a newbie hops into Go and just starts using "any" I think
         | they might assume it's a magic type that's at the base of
         | everything, missing out on the fact that they're still taking
         | advantage of interfaces.
        
           | egeozcan wrote:
           | I kind of understand what you mean, as it's similar to what
           | happened with prototypes and the late-comer class syntax in
           | JavaScript, and in that case, it was a net positive change as
           | most would probably say.
           | 
           | Let's see how this plays out.
        
         | linkdd wrote:
         | I cannot wait for the Result monad.
         | 
         | The state of error handling in Go at the moment is embarrassing
         | at best.
        
           | papito wrote:
           | People downvote it, but it's true. 2/3 of your Go code is `if
           | err` blocks. And the way you have to chain the error messages
           | to make the stack make any kind of sense is just maddening.
        
             | Vanclief wrote:
             | I used to really hate that. After reading this amazing post
             | https://middlemost.com/failure-is-your-domain I created a
             | module that makes this bearable
             | https://github.com/Vanclief/ez
        
           | the_duke wrote:
           | Emulating sum types in languages without pattern matching is
           | extremely awkward, to the point of being almost useless.
           | 
           | type Result[T] struct { ok: *T err: error }
           | 
           | Great, so how do you work with it?
           | 
           | * You can have a `ok()` getter that returns `*T`. Now you you
           | need an `if x != nil`
           | 
           | * `isOk()` + `isErr()`
           | 
           | * `unwrap() T`, which panics on errors
           | 
           | * `split() (*T, err)` that splits into separate values,
           | especially awkward since you both need `if err != nil` AND
           | dereference the pointer
           | 
           | That API is more awkward then the status quo, and doesn't buy
           | you any correctness guarantees because eventually you have to
           | do an `if x := res.ok(); x != nil` or `x, err := res.split();
           | if err != nil {` anyway.
           | 
           | Pretty much the only convenience you gain are functions like
           | `map()` or `unwrap_or`, but eventually you always have to
           | take out the value and without being able to pattern match
           | you can't get an API that improves correctness much.
           | 
           | (std::optional in C++ is a great example)
        
             | kbd wrote:
             | > because eventually you have to do...
             | 
             | Emphasis on _eventually_ instead of at every single
             | function call.
        
             | peoplefromibiza wrote:
             | you can map on ok which is an alias for map_ok and then
             | map_err for errors and or_else or_throw etc.
             | 
             | that's similar to what Java does with the Optional type,
             | not great, but not bad either
             | 
             | the alternative is checking for nulls which is worse in any
             | possibile way
             | 
             | I usually implement something like Kotlin Result when I
             | have to code in Java
             | 
             | with a couple of static helpers to build the result:
             | Result.success(T) Result.failure(Throwable t)
             | 
             | https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-result
             | /
             | 
             | also Result in Rust has been an inspiration
             | 
             | https://doc.rust-lang.org/std/result/enum.Result.html
        
             | linkdd wrote:
             | The Rust Result type has:                 - map / map_err
             | - and_then / or_else       - unwrap / unwrap_or
             | 
             | And countless of other functions making it very practical
             | to chain computations without having to pattern match
             | anything.
             | 
             | I do the same in Erlang/Elixir.
             | 
             | In Golang, I need to check every function call, and if I
             | want to know where an error come from, I need to wrap it in
             | an errors.New() because no exceptions = no stacktrace
        
               | kbd wrote:
               | > and if I want to know where an error come from, I need
               | to wrap it in an errors.New() because no exceptions = no
               | stacktrace
               | 
               | Zig manages to provide traces with very little overhead:
               | 
               | https://ziglang.org/documentation/master/#Error-Return-
               | Trace...
               | 
               | I am baffled as to why error handling in Go remains _so_
               | impoverished.
        
               | egeozcan wrote:
               | I don't see why that wouldn't be possible to implement
               | now that the generics are here.
        
               | linkdd wrote:
               | Which is exactly why I said:
               | 
               | > I cannot wait for the Result monad.
               | 
               | Generics make this possible, and will be a huge
               | improvement to Go's error handling.
               | 
               | I'm not saying it will solve everything, but it's a huge
               | step nonetheless.
        
           | Thaxll wrote:
           | Well it's better than most language with exceptions.
           | 
           | People makes it a big deal, in reality it's not.
        
             | linkdd wrote:
             | An exception has a stacktrace. This single piece of
             | information is crucial when you debug and makes handling
             | errors in Golang embarrassing.
             | 
             | I rest my case.
        
               | mseepgood wrote:
               | If you want stacktraces just panic. But that's not proper
               | error handling.
        
               | pkaye wrote:
               | Stack trace was part of a proposal to add to the error
               | package but it didn't happen. You can use third party
               | errors packages like https://github.com/pkg/errors which
               | wrap errors with stack traces.
        
       | baby wrote:
       | This is great, as much as interface{} is not great, it's still
       | part of the language and really verbose/non-descriptive. I'm
       | guessing any was a forbidden word?
        
         | shadowgovt wrote:
         | It wasn't so much that `any` was forbidden as that
         | `interface{}` practically meaning "any value" fell naturally
         | out of Go's existing type system rules, so there was no need to
         | introduce another concept.
         | 
         | But having `any` as syntactic sugar for that concept is a good
         | idea.
        
         | mseepgood wrote:
         | > I'm guessing any was a forbidden word?
         | 
         | You mean a reserved keyword? No, 'any' is not a keyword, it's
         | an identifier (a predeclared identifier). The usual shadowing
         | rules apply.
        
       | brabel wrote:
       | Their code is full of things like:                   type fileOps
       | []any // []T where T is (string | int64)
       | 
       | Go does not have neither generics nor union types. So people have
       | to do this kind of thing :( I feel sorry for them.
       | 
       | Reminds of Java 4 (15 years ago or something) where code was full
       | of this crap:                   List /* <String> */ values;
       | Map /* <String, Object> */ map;
       | 
       | Some devs spent a whole week doing nothing other than removing
       | those commented out generic type declarations once Java finally
       | got generics!
        
         | Thaxll wrote:
         | Go has generics in that commit.
        
         | qaq wrote:
         | 1.18 Beta is out today with Generics
        
         | mseepgood wrote:
         | You're lucky: Go 1.18 Beta 1 was released today, which has
         | generics.
        
           | mikojan wrote:
           | Craazzyyyyy - ty!
        
         | mappu wrote:
         | Go has had generic List<> and Map<> since before Go 1.0,
         | though.
         | 
         | It's really interesting you used those as your examples because
         | that need was fully met in a type-safe way already, and other
         | examples are actually much rarer to come by.
        
         | comeonseriously wrote:
         | > I feel sorry for them.
         | 
         | Oh good grief. There are 32,768 programming languages. People
         | are free to pick the ones they want to use and nobody wants
         | your pity.
        
           | jwandborg wrote:
           | Are we wasting that bit to spite us?
        
         | [deleted]
        
         | gameswithgo wrote:
         | You could have sum types, and not generics to cover many of
         | these cases I guess? And then Go could have the error type it
         | kind of wants to have.
        
         | amelius wrote:
         | > Some devs spent a whole week doing nothing other than
         | removing those commented out generic type declarations once
         | Java finally got generics!
         | 
         | Fast-forwarding to today, could Co-pilot have saved them the
         | trouble?
        
           | vlang1dot0 wrote:
           | I'm pretty sure sed could have saved them the trouble.
        
       | maxpert wrote:
       | I promised myself I will stay patient, but I think I am on
       | verge... It's everything I've dreamed off!
        
       | uberman wrote:
       | I love this change/alias
        
       | welder wrote:
       | Good, now we just need the ability to declare function parameters
       | and return values non-nullable (Forbid passing nil into a
       | function, and declare a function will never return nil).
       | 
       | That would get rid of the "panic: runtime error: invalid memory
       | address or nil pointer dereference" errors.
       | 
       | https://wakatime.com/blog/48-go-desperately-needs-nil-safe-t...
        
         | jchw wrote:
         | I'd kill for union types as well.
         | 
         | ... and pattern matching. Maybe just some extensions for
         | `switch`.
         | 
         | ... and one of the `try` proposals.
         | 
         | That having been said... I do appreciate that Go has gotten
         | where it is today by being radically simple, and that a lot of
         | extreme care needs to be done to add new features to the
         | language. It's hard to draw a firm line in the sand. I feel
         | like all of these features would work great together, though;
         | it'd enable Go to do something like `Result` in Rust with few
         | language-level changes.
         | 
         | I even remain somewhat skeptical about generics, but I am
         | hopeful.
        
           | masklinn wrote:
           | > I'd kill for union types as well.
           | 
           | > ... and pattern matching. Maybe just some extensions for
           | `switch`.
           | 
           | Go has type switches which are... ok. If it were possible to
           | "close up" interfaces and type switches took that in account
           | (match completeness) you'd be done about done, you would not
           | have the structural / patterned unpacking but that's probably
           | less of a concern.
        
       | Ericson2314 wrote:
       | C++, Java, JavaScript, Python, Ruby, Go, now all with popular
       | and/or official type checkers which support generic.
       | 
       | The normie PL bar is rising, slowly but surely.
        
       ___________________________________________________________________
       (page generated 2021-12-14 23:00 UTC)