I’ve once got a contract to write tiny system that had to integrate with 20-30y old system, then written in some version of c# / Microsoft framework, it was only speaking xml. I had problem with timestamp, cause depending on some internal state, it was returned different way. I had to go and read over 100pages of date+time in xml spec and implement it. Also, found that a lib they were using had bugs, so my lib had to deal with it.
I use it when I know what and where need to be done, because the complexity of the system and that making mistakes can fail the whole app. I do research in codebase using Claude ultrathink.
Our system is pretty well tested, so this helps a lot.
I know most people at my company use it, and with pretty good results(?)
Personally, I stoped voluntarily reviewing code and caring about quality of code that I’m not responsible for. The AI slop is real and reviewing it is counter-career, instead of pushing product forward and getting praised you spend it fighting with AI. I just accepted that this is how the products looks these days.
The the introduction of Python 3 wasn't a mistake. The mistake was discontinuing Python 2.
Just look at how rust does it. Rust 1.0 code still works in the latest version of rustc, you just need to set the project to the Rust 2015 edition. You can even mix-and-match editions, as each crate can have a different edition. Newer versions of rustc will always support all previous editions, and breaking changes are only ever introduced when a new edition is released every 3 years. If the crate is stable, no real reason to upgrade, it will work forever. And if you do need to update a project, you can split it into multiple crates and do it incrementally.
Just imagine how much smoother the python 3 transition would have been if you could transition projects incrementally, module by module as needed.
It seems you are both saying the same thing. Had Python not introduced a line in the sand and instead continued to support Python 2 amid future updates there would have been no reason for Python 3. The Python 2 line could have kept improving instead.
Just as you say, Python could have introduced what is found in Python 3 without breaking Python 2 support. Which is the direction Go has settled on; hence why Go 2 is off the table. Go 1.0 and Go 1.23 are very different languages, but backwards version support is retained, so no need for a new major version.
The trouble with the Rust community is that it is terrible at communication. That may be why you extend a presupposition that everyone understands the meaningful difference between Rust editions and Go version directives, but I can't tell a difference beyond the frivolous like syntax used. Based on the documentation of each they seem like the exact same concept, with the exact same goals in mind. As a result, unfortunately, your point is not yet made. Perhaps you can break the cycle and describe for every day people how Rust editions are fundamentally different?
Editions allow making breaking changes to Rust without splitting the ecosystem - no hassle caused to existing code unless it opts into the new edition and its breaking changes. There's currently editions 2015, 2018, 2021, and 2024. When a new edition is introduced, it can make breaking changes such as introducing new keywords, but every previous edition remains supported forever by newer compiler versions.
The key part is that editions are configured per-library - libraries A and B might use editions 2015 and 2021, and your application could use edition 2018 and depend on those libraries, and it works.
If you wrote a library with the original 2015 edition, and never upgraded it to deal with new `async` and `await` keywords added in the 2018 edition, that's totally fine. Newer compilers will continue to compile it in its configured edition=2015 mode, where the new keywords don't exist (so your local variable named `async` still compiles), and new code written against newer editions may still use this 2015 edition library with no issue.
Editions are different from Go version directives because you use them to say "my library needs features added in this Go version", but they don't enable Go to make breaking changes to the language.
Editions can't do every kind of breaking change however - they mostly work for syntax level changes, and don't work for things like tearing out regrettable parts of the standard library.
> The key part is that editions are configured per-library - libraries A and B might use editions 2015 and 2021
In what way is that key? It still reads as being the same as the Go version directive. Obviously there are some differences in the implementation. For example, Go puts it in go.mod, while Rust puts it in Cargo.toml, but at a conceptual level I fail to see any fundamental difference. As you describe it, and how the documentation describes it, they attempt to accomplish the same thing for the same reason.
But, as phire puts it, they are "very different". But I don't see how. The carrying on of the tradition of the Rust community being horrible at communication carries on, I'm afraid. As before, you are going to have to speak to those who aren't deep in the depths of programming languages. Dumb it down for the reader who uses PHP and who has never touched Go or Rust in their life.
> they don't enable Go to make breaking changes to the language.
What, exactly, do you mean? The change to loop variable semantics comes to mind that was clearly a breaking change to the language, but gracefully handled with the version directive. What purpose are you under the impression the directive serves if not for dealing with breaking changes?
For example, https://doc.rust-lang.org/edition-guide/rust-2021/warnings-p... - code that produced a lint warning in the 2018 edition produces a compiler error in the 2021 edition. That would be something that can't be done in a backwards compatible way without editions
Another example would be changes to the import syntax https://doc.rust-lang.org/edition-guide/rust-2018/path-chang... - the compiler will forever support the 2015 behavior in crates that use the 2015 edition, but crates using newer editions can use the newer behavior
As stated before, the documentation in both languages was already consulted. It did not clear up how Rust is any different than Go in this regard. Consider a simple example from the Go documentation: Support for numeric underscores, which was not a part of the original language and later included in a 'new edition' of Go.
i := 10_000_000
Using the 1.13 or later version of the gc compiler, if your go.mod specifies anything after 1.12 the above compiles fine. But if go.mod asserts go 1.12 or earlier, you will get a compiler error from the above code as the compiler reverts to 1.12 or earlier behaviour based on the version directive. That sounds exactly like what you described! And, like I said before, Rust's documentation too echoes to my read that editions accomplish basically the same thing and exist for the same reason Go version directives exist.
But the earlier commenter indicated that they are very different. So, unfortunately, you have again failed to break the cycle. We need something dumbed down for us regular people, not something directed at those who walk, talk, and sleep Rust.
Sorry to have disappointed you. I don't walk, talk, or sleep either Rust or Go, but was trying to provide some resources to help in case you hadn't seen them yet.
One difference I noticed in the docs is in the Go Reference it says the "go" line of the "go.mod" has to be greater than or equal to the go line of all that modules dependencies, if the go line is 1.21 or higher, so a module for 1.21 can't depend on a module for 1.22 [1]
That restriction doesn't apply for Rust, a library using the 2015 edition can use a dependency that uses the 2018 edition, for example.
That's just one difference I noticed in the implementation. The goals seem very similar if not the same
Thanks for trying. But it is the "which is very different to what go has now settled on" that we are trying to get to the bottom of. It appears from your angle that you also conclude that Go has settled on the very same thing, frivolous implementation details aside. Hopefully phire will still return to dumb it down for us.
Ok... the only thing that go version directives do is selectively enable new features. Essentially, they are only really there to help you ensure your code will continue compiling in older versions of the compiler. Hell, until recently it wouldn't even throw an error if you tried to compile code with a future version directive.
The actual backwards compatibility in go is achieved by never removing functionality or syntax. New versions can only ever add new features/syntax. If there was a broken function in the API, that function needs to stick around forever, and they will be forced to add a second version of that function that now does the correct thing.
So, you can take code written for go 1.0, slap on a "go 1.23" directive and it will compile just fine. That's the guarantee that go provides. Well, mostly. There are a few examples of go 1.0 code that doesn't compile anymore, even when you use a "go 1.0" directive.
But not being able to remove anything ever is limiting.
A good example of how this can be limiting is reserved keywords. Go has a fixed set of reserved keywords that they picked for 1.0, and they can never reserve any more, any code using them as identifiers will break. Any new feature needs to be carefully designed to never need a new reserved keyword. Either they reuse an existing keyword (which c++ does all the time), or they use symbols instead.
But rust can reserve new keywords. The 2018 edition of rust reserved "async" and "await" for future async functionality and "try" for a potential try block. Rust did reserve "yield" from the start for generators, but decided they needed a way to mark a function as a generator, so in the 2024 edition, "gen" is now a reserved keyword, breaking any code that uses gen as a function/variable name.
Do note that rust also follows the go strategy within an edition. There is only one new edition every three years, and it would be a pain if all new features had to wait for a new edition. So the async/await keywords were reserved in the 2018 edition, but didn't actually get used until the end of 2019.
This means that just because your rust version supports the 2018 edition, doesn't mean it will compile all 2018 code. The editions are just for breaking changes, and there is a seperate minimum "rust-version" field that's somewhat equivalent to go's "go 1.x" directive. Though, "rust-version" doesn't disable features, it's just there to provide a nice clean warning to users on old compilers. Ideally in the future it will gain the ability to selectively disable language features (as rust already has extensive support for selectively enabling experimental language features in nightly builds, which we haven't even talked about here).
Basically, rust editions allow all breaking changes to be bundled up and applied once every three years. They also provides a way for compilers to continue supporting all previous editions, so old code will continue to work by picking an old version. While go's version directive looks superficially similar to editions, it is there for a different reason and doesn't actually allow for breaking changes.
> The actual backwards compatibility in go is achieved by never removing functionality or syntax.
The previous version removed functionality related to loop variables, so that is not strictly true. You might be right that the project doesn't take change lightly. There has to be a very compelling reason to justify such change, and why would it be any other way? If something isn't great, but still gets the job done, there is no reason to burden developers with having to learn a new language.
Go is not exactly the most in-depth language ever conceived. There is not much functionality or syntax that could be removed without leaving it inoperable. But there is no technical reason why it couldn't. The mechanics to allow it are already there, and it doesn't even violate the Go 1 guarantee to do so under the operation of those mechanics.
So, sure, it is fair to say that there is a social reason for Go making as few breaking/incompatible changes as is possible, but we were talking about the technology around allowing breaking/incompatible changes to co-exist and how the same concept could have been applied to Python. In Rust community fashion, I am not sure you have have improved on the horrible communication. We recognized that there is some difference in implementation details right from the onset, but the overall concept still seems to be the same in both cases to me.
Again, we need it dumbed down for the every day average person. Your audience doesn't eat monads for breakfast like your expression seems to believe.
> Go 1.22, for example, removed functionality related to loop variables, so that is not strictly true.
Ah, interesting. I searched but I couldn't find any example of go actually making a breaking change. Rust has a massive document [1] documenting every single breaking in single document. With go you kind of have to dig through the release notes of each version.
So, maybe Golang are relaxing their stance slightly on backwards compatibility, now that they have a mechanism that does kind of work. Which is good, I encurage that. But their offical stance is still that most code from go 1.0 should work without issues.
> there is no reason to burden developers with having to learn a new language.
To be clear, many of the breaking changes in Rust editions are the same kind of thing as that go loop example. Edge cases where it's kind of obvious that should have always worked that way, but it didn't.
The average programmer will barely notice the changes between editions, they won't have to re-learn anything. The major changes to the language usually come in regular feature releases; They are optional additions, just like go.
While the edition mechanism could be used to make changes as big as Python 3, so far it hasn't and I don't think it ever will. Decent chance there will never be a "rust 2" either.
> In Rust community fashion, I am not sure you have have improved on communicating the difference
Sigh... you aren't wrong:
----------
The difference is more attitude than anything else.
Go strives to never have breaking changes, even if they are forced to bend that rule sometimes. They do have a mechanism that allows breaking changes, but seems to be a reasonably recent innovation (before go 1.21, it wouldn't even error when encountering a future go version directive, and they didn't use it for a breaking change until 1.22)
Rust accepts that it needs to do breaking changes sometimes, and has developed mechanisms to explicitly allow it, and make it as smooth as possible. And this mechanism works very well.
----------
BTW, I'm not even saying go's stance is wrong. Rust needs this mechanism because it's a very ambitious language. It never would have reached a stable 1.0 unless it recognised the need for breaking changes.
Go is a much simpler language, with a different target market and probably should be aiming to minimise the need for breaking changes.
My original point is that "never make breaking changes" is the wrong lesson to take away from Python 3. And that Rust's editions provide a very good example of how to do breaking changes correctly.
> My original point is that "never make breaking changes" is the wrong lesson to take away from Python 3. And that Rust's editions provide a very good example of how to do breaking changes correctly.
Here we go again, but the point of editions, as far as I can tell, is so that there are no breaking changes. A value Go also holds. As a result, both projects are still at version 1 and will likely always forever be at version 1.
So, if we round back to the start of our discussion, if Python 2 had taken the same stance, there would never be a Python 3. What we know of as Python 3 today would just be another Python 2 point release. Which is what the earlier commenter that started all this was saying – Go will not move to Go 2, and Rust won't move to Rust 2, because nobody wants to make the same mistake Python did.
I understand you have an advertising quota to fill, but introducing Rust into the discussion was conversationally pointless.
> I understand you have an advertising quota to fill
This is a ridiculous statement and you are intentionally engaging in bad faith. There's no need for this in response to people genuinely trying to answer your questions. Be better
I'd say Rust editions are more like going from Python 2.x to Python 2.y, than the 2->3 migration. The Rust standard library is still the same (and the string type is still "valid UTF-8") no matter the edition (this is why you can mix-and-match editions), the edition differences are mostly on the syntax.
> Just imagine how much smoother the python 3 transition would have been if you could transition projects incrementally, module by module as needed.
That would require manually converting strings to the correct type at each module boundary (you can't do it automatically, because on the Python 2.x side, you don't know whether or not a string has already been decoded/encoded into a specific character encoding; that is, you don't know whether a Python 2.x string should be represented by a "bytes" or a "str" on the Python 3.x side). That's made even harder by Python's dynamic typing (you can't statically look at the code and point all the places which might need manual review).
It's not that simple. If the country introduces a legislation, every company operating in it's border must comply.
If EU would introduce such legislation, it could potentially make software doing end2end encryption illegal. In such case, google would be removing it from EU Play Stores, and this would be more/less end of such messaging apps unless they comply. :-)
This is why it's important to have a reasonable legislature and laws.
> This is why it's important to have a reasonable legislature and laws.
And multiple points of control. In the EU the council acts as a check on populism through parliament (even if the nazis took over parliament it wouldn't give them a lot of power), parliament acts as a check on the council (even if the heads of 70% of EU countries decided something, parliament gets its say). Neither of those are the executive so they would be unable to push through laws which favour specific countries or groups of countries (as the commission are supposed to act primarily on behalf of the union, in the same way the US president is supposed to not favour his home state). Then outside of government you have the judiciary who look at the laws passed and interpret them in line with other laws, throwing out ones which are incompatible.
It'd give people all the more incentive to sideload and get off Google Play Store. That's a win win in my book. And Signal is a non-for-profit. I don't see why they'd care. Designing system that subvert authoritarian regimes.. what's more punk than that
If you have to ask governments for permission then that's a bad design and your system will be taken away from you when the next think-of-the-children populists are elected
If you work on the assumption all governments are eternally nice and well interventioned .. then E2E chat systems aren't all that necessary in the first place
> Chat control - one of the worst EU plans that is also being described as a surveillance monster - must be stopped. And the EU Parliament has just decided to do so! In a historic agreement on the EU Commission's Child Sexual Abuse Regulation (CSAR) the European Parliament wants to remove chat control requirements and safeguard secure encryption. The decision came after extensive backlash against the original proposal from technology and security experts, to international scientists and to citizens across Europe. This is a great win for our right to privacy and for upholding our democratic values in Europe, but the fight continues!
What did the EU Parliament decide?
Breyer writes on his website that internet services and apps must be "secure by design and default". The EU Parliament has agreed to:
"safeguard the digital secrecy of correspondence and remove the plans for blanket chat control, which violate fundamental rights and stand no chance in court. The current voluntary chat control of private messages (not social networks) by US internet companies is being phased out. Targeted telecommunication surveillance and searches will only be permitted with a judicial warrant and only limited to persons or groups of persons suspected of being linked to child sexual abuse material."
A huge win for our privacy rights is also that the EU Parliament has decided to "clearly exclude so-called client-side scanning".
In contrast to the original chat control proposal, the version of the EU Parliament wants that a new EU Child Protection Centre proactively searches publicly accessible parts of the internet for child sexual abuse material with automatic crawling, which can also take place in darknet and would be much more efficient than private surveillance measures by providers. Found abuse material must be reported and taken down by the provider.
Fight is not over
While the EU Parliament's decision is a huge win, the fight is not over. It is expected that the EU Commission will continue to push for general surveillance chat control measures. Now is the time for each and everyone of us to join this fight!
> ... which violate fundamental rights and stand no chance in court
Thankfully the EU still has the European Convention on Human Rights and an associated court which individuals can go to and sue their state: the European Court of Human Rights. This is unlike the European Court of Justice which cannot directly be seized by individuals.
That EU Convention on Human Rights contains the "right to privacy" (art. 8).
This may be what they meant by saying that this horrible text stood no chance in court: a deluge of individual going to to the EU Court of Human Rights invoking article 8.
Now I don't doubt that the sold outs and enemy of the EU states at the European Commission are going to come back with other horrible measures.
As a sidenote this whole "good cop (European Parliament) / bad cop (European Commission)" is a bit of a farce played on the EU people too.
That's why we have strong checks and balances, the commission (made up of appointees of the 26 EU government heads) will push things, the council (made up of those heads) have to agree, and the Parliament (made up from a popular vote) has to agree, then if all that fails the courts step in
But the fight isn't as much against the government, it's the hearts and minds of the people to make them care more about their own privacy and security rather than "someone think of the children".
I don’t think the average person cares about privacy, sadly. “I have nothing to hide,” etc. The best argument I heard against this crazy policy (only heard recently during these hearings) was that many creators/sharers of this CSAM material is kids themselves! Young teens exploring their sexuality, swapping nudes with each other. So that means that if you’re scanning all messages and you come across one of these chats, instead of that conversation staying between the 2 teens (like it should), it’s getting scanned by the provider, flagged, uploaded upstream to some law enforcement center where god knows how many other people are going to be looking at it, only to realize that there was no abuse happening. And of course that comes with the risk of leaks/hacks/rogue employees spreading it even further. Completely insane!
Checks and balances are working this time hopefully. Regardless our
(good) multi-stage processes and multi-chamber structure and even,
regardless matters of lobbying and money - in the moment of quiet
while smoke is still on the wind - look for the shooter. "Who wants
this?" and "What are their fears?" leads to a better leverage point
closer to values than parameters.
There are a lot of people in the world right now anxious about the
digital future. The EU Commission seem to hear too much from
Chicken-Licken's gang of sky-repellant gizmo salesmen and not from
calmer humane optimists.
I can't see any specific benefit to this for a corporation, my feeling is it's a political response to a general disquiet with the tech industry abusing people, along the lines of "something must be done, this is something, therefore this must be done"
I'm sure some companies would make a fortune, but their lobbying power would be outweighed by other multinational companies like whatsapp and smaller companies like mullvad.
reply