23

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

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
bruceboughton
  • 622
  • 5
  • 16

24 Answers24

25

F# has units of measure. Some examples from

http://blogs.msdn.com/andrewkennedy/archive/2008/08/20/units-of-measure-in-f-part-one-introducing-units.aspx

alt text

alt text

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
Scott Weinstein
  • 18,890
  • 14
  • 78
  • 115
  • 1
    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 Aug 21 '09 at 21:21
  • 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 Aug 22 '09 at 01:14
  • F# is awesome I was wondering what was happening in the background when all i see in the code is just string literals that somehow play the role of being an operator of some sort. – Jerric Lyns John Jul 16 '14 at 11:11
12

You might be interested in F# Units of Measure support

Damien_The_Unbeliever
  • 234,701
  • 27
  • 340
  • 448
10

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
  • 363,768
  • 54
  • 674
  • 675
8

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

Jared
  • 91
  • 2
4

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.

user229044
  • 232,980
  • 40
  • 330
  • 338
High Performance Mark
  • 77,191
  • 7
  • 105
  • 161
  • You guys can see what the syntax looks like here: http://research.sun.com/projects/plrg/PLDITutorialSlides9Jun2006.pdf Page 17/124 – sivabudh Mar 26 '10 at 22:07
4

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
  • 263,248
  • 89
  • 350
  • 412
  • 1
    Ada's type system is in a completely different league! Most "strongly" typed languages have a limited definition of type usually just size and composition. Ada types can be nailed down precisely to its precision, ranges and valid values. – ATL_DEV Feb 01 '23 at 22:16
3

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.
  • 7,442
  • 6
  • 30
  • 34
3

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
  • 9,101
  • 4
  • 34
  • 52
2

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
  • 305,152
  • 44
  • 369
  • 561
  • Isn't the OP referring to language support for unit notation, rather than API support for the concept of units? – skaffman Aug 21 '09 at 14:16
  • 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 Aug 21 '09 at 14:44
2

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.

Community
  • 1
  • 1
devio
  • 36,858
  • 7
  • 80
  • 143
2

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
  • 953
  • 3
  • 13
  • 18
1

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

Szczepan
  • 217
  • 2
  • 8
1

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
  • 25,330
  • 8
  • 76
  • 125
1

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
  • 127,823
  • 52
  • 194
  • 222
1

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
  • 24,851
  • 11
  • 64
  • 79
1

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
  • 21,546
  • 5
  • 36
  • 52
1

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
  • 40,327
  • 6
  • 58
  • 59
0

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
  • 4,994
  • 4
  • 28
  • 41
0

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
  • 14,808
  • 4
  • 33
  • 50
0

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
  • 29,840
  • 14
  • 57
  • 64
0

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
  • 854,327
  • 234
  • 1,573
  • 1,953
0

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

Scott Weinstein
  • 18,890
  • 14
  • 78
  • 115
0

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.
  • 44,016
  • 10
  • 73
  • 134
  • 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 Aug 21 '09 at 19:57
-1

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

my $dt = DateTime->now
$dt->subtract( hours => 1 );
Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335