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(++).
Please let me know your thoughts on this
__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?
Right now you can use a plugin to generate a source file containing
let compilationDate = ....
Unlike the other
#date would be basically static for a particular build and thus never meaningfully used more than once in a project.
Still wouldn’t see the issue with it, though
I was not objecting, only noting a distinct difference between this and the existing ones.
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.
Build system optimisations, not compiler optimisations.
#date would change each time the compiler is invoked, and would make compilation result caching impossible.
@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
Yeah why not, but please use the format
yyyy-MM-dd instead because this is parsable and easier to sort by since it's a big endian format.
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.
I see, I thought the caching would be automatic, this is interesting
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).
All of these are perfectly reasonable options for different purposes, and none of them should be compiler features.
I see, it seems too unrelated to the code being written for it to be a magic identifier unlike the other ones such as
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
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.