DEV Community

Cover image for The feature missed in C++, Java, C#, PHP, Python, Ruby and JavaScript
Artur Ampilogov
Artur Ampilogov

Posted on • Updated on

The feature missed in C++, Java, C#, PHP, Python, Ruby and JavaScript

Real objects and notions in our lives have some constraints. The height of a person cannot be a negative number, the same as age. An infant in international airlines is a baby under 2 years old. A TCP/IP port on any device cannot be a number larger than 65535.

Programming languages, like C, C++, Java, C#, PHP, Python, Ruby, and JavaScript, typically would imply the usage of a wide range of built-in types for such purposes: integer, float, and decimal. In this article, I will review an old language feature that can improve type declaration for the mentioned cases.

Range constraints

Temperature

The minimum temperature in Celsius degrees has a constant value equal to -273.15.

In 1972, in the book "Structured Programming", three well-known computer scientists mentioned an interesting approach to working with such constraints:

All structured data must in the last analysis be built up from unstructured components, belonging to a primitive or unstructured types. (...)
Although these primitive types are theoretically adequate for all purposes, here are strong practical reasons for encouraging a programmer to define his own unstructured types, both to clarify his intentions about the potential range of values of a variable, and the interpretation of each such value; and to permit subsequent design of an efficient representation.
(...) Such a type is said to be an enumeration, and we suggest a standard notation for the name of the type and associating a name with each of its alternative values.
type suit = (club, diamond, heart, spade);
(...)
type year = 1900 .. 1960;
type coordinate = 0 .. 1023;
(...) We therefore introduce the convention that a .. b stands for the inline range of values between a and b inclusive. This is known as subrange of the type to which a and b belong, (...)

Ole-Johan Dahl, Edsger W. Dijkstra, C.A.R. Hoare, Structured Programming, A.P.I.C. Studies in Data Processing, No. 8, 1972, p.97

Pascal, Modula-2, Delphi, and Ada support custom unstructured (primitive) types. For example, in Ada the temperature type can be declared as:

subtype TemperatureCelsius is Float range -273.15 .. Float'Last;
Enter fullscreen mode Exit fullscreen mode

where Float'Last is the maximum Float number.

PassengersNumber

Airline businesses may allow to purchase of tickets for a traveling group having a maximum of 10 persons in one transaction. Instead of using an integer type, it is more suitable to specify a custom type in Ada with compile and runtime checks:

type PassengersNumber is range 1 .. 10;
Enter fullscreen mode Exit fullscreen mode

Email address

An email address string input may have a constraint to be required and less or equal to 320 characters in length. In Ada, it is possible to define a new type for that purpose as:

type EmailAddress is String (1 .. 320);
Enter fullscreen mode Exit fullscreen mode

It also makes code more readable when variables do not have full names:

String cc;
String body;
// vs
EmailAddress cc;
EmailBody body;
Enter fullscreen mode Exit fullscreen mode

Type predicate

For more complex logic requiring a function check, for example, declaring a type for the standard HTTP client errors codes (4XX) it is possible to use a static predicate:

subtype HTTPClientErrorCode is Integer with
  Static_Predicate => 
    HTTPClientErrorCode in 400 .. 418 | 421 .. 429 | 431 | 451;
Enter fullscreen mode Exit fullscreen mode

Strong typing

One more important concept is lack of implicit conversion between types, also known as strong typing. For example, adding a Float value to a TemperatureCelsius value in Ada will result in an error.

The missed feature

Many modern languages after decades of improvements still do not support such an important feature, it is possible only to mimic the behavour: C++, Python, Java. It will be great for many developers to be able to create custom primitive types in an easy way.

Top comments (0)