Хочу поделиться с записями, сделанными на начало прошлого года и содержащими идеи на тему, какими фичами должен обладать ЯП, условно приближенный к идеальному.
-) Все входные аргументы подпрограмм подлежат обязательной проверке assert-подобным выражением.
procedure WriteChar
(
x: int; Math.InRange(x, 0, WndWidth - 1);
y: int; Math.InRange(y, 0, WndHeight - 1);
col: str; ANY;
)
Смысл: координаты должны быть в рамках окна, а строка цвета - любой.
Особенности:
- Объявление одного аргумента - одна строка.
- Аргумент отделяется от охраны символом ";"
- Охрана - обычное логическое выражение. Если оно включает подпрограммы, то те не должны рекурсивно ссылаться на объявляемую подпрограмму.
- Константа ANY = TRUE.
Дополнение:
Так как охрана может быть сложной и писать её полностью может быть затруднительно, неплохим вариантом видится введение соглашений (см. Соглашения).
-) Именованные параметры.
При вызове подпрограммы должны указываться пары: имя параметра ":" значение.
WriteChar(x: 3; y: 4; col: 'black');
! Исключение: если переменная/константа имеет то же имя, что и параметр, то может указываться просто имя параметра:
WriteChar(x, y, col: 'red');
-) Опциональные параметры.
Параметры, которые могут быть опущены при вызове. При этом в теле подпрограммы будут находиться проверки компилятора на проинициализированность подобных аргументов.
procedure WriteChar
(
x: ...
y: ...
optional Col: string; ANY; (* охрана типа осуществляется только, если аргумент инициализирован *)
)
{
...
if !IsSet(Col)
{
Col := Console.Col;
}
}
IsSet - проверяет, установлен ли аргумент. Прямое присваивание значения аргументу автоматически устанавливает его.
-) Аргументы со значением по умолчанию. Значение должно быть константным выражением!
function Random
(
Min: int = 0; Min >= 0; (* охрана сработает всегда *)
Max: int = 99; Max >= Min; (* охрана сработает всегда *)
): int;
-) Аргументы по ссылке:
- in - после вызова переменная получает статус Unknown (равносильно неинициализированности)
- out - внутри подпрограммы имеет начальный статус Unknown
- inout - аналог var
-) Язык со сборкой мусора.
-) procedure и function для логического разделения подпрограмм. () после имени обязательно.
-) Обязательное присвоение значений переменным при объявлении с необязательной охраной.
VAR
AbsX: int = x + Con.Window.x1; AbsX in [0; Con.Width - 1];
-) Записи-константы и записи, создаваемые на лету.
coords := (x: MyX, y); (* Заметьте, "y" не указывается два раза, та как имя переменной совпадает с именем поля в записи *)
-) Опциональные поля записей.
Cell = record
optional Opacity: float = 1.0; (* прозрачность ячейки *)
end;
-) Обязательное присвоение значений полям записи.
TCoord = record
x: int = -1;
y: int = -1;
end;
-) Соглашения.
Служат для точного указания особенностей подпрограмм.
Пусть соглашение - логическая функция.
Пусть часть функций работает с абсолютными координатами консоли, а другая с относительными (относительно границ логически подокна).
convention (Con: TConsole) UsesRelativeCoords ()
(
x: int;
y: int;
)
{
result := Math.InRange(x, Con.WndWidth - 1) and Math.InRange(y, Con.WndHeight - 1);
}
procedure WriteChar
(
x: int; ANY;
y: int; ANY;
Ch: char; ANY;
); UsesRelativeCoords;
{
...
}
Те аргументы, которые указанны в соглашении, обзяаны быть и в подпрограммах, использующих эти соглашения.