[HN Gopher] Backward Compatibility, Go 1.21, and Go 2
___________________________________________________________________
Backward Compatibility, Go 1.21, and Go 2
Author : philosopher1234
Score : 289 points
Date : 2023-08-14 16:22 UTC (6 hours ago)
(HTM) web link (go.dev)
(TXT) w3m dump (go.dev)
| deagle50 wrote:
| Call me when we get some sugar for `if err != nil`.
|
| The signal to noise ratio when reading Go code is not great.
| unethical_ban wrote:
| If Go 2 won't break Go 1 programs, shouldn't it be Go 1?
|
| I get not using semantic versioning for end user packages like a
| web browser, but for backend systems and APIs, it still makes
| sense.
|
| I don't see why go didn't use full semantic versioning (x.y.z)
| where any update that didn't break anything moved Z, new APIs or
| minor changes to behavior/compile such as in the article move Y,
| and large changes to the core language or core libraries moves X.
|
| By semantic versioning, they aren't moving off "Go 1" any time
| soon, no matter what it's called.
| mseepgood wrote:
| > If Go 2 won't break Go 1 programs, shouldn't it be Go 1?
|
| Yes, that's what the article is saying.
| unethical_ban wrote:
| Ah. So to phrase it differently,
|
| "There will never be a Go 2 unless marketing says we should
| renumber."
|
| Just stop referencing "Go 2" as if they ever think it will
| exist, then!
| dang wrote:
| Related:
|
| _Forward Compatibility and Toolchain Management in Go 1.21_ -
| https://news.ycombinator.com/item?id=37122932 (no comments yet,
| but some will probably show up)
| ilyt wrote:
| I do hope they will eventually introduce sum types and better way
| of handling errors, but keeping the old code just work is frankly
| more important on the grander scale.
| mdwhatcott wrote:
| To coin a phrase, "Go 2 considered harmful" :)
| [deleted]
| ainar-g wrote:
| https://github.com/golang/proposal/blob/d661ed19a203000b7c54...
|
| About five years too late, heh.
| mdwhatcott wrote:
| I knew it was too good to have been original.
| gigatexal wrote:
| Here's hoping they do all the wild changes they want in go 2 and
| keep go 1.x versions compatible with each other. That gets you
| the best of both worlds: legacy code can run the legacy version
| of go and the newer iteration of the language will break
| compatibility and thereby shed any tech debt and cruft as it
| learns from any previous mistakes or compromises.
| stanleydrew wrote:
| Seems you didn't get to the end: https://go.dev/blog/compat#go2
| vl wrote:
| Compatibility or not, but if object field of interface is set to
| nil, then myVar == nil should return true, unlike bizzare
| behavior now!
|
| Right now it's possible to get nil interface from one func,
| return it from another resulting in hidden cast, and this
| returned value fails nil check. This leads to hidden bugs, and
| code like this: p = makeP() if p == nil
| { return nil } return p
|
| and all this can be avoided by not requiring both fields of
| interface to be nil for successful nil check.
|
| I sure hope this will be fixed at least in 2.
|
| Also finally we got max/min. Maybe it's time for, you know, sets?
| Ordered_maps? Hashable slices? Ground breaking, I know.
| JoshGlazebrook wrote:
| I started using Go at work ~2 years ago and I love it, especially
| for the backwards compatibility. But my personal projects up
| until then were node.js backends written with Typescript. Those
| personal projects are essentially stuck in time because of the
| whole ESM/commonjs mess that is modern javascript. Some of the
| npm package I use have been updated to only support ESM modules,
| while others will never be updated, some are half and half. It's
| in such a bad state that I've decided if it does ever fully break
| I'm just going to re-write the backend in Go, and I know I'm not
| the only one just frustrated with the modern javascript ecosystem
| and have projects stuck on old node.js and npm package versions
| because of it.
| joshstrange wrote:
| In your position I'd probably do the same thing and no doubt
| the ESM/commonJS mess is a mess and huge PITA.
|
| All that said I'll probably continue with my TypeScript/NodeJS
| backends since I just absolutely love writing TypeScript and I
| love sharing code between the front and backend. I use JS/TS in
| my day job (frontend only) as well so it's super nice to be
| able to benefit from that knowledge/practice. I also use
| TypeScript to write a few apps (some for work, some for my side
| project, some for personal use) so staying in the TypeScript
| ecosystem for almost everything I do is really nice.
|
| Again, I'm not defending that annoying/bad parts of TS and
| certainly not saying I've escaped the ESM/commonJS hell
| unscathed, just that I use TS everywhere and I generally have a
| lot of fun writing/running it.
| cookiengineer wrote:
| Babel was the most enterprise thing that could happen to the JS
| ecosystem.
|
| Gone are the simple distribution channels, and all build
| pipelines have 100s of megabytes of legacy crap that nobody
| actually ever executes.
|
| If you want to tell me your page is working in IE6, you're
| lying. It will break apart in all places.
|
| Anybody remember bower and pikapkg? That was the peak in my
| opinion.
| nobleach wrote:
| Oh my.... yes. For me, that would have been Angular 1.x days.
| And while it was neat having a tool that could pull a
| deterministic flat list of dependencies, I wouldn't go back
| to those days. I do wholeheartedly agree that injecting core-
| js into every single build, in the rarest of cases that you'd
| need to support a browser that doesn't support generators, or
| some other featured added around 2015, is just plain silly. I
| cringe when I look at a dependency graph and see all those
| polyfills in my builds!!
| [deleted]
| madeofpalk wrote:
| The whole Nodejs ESM thing is the result of a bunch of
| different parties - Node, Typescript, Babel/Webpack/etc - with
| a lot of influence over the ecosysten with conflicting
| priorities. This is the price of truely "open" standards. One
| of the reasons why it's such a mess was due to bending over
| backwards maintain backwards compatibility.
|
| It's a mess. It's frustrating as a user/developer. Go has it
| significantly easier by having just one central organising
| factor behind the ecosystem. If there were multiple Go
| implementations, some moving faster on the spec (or even ahead
| of it) than others, then you would find the same pain there
| also.
| mattlondon wrote:
| > ESM/commonjs mess that is modern javascript
|
| No - only a mess in the node/npm scope.
|
| JavaScript modules are just fine if you stay away from npm and
| node. Node and npm are a total dumpster fire, but that is not
| all of JavaScript.
| pseudosavant wrote:
| Agree that node/npm are the dumpster fire of JS, but ESM is
| still going through growing pains too. I have switched off of
| Node over to Deno. It natively supports ES modules. But most
| of the time I try to consume an ESM the code was designed to
| only load in a browser. It gets especially complicated if the
| ES module is using something like WASM - using FFMPEG via an
| ESM using WASM is the current use case I'm working on.
| latchkey wrote:
| I've been maintaining a fairly popular (~40k downloads/mo)
| react component library for about 4 years now. It is a
| clusterf'ck to keep things up to date with changes over time.
| React itself has broken things several times.
|
| I knew in advance that this would be a challenge, so when I
| started the project, I wrote a lot of unit tests. The first
| test for each component was just a snapshot output of it. Then
| I had other tests for functionality and have added tests over
| time for bugs. That has saved my ass so many times.
|
| I don't know how anyone maintains a JS project without
| comprehensive tests. Actually, I do... as you said, they never
| upgrade anything.
| Zamicol wrote:
| Nice article Russ.
| [deleted]
| mseepgood wrote:
| Since Go 2 is never going to happen, maybe it's time to rename
| the "Go2" label on GitHub and remove the "Go 2:" prefix in the
| template for language change proposals. I think this confuses
| people into believing that Go 2 is a thing.
| ainar-g wrote:
| Based on the discussions I've seen, Go2 is considered to be the
| name for the process of extending the language, not an exact
| release version.
|
| With that said, the label seems to "work" by allowing people to
| first think of a backwards-incompatible way to solve a problem
| and then, possibly, arrive at a much more compatible solution
| in the process of discussion.
| mseepgood wrote:
| > Based on the discussions I've seen, Go2 is considered to be
| the name for the process of extending the language, not an
| exact release version.
|
| I know, but many people obviously don't know that, so it
| might be a bad name. Just label it LanguageChange or
| Incompatible.
| dcow wrote:
| > That raises an obvious question: when should we expect the Go 2
| specification that breaks old Go 1 programs?
|
| > The answer is never. Go 2, in the sense of breaking with the
| past and no longer compiling old programs, is never going to
| happen. Go 2 in the sense of being the major revision of Go 1 we
| started toward in 2017 has already happened.
|
| Why is backwards compatibility such a religious sin for Go?
| Python made it through a backwards-incompatible source change. I
| understand breaking backwards compatibility would be difficult on
| a short timescale, but on a long-term time scale people would
| migrate. Source rewriters would handle most of the transition.
| Over 3-5 years I could see a source-breaking change play out
| positively for some of these newer languages like Go and Rust.
| And arguably, they sorely need it.
| distrill wrote:
| this always seemed like a nightmare to me. even so today years
| after python2 was officially sunset, documentation is still all
| over the web that may never catch up.
|
| yes technically the language got over it but i would hold this
| up as an example of a reason not to break backwards
| compatibility. having to manage multiple interpreter versions
| when i'm just trying to run software on my computer, what a
| pain in the neck.
| badrequest wrote:
| > Python made it through a backwards-incompatible source
| change.
|
| It took them a decade and permanently tarnished their
| perception with many programmers. They "made it through" in a
| similar way to how cancer survivors enter remission.
| ranting-moth wrote:
| > Python made it through a backwards-incompatible source
| change.
|
| That's skipping a few fact, isn't it? Let's call it what it
| was. Python was a victim in a cataclysmic software disaster of
| biblical proportions. It spend 10 years in rehab afterwards but
| miraculously made it through yes.
| crickey wrote:
| Has python really though? still my company has a bunch of 2.7
| lying around that not one is touching. I would like to flip
| your question on its head and ask why does any language need a
| breaking change ever? Might as well create a new language in
| that case
| eviks wrote:
| > why does any language need a breaking change ever
|
| that's easy - because it's impossible to design everything
| right right away, and for many things also impossible to make
| it right later without breaking compatibility, while those
| improvements are valuable
|
| New language for each breaking change also doesn't make sense
| when there is a lot of continuity
| mrweasel wrote:
| While I can't say for sure, one or the reasons I seem to
| recall from the Python 3 transition was that the Python 2
| design was pretty much a dead end. There where so many
| limitation and wrong design choices that it would keep the
| language from moving forward. That does seem a little
| aggressive, but it does feel like Python picked up a lot of
| steam once Python 3 was viable (something that happened way
| earlier than many care to admit).
|
| Our code base wasn't huge at the time, a few 100.000 lines of
| code. Getting everything running was a week of work for three
| people. Sure many had way more complicated code, and some
| depended on some idiosyncrasies of Python 2 making thing more
| complex, but a lot of people acted like the Python developers
| shoot their dog. Mostly these people either simply didn't
| want to do the work or their particular niche was made ever
| so slightly more complex... or they depended on unmaintained
| libraries which is bad in it's own way. Python 3 was always
| going to be able to do everything Python 2 could, yet a large
| groups of people acted as if that wasn't the case.
|
| Still not the best transition ever devised, we had to wait
| until 3.2 to get the speed to a point where it's wasn't an
| issue for all but the largest users.
| LexiMax wrote:
| The Python 3 upgrade process for many projects was
| incredibly painful. "Mercurial's journey to and reflections
| on Python 3" should be required reading for anybody with
| rose-tinted glasses of the migration.
|
| https://gregoryszorc.com/blog/2020/01/13/mercurial%27s-jour
| n...
|
| There was, of course, a Hacker News thread discussing the
| article, and a fair few people decided to blame the
| Mercurial developers for handling the migration
| inelegantly. Because that's how you win over an audience of
| developers - reassuring them that if Python has a
| backwards-compatibility break, Python fans will go out of
| your way to try and blame you for writing bad code. And
| not, perhaps, the fact that Python was missing things like
| a u string prefix and % bytestring formatting until 3.3
| (2012) and 3.5 (2015!!!) respectively.
|
| If I sound peeved, I really loved Python in the 2.x days,
| and the way the 3.x transition was handled broke my heart
| and prevented me from using the language for pretty much an
| entire decade. There are lessons to be learned from the
| transition, but not if we ignore the real problems that the
| transition caused. More importantly, we need to recognize
| that Python is not the Python we know today because of how
| "well" the transition was handled, but because Numpy and
| Matplotlib swooped in and gave Python new niches to excel
| in at just the right time.
| crickey wrote:
| All well and good when u have an active dev team who knows
| the code. Have fun walking into a code base that has just
| been running for the last 5 years and all the consultants
| that created it have left.
| yakubin wrote:
| Python programmers just self-selected themselves into a set of
| programmers who care about backwards-compatibility less than
| other programmers. You can see this attitude all over the
| Python ecosystem. And even in standard Python it's not just one
| backwards-incompatible change, but a series still made from
| time to time. Programmers from C++, Java and Go worlds wouldn't
| accept it as easily.
| dgb23 wrote:
| Incompatibility, lack of stability and other churn inducing
| changes are the nemesis of software maintenance.
|
| The implied cost is immense and soul sucking.
|
| In many cases it's pure vanity as well.
|
| It's fine for early languages, research languages and toy
| languages. But outside of these categories it's not worth the
| cost.
| TeddyDD wrote:
| Go developer experience: * install the newest compiler * clone
| the code * go build
|
| Python developer experience: - clone the code - setup virtual
| env (otherwise you will break your system) - install very
| specific version of interpreter because lib x supports only
| Python from 2020, because Python breaks compatibility in minor
| versions - no, you can't just update lib x withut updating
| python and other deps - install deps (hopefully author of the
| code pinned everyting, otherwise you're fucked) - never update
| any deps or you will suffer
| vlowther wrote:
| Why the extra "clone the code" step in the Go developer
| experience? Been using Go since 1.0, never had to do that.
| TeddyDD wrote:
| Let's say I described steps to hack on some Go package.
| When installing libs/programs, go get/install is enough :)
| gen220 wrote:
| As somebody who writes a lot of python, I'm going to quibble,
| but your statement isn't unfair. :)
|
| My quibble would be "don't use lib x". 99% of the time, you
| don't need an unsupported 3rd party library from 2020. In the
| worst case, you can copy the subset of lib x that you
| actually need, the copied code will typically _just work_ ,
| verbatim, in a later python version. In summary, the "common"
| path travelled by footgun-aware python programmers is not
| this bad.
|
| But yeah, it'd be nice if the language constraints meant you
| couldn't end up in a situation like this, and it'd be nice if
| we didn't have to learn-by-footgun as much in the python
| community.
|
| TBF, Python is just an old language that comes with early-
| mover advantages and disadvantages. Like an old house, we
| have just learned to live with (i.e. avoid) certain
| floorboards.
| throwaway894345 wrote:
| > Go developer experience: * install the newest compiler *
| clone the code * go build
|
| HN screwed up your formatting, FYI.
| TeddyDD wrote:
| I'm clueless when it comes to HN formatting -\\_(tsu)_/-
| dcow wrote:
| use extra new lines liberally (when in doubt, add a
| newline) is good working advice
| jimmaswell wrote:
| Python was a disaster. I still miss print statements and
| encoding-agnostic strings. Good on Go for doing the right
| thing.
| hk__2 wrote:
| Print statements were a mistake. If you forbid breaking
| changes, you have no way to fix past mistakes in the language
| design. There's noting inherently "right" in refusing to do
| breaking changes.
| jimmaswell wrote:
| Removing the print statement was the mistake to me. It
| violated Python's own stated principle of practicality over
| purity.
| rowanseymour wrote:
| Having two ways to do the same thing is the mistake, and
| print() was always more consistent with other built in
| functions are invoked.
| masklinn wrote:
| There was nothing practical about the print statement.
|
| The print function is easier to use, meshes a lot better
| with the langage, and can actually be extended without
| C++ style syntactic nonsense.
|
| The print function is one of the best things to come out
| of p3.
| dcow wrote:
| I think if you'd ask any Python programmer today, they'd say
| Python is very much healthy and the community has
| successfully transitioned.
| jimmaswell wrote:
| Python was my first language and I still use it sometimes.
| Still run into 2 vs 3 issues often.
| mrweasel wrote:
| > encoding-agnostic strings
|
| Do you mean byte strings vs. strings in Python 3 or did you
| actually like string handling in Python 2, because that
| basically "Tell me that you only allow ASCII without telling
| me that you only all ASCII". I can see the issue with byte
| strings in Python3, it's annoying that you have to think
| about both strings and byte strings, but for dealing with
| actual text having everything just be unicode was reason
| enough to upgrade from 2 to 3. We deleted so much code
| dedicated to dealing with encoding during our switch to
| Python 3, everything just became better.
| jimmaswell wrote:
| I had an IRC markov-like bot in Python. It used to be so
| simple in Python 2:
|
| - the bytes come in from the IRC server
|
| - they go in a string in the log, I can print this log to
| the console even if it has some IRC control codes (there
| will be a garbage character here or there but that's OK)
|
| - if I want to make a bold/color/etc I can just throw
| \xwhatever in the string. if a word from the log had bold
| in it and it's repeated back it will also have the bold in
| it.
|
| Then I reluctantly ported it to Python 3 and it was awful.
| Python now had to micromanage every single string to ensure
| I don't have any "naughty" bytes in it. Conversions to/from
| byte/string _everywhere_. Massive headache every time I
| wanted to read or write IRC encoded strings to a txt file
| or print them to the console or anything.
|
| In Python 2 the encoding only lived outside the program, in
| my terminal, text editor, and IRC clients. Bytes went in,
| bytes went out, and everyone was happy. Python 3 decided it
| needed to know exactly what was going on every step of the
| way and didn't trust me anymore, forcing me to do an
| elaborate song and dance to get anything done.
|
| I prefer my tools to have as little an opinion as possible.
| Let me open the door while I'm driving, let me run my web
| browser as root, and let me print \xDE\xAD\xBE\xEF to the
| console.
| mrweasel wrote:
| > Python now had to micromanage every single string to
| ensure I don't have any "naughty" bytes in it.
|
| Oh that is annoying, our use case just fitted better into
| how Python 3 works. We went the opposite way. We
| micromanaged strings all over the place to ensure that
| encodings would always be correct. We needed unicode but
| also connected to Windows systems, which uses their own
| weird codepage system. Encoding and decoding was
| everywhere along with encoding detection. Python 3 made
| all that go away.
| jimmaswell wrote:
| Maybe my case was exceptional and most cases were like
| yours. That would explain why I'm in the minority
| preferring old strings.
| packetlost wrote:
| It's probably because Google has no interest in rewriting the
| hundreds of thousands of lines of Go code they have internally
| and don't want to expend the resources to maintain a v1 and a
| v2.
| 0cf8612b2e1e wrote:
| Especially for a compiled language, I would think it is
| significantly easier to make automated code porting which is
| guaranteed to be correct. Or at least enough to handle the 99%
| of a code base which is likely not impacted.
| dcow wrote:
| Which is exactly what Swift did when it shipped early source-
| incompatible revisions.
| zer0tonin wrote:
| > Python made it through a backwards-incompatible source change
|
| The transition took more than a decade and was kind of a mess
| for a long while. For other languages, like Perl, it really
| didn't work out.
| masklinn wrote:
| > Python made it through a backwards-incompatible source
| change.
|
| It made it, but it was a rough few years, and the string model
| changes while mostly welcome (though not perfect) were a pain,
| we still find bugs from time to time.
|
| Things also got a lot better once the community figured how to
| do proper multiversion sources even though it was more
| limiting.
|
| A statically typed langage would have it a lot easier, by
| virtue of both the API and the semantics changes being much
| more flagrant, as well as the compiler making it easier to
| actually mix different versions of the langage across different
| packages (or even source files).
| mr_00ff00 wrote:
| Python is definitely the exception, not the rule.
| dcow wrote:
| Swift shipped source-breaking updates earlier in its
| lifetime. I honestly don't really know of a story where a
| source-incompatible update killed a language. People grumble,
| then they move on.
| throwaway894345 wrote:
| The pain of breaking changes is proportional to the volume
| of code affected by the breakage. This usually means
| breakages early in the lifetime are easy because there's
| relatively little code. For mainstream languages that have
| a decade or more of widespread usage, a breakage is a big
| deal.
|
| > I honestly don't really know of a story where a source-
| incompatible update killed a language.
|
| Perl. I mean, Perl isn't strictly dead, but its share of
| the market plummeted. Python almost certainly would have
| suffered a similar fate if it weren't for the explosion of
| interest in scientific/numeric computing (which more than
| made up for massive attrition to other languages, including
| Go).
| _ph_ wrote:
| Killed, in the sense of no one ever migrated? Certainly
| not. Killed, in the sense of hugely impacting the eco
| system and the community? Quite regularly. Python seems to
| finally mostly have made the transition, but there is just
| a lot of software around which will never be ported to
| Python 3. Perl almost completely went away, until finally
| development of Perl 5 gained some traction, but also with
| promises of maintaining compatibility.
| addaon wrote:
| > I honestly don't really know of a story where a source-
| incompatible update killed a language.
|
| Perl, with the Perl 5 -> Perl 6 (later Raku) transition?
| Fortran, with the F77 -> F95 transition?
| ainar-g wrote:
| > I honestly don't really know of a story where a source-
| incompatible update killed a language.
|
| Death may not come as swiftly (heh) as you think. I know a
| few people (including myself) who, when deciding which
| language to add to their toolbox, had decided against Swift
| because of its reputation as "that language that always
| breaks code", among other reasons. There are just a few
| anecdotal data points, of course, but I don't think it's
| controversial to say that a history of messy updates
| definitely makes new people less likely to learn a language
| without an absolute necessity.
| aeturnum wrote:
| > _I understand breaking backwards compatibility would be
| difficult on a short timescale, but on a long-term time scale
| people would migrate._
|
| It's funny to see people expressing this view because the "2 to
| 3 migration problems" is still a lively conversation in the
| Python world. I happen to agree with you and view it as a price
| of success - but at the same time I think it's obvious that you
| will pay an _outsized_ price in community sentiment for even
| reasonable timescales for EOL 'ing old versions.
| jerf wrote:
| "Why is backwards compatibility such a religious sin for Go?"
|
| I think the best way to understand it is that it is a first-
| class feature of the language. Thus, for Go specifically, it is
| like asking "Why is it a statically-typed language?" or "Why is
| the language compiled rather than interpreted?"; these are not
| bad questions but to a large degree the answer is that was a
| major choice made at the start of the language. And "why won't
| they get rid of it?" is in the same class of questions as "Why
| won't Python just become a statically-typed language?", which,
| is, again not intrinsically a bad question, but one that is
| certainly in a different category from "why won't Python adopt
| this particular bit of syntax sugar in their next version?"
|
| That the designers of Go would consider that a "feature" and so
| many programmers probably find classifying "backwards
| compatibility" as a feature a completely befuddling concept
| ("that's not what a feature is!") is probably a pretty good
| microcosm of the difference between the gestalt of programmers
| as a whole and the Go designers.
| [deleted]
| morelisp wrote:
| > Python made it through a backwards-incompatible source
| change.... Source rewriters would handle most of the
| transition.
|
| It seems we have collectively learned _literally nothing_ from
| the failed plans to change Python incompatibly.
| Waterluvian wrote:
| I'm a big fan of the assertion that a future Go 2 will never
| break Go 1 compatibility. I think if you need to make changes so
| significant to a language, you may as well just fork and rename
| the language (an opinion I can see many holes in).
|
| I wonder: why not go further and say "there will never be a Go 2"
| in order to eliminate ambiguity about this? If a theoretical Go 2
| will run all Go 1 programs, what would make it different from
| some Go 1.xx release? Some might interpret this post as saying
| that, but I don't think it quite does. It says "There will not be
| a Go 2 that breaks Go 1 programs."
| flakes wrote:
| The article does state that at the end:
|
| > The answer is never. Go 2, in the sense of breaking with the
| past and no longer compiling old programs, is never going to
| happen. Go 2 in the sense of being the major revision of Go 1
| we started toward in 2017 has already happened.
| cogman10 wrote:
| Java went through this. There was a Java 1.0, 1.1, 1.2, 1.3,
| 1.4, 1.5, 1.6, and 1.7. Then, Java decided "You know what, we
| aren't breaking backwards compatibility so instead of naming
| things 1.x, let's just say Java 8, 9, 10...21"
|
| I think that ultimately makes sense.
| blackoil wrote:
| This happened at Java SE 5(1.5) after 1.4. This was at much a
| marketing decision.
| minutillo wrote:
| It goes back ever further, Java 1.2 was marketed by Sun as
| "Java 2".
|
| https://web.archive.org/web/19991010063140/http://java.sun.
| c...
| cogman10 wrote:
| That was somewhat different from the way the internal stuff
| was numbered. You'd still see "1.5" and "1.6" everywhere
| when you asked the JVM for it's version. 8 was when the JVM
| started matching the marketing (IIRC, might have been 9).
| mrweasel wrote:
| I did not know that was the reasoning or logic behind the
| Java 8, 9, 10 ... numbering, that clears up so many thing.
| twic wrote:
| Also relevant is that Sun had pulled the same trick with
| Solaris a few years earlier - Solaris 2.6 was followed by
| Solaris 7. Bigger version numbers make for better
| marketing. I am skeptical that backwards compatibility was
| strongly involved.
| hbn wrote:
| Apple also did a similar thing with OSX/macOS a few years
| ago - instead of making everything 10.XX they bump the
| major version (first number) every year now, continuing
| on from the 10 that the X represented, as if each version
| is the same increment as the jump from Mac OS 9 to Mac OS
| X (which was a jump to an entirely new codebase)
|
| Android did that too, much earlier starting with 5.0.
| Previously the major version was something of an
| indicator of a major visual/conceptual redesign. 3.0 was
| the tablet version, 4.0 was the move to the holo design
| language, 5.0 was material. Then they just kept bumping
| the major version every year since.
|
| I also assume it's just for marketing reasons.
| chipotle_coyote wrote:
| I'd argue that the "everything is 10.x" for Mac OS was
| _also_ basically marketing. :)
| cpeterso wrote:
| Sun did the same for Solaris, jumping from version 2.6 to 7:
|
| https://en.wikipedia.org/wiki/Oracle_Solaris#Version_history
| adrianmsmith wrote:
| Ironically they then went ahead and made a massive change in
| Java 9 that, for the first time in Java's history, broke
| pretty much everything. Still angry about that...
| szundi wrote:
| Was it more than internal lib references that one was not
| supposed to do anyway?
| cogman10 wrote:
| Pretty much. Most of the breaks came from touching the
| likes of "sun.misc.Unsafe". Java versions 9->~17 added
| new jdk features (such as VarHandles) to allow for the
| safe interactions that sun.misc.Unsafe exposed. Libs had
| to update to use these new patterns with 9 being the
| worst hurdle.
|
| There was also a change to how packages could be named
| that messed with stuff. 2 jars putting stuff into stuff
| like `javax.annotations` was a big no-no that broke with
| 9.
| valenterry wrote:
| Well, they removed code that was _always_ discouraged from
| using and it was _always_ and _explicitly_ stated, that
| there are no guarantees of any kind when using this code.
| The code was not living in a package called "unsafe" and
| being undocumented (to my knowledge) by coincidence.
|
| So while Java broke some big libraries/frameworks (not
| "pretty much everything though"), it can't really be blamed
| on them.
|
| In fact, look what Go has: https://pkg.go.dev/unsafe
|
| > Package unsafe contains operations that step around the
| type safety of Go programs. > Packages that import unsafe
| may be non-portable and are not protected by the Go 1
| compatibility guidelines.
|
| Let's wait until Go has reached Java's maturity and see
| what happens when they change this package ;)
| jerf wrote:
| "Let's wait until Go has reached Java's maturity and see
| what happens when they change this package ;)"
|
| They did a while back, actually. Compare
| https://pkg.go.dev/unsafe@go1.0.1#Pointer with
| https://pkg.go.dev/unsafe#Pointer , in particular the
| modern very precise description of exactly what you can
| do with an *unsafe.Pointer. I'm not sure what the cutoff
| for that was but it was a while ago, yes. Still, it
| didn't do much.
| valenterry wrote:
| Interesting!
|
| Personally I'm not a big fan of either Java nor excessive
| backwards compatibility. But I can't avoid noticing that
| a lot of people praise Go for things like the backwards
| compatible while despising Java at the same time, even
| though both languages are extremely similar in lots of
| regards.
| adrianmsmith wrote:
| > So while Java broke some big libraries/frameworks (not
| "pretty much everything though"), it can't really be
| blamed on them.
|
| I think one of the reasons people use Java is to get
| access to those big libraries/frameworks.
|
| I've worked at a few companies that used Java during the
| transition, so maybe I had access to about 10 Git repos
| that underwent this transition.
|
| I think pretty much all of them required some tweaking
| e.g. adding extra dependencies in Maven when moving from
| Java 8 to Java 11. I actually became the "go to" person
| to do these transitions, having worked out what
| incantations were needed.
|
| All of those repos, to this day, despite the effort that
| was put into them during the transition, now print out
| warnings about things being unsafe. The companies just
| ignore those warnings. I have 15 years of Java experience
| and I don't know what to do about them. My understanding
| is this is normal in the Java world now.
|
| They are just normal web applications or REST services
| using databases like PostgreSQL, using e.g. Spring Boot,
| Tomcat, etc. Maybe those libraries do things they're not
| supposed to, I don't know. I have never used
| sun.misc.Unsafe in my code or anything like that.
|
| Perhaps if I spent days studying the problem I could
| understand what was going on and what to do about it
| (although probably not, as the problems might have been
| in third-party dependencies.) But this wasn't money the
| companies I worked for wanted to spend. But anyway, my
| point is that spending days fixing stuff after an upgrade
| != backwards compatible.
| kaba0 wrote:
| You likely has a dependency of dependency of a dependency
| that uses it, and thus get the warning.
| pjmlp wrote:
| One cannot make omelette without breaking a couple of eggs.
| MichaelNolan wrote:
| Hopefully there should never be a repeat of that now that
| they have strongly encapsulated jdk internals. My
| understanding is that (nearly) all of the migration
| headaches from 8 to 9 were caused by libraries that were
| using improperly using jdk internals.
| saghm wrote:
| Devil's advocate: anything that's possible for a
| downstream user to access is fair game for them to use.
| You can certainly mark it as internal and be explicit
| that you reserve the right to break it later, but if it's
| actually possible for users to do, it's not "improper",
| even if it gets broken later.
| kaba0 wrote:
| That's why they sealed those holes shut, and only allow
| some of them with deliberate end-user command-line flags,
| so that anyone wanting to go that way only has themselves
| to blame.
| kaba0 wrote:
| If that's pretty much everything, then nothing is backwards
| compatible unless they have the same hash..
| ainar-g wrote:
| > I wonder: why not go further and say "there will never be a
| Go 2" in order to eliminate ambiguity about this?
|
| They did, five years ago. Albeit with an "if".
|
| https://github.com/golang/proposal/blob/d661ed19a203000b7c54...
|
| > If the above process works as planned, then in an important
| sense there never will be a Go 2. Or, to put it a different
| way, we will slowly transition to new language and library
| features. We could at any point during the transition decide
| that now we are Go 2, which might be good marketing. Or we
| could just skip it (there has never been a C 2.0, why have a Go
| 2.0?).
|
| > Popular languages like C, C++, and Java never have a version
| 2. In effect, they are always at version 1.N, although they use
| different names for that state. I believe that we should
| emulate them. In truth, a Go 2 in the full sense of the word,
| in the sense of an incompatible new version of the language or
| core libraries, would not be a good option for our users. A
| real Go 2 would, perhaps unsurprisingly, be harmful.
| [deleted]
| ilyt wrote:
| But Java absolutely had versions that broke old code
| tmpz22 wrote:
| > We could at any point during the transition decide that now
| we are Go 2, which might be good marketing.
|
| Among the (entirely?) dev-oriented consumers of Golang would
| the shininess of "2.0" really outweigh the "ugh documentation
| is going to get harder to find" and "ugh I now need to
| increase my auditing of dependencies" and other similar
| fatigue?
|
| Is Google universally good at marketing?
| dcow wrote:
| You might be overestimating the type of change required to
| break source compatibility. A benign example is adding a
| keyword. Let's say you want to add a new language feature and
| the community unarguably wants the feature and the right or
| only way to add it is with a new keyword. If you're not allowed
| to break source, then you can never add the feature.
|
| I understand your argument for big things like changing the
| semantics of the language. But a backwards-incompatible change
| can also be rather benign.
| rsc wrote:
| It's not true that Go can't add new keywords. Now that we
| have Go modules, all Go code is now explicitly annotated with
| the version of Go it was written against. We can add a new
| keyword in a later version of Go as long as the compiler can
| still also compile code written for the older versions of Go.
| (The go command tells the compiler which version of Go to use
| for each package it compiles.)
|
| What we're not going to do is abandon all the code written
| for older versions of Go, like Python 3 or Perl 6 did. Python
| is recovering now but it easily lost a decade to the Python 2
| -> Python 3 transition, almost certainly unnecessarily. And
| Perl lost even more.
| crickey wrote:
| I dont undestand your example, plenty of languages add new
| keywords without breaking backwards compatibility, its
| removing a keyword that would cause such and issue.
| meepmorp wrote:
| I have named a function 'foo', in current version of
| language. A future change makes 'foo' a keyword. My code
| was broken by adding a keyword.
| crickey wrote:
| I guess, some languages get around this by having a
| destinction between functions and keyword functions not
| having the () braces in the syntax. But really if ur
| defning functions as keywords u should just put it in the
| standard library
| earthboundkid wrote:
| This is not theoretical: Python broke a lot of async
| packages when they made "async" a keyword!
| kodra wrote:
| Why can't it add keywords? Adding a new keyword doesn't break
| backward compatibility. It breaks "forward compatibility."
| tptacek wrote:
| New keywords are like the textbook example of a backwards
| compatibility problem. It's probably why C overloads
| "static" so many different ways.
| kodra wrote:
| You mean new reserved words? For example, I'm quite sure
| when C# added "record" it didn't break backward
| compatibility, as old code that uses "record" as a
| variable name still compiles.
| tptacek wrote:
| Go has made changes like that by adding new predeclared
| identifiers ("any" is an example, I think?) but there's a
| distinction between predeclared identifiers and keywords.
| pcwalton wrote:
| You can sort of add new keywords backwards-compatibly
| using a trick called "contextual keywords": you require
| that they be placed in a syntactic position in which no
| identifier could legally go, and you maintain them as
| legal identifiers for compatibility. C++ used this trick
| to introduce "final" and "override" by moving them before
| the opening "{".
| Dylan16807 wrote:
| Old code becoming a compiler error sound like a backwards
| compatibility issue to me.
| kodra wrote:
| I guess it's a terminology thing. As someone from a C#
| background, not all keywords are reserved words. Only new
| reserved words break backward compatibility.
|
| C# has added some keywords (record, and, or) without
| breaking backwards compatibility.
| 015a wrote:
| I'm not sure that's a relevant distinction. If you take the
| stance that a major version _has_ to mean breaking API
| compatibility with the previous major version, semver style,
| then their statement is equivalent to saying "there will never
| be a go2". If you don't take that stance, then their statement
| leaves open the possibility that, fifty years from now, we'll
| be at go1.102 and someone will say "hey, these numbers are
| getting pretty big, maybe we should just call this next release
| go2"; and that's fine. That's literally and exactly what Linux
| does; when the number gets big, it becomes easier to type
| smaller first number, so rename version to smaller first
| number. Its not semver, but semver doesn't have a monopoly on
| how software must be versioned, and leaving room in the
| language today to do that is totally cool.
| sudhirj wrote:
| It becomes a semantic difference at that point. If Go is doing
| semver, and there are going to be no backward-incompatible
| changes, there's no reason to ever increment the major version.
| Everything is a minor version (compatible additions) and patch
| version (bug fixes).
| jdc0589 wrote:
| > I wonder: why not go further and say "there will never be a
| Go 2"
|
| Pretty sure they've said this in the past.
| afavour wrote:
| I'd argue Rust's editions are a good counter argument to that.
| The differences between editions really aren't huge despite
| being breaking changes.
|
| In theory I like the idea of backwards compatibility never
| changing but in reality some breaking changes really do make
| sense and being permanently on the hook for a language feature
| that didn't take X or Y into account when it was created
| doesn't feel like a win.
| parhamn wrote:
| Love this. Nothing better than coming to a go codebase and
| bumping the go version knowing everything will work fine.
|
| One thing I worry about is that the type system can't get
| improved significantly without breaking changes in the "this was
| wrong and wont compile now" sense. Although I'm not sure theres
| interest for this stuff in the golang team at all. But there are
| many low hanging type system improvements in go that are major
| compile time robustness wins for folks, with no language
| additions.
|
| 1) reporting unchecked nils, might require formalizing [T, nil] |
| [nil, err] so err != nil guarantees T (obviously concurrent
| pointer access makes it tricky but thats special code with
| special considerations, not the 99% case)
|
| 2) unchecked array access
|
| 3) inferring types of nested struct literals. Writing nested GRPC
| calls is such a damn pain go, this is literally only one layer of
| type inference... its in the damn function signature I'm calling!
|
| 4) Exhaustive enum matches
|
| But now I'm curious, is there any interest for these changes in
| the golang community? None are adding "features" (like say
| generics) but would be huge robustness wins and seem pretty easy.
| josephg wrote:
| Just to beat this drum from outside the go community, rust /
| swift style enums with parameters are mana from heaven. So many
| programs get easier to write using them. If there's one way I'd
| love the go type system to be improved, it would be by adding
| these simple, lovely algebraic data types.
|
| Trust me, they would look great in Go. Treat yourself.
| andyferris wrote:
| I agree. If go had sum types I'd use it in a heartbeat!
| valzam wrote:
| The irony is that Go actually does have sum types, but only
| for generics!
|
| type A interface { Foo | Bar | Baz }
|
| Can't use this anywhere but in generic type signatures though
| :(
| pjmlp wrote:
| Looking forward to Go 1.99999999999999....
| nadermx wrote:
| Moving some code from python to Golang was instrumental in
| helping me scale. I am so glad to read they are going to stick to
| their core statement of backwards compatability
| sudhirj wrote:
| Amen to that. I get super excited about Go releases because they
| often add useful stuff with zero breakage of anything (just free
| wins all around). It's not clear that any part of the language is
| so broken that backward compatible changes can't fix it. Even the
| few foot guns like loop variable assignment have proposals that
| mostly preserve compatibility.
| sedatk wrote:
| Interesting because I observe the opposite sentiment among .NET
| developers for features added in C# despite that its backwards
| compatibility is also fully preserved. They say "the language
| is getting bloated", "it becomes harder to learn". I totally
| have your perspective on this, but the difference in attitudes
| is noteworthy.
| jerf wrote:
| In the past ten years, here's a list of significant feature
| additions to the Go language itself: *
| Generics
|
| And even that has not been the shocking revolution some
| people expected; it turns out to overall be a nice little
| addition rather than something that rewrote what good Go was.
| Nothing like the Python transition to "new style" classes, or
| the Python 2 -> 3 transition, or the Python async ecosystem
| transition, and that's just one language. For the most part a
| Go 1.4 programmer suddenly transported to today would not
| find it a terribly difficult task to read code using the
| generics.
|
| And broadly speaking, the language didn't start with a lot of
| features either.
|
| Go has had a lot of library improvements, it's had a lot of
| tooling improvements, but the language itself is extremely
| stable. I've seen a few people actually complain about Go
| moving too fast, to which I wonder what exactly would make
| them happy if even Go is zooming along too quickly for them,
| because I honestly don't know a language moving more slowly
| than Go, for all the advantages and all the disadvantages
| that incurs. I've honestly sort of wished I could sit down
| with them for 15 minutes and see if I could figure out what
| their real problem is, or if they really are upset that there
| was ever a major change.
| arp242 wrote:
| The biggest problem has been the GOPATH - modules
| conversion, which broke lots of (or all?) tooling. For
| example, I had written a fairly nice program to analyse Go
| code and generate an OpenAPI document, but when modules
| came around quite a bit of that broke, and it's non-trivial
| to fix. It still works in "GOPATH mode", but few people use
| that these days.
| xmprt wrote:
| I'm curious to learn what sort of issues you've seen when
| trying to use modules instead of GOPATH? Most of the
| migrations I've done have been pretty seamless and the
| few that had issues where all easy to resolve with a few
| replace directives or similar.
| arp242 wrote:
| Anyone who has written any tooling that works with Go
| code saw issues because almost everything changed in this
| regard. I was maintaining vim-go at the time, and quite a
| few changes were needed there too. I don't have a list of
| issues at hand because it's been a while, but generally
| speaking the only reason things went "pretty seamless" is
| because people spent time updating the tooling.
| neonsunset wrote:
| C# mostly suffers from having way too many options to do
| something. The quality of the average codebase written in 10
| layer-abstraction-heavy OOP style that does not leverage the
| language features for writing concise and understandable code
| does not help either.
|
| This is one of the reasons people rave about F# - it's less
| about the language and more about not suffering from really
| bad tradition that has settled over the years.
|
| Don't get me wrong, the situation improves significantly each
| year, but the developers who require extensive explanatory
| work to get any semblance of buy-in to stop doing things the
| painful and cargo-cult-y way are still in the majority.
|
| Otherwise, I think C# is very approachable thanks to it being
| extremely forgiving language* in general and standard library
| offering easy-with-pretty-good-defaults shortcut options to
| do the basics like networking, file io, hashing, creating
| simple web servers and UI applications, etc. Its both CLI and
| IDE tooling is also top notch today.
|
| * Forgiving as in, mistakes usually tend to decrease
| otherwise excellent (better than Go) performance rather than
| cause critical failures.
| tester756 wrote:
| >The quality of the average codebase written in 10 layer-
| abstraction-heavy
|
| This meme needs to die. I've seen "10 layer abstraction
| heavy" code base only once
|
| The code was simulating hardware/firmware behaviour when
| the real impl. was not available, and when the real impl.
| was delivered, then it was called instead.
|
| So that was quite reasonable why they went with this like
| that.
|
| Normal apps are mostly MVC-like where controller receives
| HTTP request (like 5 LoC?),
|
| moves it to some handler which performs business logic /
| calls db and the returned stuff is either HTML or JSON.
|
| That's your average web app.
| philosopher1234 wrote:
| The ten layer abstraction continues to exist in Java
| land. I see it every day at work.
| trallnag wrote:
| You get a few layers for free by using Spring alone
| 38 wrote:
| > This meme needs to die. I've seen "10 layer abstraction
| heavy" code base only once
|
| I dont think so. I like Go code because its usually
| pretty "flat" unless you find someone from a Java or C#
| background. C# code is similar to Java in that nearly
| everyone writes it with an IDE, so you end up with nested
| folders like 8 levels deep. it makes reading the code
| stupidly hard, unless you download and load into an IDE
| or something like GitHub with essentially a web IDE. so
| anyone used to just a normal editor like Vim or similar
| is basically out of luck.
| zimpenfish wrote:
| > The quality of the average codebase written in 10 layer-
| abstraction-heavy OOP style
|
| They did not learn from Perl, it seems.
| zigzag312 wrote:
| I've seen this repeated a few times in online forums, but
| that's not my experience. Language itself has gotten bigger,
| but code has become much less bloated and elegant. To me,
| it's easier to read new C# code than the old one.
|
| I'm probably biased as I use C# a lot. But I think that with
| advent of GPT tools, larger languages have become much less
| of an issue that they were in the past. They make it really
| easy to get explanation of code or feature you don't
| understand right there on the spot.
| sudhirj wrote:
| I haven't used C# in over a decade, but I was already feeling
| that way - there's just a lot in there. Go seems to start
| with a default no to things, so that might be why it has a
| relatively small surface area.
| kaba0 wrote:
| Which are valid fears -- C# has become a language with an
| insanely big surface area, almost comparable to C++'s. This
| surface area _will_ get rough, unforeseen edges when multiple
| different features are used together (no matter how generally
| good C# 's design is), so on the end-user dev it is not even
| a linear-only weight to learn.
|
| Java is a common butt of jokes among C# devs, but in my
| opinion its addition of features to the language while
| committing to backwards compatibility is simply the best in
| the industry and should be copied by every language
| pertaining to a similar status (not for research languages
| obviously, they should be the ones experimenting) -- they
| seldom add new features, only those that have been proven by
| others and trying to kill multiple birds with a single stone
| in each case.
|
| Also, .NET does have a dubious past regarding backwards comp.
| from what I gathered, "its" frontend churn alone is
| remarkable, the only thing more spectacular is their
| renamings.
| pjmlp wrote:
| > Java is a common butt of jokes among C# devs....
|
| And those of us Polyglot devs, have positive and negative
| arguments that go both ways.
| kaba0 wrote:
| Indeed, both languages have plenty positives and quite a
| few warts as well. While I do prefer Java personally, I
| consider C# an absolutely fine choice for almost every
| usecase.
|
| Go on the other hand, I'm much less forgiving about.
| ilyt wrote:
| I don't see any language advantages of Go if you know C#
| or Java already.
|
| On the other side we use it for ops because new hire,
| regardless of what language they know, can learn it in a
| week or two and produce not-shit code and don't suffer
| any of the Python or JS problems.
| pjmlp wrote:
| C# is getting some strange design decisions of lately,
| see inline arrays, and interceptors.
|
| Yeah, they had plenty of hindsight, and still....
| zigzag312 wrote:
| Why are they strange? Interceptors seem to enable
| migration away from reflection, for better support of AOT
| compilation.
|
| For example:
| https://github.com/DapperLib/Dapper/issues/1909
| metaltyphoon wrote:
| Which are both fine?
| ilyt wrote:
| I'd like to see sum types and some better way to deal with
| error verbosity.
| afavour wrote:
| > It's not clear that any part of the language is so broken
| that backward compatible changes can't fix it
|
| Broadly I agree but the future is kind of unknowable. For
| example Rust's 2018 edition introduced the async keyword, a
| breaking change because you could have made a variable or
| function named "async" in the 2015 edition.
|
| Async functions weren't something the first version of Rust and
| they were introduced with a breaking chance. I like backwards
| compatibility but am unsure about a future where Go can't do
| innovation X because it would break compatibility.
| chrisdinn wrote:
| I write a lot of Go and I can't tell you how much this warms my
| heart.
|
| Compatibility probably isn't much fun for the language team,
| always having to keep one foot firmly in the "distant" past. But
| for those of us that have to maintain large Go systems it's such
| a gift.
| nappy-doo wrote:
| I worked on the Go compiler for a couple of years, and it
| wasn't a big deal. We just thought carefully about things, and
| dealt with a lot of rejection of ideas. If we couldn't make it
| fit, it wasn't right, and we'd try again. If we still couldn't
| make it fit, we probably didn't have a good handle on the
| problem, and it was right to stew on it longer.
|
| Frankly, I truly appreciated working with people who thought
| carefully and tried to make sure the right ideas were in. I
| appreciated Russ being a BDFL, Ian, Rob, and Rob. I'm glad I
| did it, and it made me a much better engineer.
| iraqmtpizza wrote:
| I can't respect a language run by contributor covenant clowns who
| cajole people into pledging to never talk about anyone's body
| size. This means Go, Rust, and Python.
|
| JVM languages remain based and redpilled.
| kodra wrote:
| Interesting to see the first two comments in this thread have the
| opposing opinions on backward compatibility. I guess it depends
| on how deeply Python cut you.
| [deleted]
| fullstackchris wrote:
| darn i was hoping for at least a hint or mention when Go 2 might
| be released... no dice
| tptacek wrote:
| The article ends with a definitive answer to that question.
| sudhirj wrote:
| Go 2 is coming out every six months as continuous Go 1.x
| releases.
| euroderf wrote:
| I would expect a Go 2 to dispense with accumulated API cruft
| and to overhaul syntax with something radically different. But
| to otherwise maintain compatibility.
| AtNightWeCode wrote:
| I suggest Go and Dart morph into one lang. Then you could use the
| power of Go with the more logical syntax of Dart.
| rstat1 wrote:
| So you want them to completely break every pre-existing Go
| program, for no practical benefit?
|
| That seems dumb.
| AtNightWeCode wrote:
| No. It would only be a flag to allow obsolete Go code in
| practice I guess.
|
| EDIT: C++ did not break C. The people managing Go have full
| understanding of dependencies even though they made breaking
| changes.
| AtNightWeCode wrote:
| Could some of the genius down-voting argue for the reason why
| Google needs both of these more or less dying langs?
| Joker_vD wrote:
| Ah, parsing IPs. Just how exactly was the BSD's original
| inet_ntoa written, I wonder? The atoi/atol and sscanf with %d/%u
| always parse exactly decimal integers; it would had to use either
| %i or strtou with 0 base to have this silly effect.
| wahern wrote:
| No need to guess. My man page for inet_aton says it comes from
| 4.3BSD: https://github.com/dank101/4.3BSD-
| Reno/blob/master/lib/libc/...
|
| The earlier inet_addr from 4.2BSD has the same logic:
| https://github.com/dank101/4.2BSD/blob/master/lib/libc/inet/...
|
| inet_aton and inet_addr parse addresses the obvious way. Using
| something like strtoul or especially sscanf would be stilted.
| The beauty of C pointers is that it makes simple parsing tasks
| very easy--perhaps too easy.
| Joker_vD wrote:
| O_O
|
| They've _intentionally_ coded it that way? This is atrocious.
| And this hand-rolled mess that doesn 't even parse numbers
| correctly! It would parse "099" as 81 and "99999999999999999"
| as whatever it is modulo (MAX_ULONG+1), without any overflow
| detection. Well, at least they don't accept negative numbers,
| that's something.
|
| Anf mind you, beauty of C pointers has nothing to do with
| neither of these two bugs not the original decision to
| support octals and hexadecimals.
| doctor_eval wrote:
| I laughed when I read that. "Back in the day" I decided to
| "clean up" my /etc/hosts by zero padding the quads.
|
| Anyway, the outcome was that I had to go back and remove the
| zeroes.
| jokoon wrote:
| BTW, I've read the Go GC can be disabled, but what happens if you
| do? Wouldn't you have to avoid memory leaks?
| llimllib wrote:
| https://go.dev/doc/gc-guide is the docs on mucking with the GC,
| including disabling it.
|
| > Wouldn't you have to avoid memory leaks?
|
| I've not played with it, but I'd expect that every heap
| allocation would essentially be a memory leak in that mode
| oefrha wrote:
| There are at least two cases where GOGC=off could make sense
| for increasing performance:
|
| 1. You know you're definitely not allocating on the heap;
|
| 2. Your workload is bursty and you can simply keep everything
| until the process dies and memory is released.
| throwaway894345 wrote:
| If you're definitely not allocating on the heap, setting
| GOGC=off should make no difference, right?
| _ph_ wrote:
| You might be allocating on the heap, but if you know in
| advance that the allocated memory never goes out of scope,
| then switching off the gc is quite reasonable.
| bheadmaster wrote:
| Go compiler performs _escape analysis_ , which determines
| whether or not a particular object "escapes" the function it
| was created in - and if it doesn't, the compiler allocates it
| on the stack instead of the heap, thereby removing the need for
| GC.
|
| So, as long as you write Go in malloc-less C-style (which,
| admittedly, is a non-insignificant restriction), your program
| will be able to run just fine forever.
| throwaway894345 wrote:
| > So, as long as you write Go in malloc-less C-style (which,
| admittedly, is a non-insignificant restriction), your program
| will be able to run just fine forever.
|
| What happens if you write your Go functions in this malloc-
| less C style and they have to grow their stack? Doesn't this
| mean the old stack is now leaked memory?
| bheadmaster wrote:
| I see no reason why would de-allocating a stack require
| action from the garbage collector - afterall, once a
| goroutine grows its stack and copies the contents of the
| old stack to the new stack, there aren't any reachable
| objects left on the old stack, so it can be deallocated
| without any GC intervention.
|
| But I don't know enough about Go internals to be 100% sure.
| ainar-g wrote:
| It can, by setting GOGC=0 or from within the program. And yes,
| you would. It's essentially like writing in C, but not being
| able to call free(); i.e. allocating a fixed amount of
| resources at the start of the program and work on them. Which
| is also a recommendation[1] for safety-critical C code made by
| a NASA person, incidentally, heh.
|
| [1]:
| https://en.wikipedia.org/wiki/The_Power_of_10:_Rules_for_Dev...
| throwaway894345 wrote:
| Most of that seems reasonable, but the "do not use function
| pointers" boggles my mind. I'm pretty sure the alternative is
| a bunch of conditionals wherever you would otherwise use a
| function pointer. I've definitely seen some really ugly code
| written with this axiom which would certainly be a lot
| cleaner if rewritten to use function pointers. I'm curious if
| anyone can make a compelling argument against function
| pointers?
| ainar-g wrote:
| It's in the original:
|
| > [...] Similarly, function pointers should be used only if
| there is a very strong justification for doing so because
| they can seriously restrict the types of automated checks
| that code checkers can perform. For example, if function
| pointers are used, it can become impossible for a tool to
| prove the absence of recursion, requiring alternate
| guarantees to make up for this loss in checking power.
|
| In other words, static analysis beats code cleanliness, in
| this perspective.
| ilyt wrote:
| You will leak memory when you disable it.
|
| However, you might not care (app running too short), or you
| might turn it off only temporarily (say time-critical section
| you don't want to be interrupted by GC).
| jeeyoungk wrote:
| If your program is short running, then it may be more efficient
| to disable GC and let the dying process to take care of it all.
| 0cf8612b2e1e wrote:
| There many tales about programs foregoing any kind of memory
| collection and relying upon the business process itself to
| resolve the issue.
|
| My favorite is a missile. Evidently the program leaks memory
| like crazy. Solution was to determine how much memory would
| be required for the platform to fly to its farthest possible
| target + some margin.
|
| Alternatively are stock trading platforms written in Java.
| Disable the GC entirely because trading hours are only a a
| limited portion of the day. Restart the program daily.
| titzer wrote:
| > My favorite is a missile.
|
| This might be apocryphal, as software for this class of
| embedded system almost certainly doesn't dynamically
| allocate anything; probably doesn't even use pools.
|
| I have a friend who works on missile software at a big
| defense contractor, and they do actually clean up their
| memory.
| 0cf8612b2e1e wrote:
| I found a source, quoting the quote, so provenance is
| what it is
|
| > This sparked an interesting memory for me. I was once
| working with a customer who was producing on-board
| software for a missile. In my analysis of the code, I
| pointed out that they had a number of problems with
| storage leaks. Imagine my surprise when the customers
| chief software engineer said "Of course it leaks". He
| went on to point out that they had calculated the amount
| of memory the application would leak in the total
| possible flight time for the missile and then doubled
| that number. They added this much additional memory to
| the hardware to "support" the leaks. Since the missile
| will explode when it hits its target or at the end of its
| flight, the ultimate in garbage collection is performed
| without programmer intervention.
|
| [0] https://devblogs.microsoft.com/oldnewthing/20180228-0
| 0/?p=98...
| hbn wrote:
| I like to think the stock market thing is actually the
| reverse, and they shut it down every night because all the
| programs that keep it running were written in a memory-
| leaking tech stack that needs restarting
| rsc wrote:
| If you turn off the GC then no memory is collected. In general
| this is not something people actually do. The only time I've
| ever even seen it mentioned is in an old blog post by ESR, and
| between him and me, at least one of us didn't understand what
| he was saying.
| ash_gti wrote:
| If you have a short lived CLI tool, disabling the GC might be
| useful but that's likely an exceptional case.
| 015a wrote:
| There are popular problem domains where turning off the GC is
| useful. The best example is Lambda functions/FaaS. Most
| invocations are short-lived enough that the GC never triggers
| anyway, but being able to turn it off can help smooth down
| your P99s where it does trigger, but the world is going to be
| thrown away in 50 milliseconds anyway. This is a known, not-
| uncommon performance optimization in other languages on
| Lambda; but I have less experience using Go on Lambda.
| wongarsu wrote:
| It's not even exclusive to GC'd languages. A toy raytracer
| I've written in the past got notably faster if I just
| didn't deallocate anything. Memory management is expensive,
| and for unix-y software that runs on some input and then
| quits it can be worth it to just let the OS do the cleanup.
| coder543 wrote:
| That doesn't seem like a real thing. Lambda and every other
| FaaS that I'm aware of will reuse a single instance of the
| function for multiple invocations. It is not started from
| scratch with each invocation. Each instance can live for
| hours, handling a very large number of (sequential)
| invocations during that time.
|
| If you're not GCing, you will almost certainly run into
| OOMs.
| cratermoon wrote:
| If the FaaS can catch the OOM, restart the instance and
| re-run the request, the visible effect would be somewhat
| greater latency for that request. If the service is
| configured to automatically kill and restart instances
| after some time or some number of requests, it seems like
| a reasonable tradeoff. Am I missing something?
| coder543 wrote:
| > If the FaaS can catch the OOM, restart the instance and
| re-run the request, the visible effect would be somewhat
| greater latency for that request.
|
| I'm not aware of an FaaS that would hide the OOM... that
| falls under the "not a real thing" category I mentioned
| previously. It would just be a failed request, which is a
| very visible effect.
|
| Would you like to link me to the Lamda docs that say it
| will automatically retry the request in case of an OOM?
|
| Also consider that code which OOMs will do so
| unpredictably. It may have completed half of a task,
| leaving that task in a corrupt state that requires manual
| intervention from a human to recover from. If everyone
| wrote fully idempotent code that can somehow skip the
| already-completed updates and continue where the OOM
| occurred, this wouldn't be a problem, but that isn't what
| everyone does. This is certainly a large reason why FaaS
| do not retry requests automatically at all, in most
| cases.
|
| > If the service is configured to automatically kill and
| restart instances after some time or some number of
| requests, it seems like a reasonable tradeoff.
|
| I don't believe Lambda has any configuration parameters
| for those things. That's not how this is meant to work.
| Lambda will kill the instance when it has been idle for
| too long, and that's the primary factor.
|
| You could manually exit the process when your conditions
| are met, but why? The benefits of turning off the GC are
| likely to be negligible. This is a lot of complexity for
| no real gain. It would take some seriously huge gains
| demonstrated by well-written benchmarks to convince me
| that any of this is worthwhile for a FaaS function.
|
| Grug would rather fight t-rex.[0]
|
| If you need absolute performance and control over garbage
| collection, it's better to just write the lambda in Rust
| than to try to hack together a solution by turning off
| the GC and hoping it doesn't blow up at the wrong moment.
|
| [0]: https://grugbrain.dev/
| davidjfelix wrote:
| https://docs.aws.amazon.com/lambda/latest/dg/invocation-
| retr... Lambda retry docs. I still would strongly not
| advice intentionally disabling the GC and explicitly said
| not to above for the same reasons you're concerned.
| coder543 wrote:
| Glad you generally agree.
|
| From that link, here are two choice quotes that I think
| are highly relevant:
|
| > When you invoke a function, two types of error can
| occur. Invocation errors occur when the invocation
| request is rejected before your function receives it.
| Function errors occur when your function's code or
| runtime returns an error.
|
| > [...]
|
| > When you invoke a function directly, you determine the
| strategy for handling errors related to your function
| code. Lambda does not automatically retry these types of
| errors on your behalf. To retry, you can manually re-
| invoke your function, send the failed event to a queue
| for debugging, or ignore the error. Your function's code
| might have run completely, partially, or not at all. If
| you retry, ensure that your function's code can handle
| the same event multiple times without causing duplicate
| transactions or other unwanted side effects.
|
| So, it won't automatically retry if a function is being
| directly invoked and OOMs, which I believe was the
| context of my most recent reply.
|
| There are a few limited scenarios where certain AWS
| services that are invoking a Lambda asynchronously will
| decide to retry a couple of times, because it assumes
| that this type of function will be okay to call multiple
| times with the same input. Definitely not something worth
| relying on.
| davidjfelix wrote:
| Do not do this in AWS lambda or OpenFaas. Lambda processes
| are reused in "warm" invocations and are only short lived
| in cold, infrequent use cases (read: once every > 45
| minutes). This is useful when the process dies at the end
| of every request (in which case you're relying on the OS to
| do the GC for you).
| TylerE wrote:
| Also things like compilers...which tend to make lots of
| garbage but the processes are so short lived who really
| cares? All the memory is getting released in no more than a
| few seconds, worst case.
| chrsig wrote:
| there is of course one notable use for turning off garbage
| collection
|
| https://devblogs.microsoft.com/oldnewthing/20180228-00/?p=98.
| ..
| aatd86 wrote:
| If you allocate everything in advance and use free lists, you
| can probably do it. I believe that it is one of the few ways
| tinygo handles memory. (so embedded as a use-case)
|
| Note that GC can be triggered manually.
|
| I've had to do that using the wasm target so that I'd only
| trigger go GC cycles when the browser was idle. Eventually that
| use-case might disappear as the integration with a garbage-
| collected wasm gets deeper.
| varispeed wrote:
| Since they announced adding malware in the toolchain (sorry,
| khem, telemetry) I somewhat lost interest in Go.
|
| How do I know which version has spying turned on or whether this
| was abandoned?
|
| edit: I wonder if this was mandated by Chinese government, as
| certain Go tools that help circumvent censorship are written in
| Go and maybe government wants to know who compiles them.
| gavinhoward wrote:
| As a language designer, I respect the decisions they made here,
| including you never have a real Go 2.
|
| I'm also going to pilfer their techniques for ensuring
| compatibility.
| the_duke wrote:
| Never breaking compatibility is hardly a new idea.
|
| Java and C++ have invested tremendous amounts of effort into
| preserving backwards compatibility for decades, often requiring
| bending over backwards and very suboptimal designs for new
| features, especially in C++.
|
| But it keeps users happy. At least the ones with large old code
| bases.
|
| I think Rust has one of the cleanest models for this, which keeps
| complexity low: editions.
|
| The compiler will always support old code written against older
| editions, but the language can still introduce breaking changes
| in newer editions. Developers can either opt in to new editions
| and migrate their code, or do nothing, and things continue to
| work fine. There is seamless/transparent interoperability.
|
| Of course Rust is still pretty young, and if this model will work
| long term remains to be seen. For example, I imagine this causes
| a lot of implementation complexity in the compiler, the standard
| library is much more restricted and must remain stable across
| editions, and major overhauls probably won't be possible.
|
| But so far it has worked out really well, allowing the team to
| fix warts and mistakes in the language.
| izacus wrote:
| Can you explain in what way is that different from e.g. C++,
| where a compiler will take "-std=<C++ revision>" parameter
| which chooses the "edition" of the language?
|
| And even link different versions together?
|
| Because it sounds like Rust uses the same approach with the
| benefit of not hitting all the problems this causes... yet.
| kaba0 wrote:
| I would also be interested in it. As far as I know editions
| only allow for syntax changes, the semantics _will_ change if
| incompatible, especially that Rust doesn 't link across
| different versions in the same way as C++ does.
| zigzag312 wrote:
| I would upvote this twice if I could.
|
| We will never break compatibility is code for _" we will never
| fix warts and mistakes in the language"_.
| tptacek wrote:
| It obviously isn't, as the text of the article repeatedly
| observes.
| glenjamin wrote:
| Did you read the article?
|
| > The compiler will always support old code written against
| older editions, but the language can still introduce breaking
| changes in newer editions. Developers can either opt in to new
| editions and migrate their code, or do nothing, and things
| continue to work fine. There is seamless/transparent
| interoperability.
|
| This is exactly what the GODEBUG scheme described in the
| article is intended to allow.
| the_duke wrote:
| Edit: I had some wrong assumptions here.
|
| The Go approach does indeed seem to enable similar
| functionality. Although I'm not quite sure I understand how
| the individual settings and the module level version
| declarations compose, and how much complexity that
| introduces.
|
| With both module-level versions and GODEBUG, the whole thing
| does seem quite a bit more complicated than editions.
| tick_tock_tick wrote:
| It's basically a much more featured, flexible, extendable,
| and usable version of editions. Anything you could do with
| editions you could do with this; you could implemented
| "editions" via this functionality.
| the_duke wrote:
| Yes, but that's sort of my point regarding complexity.
|
| "This crate is edition X, and an edition comes out every
| 3 years or so" is much easier to deal with.
|
| It reminds me a bit of Haskell language pragrams, which
| can be toggled per source file (module), and which are a
| huge mess.
| vocx2tx wrote:
| > The setting is opt-out, requiring manual intervention.
|
| No. If a module's go.mod files declares go1.21, the
| compiler will use go1.21 semantics when building it, even
| if 1.22 has already been published and the module is being
| used from a 1.22-enabled program. This is explicitly
| mentioned in the blog post.
| [deleted]
| w10-1 wrote:
| The question for compatibility is not whether but how. And it's
| not really backwards: you want your code to just work, from now
| on.
|
| Go 1.21 offers two essential features not matched by any other
| language ecosystem:
|
| 1. A GODEBUG setting for each change, together with _per-change_
| opt-out and _per-change_ metric for detecting use of the prior
| implementation.
|
| 2. A per-module toolchain version, together with automatic
| fetching of both older and newer go toolchains (deployed safely
| as modules)
|
| As an amazing bonus, if you specify a given version of go (e.g.,
| 1.21.2), then when running under a newer version of go, go will
| automatically apply the relevant opt-out configuration so you
| won't get the new behavior until you ask for it.
|
| Finally, as ever you can declare things in code, in go.mod, and
| in environment.
|
| That basically covers all the use-cases for compatibility, from
| developers through deployers.
|
| Simple, and beautiful.
| ilyt wrote:
| Perl does something similar; use v5.24
|
| at start of the file will make it work as if the version of
| Perl was 5.24, and it works on per-file basics, not only per
| module
| mcbrit wrote:
| Apologies, but this actually sounds like a nightmare to me, if
| you have at least 1-10m+ loc over enough teams, enough teams
| being probably 5+ depending on org boundaries.
|
| Either you support the new version or you don't is more than
| enough complexity to cause arbitrarily ridiculous problems,
| because there is a deep valley of you /think/ you support the
| new version and the new version thinks that it supports you but
| you both miss.
|
| (who wants the t-shirt saying that they have been responsible
| for a 1m+ code base on top of 10m+ for at least 20 years?)
| jrockway wrote:
| If Team A requires compatibility with go 1.21, their go.mod
| will start with "go 1.21". Even if the code is compiled with
| go 1.22, their code will run unchanged, as the toolchain now
| treats the go version line as the toolchain to be compatible
| with. Similarly, if Team B requires compatibility with go
| 1.22 but their code is being compiled with go 1.21, go will
| download the 1.22 toolchain and run with that instead. It's
| sneaky and crazy, but so crazy it just might work.
|
| (As a user of CircleCI convenience images for a few tests
| suites, I appreciate this feature. When there is some
| security vulnerability that requires updating to go 1.21.1, I
| don't have to wait for Circle to build a new convenience
| image. I can just change go.mod and start using 1.21.1
| immediately. This saves a day of telling people to ignore
| govulncheck.)
|
| The TL;DR is that the compiler version is now something you
| can declare in your go.mod file like any other dependency.
|
| If you share one go.mod file across all teams or have a One
| Version Policy, then there will always be work to do. No
| doubt there are several dedicated (in practice) employees to
| manage "there is a critical security release for
| github.com/whatever/frob@1.2.3 but the Team A's tests fail
| when updating to github.com/whatever/frob@1.2.4", which is
| inevitable at this scale.
| Groxx wrote:
| It's not downgrading (unless that changed recently), it's
| just new emulating old. And only partially at that.
|
| E.g. `go fmt` with a new Go will use new-Go's formatting,
| not the module's version's formatting (comment format
| thrashing is fun!). And then they special-case backwards
| compatibility stuff like the `//go:build` syntax change,
| and _that behavior_ pays attention to module version. API
| accessibility and module file formatting follows module
| version, I don 't believe `go vet` does (in general, nor do
| I think it necessarily should), compiled implementation of
| stdlib _absolutely_ does not, etc.
|
| Rust (cargo) by contrast _actually does_ version the tools,
| and automatically pulls the stated rustc, stdlib, docs,
| everything (set in rust-toolchain.toml, among others:
| https://rust-lang.github.io/rustup/overrides.html). I'm not
| sure if cargo versions itself or not.
| jrockway wrote:
| I believe it's emulated.
|
| There's a tradeoff; the old toolchain may actually build
| code that is vulnerable to some security vulnerability,
| but the new toolchain will produce (in theory) code that
| produces the same output from the same input, but without
| the vulnerability. So it's not clear that either
| direction is a clear win; old is "known", but old can be
| dangerous. But, you can only write so many tests to
| ensure that emulation is as good as the original. Which
| direction you are less paranoid about dictates the
| direction you'll go.
|
| Having used Go since ~1.3 and having been responsible for
| the version in use for my project since about ~1.9, I'd
| say that on average I upgrade on release day and it has
| never caused a regression. But, the article mentions a
| handful of bugs that have occurred due to fixing library
| bugs, so they aren't nonexistent. How much risk you want
| to take here is up to you.
| [deleted]
| brunojppb wrote:
| > Boring is good. Boring is stable. Boring means being able to
| focus on your work, not on what's different about Go.
|
| This really resonates with me. I work with NodeJS and the JS
| ecosystem in general on my day job and I have to tell you, the
| struggle is real. The ecosystem is fragmented, everyone is doing
| their own thing, which is hard to make things stable. Don't get
| me wrong, I still enjoy this work, but I really wish the JS
| ecosystem could have a stable modern foundation we could rely on.
| [deleted]
| KronisLV wrote:
| I wonder why Go isn't the new Java/.NET (yet?).
|
| Clearly a lot of tools and APIs have been written in it, many
| would describe not needing a separate runtime on the target
| system as a big plus and the language seems simple enough to
| learn and utilize (with VSC support and GoLand both being
| good), even the typical complaints like the error handling
| don't seem like dealbreakers.
|
| I wonder what's missing for Go to become a mainstay of
| development for the decades to come, or at least take up a huge
| chunk of the job market instead of being considered a niche
| language in some places.
| slantedview wrote:
| > I wonder why Go isn't the new Java/.NET (yet?).
|
| Go is moving too slowly (ex: most of the SDK still doesn't
| support generics). Meanwhile, Java is moving relatively
| quickly, as are new contenders like Rust.
| coffeebeqn wrote:
| Moving towards what?
|
| I use it to build services that can serve lots of requests,
| I don't need the language to be moving fast underneath me
| booleandilemma wrote:
| Go is moving slowly, or trying not to move at all, on
| purpose, and I have to say, as a C# developer having to
| constantly learn new syntax, it seems refreshing. At the
| rate it's adding new syntax, C# may fall apart under its
| own weight and become the next C++.
| tmerr wrote:
| Maybe the decline of desktop applications (Java, C#) and
| Android (Java)? And then Go coming out with some killer
| frameworks? I have to stretch my imagination to imagine
| anything causing Go to outpace C# or Javas ecosystem.
| AtNightWeCode wrote:
| Go ecosystem is like a fraction of what .NET/Java is. Both in
| quality and size. Dart for instance is a better lang. It is
| also from Google. It also compiles to binaries. Why is that
| not the new...
|
| The slim spot for Go is the devops tools space. Where Go may
| or may not survive. Considering the march of Rust.
| kaba0 wrote:
| Why would it be the new Java/.NET? You vastly overestimate
| that separate runtime as being a huge positive, it is almost
| indifferent to most niches where these two are most common:
| servers, especially on the bigger side of things. For a
| devops team with a proper CICD pipeline, monitoring, whatnot,
| installing a runtime is beyond trivial, especially that many
| of it is container-based.
|
| So even if all else were equal, Go would need much much more
| positives to even start turning the wheel towards itself,
| momentum is huge in the industry (old Cobol systems are still
| clocking at places, even if they do so in a VM, as the
| hardware they are hardcoded against are too old now).
| Especially that it is not at all a net positive in many
| people's eyes:
|
| - it is very verbose (yes, it is in fact more verbose than
| Java, that had been bullied by everyone forever for being
| verbose..) - has terrible expressivity (java streams/.net
| linq) - smaller ecosystem (java is much larger than even
| .net, let alone go) - slow reflection (on the more
| enterprise-y end of the industry you sometimes need more
| dynamic workloads)
|
| Also add that both Java and .NET has native AOT compilation,
| so even that small benefit you mention may not be a
| dealbreaker, even if those are not as smooth a rides as go's.
| za3faran wrote:
| Well said. In addition, golang seems to shun everything
| under the guise of "keeping things simple", so you don't
| see frameworks like Spring or ASP.NET.
|
| Of course pretending the issue doesn't exist doesn't make
| it so. At an employer, the reinvented a dependency
| injection + application framework, but poorly of course
| compared to the extremely mature offerings on the JVM and
| .NET, not to mention millions of dollars sank into
| maintaining it.
| doctor_eval wrote:
| Whenever someone mentions Java AOT, I look it up, and it's
| a nightmare. Has it changed recently?
|
| I developed server software in Java for two decades, and I
| can tell you that the huge JVM was _always_ a PITA for us,
| even after Docker became a thing. All those frameworks? We
| ended up throwing them out. And the slow startup speed of
| Java apps made our tooling sluggish. It was also a pain to
| ship tooling to non developers, for all the same reasons.
|
| Using Go after all this time was like a breath of fresh
| air.
|
| It's fine for you to assert your own preferences and biases
| but you don't represent all enterprise server developers.
| gen220 wrote:
| I think Go is on that Java/.NET adoption curve, but it's
| climbing it slowly because backend programming, as a whole,
| is a lot bigger, mature and diverse today, than it was when
| Java/.NET emerged.
|
| I think there's a decent chance that, `[java.age - go.age =
| 15 years]` from today, Go is high up on the totem pole. From
| my perspective, its ecosystem is vibrant but still young - we
| still need to decide on the Go equivalent of Flask, Django,
| Spring, etc.
| guggle wrote:
| There are plenty of Flask equivalent in Go IMO. Django...
| not so much.
| coffeebeqn wrote:
| You also don't need to have frameworks for everything
| when the std library delivers
| gen220 wrote:
| Yep! I think, at this stage, `plenty` is the point of my
| comment. While there are many competing and quality
| options (vibrant), none of them are the de facto leader
| (young).
|
| I think, given where we are in 2023, it'd be difficult
| for a Django (i.e. ORM + templates + web framework all-
| in-one) to emerge in Go - it's possible we never end up
| with one, and that's OK. [I don't think there's much
| stomach for good people to work on sprawling projects
| like that anymore - we're in an season of backend
| development that favors separation (vs bundling) of
| concerns, from my perspective].
|
| I'm not sure if it's a unique feature of the Go ecosystem
| that there isn't one clear winner in the "minimalist +
| pluggable web framework" or "ORM" categories, or if we
| just need to wait for the winner to emerge. Ironically, I
| think the quality of `net/http` and `database/sql` might
| have been an anti-catalyst for the development of leading
| libraries in those verticals.
| [deleted]
| hermanradtke wrote:
| The JS eco-system (npm, React, etc)? Sure. Let us also
| acknowledge that JavaScript, the language, has been
| prioritizing backwards compatibility before golang even
| existed.
| ilyt wrote:
| Well, it is a bit easier if you have no stdlib to speak of
| afavour wrote:
| > I really wish the JS ecosystem could have a stable modern
| foundation we could rely on.
|
| I actually think we do now. ES modules, ES2020 code. Both
| supported by Node and major browsers. Node even has a built in
| test runner now! The problem is getting everyone up to this
| bar. Once we're there I think things are going to feel a lot
| better.
|
| I think part of the problem is that the JS ecosystem also
| encompasses frontend UI work and there are so many different
| applications for it that multiple implementations is
| inevitable. Desirable, even.
| devjab wrote:
| JavaScript is famously backwards compatible. That's exactly why
| it's the mess you describe.
___________________________________________________________________
(page generated 2023-08-14 23:00 UTC)