digitalmars.D - Good examples of version() algebra in real code
- Dennis (30/35) May 21 2023 D's version() statement deliberately does not allow composing
- Guillaume Piolat (23/26) May 21 2023 No big problem, but sometimes you need to do:
- Steven Schveighoffer (4/39) May 22 2023 One of the largest problems with this scheme is it needs to be repeated
- Guillaume Piolat (9/14) May 22 2023 Yes, maybe add those 3 common version identifiers directly, which
- max haughton (9/43) May 21 2023 It's not bad to try and make good look good. Most programming
- Hipreme (12/49) May 21 2023 Keep in mind that I have found plenty of codes when defining a
- Walter Bright (37/43) May 22 2023 version(linux) enum ExtraFunctionality = true;
- Walter Bright (7/7) May 22 2023 ```
- Hipreme (14/21) May 22 2023 When I programmed for Haxe, it did have a feature which you could
- Walter Bright (6/15) May 22 2023 Yup, that works well.
- Max Samukha (4/7) May 22 2023 I sense echoes of the infamous "Clean Code" debate. Why can't we
- Walter Bright (4/7) May 22 2023 Blind adherence to any nostrum leads to hell.
- Richard (Rikki) Andrew Cattermole (9/11) May 22 2023 If you want to be principled about it, one way to consider it is that
- Walter Bright (5/9) May 22 2023 Sometimes, something really is a Windows-only thang. But when it's a Win...
- Hipreme (34/81) May 22 2023 Yes, I do understand. Although I prefer `static assert` to not be
- Walter Bright (14/43) May 22 2023 Runtime assert doesn't work at module scope. Also, it's usually better t...
- Adam D Ruppe (2/5) May 22 2023 http://dpldocs.info/this-week-in-d/Blog.Posted_2023_02_20.html#static-as...
- Petar Kirov [ZombineDev] (20/25) May 22 2023 I agree with you that having the option of using run-time guards
- Petar Kirov [ZombineDev] (6/17) May 22 2023 This needs to be a different, explicitly opt-in compilation mode,
- Timon Gehr (8/22) May 22 2023 ```d
- Petar Kirov [ZombineDev] (5/28) May 23 2023 Two issues:
- Walter Bright (2/3) May 22 2023 A good article!
- Walter Bright (13/13) May 22 2023 I don't have links, it was a long time ago, but there was a time when so...
- Basile B. (11/48) May 23 2023 One thing that is not mentioned is the grammar of version
- Basile B. (2/14) May 23 2023 image for the children : https://imgflip.com/i/7mropf
D's version() statement deliberately does not allow composing version conditions with boolean operators `! || &&`, in order to avoid C's `#ifdef` hell. This is a controversial design decision though, because some people don't like the resulting verbosity you sometimes get. Discussions about this come up now and then, see for example [Issue 7417](https://issues.dlang.org/show_bug.cgi?id=7417) and its duplicates. The most recent incarnation of this comes from this Phobos PR proposing a library solution: [std.compiler.Version](https://github.com/dlang/phobos/pull/8750) ```D import std.compiler; static if (Version.D_InlineAsm_X86 || Version.D_InlineAsm_X86_64) { version = UseX86Assembly; } ``` I don't expect this to get approval though, I said in the PR discussion:I'll bring this up in the next DLF monthly meeting, but without new compelling arguments, I don't expect a different outcome. If you can demonstrate problems (other than it not looking nice) in existing projects that the current logic causes, you'll have a stronger case.So far I haven't received any real code examples, so I'm asking here: Do you have any examples of existing projects (on github, dub, etc.) that either: - demonstrate version algebra done well - use a `Version`-like template successfully - have real problems with existing `version()` statements (besides 'it looks ugly') Please reply with links and don't rekindle the old arguments. I can't stop you, but know that it will only be counter-productive.
May 21 2023
On Sunday, 21 May 2023 at 18:43:32 UTC, Dennis wrote:- have real problems with existing `version()` statements (besides 'it looks ugly')No big problem, but sometimes you need to do: version(X86) version = AnyX86; version(X86_64) version = AnyX86; or version (OSX) version = Darwin; else version (iOS) version = Darwin; else version (TVOS) version = Darwin; else version (WatchOS) version = Darwin; or version (D_InlineAsm_X86) version = UseX86Assembly; version (D_InlineAsm_X86_64) version = UseX86Assembly; and those are the only case I remember being a tiny bit annoyed at `version`. I wouldn't use the above library solution to save one import.
May 21 2023
On 5/21/23 3:09 PM, Guillaume Piolat wrote:On Sunday, 21 May 2023 at 18:43:32 UTC, Dennis wrote:One of the largest problems with this scheme is it needs to be repeated in every module that uses e.g. `version(Darwin)`. -Steve- have real problems with existing `version()` statements (besides 'it looks ugly')No big problem, but sometimes you need to do: version(X86) version = AnyX86; version(X86_64) version = AnyX86; or version (OSX) version = Darwin; else version (iOS) version = Darwin; else version (TVOS) version = Darwin; else version (WatchOS) version = Darwin; or version (D_InlineAsm_X86) version = UseX86Assembly; version (D_InlineAsm_X86_64) version = UseX86Assembly; and those are the only case I remember being a tiny bit annoyed at `version`. I wouldn't use the above library solution to save one import.
May 22 2023
On Monday, 22 May 2023 at 12:41:24 UTC, Steven Schveighoffer wrote:One of the largest problems with this scheme is it needs to be repeated in every module that uses e.g. `version(Darwin)`. -SteveYes, maybe add those 3 common version identifiers directly, which doesn't change the design of `version`. Also maybe Hipreme's idea avoids the #ifdef hell problem (abondance of names and double negations).Maybe if there was a construct for allowing **only version declaration** with boolean operators like:`version RelaxedSystems = version(Windows && linux && !OSX)` (it would not be global as the `version` is right now. i.e: not allow this syntax to be used standalone.
May 22 2023
On Sunday, 21 May 2023 at 18:43:32 UTC, Dennis wrote:D's version() statement deliberately does not allow composing version conditions with boolean operators `! || &&`, in order to avoid C's `#ifdef` hell. This is a controversial design decision though, because some people don't like the resulting verbosity you sometimes get. Discussions about this come up now and then, see for example [Issue 7417](https://issues.dlang.org/show_bug.cgi?id=7417) and its duplicates. The most recent incarnation of this comes from this Phobos PR proposing a library solution: [std.compiler.Version](https://github.com/dlang/phobos/pull/8750) ```D import std.compiler; static if (Version.D_InlineAsm_X86 || Version.D_InlineAsm_X86_64) { version = UseX86Assembly; } ``` I don't expect this to get approval though, I said in the PR discussion:It's not bad to try and make good look good. Most programming language design decisions boil down to some kind of aesthetically driven heuristic. Current state of affairs is oppressive because it makes common cases expensive. That being said a lot of `version` usage shouldn't exist. Let the compiler constant fold the details for you so your code ports to new architecture/cross target more easilyI'll bring this up in the next DLF monthly meeting, but without new compelling arguments, I don't expect a different outcome. If you can demonstrate problems (other than it not looking nice) in existing projects that the current logic causes, you'll have a stronger case.So far I haven't received any real code examples, so I'm asking here: Do you have any examples of existing projects (on github, dub, etc.) that either: - demonstrate version algebra done well - use a `Version`-like template successfully - have real problems with existing `version()` statements (besides 'it looks ugly')
May 21 2023
On Sunday, 21 May 2023 at 18:43:32 UTC, Dennis wrote:D's version() statement deliberately does not allow composing version conditions with boolean operators `! || &&`, in order to avoid C's `#ifdef` hell. This is a controversial design decision though, because some people don't like the resulting verbosity you sometimes get. Discussions about this come up now and then, see for example [Issue 7417](https://issues.dlang.org/show_bug.cgi?id=7417) and its duplicates. The most recent incarnation of this comes from this Phobos PR proposing a library solution: [std.compiler.Version](https://github.com/dlang/phobos/pull/8750) ```D import std.compiler; static if (Version.D_InlineAsm_X86 || Version.D_InlineAsm_X86_64) { version = UseX86Assembly; } ``` I don't expect this to get approval though, I said in the PR discussion:Keep in mind that I have found plenty of codes when defining a `version` based on `static if`. This bug probably occurs for them being parsed at different stages of the compiler, I would be using that if weren't for the bugs. Right now I've come to understand that using feature based versions instead of real versions really makes a lot of difference. But as Guillaume pointed out, there is still this other problem of defining a feature based on multiple platforms and this solution doesn't really make one write a lot less, so I still find this solution lacking for our problem which makes me wonder if there really exists a good solution for that.I'll bring this up in the next DLF monthly meeting, but without new compelling arguments, I don't expect a different outcome. If you can demonstrate problems (other than it not looking nice) in existing projects that the current logic causes, you'll have a stronger case.So far I haven't received any real code examples, so I'm asking here: Do you have any examples of existing projects (on github, dub, etc.) that either: - demonstrate version algebra done well - use a `Version`-like template successfully - have real problems with existing `version()` statements (besides 'it looks ugly') Please reply with links and don't rekindle the old arguments. I can't stop you, but know that it will only be counter-productive.
May 21 2023
On 5/21/2023 7:01 PM, Hipreme wrote:Right now I've come to understand that using feature based versions instead of real versions really makes a lot of difference. But as Guillaume pointed out, there is still this other problem of defining a feature based on multiple platforms and this solution doesn't really make one write a lot less, so I still find this solution lacking for our problem which makes me wonder if there really exists a good solution for that.version(linux) enum ExtraFunctionality = true; else version(OSX) enum ExtraFunctionality = true; else version(Windows) enum ExtraFunctionality = false; else static assert(0, "system not accounted for"); The static assert is there because a very common failure of #ifdef hell is to have defaults that botch things up when a new version is added. This happens sometimes in the druntime imports, when I discover them I add the static assert. There are still other ways to do it: ``` import extra; void foo() { extraFunctionality(); } ``` ``` module extra; void extraFunctionality() { version(linux) doit(); else version(OSX) doit(); else version(Windows) { } else static assert(0, "system not accounted for"); } ``` Another way is to write a "personality module" for each operating system, and then import the right one: ``` module extra; version (linux) import extraLinux; else version (OSX) import extraOSX; ... and so on ... ``` Personally, I like to make the core code version-independent and OS-independent and hide the variances in separate modules. Isn't foo() clean looking?
May 22 2023
``` version(linux) enum ExtraFunctionality = true; else version(OSX) enum ExtraFunctionality = true; else version(Windows) enum ExtraFunctionality = false; else static assert(0, "system not accounted for"); ``` (forgot to use Markdown! Oops!)
May 22 2023
On Monday, 22 May 2023 at 08:23:31 UTC, Walter Bright wrote:``` version(linux) enum ExtraFunctionality = true; else version(OSX) enum ExtraFunctionality = true; else version(Windows) enum ExtraFunctionality = false; else static assert(0, "system not accounted for"); ``` (forgot to use Markdown! Oops!)When I programmed for Haxe, it did have a feature which you could for example name your file based on the target OS: Imagine we had the `module input`. Since all OS have a different way to get input, we can basically separate them as you just said, by files. How Haxe solves that is by letting users define a special file name such as: `input.windows.hx` and `input.javascript.hx`. Whenever you import that file for usage, it will automatically import the correct file based on your target. I did use that feature and in my experience: This is quite cool and can lead to a single file to read without having any extra concern. The problem is that it did generated a bit of code duplication. Which could be solved by putting the common code in another file.
May 22 2023
On 5/22/2023 4:12 AM, Hipreme wrote:Imagine we had the `module input`. Since all OS have a different way to get input, we can basically separate them as you just said, by files. How Haxe solves that is by letting users define a special file name such as: `input.windows.hx` and `input.javascript.hx`. Whenever you import that file for usage, it will automatically import the correct file based on your target. I did use that feature and in my experience: This is quite cool and can lead to a single file to read without having any extra concern. The problem is that it did generated a bit of code duplication. Which could be solved by putting the common code in another file.Yup, that works well. A nice dividend is, you want to port to a new platform? The only code needed to be looked at is the personality module. Much better than it being peppered through the source code, and even worse, be unfindable because of the use of defaults.
May 22 2023
On Monday, 22 May 2023 at 08:21:50 UTC, Walter Bright wrote:Personally, I like to make the core code version-independent and OS-independent and hide the variances in separate modules. Isn't foo() clean looking?I sense echoes of the infamous "Clean Code" debate. Why can't we just let the programmer decide whether to put the versions inline or to hide them behind an abstraction?
May 22 2023
On 5/22/2023 1:40 AM, Max Samukha wrote:I sense echoes of the infamous "Clean Code" debate. Why can't we just let the programmer decide whether to put the versions inline or to hide them behind an abstraction?Blind adherence to any nostrum leads to hell. However, I'm pleased that the dlang code has not devolved into version hell, which every long term C and C++ project I'm familiar with descended into.
May 22 2023
On 22/05/2023 8:21 PM, Walter Bright wrote:The static assert is there because a very common failure of #ifdef hell is to have defaults that botch things up when a new version is added.If you want to be principled about it, one way to consider it is that not having an else branch (even if empty) should be an error. Because you clearly didn't think about the multiplicative issues of the versions. Regardless, or'ing isn't the issue, its when you and versions that you get an explosion of multiplicative issues. An option could be to use comma instead of ``||`` to handle or'ing. That way people won't be so tempted to "just extend it" to other operators like and.
May 22 2023
On 5/22/2023 1:49 AM, Richard (Rikki) Andrew Cattermole wrote:If you want to be principled about it, one way to consider it is that not having an else branch (even if empty) should be an error. Because you clearly didn't think about the multiplicative issues of the versions.Sometimes, something really is a Windows-only thang. But when it's a Windows or OSX thing, enumeration of all the platforms is the way to go.An option could be to use comma instead of || to handle or'ing.That goes to version hell, too. Some of this remains in the backend, and it isn't pretty.
May 22 2023
On Monday, 22 May 2023 at 08:21:50 UTC, Walter Bright wrote:On 5/21/2023 7:01 PM, Hipreme wrote:Yes, I do understand. Although I prefer `static assert` to not be used, but the runtime `assert`. I have done a port of the druntime and the `static assert` usage really is a pain since there is just a plain lot of code which is not used by me, but only for its existence, it causes a compilation error. I think the feature based is cleaner to read most of the time (and scalable), I have done a good refactor in a lot of D code already using that, and IMO, it did done wonders into making the code intention crystal clear even for non maintainers. This is a thing which I've come to understand the decision of not allowing boolean operators on `version`. Maybe if there was a construct for allowing **only version declaration** with boolean operators like: `version RelaxedSystems = version(Windows && linux && !OSX)` (it would not be global as the `version` is right now. i.e: not allow this syntax to be used standalone. So, the operators aren't really the hell that causes the `#ifdef` hell as you said. The problem are 2: 1: They being defined over all files. While trying to port newlibc, I've come to find a type to be defined over 6 files. Which meant I really went jumping from a file to file until I was able to find how the type were defined. This is a real problem since the type is not self contained so it is super hard to look. How to solve that: D has solved! Just make the `version =` not spam into multiple files. 2: Operators: they don't really make sense when other people are looking into them, which is solved by having the feature named, so, enforcing the naming to use the operators could be a problem solving in the syntax. Since they aren't global, they are painful to keep writing all the time the same thing (I've tried doing that on directx-d binding and omg, I basically got a 8 line headers in almost all files, sure, it is easier to read than C, but it was painful writing them).Right now I've come to understand that using feature based versions instead of real versions really makes a lot of difference. But as Guillaume pointed out, there is still this other problem of defining a feature based on multiple platforms and this solution doesn't really make one write a lot less, so I still find this solution lacking for our problem which makes me wonder if there really exists a good solution for that.version(linux) enum ExtraFunctionality = true; else version(OSX) enum ExtraFunctionality = true; else version(Windows) enum ExtraFunctionality = false; else static assert(0, "system not accounted for"); The static assert is there because a very common failure of #ifdef hell is to have defaults that botch things up when a new version is added. This happens sometimes in the druntime imports, when I discover them I add the static assert. There are still other ways to do it: ``` import extra; void foo() { extraFunctionality(); } ``` ``` module extra; void extraFunctionality() { version(linux) doit(); else version(OSX) doit(); else version(Windows) { } else static assert(0, "system not accounted for"); } ``` Another way is to write a "personality module" for each operating system, and then import the right one: ``` module extra; version (linux) import extraLinux; else version (OSX) import extraOSX; ... and so on ... ``` Personally, I like to make the core code version-independent and OS-independent and hide the variances in separate modules. Isn't foo() clean looking?
May 22 2023
On 5/22/2023 4:06 AM, Hipreme wrote:Yes, I do understand. Although I prefer `static assert` to not be used, but the runtime `assert`. I have done a port of the druntime and the `static assert` usage really is a pain since there is just a plain lot of code which is not used by me, but only for its existence, it causes a compilation error.Runtime assert doesn't work at module scope. Also, it's usually better to catch porting errors at compile time, rather than after the code was shipped.I think the feature based is cleaner to read most of the time (and scalable), I have done a good refactor in a lot of D code already using that, and IMO, it did done wonders into making the code intention crystal clear even for non maintainers. This is a thing which I've come to understand the decision of not allowing boolean operators on `version`. Maybe if there was a construct for allowing **only version declaration** with boolean operators like: `version RelaxedSystems = version(Windows && linux && !OSX)` (it would not be global as the `version` is right now. i.e: not allow this syntax to be used standalone.As I mentioned elsewhere, that goes wrong, too.So, the operators aren't really the hell that causes the `#ifdef` hell as you said. The problem are 2: 1: They being defined over all files. While trying to port newlibc, I've come to find a type to be defined over 6 files. Which meant I really went jumping from a file to file until I was able to find how the type were defined. This is a real problem since the type is not self contained so it is super hard to look. How to solve that: D has solved! Just make the `version =` not spam into multiple files.Yup. D does not "import" versions from other modules. This was another crucial design decision that has paid off handsomely. How miserable it is in C to figure out where a #define is coming from in the typical rat's nests of #include's, or even if it is #define'd at all.2: Operators: they don't really make sense when other people are looking into them, which is solved by having the feature named, so, enforcing the naming to use the operators could be a problem solving in the syntax.Most people read code a hundred times more than they write code, so being a bit verbose to improve reading is a worthwhile tradeoff.Since they aren't global, they are painful to keep writing all the time the same thing (I've tried doing that on directx-d binding and omg, I basically got a 8 line headers in almost all files, sure, it is easier to read than C, but it was painful writing them).The technique, as I mentioned in the upstream post, is to have the feature versions in one file, have `extraFunctionality()` defined as doing something or a noop in that file, and just call `extraFunctionality()` elsewhere. I should write an article about this.
May 22 2023
On Monday, 22 May 2023 at 08:21:50 UTC, Walter Bright wrote:Personally, I like to make the core code version-independent and OS-independent and hide the variances in separate modules. Isn't foo() clean looking?http://dpldocs.info/this-week-in-d/Blog.Posted_2023_02_20.html#static-assert-patterns-arguably-harmful-for-porting
May 22 2023
On Monday, 22 May 2023 at 11:23:32 UTC, Adam D Ruppe wrote:On Monday, 22 May 2023 at 08:21:50 UTC, Walter Bright wrote:I agree with you that having the option of using run-time guards like `assert(0)` / `throw new NotImplementedEx()` and even using empty declarations at compile-time is very convenient in practice to get going with a port. On the other hand, I also find a great amount in being able to get an almost complete list of things that I need to fix at compile-time in terms of planning my work. Based on your blog post it would seem that two approaches are opposite to each other, but I think we should find a way to have our cake and eat it. A better solution (in that it works with the existing code using `static assert`s) would be having fully lazy compilation model further along the lines of `dmd -i`: starting from set of root symbols (e.g. `main`, `unittest` when unit tests are enabled, and functions explicitly marked as `export`) the compiler should semantically analyse only the declarations which are referenced (directly or indirectly) from the root set. That way, if any symbol (be it `enum`, `struct`, function, etc.) is not referenced, it won't analysed and the `static assert` won't be hit.Personally, I like to make the core code version-independent and OS-independent and hide the variances in separate modules. Isn't foo() clean looking?http://dpldocs.info/this-week-in-d/Blog.Posted_2023_02_20.html#static-assert-patterns-arguably-harmful-for-porting
May 22 2023
On Monday, 22 May 2023 at 11:46:10 UTC, Petar Kirov [ZombineDev] wrote:[..] A better solution (in that it works with the existing code using `static assert`s) would be having fully lazy compilation model further along the lines of `dmd -i`: starting from set of root symbols (e.g. `main`, `unittest` when unit tests are enabled, and functions explicitly marked as `export`) the compiler should semantically analyse only the declarations which are referenced (directly or indirectly) from the root set. That way, if any symbol (be it `enum`, `struct`, function, etc.) is not referenced, it won't analysed and the `static assert` won't be hit.This needs to be a different, explicitly opt-in compilation mode, because it would change the meaning of existing programs using introspectio language features like `__traits(allMembers, X)`, `is(X)`, `__traits(compiles, E)`.
May 22 2023
On 22.05.23 13:46, Petar Kirov [ZombineDev] wrote:On Monday, 22 May 2023 at 11:23:32 UTC, Adam D Ruppe wrote:```d version(Windows) foo(); else version(linux) bar(); else version(fail_early) static assert(0); else assert(0); ``` :o)On Monday, 22 May 2023 at 08:21:50 UTC, Walter Bright wrote:I agree with you that having the option of using run-time guards like `assert(0)` / `throw new NotImplementedEx()` and even using empty declarations at compile-time is very convenient in practice to get going with a port. On the other hand, I also find a great amount in being able to get an almost complete list of things that I need to fix at compile-time in terms of planning my work.Personally, I like to make the core code version-independent and OS-independent and hide the variances in separate modules. Isn't foo() clean looking?http://dpldocs.info/this-week-in-d/Blog.Posted_2023_02_20.html#static-assert-patterns-arguably-harmful-for-porting
May 22 2023
On Monday, 22 May 2023 at 14:10:24 UTC, Timon Gehr wrote:On 22.05.23 13:46, Petar Kirov [ZombineDev] wrote:Two issues: * Requires changing all existing code * Doesn't work for declarations (e.g. defining an `enum`, `struct`, etc. at module scope)On Monday, 22 May 2023 at 11:23:32 UTC, Adam D Ruppe wrote:```d version(Windows) foo(); else version(linux) bar(); else version(fail_early) static assert(0); else assert(0); ``` :o)On Monday, 22 May 2023 at 08:21:50 UTC, Walter Bright wrote:I agree with you that having the option of using run-time guards like `assert(0)` / `throw new NotImplementedEx()` and even using empty declarations at compile-time is very convenient in practice to get going with a port. On the other hand, I also find a great amount in being able to get an almost complete list of things that I need to fix at compile-time in terms of planning my work.Personally, I like to make the core code version-independent and OS-independent and hide the variances in separate modules. Isn't foo() clean looking?http://dpldocs.info/this-week-in-d/Blog.Posted_2023_02_20.html#static-assert-patterns-arguably-harmful-for-porting
May 23 2023
On 5/22/2023 4:23 AM, Adam D Ruppe wrote:http://dpldocs.info/this-week-in-d/Blog.Posted_2023_02_20.html#static-assert-patterns-arguably-harmful-for-portingA good article!
May 22 2023
I don't have links, it was a long time ago, but there was a time when someone introduced enums to druntime modules and used them with non-trivial static if expressions. People started extending this, and it soon became quite a tangle of some static ifs depending on other static ifs and the declarations of the enums became embedded in static ifs and then, inevitably, circular imports came into play. Then, the whole thing reached a point where nobody could figure out whether particular static ifs were being triggered or not. The problem got dumped in my lap, and I yanked out all the static if's and replaced them with trivial logic. In getting ImportC to work with system .h files, written by the best C experts on the planet, I've been re-acquainted with #ifdef hell. I used to write #ifdef hell myself. It's very seductive. So, yes, you can use static if and enums to implement version hell. But not in any official Dlang repositories.
May 22 2023
On Sunday, 21 May 2023 at 18:43:32 UTC, Dennis wrote:D's version() statement deliberately does not allow composing version conditions with boolean operators `! || &&`, in order to avoid C's `#ifdef` hell. This is a controversial design decision though, because some people don't like the resulting verbosity you sometimes get. Discussions about this come up now and then, see for example [Issue 7417](https://issues.dlang.org/show_bug.cgi?id=7417) and its duplicates. The most recent incarnation of this comes from this Phobos PR proposing a library solution: [std.compiler.Version](https://github.com/dlang/phobos/pull/8750) ```D import std.compiler; static if (Version.D_InlineAsm_X86 || Version.D_InlineAsm_X86_64) { version = UseX86Assembly; } ``` I don't expect this to get approval though, I said in the PR discussion:One thing that is not mentioned is the grammar of version algebra...what would be allowed ? Do we want things like version(mixin(someCtfeCall(()) How would be handled the fact that enum BigEndian = 0.123; is ATM legal, i.e identifiers can be both expressions and sealed version identifiers ? There are already bugs caused by the fact that `static if`s can introduce `version`s... it's probably not worth introducing version algebra until those get fixed.I'll bring this up in the next DLF monthly meeting, but without new compelling arguments, I don't expect a different outcome. If you can demonstrate problems (other than it not looking nice) in existing projects that the current logic causes, you'll have a stronger case.So far I haven't received any real code examples, so I'm asking here: Do you have any examples of existing projects (on github, dub, etc.) that either: - demonstrate version algebra done well - use a `Version`-like template successfully - have real problems with existing `version()` statements (besides 'it looks ugly') Please reply with links and don't rekindle the old arguments. I can't stop you, but know that it will only be counter-productive.
May 23 2023
On Tuesday, 23 May 2023 at 10:01:37 UTC, Basile B. wrote:On Sunday, 21 May 2023 at 18:43:32 UTC, Dennis wrote: [...] One thing that is not mentioned is the grammar of version algebra...what would be allowed ? Do we want things like version(mixin(someCtfeCall(()) How would be handled the fact that enum BigEndian = 0.123; is ATM legal, i.e identifiers can be both expressions and sealed version identifiers ? There are already bugs caused by the fact that `static if`s can introduce `version`s... it's probably not worth introducing version algebra until those get fixed.image for the children : https://imgflip.com/i/7mropf
May 23 2023