Language agnostic 有任何编程语言支持对基本数据类型定义约束吗?

Language agnostic 有任何编程语言支持对基本数据类型定义约束吗?,language-agnostic,programming-languages,language-design,Language Agnostic,Programming Languages,Language Design,昨晚我想编程语言可以有一个功能,我们应该能够约束分配给原始数据类型的值 例如,我应该说int类型的变量只能有0到100之间的值 int<0, 100> progress; int进程; 这将在所有场景中充当正常整数,但不能指定超出约束中定义的范围的值。编译器不会编译代码progress=200。 此约束可以与类型信息一起进行 这可能吗?它是用任何编程语言完成的吗?如果是的话,那么是哪种语言拥有它,这种技术叫什么?我真的怀疑你能做到这一点。毕竟这些都是原始数据类型,重点是原始数据!

昨晚我想编程语言可以有一个功能,我们应该能够约束分配给原始数据类型的值

例如,我应该说int类型的变量只能有0到100之间的值

int<0, 100> progress;
int进程;
这将在所有场景中充当正常整数,但不能指定超出约束中定义的范围的值。编译器不会编译代码
progress=200
。 此约束可以与类型信息一起进行


这可能吗?它是用任何编程语言完成的吗?如果是的话,那么是哪种语言拥有它,这种技术叫什么?

我真的怀疑你能做到这一点。毕竟这些都是原始数据类型,重点是原始数据! 添加约束将使类型成为其原始状态的子类,从而扩展它

来自维基百科:

基本类型是由编程语言作为基本构建块提供的数据类型。大多数语言都允许从基本类型开始递归构造更复杂的复合类型

内置类型是编程语言提供内置支持的数据类型

所以就个人而言,即使有可能,我也不会这么做,因为这是一种糟糕的做法。相反,只需创建一个返回此类型和约束的对象(我相信您已经想到了此解决方案)。

我相信Pascal(和Delphi)提供了与此类似的功能


我认为这在Java和Ruby中都是不可能的(在Ruby中可能是可能的,但需要一些努力)。不过,我对其他语言一无所知。

这通常是不可能的。在没有任何算术运算符的情况下使用整数是没有意义的。使用算术运算符,您可以实现以下功能:

int<0,100> x, u, v;
...
x = u + v; // is it in range?
intx,u,v;
...
x=u+v;//它在射程内吗?

如果您愿意在运行时进行检查,那么是的,有几种主流语言支持它,从Pascal开始。

Pascal有子范围。Ada对此进行了一点扩展,因此您可以执行类似于子范围的操作,或者您可以创建一个具有现有类型特征的全新类型,但与之不兼容(例如,即使它在正确的范围内,您也无法基于整数为新类型分配整数)

C++不直接支持这个想法,但它足够灵活,如果您愿意,可以实现它。如果您决定支持所有复合赋值运算符(+=、-=、*=,等等),那么这可能需要大量的工作

<>其他支持运算符重载的语言(例如,ML和公司)可能支持它与C++ ++ ./p>非常相似。
还要注意的是,设计中涉及到一些非常重要的决策。特别是,如果类型的使用方式可能/确实会导致中间结果溢出指定范围,但最终结果在指定范围内,您希望发生什么?根据您的情况,这可能是一个错误,也可能是完全可以接受的,您必须决定哪一个。

这当然是可能的。有许多不同的技术可以做到这一点,但“依赖类型”是最流行的

编译器甚至可以在编译时静态检查约束。例如,见Agda2和ATS(ATS-lang.org)

我认为,在没有完全依赖类型的情况下,较弱形式的“范围类型”是可能的

搜索研究论文的一些关键词: -防护类型 -补给类型
-子范围类型

Ada允许类似于您描述的范围:

type My_Int is range 1..100;
因此,如果您尝试为小于1或大于100的My_Int赋值,Ada将引发异常约束错误


请注意,我从未使用过Ada。我只读过有关此功能的文章,所以在深入研究之前请先进行研究。

SQL有域,域由一个基本类型和一个动态检查的约束组成。例如,您可以将域电话号码定义为具有适当位数、有效区号等的字符串。

当然!万一你错过了:C。你是C吗?你不喜欢C?你不把
short
算作整数的约束吗?好的,所以C只提供预打包的约束类型

顺便说一句:Pascal有子范围类型的答案似乎没有抓住它们的重点。在Pascal中,不可能出现数组边界冲突。这是因为数组索引必须与使用声明的数组的类型相同。反过来,这意味着要使用整数索引,必须将其强制降到子范围,这就是执行运行时检查的地方,而不是访问数组


这是一个非常重要的想法,因为这意味着数组索引类型上的for循环可以安全地访问数组组件,而无需任何运行时检查。

我所看到的语言通过接口契约强制执行了这些约束(通过编译器作为用法的静态限定符,而不是通过类型信息,在代码中自动下推)。请参阅Eiffel和SpecSharp()如果你觉得结果类型不再是原始的,或者这样的支持是用一个库添加的?如果是这样,那么C++就应该能够很容易地做你想做的事情。在C++中,我们可以重载赋值操作符并在其中抛出异常,所以是的,你是对的,它可能是通过创建一个非本原类型来向原始EQ隐式转换的。但是唯一的问题是编译器不能静态地检查它。正如你所接受的答案所说的,你可以重载比赋值运算符多得多的东西。但是,是的,你要么在运行时进行检查,要么进行非常奇怪的类型转换,这可能会使你的c语言很难做任何有用的事情受过训练的类型。