Open lizmat opened 1 year ago
It has been argued that not specifying a language version would be confusing for newbies, as the exact semantics of the language could be shifting.
I think this argument can only hold true for a very insignificant part:
Most newbies will have way more trouble grokking general Raku Language concepts, so will mostly stick to simple Raku anyway, of which the semantics wouldn't be changing much anyway.
Newbies should be told to specify the language level that they expect for their code as soon as possible. As that is what will guarantee their code working in the long run.
Does specifying it in the META6l.json alone and not in module code satisfy that requirement?
I suppose that could be construed as confusing or bad practice by new Rakuer.
I think that specifying it in the META6.json
should be enough for the language version, but also for the module version / auth / api
I think the proposal addresses a long-anticipated issue but it does so the wrong way around.
It has been argued that not specifying a language version would be confusing for newbies, as the exact semantics of the language could be shifting.
I think this argument can only hold true for a very insignificant part
I think actually that is the right direction. First I'm going to counter-argue with the points here, then roll out the whole argument.
Most newbies will have way more trouble grokking general Raku Language concepts, so will mostly stick to simple Raku anyway, of which the semantics wouldn't be changing much anyway.
First, it's hard to decide what "simple Raku" even is (let alone when none of us are really "simple Raku users"), or generalize over "most newbies" (let alone when none of us are newbies). Let me just say one example: truthiness of Range
s. Lately, it has been discovered that infinite Range
s are False
-y for a banal technical reason but it cannot be brought to existing versions. This illustrates that some user code already depended on it, and it is pretty simple. The irony is that it was pretty old code that specified "perl": "latest" in the META and nothing in the compunit so it will break anyway, except we can say "it broke rightfully" when it finally does.
Newbies should be told to specify the language level that they expect for their code as soon as possible. As that is what will guarantee their code working in the long run.
This is part of my core argument actually: if it's universally accepted that new users should be told to specify the language level, why not be proactive and warn about the lack of it? That is something we can control, unlike what individual users are told. And even if they are told about it but forget it or don't estimate the importance of it correctly: do they deserve a landmine in their code? It feels like such an unnice thing, to make the wrong thing the easiest thing and then blame them when it explodes on them.
So, my way of thinking can be compiled into the following points.
use version
pragma seems overboard, especially for a transition. Since the education process is similar to deprecations (e.g .pm extension recently), "worries" seem to be the way to go.Anyway, I think even just locking the inferred version is better than the current behavior, and even the current behavior is better than the proposed "bleeding edge" behavior, saving a couple of characters for the well-informed and inviting to do something fragile for all the others.
After reading the responses so far, I realized I've conflated two issues in here, that potentially muddy the arguments. Since most of the responses so far have been about the behaviour of Raku in absence of a version statement, I'll rename this issue accordingly and start another issue about how we develop FOUR further.
My ¢2: use v6x
statements are strongly encouraged and are likely to be absent in only two main places: very short scripts and code by very new Raku users (perhaps users trying Raku out for the first time).
Thus, in my view the best way to answer the question "What should the absence of a use v6x
statement mean?" is to answer the question "What language version do we want to be used by short scripts and new users?". And my answer to that question is "a reasonably recent but stable version of Raku". In particular, I wouldn't want either of those use cases to miss out on a huge number of Raku features (as they would with an especially old Raku version) or to run into not-yet-caught bugs (as they might with a preview Raku version).
But others might answer that second question differently, and I'll be interested to hear other's views. Nevertheless, I think that scripts/new users are the use case that should drive our decision about how to act in the absence of a use v6x
statement.
I would argue that newbies generally would not build their own Rakudo, and thus would be using 1. a language level release, or 2. maybe a (monthly) Rakudo release. 1. would ensure very stable, and 2. would ensure some level of stability which bleed would not give.
use v6x
statements are strongly encouraged and are likely to be absent in only two main places: very short scripts and code by very new Raku users (perhaps users trying Raku out for the first time).
Genuine question: have you ever checked the ecosystems to confirm this statement? Or where do you get this impression from?
Honestly, I'm just checking code that I released (more often I just maintain them rather than initiated them but still, it's mostly my responsibility at this point): Template6 has no use v
statement (and "perl": "6.*"
in the META file, uh-oh), HTML::Tag just spams use v6
and has no META-level versioning whatsoever, Int::Polydiv has no use v
and weirdly for 2022, it has "perl": "6.d" - I surely didn't type this one out, where did I get it from...
Now, of course I can walk around and fix this issue for a lot of packages but the point is still that quite easily the majority of code out there has no use v
indication, and quite often not even a sensible META field. Encouraging people to add it doesn't seem to be enough, especially considering that the lack of it is basically wrong for any released code.
FWIW, in the case of modules, a language version specification in the META6.json should be leading for the modules in that distribution.
Even with a monthly Rakudo release, use v6.e.PREVIEW
gives a very different feature set than use v6d
and, if I understand correctly, we (Raku/Rakudo) generally don't promise the same level of bug-checking/stability guarantees with the PREVIEW
build.
Maybe part of the problem is that we're actually not at all explicit about what backwards compatibility guarantees we make, and thus aren't clear at all what the difference between release
and PREVIEW
guarantees are?
Lack of a specific version should indicate the latest version up 6.e
. Afterwards Raku should complain about that lack. After 6.e
die
ing. The timeline is subject to dispute; I favor not letting the problem grow.
In this context, PREVIEW
is part of 6.*.PREVIEW
.
I'm still musing about it, but have some thoughts.
use v6.<something>;
at the start of your code. We'll get back to it later, but for now just remember this simple rule.'PREVIEW
suffix. It was decided that code using it must work with a released language version as if nothing has changed. Having written some code with actively used v6.e.PREVIEW I now see a good point in that approach. It would barely make anybody happy about their code start generating warnings simply because a dependency hasn't got time to get rid of the suffix.Another big point: compiler version dependency can't be avoided altogether.
First of all, even though we are far from being there yet, but imagine an alternative to Rakudo implementation of Raku which doesn't offer the same set of implemented features, as Rakudo does. Any code wishing to work for any compiler would either have to stop using "controversial" features or check what compiler it's being compiled by.
BTW, the latter paragraph could spur a big discussion about Roast. There are still a lot of tests that are supposed to be part of 6.c but are not implemented by Rakudo so far. We would have to address this matter too because otherwise the meaning of 'language version semantics' is fuzzy and kind of a moving target. But this subject alone is so big that I would just mention it and do no more.
Second, when it comes down to bug fixing then compiler version test is something unavoidable sometimes too. It is no so uncommon to misinterpret a bug as an intended semantics and rely on it. Fixing such bug would create a dilemma: either drop support for older compilers, or make sure we support both broken and fixed versions.
And, in the conclusion, let me find a fly in the ointment. Sometimes it is not possible to implement a feature for a specific Raku CORE. There no single reason why. For example, implementing it may require reliance on a lexical variable available in a scope of an older CORE. Not a very common situation, but not impossible. In such case it might turn out that implementing something new within older core would prove to be more efficient than any kind of workaround.
I don't have a solution for the problem whatsoever. Best if it is entirely pulled out of thin air. But I'm cannot convince myself that it is.
Another big point: compiler version dependency can't be avoided altogether.
On Tuesday, 26 September 2023 05:46:37 CEST Vadim Belman wrote:
- No version should be a warning.
That would suck for shell one-liners. I think there's a reasoable compromise though. No version should be a warning when precompiling, i.e. for modules. Chances of those getting published/used in the long term are much higher than for one-liners or scripts, so it makes sense to be more strict with those.
No version should be a warning … for modules.
I like that. Maybe also a warning for bin scripts in when uploading a distribution (though I guess that's more of a fez issue than a Raku one).
@vrurg, I am with @niner regarding one-liners, a possible solution below.
That 6.d
should be the default when the version is unspecified is great assuming a timely decision.
PREVIEW
is problematic as @lizmat (IIRC) stated: What does PREVIEW
promise?
My assumption was that it is unstable. So it is reasonable that any script which is without version or is not v6.*.PREVIEW
dies upon use
ing a PREVIEW
. That v6x.PREVIEW
means v6x
at some point in time seems bad because the action of the PREVIEW
is variable over time. If the behavior of PREVIEW
is to change, the name should change. I endorse ALPHA
.
The compiler executable's name could dictate some behavior. Rakudo seems to usually install a binary raku
. To me that implies that no rakudoisms should be enabled by default. That that default be applied to all rakudo binaries would partly
address some of @vrurg's concerns, by showing a line between Raku and Rakudo -- a clearer starting point.
Some name could designated for one-liners disabling the unspec-ed error.
I agree with @codesections that fez
is a good tool to address this. But the definition of best practices for code distribution should be defined here, and best by some koalatee
tool.
I am a beginner and from a starters perspective it shall be as easy as possible, avoiding as much boilerplate code as possible. Requiring a use v...
is IMHO boilerplate.
I learned that I shall inject custom module paths by using raku -I path/to/lib ...
instead of hardcoding use lib '/path/to/lib'
inside my script. So why not use the same approach for specifying a specific Raku version, IF required at some point in the future by users of a script? This would allow users to omit use v6.whatever
in scripts but ensure at the same time that IF a script, that was ment to be used for 5 minutes is still in use after years, CAN be used, without changing it, just by simply setting some environment variable or adjusting the call (in you crontab or wherever you start the script) by a simple parameter like raku --use 6.old.version.WHATEVER quick-and-dirty-that-lasted.raku
For modules the depreciation warning "... change to .rakutest" worked IMHO quite well, so why not do the same to get rid of missing and wrong version statements in META6.json. This is also in line with the approach of encouraging developers to specify specific <auth>
and/or <version>
and/or <api>
in the META6.json for the dependencies they use in their module - if a developer bothers/needs to do so.
JM2C
Note: this is NOT about naming versions. That is another discussion. To avoid that discussion, I'll be using
ONE
to indicate6.c
,TWO
to indicate6.d
,THREE
to indicate what is now6.e.PREVIEW
, andFOUR
for what will be6.f.PREVIEW
if we stick to the current language level scheme. For the record: this (1,2,3) is now the internal numbering scheme that is used in the Rakudo compiler.If there is no explicit version specified in code, we assume the current "standard" version (which is now
TWO
). I think it could be argued that this is wrong.If there is no indication of a language version (or a bare
use v6
), it can not be determined in which version the code is supposed to run. We therefore recommend people to specify the required language version in their code. But many people don't. Which either indicates a lack of interest, or the assumption that it will run on any version, as the code is maybe just using very basic functionality.Specifying
use v6.d
currently, does not fixate a set of semantics and capabilities, sadly. Since the release ofTWO
, many features have been added. Which has led people to having to specify a Rakudo compiler release in their code to ensure proper functioning. I think we should not make that mistake with the release ofTHREE
again.If you want your code to use capabilities of
THREE
, then you will have to specifyuse v6.e.PREVIEW
. This means that your code will start producing warning whenever it runs with a released version ofTHREE
, because thePREVIEW
part has become obsolete on that language version. It would be an option to be silent about this, but that feels like covering up.Specifying a language version in your code should indicate a fixed set of semantics and capabilities. Let's at least make sure we don't add semantics and capabilities to
THREE
once it has been released, and make sure that all developments take place inFOUR
.I think it is a good idea to force people to be explicit about the semantics that they want. I think that therefore we should make the
FOUR
the default language version whenTHREE
is released. This will make sure that we have a fixed set of capabilities and semantics if someone specifies a required version in their code. If they do not, they get the bleeding edge. Which most likely will do what is expected anyway.