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 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:

>

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

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 asserts) 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.

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 asserts) 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 5/21/23 3:09 PM, Guillaume Piolat wrote:

>

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.

One of the largest problems with this scheme is it needs to be repeated in every module that uses e.g. version(Darwin).

-Steve

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:
>> 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
> 
> 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.

```d
version(Windows) foo();
else version(linux) bar();
else version(fail_early) static assert(0);
else assert(0);
```

:o)
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).

-Steve

Yes, 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 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 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 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.