As everyone reading this hopefully knows, Swift has a couple of compiler macros, also known as “Magic Identifiers” in the code, those being;
#file: Returns the name of the file being compiled
#line: Returns the current line being compiled, as an integer
#function: Returns the function signature of the function from which the code is being compiled
I propose that a new magic identifier be added, called #date, returning the current date that the file is being compiled as a String, in the format mmmm dd yy (for example, May 28 2022), which is also the same format used by the __DATE__ preprocessor macro in C(++).
Macros like __DATE__ and __TIME__ make compilation an impure compilation, invalidating or complicating build system optimisations like caching and distribution. While they may seem convenient, it’s better to generate a file with the required content as part of your build process.
Why would this complicate compiler optimizations? Wouldn’t this literally just be the same as #file but instead of giving the filename, the compiler gives the current date instead?
If adding this, would argue to use ISO8601 instead of adhering to us-centric historical date displays. More inline with using eg. Unicode instead of ASCII. ISO8601 is basically most-significant-datetime-component first.
@jayton@Jean-Daniel But about caching, wouldn’t the only file that would need to be recompiled just the one using #date? Because as pointed out, it’s likely just going to be used once in a project
Probably, but it will requires all build systems to learn about that, and find a way to define which file is using #date and which one isn't (ie marking the file as dirty even if it didn't change).
Another drawback of #date is that its usage must be prohibited in any code base that requires reproducible build, forcing such project to update their guidelines, and implement tools to detect its usage.
The issue is that a file containing date should be recompiled every time - so the compiler needs to know that the file contains that magic symbol somehow…. Usually you could check timestamp when the file last was modified but that would break here.
To address the mentioned compilation impurity, the date could be the source file modification date instead of a build date. Alternatively depending upon how this feature is going to be used it can be, say, md5 checksum instead of a date. In one of the projects I remember incorporating the git commit hash (the script extracted the current commit hash and placed into a version.swift file, that file was part of the project and it was ignored from git to not cause a change).
I've spent way too much of the last few months implementing a datetime data type and trying to write unit tests against it.
From the point of view of a testing environment, as soon as you have something generating a value related to current date or time, you have turned your assertions into having to be not only dynamically generated but generated using a different mechanism to the thing being tested.
You have to ensure that both the first and second methods of date generation have the same logic with regards to timezones. I had one test failure that only happened within midnight - 8am, because I'm in GMT+8.
It generates a LOT of noise.
You can already run build scripts in separate languages that put a datetime into a file or macro, this doesn't need to be in a compiler.
Playing devils advocate... #file gives you one piece of file metadata (its name) and it won't be unreasonable to have yet another piece of metadata available as #fileModificationDate.
What's the problem you're trying to solve, here? Alone, this feels kind of like an attempt at identifying a particular time the object code got built -- but that's almost never the question one asks of a program. In my experience, one is much more likely to wonder things like what source code generated the program, or what toolchain compiled the source.