I guess we'd call these "type extensions"? F# supports this just fine, and C# can do a bit, too.
Overall, I haven't found I need type extensions that much, if I have flexible function handling. It's the same level of expressiveness to write "fromNow 2 days". (fromNow having signature (int -> (int -> TimeSpan) -> DateTime). Or even "2 |> days |> fromNow" (fromNow being TimeSpan -> DateTime).
Actually, this example is pretty terrible, as even C#'s basic format would be "DateTime.Now.AddDays(2)" which seems pretty fine to me - add a top-level binding for now and it's on the same level of conciseness. Also, adding type extensions to integers for time seems quite ugly. Most 3rd party libraries I've seen don't use type extensions in a graceful manner, and end up slapping members on everything and it's just silly. (And I'm ignoring the fact that using .Now in .NET is rarely correct since it's rare when you don't want to use whatever random timezone the server's configured for, instead of UTC.)
"2.days.from_now" is different from DateTime.Now.AddDays(2), because it can be broken in two parts:
- 2.days is a duration, or a time delta, or time span, or whatever you want to call it
- from_now is a method called on this duration value
This construct "2.days" is useful on its own. It's actually more useful than "DateTime.Now", as durations are often part of public interfaces, whereas usage of concrete timestamps is very often hidden. The equivalent in C# for it would be "new TimeSpan(2, 0, 0, 0)". That's much more unreadable than just "2.days" and often, instead of thinking about the problem, developers fallback to specifying time spans as Ints in seconds or similar.
On TimeZone, "2.days.from_now" is a timestamp. If the underlying library is not totally fucked up, like "java.util.Date" is, then it does have an attached timezone. Or in case this yields a Unix timestamp, it's really not a Unix timestamp unless it was calculated since 1970-01-01 00:00:00 UTC.
I just don't get it. So a literal like "0.2f" to denote a Float (and not a Long) is acceptable. A literal like "300.5m" to denote a decimal and not a floating-point is acceptable.
But somehow other kinds of literals for other units of measurement are not, because Dear God, magic, magic!!!
I agree that the constructor isn't very easy to read for TimeSpans. But there's a shorthand, you can write "TimeSpan.FromDays(2)" to create a span of 2 days.
Overall, I haven't found I need type extensions that much, if I have flexible function handling. It's the same level of expressiveness to write "fromNow 2 days". (fromNow having signature (int -> (int -> TimeSpan) -> DateTime). Or even "2 |> days |> fromNow" (fromNow being TimeSpan -> DateTime).
Actually, this example is pretty terrible, as even C#'s basic format would be "DateTime.Now.AddDays(2)" which seems pretty fine to me - add a top-level binding for now and it's on the same level of conciseness. Also, adding type extensions to integers for time seems quite ugly. Most 3rd party libraries I've seen don't use type extensions in a graceful manner, and end up slapping members on everything and it's just silly. (And I'm ignoring the fact that using .Now in .NET is rarely correct since it's rare when you don't want to use whatever random timezone the server's configured for, instead of UTC.)