Reputation: 642
When writing the following today in C#
DateTime.Now.AddYears(-60)
I wondered whether there are any languages that allow a more natural syntax with units:
DateTime.Now - 60years
Does anyone know of any? Specifically, I'm interested in the presence of unit operators(?) that turn "60years" into e.g. "TimeSpan.FromYears(60)". It'd also be neat to be able to define your own unit operators, similar to how you can write conversion operators in C#
(Yes, I know TimeSpan doesn't cater for years -- it's an example.)
Upvotes: 25
Views: 2737
Reputation: 9459
Unum does pretty much exactly that for Python, allowing code like:
>>> TON + 500*KG
1.5 [t]
>>> 5E-8*M - 28*ANGSTROM
472.0 [angstrom]
>>> 3*H + 20*MIN + 15*S
3.3375 [h]
>>> H == 60*MIN
True
>>> 10000*S > 3*H + 15*MIN
False
>>>
Upvotes: 4
Reputation: 78316
Sun's new language Fortress supports units and, if memory serves, is smart enough to stop you doing odd things such as subtracting measures of time from measures of length.
And Mathematica has units of measure and a not-too-unwieldy syntax for handling them.
Upvotes: 4
Reputation: 273376
Ada and its cousin, VHDL, directly support the concept of units. Since these languages are extremely strongly typed, units are a natural ability of the strictness of types.
Upvotes: 4
Reputation: 41755
Frink is a language purpose-built for "physical calculations" like that. From the documentation:
Frink is a practical calculating tool and programming language designed to make physical calculations simple, to help ensure that answers come out right [..]. It tracks units of measure (feet, meters, kilograms, watts, etc.) through all calculations, allowing you to mix units of measure transparently [..]
Your example in Frink:
now[] - 60 years
Upvotes: 1
Reputation: 21996
I know what you mean, and I too have been curious about this. (My high school chemistry teacher was adamant that numbers without units were fairly meaningless. Anyway...)
With any strongly typed language, you can write classes for these concepts. I've written them in C++, Java and Pascal. Google "Units" and "Java" and you can find a library that has all sorts of physical measurements encapsulated like this.
C++, with it's slicker type conversions and operator overloading can make this look more natural. You can actually make things pretty slick, getting at what I think you want. Java, although it does this, will require more explicit conversions and awkward syntax.
But no, I haven't seen it.
Look for domain specific languages created for scientists, even "educational" ones.
Upvotes: 1
Reputation: 44804
Syntacticly, I'm not really sure what the benifit would be of
DateTime.Now + 60 years
Over
DateTime.Now.AddYears (60)
My typical method for dealing with "units" is to define constants that convert those units into the data object's base unit if multiplied. Since someone (breifly) tagged this with Ada, the Ada version would be:
Years : constant := 60.0 * 60.0 * 24.0 * 365.0;
DateTime.Now := DateTime.Now + (60.0 * Years);
I think you can do pretty much the same think in C++, except that their time objects are liable to be large integers instead of reals.
Upvotes: -1
Reputation: 7592
When you use units, you're actually assigning a type. The conversions could be implemented through casting, or through differentiating function calls based on parameter types (function overloading). Just about any statically typed language (that allows you to define types thoroughly) would allow you to do something similar. It would make your program more robust, though those who prefer dynamically typed languages may argue that gains are small relative to time spent implementing such a thorough type system for most applications. Building a Mars Climate Orbiter would, on the other hand, merit such a type system.
The syntax is a little different, but your example strikes me as very similar to common examples of how some would use Haskell's type system (or that of any typed functional language), though, as I mentioned, this is also doable in C-like languages as well.
Upvotes: 3
Reputation: 973
Not units, per se... but one way to use extension methods to give you unit-like functionality. This example is for TimeSpan, specifically.
static class TimeExtensions
{
public static TimeSpan ToDays(this int i)
{
return new TimeSpan(i, 0, 0, 0, 0);
}
public static TimeSpan ToHours(this int i)
{
return new TimeSpan(0, i, 0, 0, 0);
}
public static TimeSpan ToMinutes(this int i)
{
return new TimeSpan(0, 0, i, 0, 0);
}
public static TimeSpan ToSeconds(this int i)
{
return new TimeSpan(0, 0, 0, i, 0);
}
public static TimeSpan ToMilliseconds(this int i)
{
return new TimeSpan(0, 0, 0, 0, i);
}
}
Then, simply 4.ToMinutes() gives you a TimeSpan of 4 minutes. If you have similar base classes to work with to represent other unit types, the same sort of extension functionality can be added.
(Note: this is merely a C# representation of the Ruby example.)
Upvotes: 2
Reputation: 308743
Java's JODA library works that way.
And there's JSR-275 that proposes a units framework.
I first heard about this issue back in 1997 from Martin Fowler. He wrote about it in his "Analysis Patterns".
Upvotes: 2
Reputation: 19117
PowerShell has some basic support. For instance 5GB/1MB
evaluates to 5120
Upvotes: 0
Reputation: 239646
You might be interested in F# Units of Measure support
Upvotes: 12
Reputation: 132244
SQL, or atleast MySQL has some basic time based unit support.
mysql> SELECT DATE_SUB(NOW(), INTERVAL 1 DAY) AS `yesterday`, NOW() + INTERVAL 1 DAY AS `tomorrow`;
+---------------------+---------------------+
| yesterday | tomorrow |
+---------------------+---------------------+
| 2009-08-20 06:55:05 | 2009-08-22 06:55:05 |
+---------------------+---------------------+
1 row in set (0.00 sec)
Upvotes: 1
Reputation: 881243
Not part of the language, but I've seen that done before in C, something like:
#define NOW time(0)
#define PLUS +
#define AND +
#define MINUS -
#define SECOND * 1
#define SECONDS * 1
#define MINUTE * 60
#define MINUTES * 60
#define HOUR * 3600
#define HOURS * 3600
#define DAY * 86400
#define DAYS * 86400
time_t waitUntil = NOW PLUS 1 HOUR AND 23 MINUTES;
It seemed like an abomination to me at the time, in the same class as "#define begin {"
and "#define end }"
- if you don't like the way the language works, use a different language; don't try to bend it to your will in such a hideous way.
It still seems like an abomination, but I've mellowed in my old age and can at least understand why maybe someone thought it was a good idea.
Upvotes: 0
Reputation: 37205
See the answer on C# Extensions where the int class is extended to support methods such as Hours(), Days(), etc.
Powershell has the kB, MB, and GB operators for handling file sizes etc.
The DATE_ADD() function in MSSQL accepts units such as day, hour etc for date arithmetic.
Upvotes: 2
Reputation: 25371
MySQL has this feature
mysql> SELECT '2008-12-31 23:59:59' + INTERVAL 1 SECOND;
-> '2009-01-01 00:00:00'
mysql> SELECT INTERVAL 1 DAY + '2008-12-31';
-> '2009-01-01'
mysql> SELECT '2005-01-01' - INTERVAL 1 SECOND;
-> '2004-12-31 23:59:59'
Upvotes: 1
Reputation: 30394
PHP's strtotime() function does it very nicely. It takes a string and an optional time as parameters and will parse the string to figure out a new time.
Examples:
$newTime = strtotime('last monday');
$newTime = strtotime('- 2 days', $originalTime);
$newTime = strtotime('- 60 years', $originalTime);
$newTime = strtotime('+ 1 week 1 day', $originalTime);
More here: https://www.php.net/strtotime
Upvotes: -1
Reputation: 91
There is a Boost C++ library for Units that makes extensive use of template metaprogramming to provide something similar to the syntax you desire.
quantity<force> F(2.0*newton);
quantity<length> dx(2.0*meter);
quantity<energy> E(work(F,dx));
http://www.boost.org/doc/libs/1_37_0/doc/html/boost_units.html
Upvotes: 8
Reputation: 15118
I'm sure it's not what you're looking for, but in the area of test and measurement equipment, it would not be unusual for a 'test program' to include statements which operate on values expressed with voltage, current or time units.
Very specialised stuff, though, and barely recognisable by most as programming languages.
Upvotes: 0
Reputation: 25513
I don't know if one exists yet, but I would expect to start seeing such things popping up as DSLs in the next couple of years. I'm thinking sort of like a next generation MATLAB or something. I'm sure there are loads of mathematical, scientific, and engineering uses for such things.
Upvotes: 1
Reputation: 370112
Well the ActiveSupport library for ruby extends the Integer class with methods like hours and days which allows you to write things like:
Time.now + 5.days
But that's not really a syntax feature - it's just a method call and is possible in any language that allows you to add methods to an existing class. You could do it in C# with extension methods - though it would have to be 5.days()
there.
Upvotes: 10
Reputation: 5043
I have not seen such a language that supports it inherently. However you could certainly write your own Date based objects in a variety of languages, if your so inclined.
Upvotes: 0
Reputation: 943207
In Perl, you can use DateTime which allows such things as:
my $dt = DateTime->now
$dt->subtract( hours => 1 );
Upvotes: -1
Reputation: 217
I gues C++ , you can make unit class with overloaded operators and some #define macros
Upvotes: 1