bruceboughton
bruceboughton

Reputation: 642

Are there any languages that allow units?

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

Answers (24)

mavnn
mavnn

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

High Performance Mark
High Performance Mark

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

Eli Bendersky
Eli Bendersky

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

earl
earl

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

ndp
ndp

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

T.E.D.
T.E.D.

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

T.R.
T.R.

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

Jonathan Mitchem
Jonathan Mitchem

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

duffymo
duffymo

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

Scott Weinstein
Scott Weinstein

Reputation: 19117

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

Upvotes: 0

Damien_The_Unbeliever
Damien_The_Unbeliever

Reputation: 239646

You might be interested in F# Units of Measure support

Upvotes: 12

Matthew Scharley
Matthew Scharley

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

paxdiablo
paxdiablo

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

devio
devio

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

vava
vava

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

Scott Saunders
Scott Saunders

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

Jared
Jared

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

pavium
pavium

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

Joseph
Joseph

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

sepp2k
sepp2k

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

Jay
Jay

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

Quentin
Quentin

Reputation: 943207

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

my $dt = DateTime->now
$dt->subtract( hours => 1 );

Upvotes: -1

Szczepan
Szczepan

Reputation: 217

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

Upvotes: 1

Related Questions