Это то же самое, что типы данных, но для логики приложения, а не логики исполнителя (CPU).
Пример constraint'а: «constrX is integer, [0..55],[117..200],999»
Другой пример: «constrY is string, regexp(^fo+\s+bar$)»
По-моему по сравнению с ограничениями на внешние данные в духе «вот в этом поле число не должно быть больше 2^32-1» потому что у нас битовая разрядность такая - contraint'ы были бы гиганстким шагом вперёд, позволили бы существенно сократить «проверяющий» код и оптмизировать выполнение за счёт того, что нам не пришлось бы создавать объект только ради того, чтобы убедиться в консистентности значения.
Оптимальным видится такой вариант использования: переменная, заполняемая из внешнего источника -> наложение constraint'ов -> внутренняя переменная с мета-тегом «пройдён constraint такой-то».
Т.е. ограничения - это механизм преимущественно для рантайма, во многом упрощающий тестирование и сопровождение софта. Для проверок соответствия ограничениям нужно писать декларативные определения, а не заниматься индусскими изысками с написанием соотв. кода вручную - желательно, ещё и в 30 разных местах.
Например, во всеми нелюбимом perl'е есть уже львиная доля такой логики: а именно taint mode, когда переменные делятся на «грязные» (из внешних источников) и «чистые». Недостаток - как раз в отсутствии простого механизма наложения ограничений, который бы и «очищал» переменную.
Речь о том, что сами по себе типы данных в компилируемых языках - это сказка о повышении производительности, но никак не о повышении стабильности кода. Потому что если в вашу переменную типа UInt8, которая не может быть за диапазоном [101..143] приехало вдруг 235, а вы это не проверили в рантайме - ну как бы тип данных вас точно не спасёт.
В общем, я же правильно понимаю, что везде подобные вещи реализованы сбоку, а не как встроенное средство самого ЯП?