It would be useful to be able to check the Chapel version number within a Chapel program at compile-time.
A viable solution today is implementing the versions as individual params:
// Just making up the names for now...
param chplMajorVersion = 1,
chplMinorVersion = 14,
chplUpdateVersion = 2,
chplBugfixVersion = 3;
// Single param for version comparisons:
param chplVersion = chplMajorVersion*1000000 + chplMinorVersion*10000 + chplUpdateVersion*100 + chplBugfixVersion;
writeln(chplVersion); // 1140203 (1.14.2.3)
We could also create a primitive to access the compiler's internal copy of the version number, so that we don't need to maintain the version numbers in both the compiler and module code.
Here are some more appealing options that would rely on features not yet available in Chapel:
param chpl_version = (1, 14, 0);
if chpl_version < (1, 13, 0) then
compilerError('This program requires at least Chapel 1.13.0');
param chpl_version = (major=1, minor=14, update=0); // using Pythonic named tuple syntax
if chpl_version.major < 2 then
compilerError('This program requires at least Chapel 2');
I would like to work on this issue. I build the code and get familiarize myself with the chapel, I am new to chapel, please help me solving the issue.
Hi @sagar-sam, thanks for your interest in contributing. However, I believe the primary effort required on this issue is coming to a consensus on how this should be implemented, rather than the implementation itself (otherwise, I would have thrown an easy label here.)
I don't believe there are any pressing issues that depend on this being implemented at the moment, but it should certainly be implemented by Chapel 2.0.0
I've got a start on this in this branch:
https://github.com/bradcray/chapel/tree/ChplVersionModule
Main remaining step is to simplify the pre-release vs. official versions
This is now far enough along that I've opened a PR for people to start looking at:
Let's have some discussion on what these variables should be named and what their values should be. Here's what I've got currently for release and pre-release versions, but don't feel particularly wed to:


camelCase rather than ALL_CAPS?I'm OK with all caps for this naming scheme.
I'm OK with the current naming scheme, as it follows that of ChapelEnv.
I'd also be OK with dropping the CHPL_ prefix, e.g.
ChapelVersion.version = "1.20.0";
ChapelVersion.versionMajor = 1;
ChapelVersion.versionMinor = 20;
// ...
This could cause collisions with user code, however. Namely, if users were using version for their package version. No convention for this exists today AFAIK.
Here are some other language versions for reference:
# python
import sys
# Tuple of ints
sys.version_info
// go
import "runtime"
// string
runtime.Version()
// swift
#if swift(>=5.0)
Rust - not a standard way to do this, but some user-written crates support it.
CHPL_VERSION_SHA="N/A" seems like an odd default value, but I do like that it is not empty string so that the value can be recognized more easily when printed.
I'd advocate for ChapelVersion to follow ChapelEnv naming convention.
- should they be
camelCaserather thanALL_CAPS?
Yes, and remove the chpl_ prefix.
- are there better names to use?
With the prefix removed, I think version should actually be versionString.
- are there better values to use?
A function returning a tuple of (major, minor, update) seems handy, as do comparison functions (at least < and ==) on version tuples.
Why shouldn't versionSHA have a valid SHA even when the version is for an official release?
- what about the name of the module itself?
Following @ben-albrecht, ChapelVersion seems nice.
Why shouldn't versionSHA have a valid SHA even when the version is for an official release?
There are a few reasons I was worried that doing so would be a can of worms:
1) Most of our existing version-oriented logic doesn't involve SHAs once we do official releases (e.g., chpl --version on a release doesn't print a SHA), so providing one seemed like it would require more work to plumb it through the various scripts and release-building jobs that exist
2) I was imagining that typical users (as compared to developers) wouldn't need it
3) I feel like the SHA of a release is a slightly wiggly thing... Between the time that we freeze the source and make the branch and then work through any issues, we tend to refer to the thing we're building and releasing as Chapel 1.20.0, and have sometimes even done later builds of a given release number or minor mods to the online documentation pulling in late-breaking changes that don't logically affect the release. So pinning it to a specific SHA seemed challenging and potentially confusing (e.g., "the online web-based documentation for 1.20 says that it's SHA is 12345678 but my personal installation of the compiler says that it's abcdef00, what gives?"). I can imagine arguments that this really shouldn't be the case, but I don't think that's the reality we're living in (e.g., I don't think there's been a release yet where someone hasn't asked me to patch in some updated documentation to the website that didn't make the cut for the doc freeze).
The proposal looks great to me. I find the alternate spellings harder to read and prefer what was originally proposed.
It would be nice to have a simple-to-access mechanism that provides a monotonically increasing version. As proposed, the string is not it, because, for example, "1.20.0 pre-release (7561570)" > "1.20.0". From experience working with compiler version numbers in Chapel support code, it can sometimes be complex to deal with major and minor version numbers, although we definitely always want to know what those are.
One solution might be to keep what has been proposed and also add a date in int format, such as the following.
param CHPL_VERSION_DATE: int = 20180920
This could be handled a couple of ways. We could make it the date of the most recent release, so when CHPL_VERSION_OFFICIAL == false it looks backwards, or we could make it the date of the most recent commit whenever CHPL_VERSION_OFFICIAL == false, or something similar. That would facilitate tests that just need to know whether the version is recent enough to have a certain Chapel feature in the language.
In off-line discussion, it was pointed out that it might be useful to add a timestamp, to distinguish between multiple commits in the same day.
I should point out that "1.9.0" > "1.20.0" as well, so that's a complexity to take into account if the string is modified to be a monotonically-increasing version.
On first reading, I didn't see Greg's mention of using a tuple. That would also be a good way to get a monotonically increasing version.
If anybody remembers this issue anymore, I've updated my branch to use the following names based on feedback here and on the PR itself:

I'd hoped to get this PR merged by this past Monday, but then import and modules took over my weekends and evenings. On one hand, I'd like to play by the rules and not advocate for merging it this week. On the other hand, I hate to think of another release going by without the ability to start querying this stuff... :'(
I find the current interface to be pretty clunky to actually use. If I want to check at compile time for a feature that's only in say 1.21 I have to do something like:
if versionMajor > 1 || versionMajor == 1 && versionMinor >= 21 then ...
I think the interface I'd prefer is a record, but then we'd need compiler support for param-ness. The way I'd want to be able to check versions is something like:
if chplVersion >= Version(1, 20) then ...
Does the versionTuple not give you what you want? I think in previous comments, @gbtitus and @dmk42 were thinking that it would support this sort of comparison through normal < and > operators. E.g. if versionTuple > (1,21,0) then ....
(oh, but that doesn't give param-ness).
Right, tuple doesn't give you param-ness and you always have to specify the full version (1, 21, 0) instead of just (1, 20)
I don't disagree with your comments. But are you saying "we shouldn't support the ability to reason about versions in Chapel until we have a param collection type?"
A user could write param utility routines to keep their code cleaner. Or we could introduce such routines with more design effort.
I don't disagree with your comments. But are you saying "we shouldn't support the ability to reason about versions in Chapel until we have a param collection type?"
I just meant the current interface seems cumbersome to me. It doesn't strike me as something I'm particularly fond of, so I'd have a hard time justifying trying to cram it into this release.
Looking at it a little more, would a record require compiler machinery? Something like the following seems to work:
record Version {
param major : int = 0;
param minor : int = 0;
param update: int = 0;
}
inline proc <(a: Version(?), b: Version(?)) param {
if a.major < b.major then return true;
if a.major == b.major && a.minor < b.minor then return true;
if a.major == b.major && a.minor == b.minor && a.update < b.update then return true;
return false;
}
const chplVersion = new Version(1, 21, 0);
writeln(chplVersion < new Version(1, 22)); // true
I would like to be able to write that on types so it's something like:
inline proc <(type a: Version(?), type b: Version(?)) param {
if a.major < b.major then return true;
if a.major == b.major && a.minor < b.minor then return true;
if a.major == b.major && a.minor == b.minor && a.update < b.update then return true;
return false;
}
type chplVersion = Version(1, 21, 0);
writeln(chplVersion < Version(1, 22));
But I _think_ < is interpreted as "is subtype" instead of resolving to that proc < so that doesn't work.
I'd have a hard time justifying trying to cram it into this release.
I'm fine with that, but would like to merge it to master just after the release if not before.
Something like the following seems to work:
And you claim not to know Chapel.. :)
But I think < is interpreted as "is subtype" instead of resolving to that proc < so that doesn't work.
I think you must be right. With more effort, it seems like we could try to resolve < for a pair of types if there's an explicit overload and then fall back to the compiler-provided "is subtype" interpretation if it doesn't resolve. But then that raises a question as to whether that's more confusing than helpful ("<" means different things in different cases).
But maybe all you really want is a helper function named Version that returns a Record type with the params you sent into it?
record version { ... }
proc Version(param major, param minor, param update=0) type {
return version(major, minor, update);
}
That said, is the goal of this part of the design is to avoid having to type the word new?
[edit: I think that the provided Chapel version record should be a record rather than a type; it seems odd to have something that essentially is a value represented as a type]
Yeah, the new seemed a little out of place to me so I was trying to avoid that.
I like the param record idea. I'll try that in my next draft.
I've taken another swipe at this "version introspection" feature to take Elliot's ideas and feedback into consideration, which I really liked. Here are the results as currently documented:




See the open questions in my PR for design questions I'm particularly curious for feedback on:
For those following this issue, there's a new draft of PR #13191 that incorporates feedback so far and is ready for more feedback. The OP there has been updated to illustrate what's currently implemented.
Most helpful comment
On first reading, I didn't see Greg's mention of using a tuple. That would also be a good way to get a monotonically increasing version.