有没有允许单位的语言?

问题描述 投票:23回答:24

今天在C#中编写以下内容时

DateTime.Now.AddYears(-60)

我想知道是否有任何语言允许使用单位更自然的语法:

DateTime.Now - 60years

有谁知道吗?具体来说,我对单位运算符(?)的存在感兴趣,它将“60年”变成例如“TimeSpan.FromYears(60)”。能够定义自己的单元运算符也很简洁,类似于在C#中编写转换运算符的方式

(是的,我知道TimeSpan多年来都不满足 - 这是一个例子。)

programming-languages syntax
24个回答

2
投票

使用单位时,实际上是在分配类型。转换可以通过转换或通过基于参数类型(函数重载)区分函数调用来实现。几乎任何静态类型语言(允许您彻底定义类型)都可以让您做类似的事情。它会使您的程序更加健壮,尽管那些喜欢动态类型语言的人可能会认为相对于为大多数应用程序实现这种彻底类型系统花费的时间而言,增益很小。另一方面,建立一个Mars Climate Orbiter值得这样的类型系统。 语法有点不同,但你的例子让我觉得非常类似于一些人如何使用Haskell的类型系统(或任何类型的函数式语言)的常见例子,但是,正如我所提到的,这在C类中也是可行的语言也是如此。


2
投票

Ada及其堂兄VHDL直接支持单位的概念。由于这些语言的类型非常强,因此单位是类型严格的自然能力。


1
投票

我猜C ++,你可以使用重载运算符和一些#define宏来创建单元类


1
投票

我不知道是否存在,但我希望在接下来的几年里能够看到像DSLs这样的东西。我觉得有点像下一代MATLAB或其他东西。我相信这些东西有很多数学,科学和工程用途。


1
投票

MySQL有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'

1
投票

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)

1
投票

我知道你的意思,我也对此感到好奇。 (我的高中化学老师坚持认为,没有单位的数字是毫无意义的。无论如何......)

使用任何强类型语言,您可以为这些概念编写类。我用C ++,Java和Pascal编写了它们。谷歌“单位”和“Java”,你可以找到一个包含这种封装的各种物理测量的库。

C ++,它具有更流畅的类型转换和运算符重载可以使这看起来更自然。你可以让事情变得非常光滑,达到我想你想要的东西。 Java虽然这样做,但需要更明确的转换和笨拙的语法。

但不,我还没有看到它。

寻找为科学家创建的领域特定语言,甚至是“教育”语言。


1
投票

Frink是一种专门用于“物理计算”的语言。从文档:

Frink是一种实用的计算工具和编程语言,旨在简化物理计算,以帮助确保答案正确[...]。它通过所有计算跟踪测量单位(英尺,米,千克,瓦特等),允许您透明地混合测量单位[...]

你在Frink的例子:

now[] - 60 years

0
投票

我没有看到这种语言本身就支持它。但是,如果您愿意,您当然可以用各种语言编写自己的基于日期的对象。


0
投票

我确信这不是你想要的,但在测试和测量设备领域,“测试程序”包含对电压,电流或时间单位表示的值进行操作的语句并不罕见。

但是,非常专业的东西,大多数人都不太能识别为编程语言。


12
投票

您可能对F#Units of Measure支持感兴趣


0
投票

PHP的strtotime()函数做得非常好。它需要一个字符串和一个可选的时间作为参数,并将解析字符串以找出新的时间。

例子:

 $newTime = strtotime('last monday');
 $newTime = strtotime('- 2 days', $originalTime);
 $newTime = strtotime('- 60 years', $originalTime);
 $newTime = strtotime('+ 1 week 1 day', $originalTime);

更多这里:http://us2.php.net/strtotime


0
投票

不是语言的一部分,但我在C之前看到过这样的事情,例如:

#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;

当时我和"#define begin {""#define end }"在同一个班级里似乎是令人憎恶的 - 如果你不喜欢语言的工作方式,那就用另一种语言;不要试图以这种可怕的方式将它弯曲到你的意志。

它似乎仍然是令人厌恶的,但我在我的晚年已经成熟,至少可以理解为什么有人认为这是一个好主意。


0
投票

PowerShell有一些基本的支持。例如,5GB/1MB评估为5120


0
投票

从语法上讲,我不确定它的好处是什么

DateTime.Now + 60 years

过度

DateTime.Now.AddYears (60)

我处理“单位”的典型方法是定义常量,将这些单位转换为数据对象的基本单位(如果相乘)。由于有人(breifly)用Ada标记了这个,Ada版本将是:

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

我认为你可以在C ++中做同样的想法,除了他们的时间对象可能是大整数而不是实数。


-1
投票

在Perl中,您可以使用DateTime,它允许以下内容:

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

10
投票

那么ruby的ActiveSupport库使用小时和天等方法扩展Integer类,允许你编写如下内容:

Time.now + 5.days

但这并不是一个真正的语法特性 - 它只是一个方法调用,并且可以在任何允许您向现有类添加方法的语言中实现。您可以使用扩展方法在C#中完成它 - 尽管它必须是5.days()


7
投票

有一个单元的Boost C ++库,它广泛使用模板元编程来提供类似于你想要的语法。

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


4
投票

Sun的新语言Fortress支持单位,如果记忆服务,它足够聪明,可以阻止你做一些奇怪的事情,比如从长度测量中减去时间的测量。

Mathematica具有度量单位和处理它们的不太笨拙的语法。


3
投票

Unum与Python完全相同,允许代码如下:

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

>>>

2
投票

请参阅C# Extensions上的答案,其中扩展了int类以支持诸如Hours(),Days()等方法。

Powershell有kB, MB, and GB operators用于处理文件大小等。

MSSQL中的DATE_ADD() function接受日期算术等单位,如日,小时等。


2
投票

Java的JODA库以这种方式工作。

并且有JSR-275提出单位框架。

我早在1997年就从Martin Fowler那里听说过这个问题。他在他的"Analysis Patterns"写了这篇文章。


2
投票

本身不是单位......而是一种使用扩展方法为您提供类似单位功能的方法。此示例适用于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分钟的TimeSpan。如果您具有类似的基类来表示其他单元类型,则可以添加相同类型的扩展功能。

(注意:这只是Ruby示例的C#表示。)

© www.soinside.com 2019 - 2024. All rights reserved.