My thoughts on Roger's proposed extension to 6!:0:
For example, in Roger's current mock up (obviously nascent), one cannot have fields which preclude leading zeros, but include non-zero leading values. That is, the timestamps must have a constant length. For example, using 6!:0 'HH' when the hour is 12 would produce 12, and 01 when the hour is 1. There are situations where the leading 0 is undesirable (we're formatting strings for presentation here, so presentation matters). But trying to work around this problem with 6!:0 'H' would produce 1 in the first case and 0 in the last case.
For another example, 2-digits years will result in the Millenium-Century , instead of Decade-Year. When the year is 2007 then 6!:0 'YYYY' produces 2007, but 6!:0 'YY', a very common format, produces 20.
You can work around this in two ways: instead spell 'YY' like 'CCYY'. That's acceptable, but would cause problems when users try the "obvious" format 'YYYY MM DD'. Ignoring that hurdle, the problem hasn't disappeared, it has only manifested as the inability to print the 3-digit year, 'YYY' (admittedly uncommon, but why impose the restriction?). to solve this we could iterate our solution, and just spell the year 'MCYY'.
Except, of course, 'M' conflicts with Month, and the problem still persists: now we can't print just the year. So, we're left with a couple of options: assign a distinct code to each digit the user could possible want to print independently (ie all of them), resulting in (A) utterly non-mnemonic codes and (B) possible exhaustion of codes.
Or, we could print numbers backwards, least significant digits first, so Y prints just the year, YY prints the decade and year, etc. That has appeal, and it nearly solves the above bullet (6!:0 'H' prints 1 at one-o'clock but still just 2 at noon).
But, then we run into conflicts if we want to format word-dates, like 'February'; there, the MOST significant digit must be printed first. That is, assuming the code for month-name is 'F' and it's February , then we'd like 6!:0 'FFFFFFFF' to print 'February', and 6!:0 'FFF' to print 'Feb' and 6!:0 'F' to print 'F'. But, if we print least-significant first, as we do for numbers, then the latter will print 'y' (as it would in, e.g., January).
Which highlights another problem with fixed-format strings: date-words are not of fixed length (nor globally standardized, like numbers). So if 6!:0 'FFFF' prints 'June' in June, what does it print in May?
Fixed formats are nice for picking apart, because elements are dependable and identifable. But here, we already know what the formatted string represents, because we provided as (a possible implicit) input. If we want individually formatted date-pieces, we can request them explicitly with x 6!:0 L: 0 'YYYY';'MM';'DD'). So, it would be best if 6!:0 produced variable-length (possibly boxed) strings, because that's more flexible in this context.
If this many problems occur to me in the first 30 minutes of consideration, they must only be the tip of the iceberg. We could solve this by punting, and use a 3rd-party library, as we do for 8!:, but that is not very satisfying.
The other option is to maintain our own code, but steal someone else's interface. Ideally someone with a large userbase (so our format semantics would be familiar to a large extant population), someone who has long experience in the field, and someone who has (presumably) spent a lot of time in researching and designing that interface. I suggest Java or .NET. Some links:
I also think it's important to carefully weigh the semantics of valence and inversion. For example, if I see 6!:0 'YYYY MM' produces a 7-character string, and 6!:0 'YYYY' produces a 4-character string, then I might infer that 6!:0'' produces a 0-character string. But it does not; it produces a 6-element numeric vector.
These ideas haven't gelled yet, but to throw them out there:
1 = 6!:0 b. 0 NB. 6!:0 is rank-1 1 1
x 6!:0 y produces a 6-element numeric vector (as 6!:0'' does currently)
x controls the times produced, y controls the format of their input.
The monad 6!:0 y is (current time) 6!:0 y
x 6!:0^:_1 y produces a string timestamp
x controls the times produced, y controls the format of their output.
The monad 6!:0^:_1 y is (default format) 6!:0^:_1 y
In .NET "default format" is controlled by the user's "cultural context"
There could be some kind of cover function that detects whether x is literal or numeric, and calls the 6!:0 y or 6!:0^:_1 y as appropriate (though that wouldn't work if we include intervals expressed as string constants, see below).
It would be nice to incorporate durations or time intervals. Perhaps these could be represented as laid out by Neville Holmes in the Forums. We could distinguish "standard timestamps" from "interval timestmaps" by checking the type of x. That argument is usually a vector of 6 numbers representing a datetime, but for intervals, it is instead a string. This string would be "interval constants" in Neville's clear, concise format (or a more standard one, if we can find it). For example, '5d3h15m42s12.3 -3h2s +5d-2h' 6!:0 y would add those intervals to the current time, formatted by y.
This latter could be useful for producing "dates" like 'Next Monday' or 'Last Easter', as provided by the link, above.
- This is getting complex and maybe should be handled by a script.
- I will think about creating that script.
- The script will need a LOT of test cases. Maybe we could test against calls to .NET (only the developer of the script (me) will need .NET on his system; end-users will not)
I'm jealous. You've motivated Roger to make a visible and useful change to the language. He even credits you on his new wiki page. The worst part is I had the same idea (format argument to 6!:0 ) when Randy first posted, but thought I'd already been too verbose on the Forums that day, so I forebore posting. That'll teach me to (not) keep my trap shut. ;)
It's funny because it was a real throw-away idea - I figured it was the sort of thing he doesn't care about because it's a "dirty" sort of problem. That's why I suggested it was appropriate for his dotage.