Proposal: Go 2 transition
github.com
github.com
(1) Announce the next major version to be far off into the future, and say it will be as backwards compatible as possible to keep developers supporting the old version, e.g. Go 1->2.
(2) Build next version to be a little different to current version, provide no facility for interoperating between versions, then expect developers to switch over because of the branding, e.g. Python 2->3.
(3) Announce next version to be far off into the future, and say it will be a totally different language and expect developers to switch because of the branding, e.g. Perl 5->6.
(4) Don't announce or build a new major version, and keep profiting from developers using the current version for as long as possible, e.g. Java 1.x.
(5) Announce next version to be very soon, but delay it for as long as possible with unofficial roadblocks and keep profiting from developers using the old version for as long as possible, e.g. Apache Groovy 2->3.
Calling a Perl 5 module from Perl 6 can work I believe ( as well as other languages!), which is somewhat of a miracle. But it's interfaced using Perl 6.
To call Perl 5 code from Perl 6, we currently have Inline::Perl5 (https://modules.perl6.org/dist/Inline::Perl5:cpan:NINE):
> Supports Perl 5 modules including XS modules. Allows passing integers, strings, arrays, hashes, code references, file handles and objects between Perl 5 and Perl 6. Also supports calling methods on Perl 5 objects from Perl 6 and calling methods on Perl 6 objects from Perl 5 and subclass Perl 5 classes in Perl 6.
In a similar vein, there are Inline::Python (https://github.com/niner/Inline-Python/blob/master/README.md) and other Inline modules (https://modules.perl6.org/search/?q=Inline ) that can be called from Perl 6.
In fact C has an ABI and doesn’t suffer the problem that sibling commenter mentioned.
And C++ just piles up features, supporting everything forever...
I’m not a language lawyer, but one would be able to rattle of a long such list.
With straight native code, the story is a bit different.
I really don't like the idea of always thinking of Backward compatible though. Things will need to move forward. I think for a major version of a programming languages, it must provide something that offer major incentive for programmer to switch. For example if you want JIT that offers 2-5x the performance, it should only be working with new version going forward, and gets a chance to clean up any debt in the languages made over the past decade.
JS is looking a lot like the C++ story. Totally different language.
I'm fine with the burden of the upgrade being transferred to users of the C API - that seemed like a very astute trade to me - but the process could've been made a lot easier with a proper upgrade guide rather than a few hasty, incomplete notes in the wiki.
> A real Go 2 would, perhaps unsurprisingly, be harmful.
Nicely done!
Back to Go!
Also, please try Perl 6. The marketing may be a cautionary example, but the language itself reflects 15 years of polish.
While I respect that Perl development is still going, I haven’t seen it used by anyone in production for at least 15 years.
You should have skipped cPanel though from that list. That doesn’t build credibility ;)
I think by that they meant "where I've actually seen" (e.g. c ompanies parent worked, visited, friends have etc), not that in general one can't get 10 or 1000 examples of businesses still using Perl from the whole of the internet.
It would also likely be better (more readable and maintainable) and faster written in something else (did a partial Python port to understand what kind of munging the script actually did, the Python version was 50% faster, and a bit shorter though the latter may have been because I didn't test/check all features and some of the edge cases may have been missing in the non-default options).
Yep it is JavaScript: https://github.com/google/pprof/blob/master/third_party/d3fl...
I couldn't be happier for the choice I made: I'm working remotely from Romania for a US based company since 2015, making multiple times the average national income.
I am contacted quite often on LinkedIn for new Perl job opportunities.
I would say Perl is quite a vibrant and well living language, with a great career perspective for those who learn it.
For instance, say Go wanted to introduce a moving GC, and say that required removing interfaces as map keys. How could a function that returned a map[interface{}]int in one module be called from another that was compiled with a later version of Go?
Would the whole program would have to be compiled with the non-moving GC?
Perhaps the answer is that Go would never introduce such a change.
Like with randomizing hashmap keys, they randomly enforce the rule to make sure that no one relies on it just happening to work since Go's GC doesn't currently move pointers.
Another approach would be to use two different map implementations, and use a less efficient one for older code that used an interface type as a map key.
It's an interesting example, though. You're right: if there is an old language feature that can not be supported by a newer runtime, then there needs to be some sort of shim to let the older code keep working. That necessity may prevent us from making certain sorts of language changes.
We all know how bad evolution is in commercial world, force evolution is a need. Software is not a product, can't last forever untouched.
Am I alone in thinking that's a terrible idea, that having module authors around the globe define a maximum version is going to result in masses of libraries pinned needlessly to old versions, and masses of unmaintained but otherwise solid and complete libs unpinned, despite them now needing a maximum version pin?
I agree that unmaintained libraries that don't adapt to modules could be a problem. We'll have to see what happens.
It is pointless to compile source code of a certain version (e.g. C++17) with the wrong options switch.
Actually, even those people aren't what hobbled the Python migration. What made it such a mess was that the core team didn't tell that crowd to fuck right off and get with the program or get left behind.
And even now with 2.7 nearing end of life, those same grumpy curmudgeons hang around web forums and reddit and blogs here and there, giving new people bad advice, complaining about how much better the old days were before unicode and async and types. I even saw someone griping about those new-fangled decorators and how monkeypatching was better.
The thing that made a mess out of the transition was the core team trying too hard to coax people who didn't want to move into coming along with them with a small bucket of carrots and no sticks. They tried to pull the bandaid off slowly and it took too long and still hurt like hell.
Yes, you have to write correct code now. Yes, this requires changing some stuff. But yes, this is better for everyone in the (not so) long run.
https://docs.python.org/3.0/whatsnew/3.0.html#removed-syntax
The removals were actually an easier pill to swallow than the numerous subtle changes in behavior introduced by the big, deep switch to Unicode. I'm over it now, but that was painful!
One example comes from the new-style / old-style classes distinction and the method resolution order when considering multiple inheritance.
Python 2.3 introduced "new-style" classes which inherit from `object` and use the C3 resolution algorithm [1]. For backwards compatibility reasons, "old-style" classes without an explicit `object` base class still used the old method resolution semantics.
Python 3 does away with "old-style" classes entirely and all classes must use the "new-style" semantics.
There's presumably a ton of code that doesn't specify `object` as an explicit base class, and thus may have subtle broken behaviour under "new-style". Given Python 3's inability / unwillingness to simulate the old behaviour, I'm unaware of any tool that's able to rewrite Python 2 to 3 in a bullet proof fashion [2].
This is not the same kind of breakage that other people mention, like `print` being a function or `reduce` being moved to `functools`. Those are simply backwards incompatible "movements", not outright removals, and thus can be rewritten by automated tools.
[1] https://www.python.org/download/releases/2.3/mro/ [2] https://portingguide.readthedocs.io/en/latest/classes.html#n...
python 2:
print "foo" # foo
3 / 5 # 0
apply # <built-in function apply>
python 3: print "foo" # SyntaxError: Missing parentheses in call to 'print'
3 / 5 # 0.6
apply # NameError: name 'apply' is not definedWhen working with a wire protocol like ssh, you need to work with sequences of bytes, not Unicode strings, and porting code that assembled them using % formatting was a huge pain; I tried and failed to port paramiko to python 3.
python3 code cannot import python2 libraries. That split the ecosystem.
Go intends for a go2 library to be able to import and use a go1 library.
This means there isn't a split in the ecosystem at any point in time.
It's fine to remove a feature as long as old programs still build because you must opt in to the removal via setting "version=go2" or whatever in go.mod.
This is distinctly different from being the perl and python transitions because the new compiler can still build old code, including with removed features, until you opt into the new language version.. and even once you do opt in, all your dependencies are fine whether they have opted in or not.
This is different from python 3 because python 3 cannot run python 2 code, even if told that some library is python 2. That is where the migration pain came from.
A) being overly restrictive, and declaring the current released version as your max, breaking for a short time on each new lang version
B) being psychic, and knowing when (without the aid of semver) your package might break
An unmaintained package will not be updated with the max flag when the breakage occurs.
Any package always declaring the current version will have to be updated for every new release.
Both seem like a lot of admin.
I know using unmaintained packages isn't ideal in the first place, but it happens, and packages exist that are pretty much "finished" and very light on bugs, if they were stable and heavily exercised for some time before losing their maintainers.
I.e. future compilers can understand previous version of the language spec.
They both ended up with very similar results (define a version in cargo.toml/go.mod, use that version of the language to build), but there's also more to it than that, and the rust proposal could help guide discussion of other possible issues too.
I use rust a lot, and it’s been heavily geared towards nightly for a long time.
The whole rust nightly/beta/stable hasnt worked well, because (afaik) the beta usage is tiny and people tend to jump on nightly or stable. It’s only very recently any effort has been made to change this for the new edition.
...so, you know, the comment may not be entirely accurate, sure, but it’s our fault people have come away from rust feeling that way.
The OP is not at fault here, and definitely not, I think, willfully lying.
Take a deep breath; there’s no need for this sort of attitude, and frankly it reflects badly on the rest of us (rust users).
My impression was that most people feel the Beta toolchain is doing its job just fine, because most projects that use CI include a Beta test run. I don't think the plan was ever to have people using Beta on the command line as their daily driver.
Notice specially the last month or so of actively asking people to try the beta.
If it wasn’t a problem, that wouldn’t be happening.
> Notice specially the last month or so of actively asking people to try the beta.
This is because for the last month the beta has represented the first release candidate for Rust 2018, which is more important than normal releases in all three of implementation scope, backwards compatibility concerns, and marketing potential.
Rocket requiring nightly is unfortunate, and I wish it didn't, but aside from Rocket stable has been a good forcing function to get crate authors to not add nightly dependencies.
Anyway, from what I see, actix seems to get more buzz than Rocket these days, precisely because the former works on stable.
It’s not like we’re past the nightly being the first toy people reach for to solve problems; that is still very much a thing.
Some crates will always require nightly because there will always be some people that want to take advantage of the latest features. That's a good thing to a degree, because it encourages experimentation with said features before stabilizing them. This is completely different from implying that nightly Rust is required by a lot of popular crates, which just isn't true. Most people are productively using stable Rust.
/shrug
The OPs point about some/many/[??? numbers of] people not using stable isn’t that unreasonable imo...
A year is a long time!
No, it doesn't.
It seems unlikely, if Rust's policies do a good job of maintaining guarantees in a chaotic environment like that, that they would fail in a more placid environment.
Whether Rust has some differences in its versioning, the situations are similar enough that I assert Rust's choices are relevant.
The fact that Rust itself may or may not have stability or backwards compatibility (I mean, I think it objectively does) isn't actually as important as the fact that the rust team wants to have those things and has thought hard about basically the same problem Go is tackling now, and has already taken the effort to write down its thoughts and conclusions.
If you want to claim I shouldn't bring up Rust's "editions" work, I'd rather you talk about the "editions" RFC rather than Rust's slightly different versioning scheme.
Rust also adds real sum types and a tuple type. Multi-value returns are just tuples, they aren't a special case of the semantics. Result types let you avoid writing if err != nil everywhere, but we still believe in the mantra of not panicking for things that are not truly exceptional.
Rust is also closer to C++s performance, and it's a strongly community driven project. We also have great concurrency primitives. We have channels, but we also have futures, which can be scheduled on green threads in a CSP style just like Go, or can be run behind the Actor model, using async/await syntax with polling... there's a lot more flexibility there to align the language to your business needs.
On the topic of the original thread, I wonder why Rust wasn’t included; maybe it’s because our first release that’s achieving similar goals is happening six weeks from now, and they wanted to see how things played out in practice, not in theory.
Well that's true for most not-so-semi-trivial stuff one has to learn, it doesn't mean is always a good idea though.
Just giving a different perspective to beginners.
What's happening in the next release? Any backward compatible breaking changes?
When you grow to a certain size though, it becomes very messy. Go has very little facility for abstraction despite being a higher level language with a GC and a substantial runtime. I also personally find the error handling frustrating. Most of the time all you want to do with an error is send it to the caller, who has more context on how to handle it.
I still write Go alongside Rust, but I use it as a scripting language, for all the things I used to use Python for. Rust just has the tools I need to build abstractions, and lets me avoid continually rewriting data structures.
Having ADTs/Sum types will improve the reliability of your software immensely just by being available. It's truly absurd just how much work they can do: They can replace "null", they can ensure that there are no surprises in a state machine where some state carries over unexpectedly, etc. etc.
[1] Not higher-kinded, but that's probably a distraction for the point I'm making.
Tangent: I wish Rust had optional chaining like swift, which I know is a limitation due to Option just being a normal sum type. Having to pattern match every optional is burdensome
[1] I'm using this as a proxy name for a trick I saw on cppreference where you can (via template tricks, why not?) write code very similar to pattern matching, but it's ultimately quite simplistic and brittle.
This is the trade off.
Sure the upfront investment in Rust higher, Go is almost too small, but the upfront cost of Rust is amortized via the hours you save with all the abstractions and performance you get right out of the box.
It’s just too confusing of a term these days, and nobody knows what it actually means, so it’s not useful.
Likewise those universities doing OS research in Go, submitting their findings to USENIX.
I agree, but I think many people assume that this is the only benefit achieved. The presence of the borrow checker and rigorous memory safety requirements allows the compiler to take substantially more advantageous paths in allocation/deallocation compared to e.g. C. The benefit attained is similar to the benefit of switching from C to very well memory-managed C++, except it comes by default.
This is a significant advantage even in code that is not concurrent at all. I feel like it's a shortcoming of Rust's marketing, if anything, that the safety restrictions are often pitched only in context of thread-safety rather than memory-usage-optimization.
If they would give me generics and ADT, I don't think I would ever use any other language.
When I write code that is going to run on the customer’s device, I choose Rust for the guarantees it offers me, (I know it will not crash because of my mistake). For server side code on the other hand, something easy going as Go is much preferred.
FWIW, async/await does produce a “stack full” coroutine: you get a single, exactly sized stack for each task, every time. This is made possible by coroutines being fundamentally stackless, but in the end, tasks still have stacks.
I see, thanks for the info. I wasn't talking so much about the implementation but the difference between the program control flow differences between the two models, go-routines vs async/await.
And nobody's going to provide their data structures specialized to every type you could possibly want. Case in point: container/heap from the standard library takes and returns interface{}.
Its more fun for some to do so, for ex: the Go2 proposal might be too boring to discuss.
http://www.ada-auth.org/standards/index.html
Like with other languages, each vendor is free to do their best for optimizations, while keeping language semantics.
Besides Ada Core, there are a couple others but at enterprise budget levels.
Rust just happens be extremely popular right now, along with python and go.
Rust is a C replacement, Go is a replacement for everything else ;)
It's kind of in-between C and C++ in terms of capabilities, and neither a subset nor a superset of Ada's features in terms of safety. Some of Rust's memory safety features are only now being added to Ada and not yet in the forthcoming standard, whereas Ada has many features that Rust still lacks (e.g. integer range subtypes, OOP with inheritance). Rust is less secure than Ada/Spark, though, and clearly not intended for high integrity systems.
It seems that the niche Rust is aiming for is "safe general system's programming for people who primarily use C and C++ but have never used much Ada or Haskell", and in that area it's quite successful.
Both Rust and Go are odd, because they have less features of C++ (plus added safety) and attempt to sell a lack of features as advantages, whereas in reality no one forces you to use a feature and their developers are merely pushing their own, personal agenda about "what's the right thing to do". I personally don't like C++, but one of its benefits is that it leave its users the choice of what's the right thing to do and offer as many zero-cost abstractions as possible. Rust and Go are way more patronizing.
I really like Rust and use it for major projects, but I fail to see how it's much on topic. I agree with other comments that it gets compared to Go all the time, often without prompting or relationship to articles. Want to do that, why not write an article or do a separate post? Hijacking the comments and/or shilling Rust is getting old.
I have to say that although I love Rust and somewhat despise Go, if it works for you, use it. Go is good at a lot of things - identify what they are and use it because it solves your problem. If another language does that better, use that instead. If you don't know what those things are, you probably need to spend some time not only reading, but writing actual code in that language.
Don't pick one language to solve all your problems and don't look for problems because you like a language or some specific features of a language. Consider the entire scope of your issues, both technical and non-technical. In that sense, I can see why a lot of people choose Go and it is just as valid as any other language choice.
Other users have started to complain about you doing this repeatedly, so we need to ask you to stop. No more of this, please, regardless of how much you like Rust.