views:

629

answers:

24

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.)

+1  A: 

I gues C++ , you can make unit class with overloaded operators and some #define macros

Szczepan
For example using Boost Units: http://www.boost.org/doc/libs/1_37_0/doc/html/boost_units.html
Ferdinand Beyer
A: 

In Perl, you can use DateTime which allows such things as:

my $dt = DateTime->now
$dt->subtract( hours => 1 );
David Dorward
A: 

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.

Jay
+2  A: 

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".

duffymo
Isn't the OP referring to language support for unit notation, rather than API support for the concept of units?
skaffman
Of course, but I didn't know of one. Even FORTRAN, the ne plus ultra of scientific computing languages, didn't support units when I last used it.
duffymo
+10  A: 

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.

sepp2k
or extension property -> 5.days . Althrough, it will break almost every 'good programming advice' i'm aware of.
Yossarian
Yes, extension methods are one way to do it in .NET, converting 5.Days() into TimeSpan.FromDays(5).
bruceboughton
+1  A: 

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.

Joseph
wolframalpha.com does that
DmitryK
A: 

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.

pavium
+5  A: 

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%5F37%5F0/doc/html/boost%5Funits.html

Jared
And with C++0x we can say `auto Table = 2.0*meter * 3.0*meter;`.
MSalters
A: 

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: http://us2.php.net/strtotime

Scott Saunders
String parsing doesn't really count as a programming language syntax feature!!
bruceboughton
+2  A: 

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.

T.R.
A: 

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)
Matthew Scharley
It is even better than that :)
vava
A: 

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'
vava
+2  A: 

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.

devio
A: 

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.

paxdiablo
#define MINUTE * 36 ?
Dave
Thanks, @Dave, typo on my part.
paxdiablo
If you threw out the first 4 #defines and used proper math, it wouldn't be bad C.
T.E.D.
+12  A: 

You might be interested in F# Units of Measure support

Damien_The_Unbeliever
+18  A: 
Scott Weinstein
If I'm reading that post right, a) that's awesome... b) F# must implement its own `float` type then, seperate from `System.Float`? If so, can we use this system from other .NET language with some syntactic nasties?
Matthew Scharley
a) F# uses the standard .Net Float and Double, but add on it's own type inference and checking. b) there's good interop between F# and other .Net languages
Scott Weinstein
+1 for the suicidal code
Epaga
A: 

PowerShell has some basic support. For instance 5GB/1MB evaluates to 5120

Scott Weinstein
+3  A: 

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.

Regards

Mark

High Performance Mark
You guys can see what the syntax looks like here:http://research.sun.com/projects/plrg/PLDITutorialSlides9Jun2006.pdfPage 17/124
ShaChris23
+2  A: 

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

>>>
mavnn
A: 

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.

T.E.D.
I was not asking out of need for such a syntax, more out of curiosity. Certainly for my example, unit syntax doesn't really offer much.
bruceboughton
+2  A: 

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.)

Jonathan Mitchem
+1  A: 

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.

ndp
+1  A: 

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
earl
+1  A: 

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.

Eli Bendersky