Есть ли языки, которые позволяют юниты? - PullRequest
23 голосов
/ 21 августа 2009

При написании следующего сегодня в C #

DateTime.Now.AddYears(-60)

Я задавался вопросом, существуют ли языки, которые допускают более естественный синтаксис с единицами измерения:

DateTime.Now - 60years

Кто-нибудь знает что-нибудь? В частности, меня интересует присутствие операторов единиц (?), Которые превращают «60 лет» в, например, "TimeSpan.FromYears (60)". Также было бы неплохо иметь возможность определять свои собственные операторы модулей, подобно тому, как вы можете писать операторы преобразования в C #

(Да, я знаю, что TimeSpan не обслуживает годами - это пример.)

Ответы [ 24 ]

2 голосов
/ 21 августа 2009

Не единицы, как таковые ... но один способ использовать методы расширения, чтобы дать вам функциональность, подобную единице. Этот пример специально для TimeSpan.

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);
    }
}

Затем просто 4.ToMinutes () дает вам интервал времени в 4 минуты. Если у вас есть схожие базовые классы для работы с другими типами модулей, можно добавить такие же функциональные возможности расширения.

(Примечание: это просто представление C # примера Ruby.)

1 голос
/ 21 августа 2009

Я догадываюсь, C ++, вы можете создать класс модулей с перегруженными операторами и некоторыми макросами #define

1 голос
/ 21 августа 2009

Frink - это язык, специально созданный для подобных "физических вычислений". Из документации:

Frink - практичный инструмент расчета и язык программирования, предназначенный для сделать физические вычисления простыми, чтобы помогите получить ответы право [..]. Отслеживает единицы измерения (футы, метры, килограммы, ватты и т. д.) через все расчеты, что позволяет вам прозрачно смешивать единицы измерения [..]

Ваш пример в Frink:

now[] - 60 years
1 голос
/ 21 августа 2009

Я знаю, что вы имеете в виду, и мне тоже было любопытно по этому поводу. (Мой учитель химии в средней школе был непреклонен, что числа без единиц были довольно бессмысленными. Во всяком случае ...)

На любом строго типизированном языке вы можете написать классы для этих понятий. Я написал их на C ++, Java и Pascal. Google "Единицы" и "Java", и вы можете найти библиотеку, которая содержит все виды физических измерений, как это.

C ++, с его более плавными преобразованиями типов и перегрузкой операторов может сделать это более естественным. Вы можете сделать все довольно гладко, получая то, что я думаю, что вы хотите. Java, хотя и делает это, потребует более явных преобразований и неудобного синтаксиса.

Но нет, я этого не видел.

Ищите предметно-ориентированные языки, созданные для ученых, даже "образовательные".

1 голос
/ 21 августа 2009

Я не знаю, существует ли он еще, но я ожидаю, что через несколько лет начнут появляться такие вещи, как DSL s. Я думаю, что-то вроде следующего поколения MATLAB или что-то в этом роде. Я уверен, что есть множество математических, научных и технических применений для таких вещей.

1 голос
/ 21 августа 2009

MySQL имеет эта функция


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'
1 голос
/ 21 августа 2009

SQL, или, по крайней мере, MySQL имеет базовую поддержку единиц времени.

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)
0 голосов
/ 21 августа 2009

Синтаксически, я не совсем уверен, какой будет польза от

DateTime.Now + 60 years

Более

DateTime.Now.AddYears (60)

Мой типичный метод для работы с «единицами» - это определение констант, которые преобразуют эти единицы в базовую единицу объекта данных при умножении. Поскольку кто-то (кратко) отметил это с помощью Ada, версия Ada будет выглядеть так:

Years : constant := 60.0 * 60.0 * 24.0 * 365.0;
DateTime.Now := DateTime.Now + (60.0 * Years);

Я думаю, что вы можете сделать то же самое в C ++, за исключением того, что их временные объекты могут быть большими целыми числами, а не действительными.

0 голосов
/ 21 августа 2009

Я не видел такого языка, который бы поддерживал его по своей сути. Тем не менее, вы можете написать свои собственные объекты на основе даты на разных языках, если хотите.

0 голосов
/ 21 августа 2009

PowerShell имеет базовую поддержку. Например, 5GB/1MB оценивается в 5120

...