Ну, то, что рядом с ":=" есть и ключевые слова для дефиниции -- "выкрутиться" несложно. Мол, некое "let a := expression" выглядит как и в математических текстах в виде частого употребления "пусть a := expression", это слово "пусть" (с разновидностью аля "var"/"function", или совместно в стиле "let fn f(x: int) := ...") становится частью технологического языка. Пожалуй, лишь "def" рядом будет смотреться коряво, на чём акцентировалось выше в теме.
Тогда есть возможность задать тот же функциональный тип (именно определение типа) и через "равно". Сейчас, к примеру, функции в PascalABC могут возвращать и кортежи, какая может быть форма декларации типа в таком случае -- на примере функции вычисления площади и периметра прямоугольника по ссылке ниже, где в док-ции тип результата (выводимый автоматически), всё-таки, не указан:
http://pascalabc.net/downloads/pabcnethelp/index.htm#page=LangGuide/Types/tuples.htmlКод:
// Реализация функции:
function SP(a,b: real) := (a*b, 2*(a+b));
// Возможные формы объявления её типа:
function SP(a,b: real): (real, real);
function SP(a,b: real): (real*real);
function SP(a,b: real): real*real;
function SP: (real, real) -> (real, real);
function SP: (real*real) -> (real*real);
function SP: real*real -> real*real;
В PascalABC не уверен, что поддерживается логическая форма записей кортежей через "*", как и типов-сумм через "+". Однако эти формы, как и классические математические формы определения функции в виде "f: t -> t" удобны в рамках соответствующих математических предметок. Традиционный "паскалевский" вид "f(t): t" в случае результата-кортежа не очень-то приглядный из-за возникающего сочетания скобок и ":", особенно если рядом указана и реализация:
Код:
function SP(a,b: real): (real, real) := (a*b, 2*(a+b));
Мне понравился способ в Lustre (ML-диалект, здесь на форуме есть тема про Esterel и смежные технологии), где для инженеров, занимающихся прикладной рутиной, предлагают все декларации типов через "=", включая и функциональные (в дополнение к обычным формам, приведенным выше), в стиле:
Код:
// Объявление типа и реализации:
function SP(real, real) = (real, real);
function SP(a, b) := (a*b, 2*(a+b));
// Традиционная, не краткая, форма реализации, совмещенная с объявлением типа,
// с использованием именованных и результатов:
function SP(a,b: real) = (s,p: real)
begin
s := a*b;
p := 2*(a+b);
end;
В самом Lustre нет кратких форм реализации, здесь как раз ":=" к месту. Вместо "равно" можно использовать слово "return" (как и в Ada) для длинных определений, если необходимо разбивать текст на множество строк.
Использование именования для всех параметров и результатов, фактически, вырисовывается таким же, как и в Go (что есть и в Lustre, но там иная "императивщина").
Значения по умолчанию для параметров процедур необходимо задавать через "=", поскольку это внутренняя декларация типа, т.е. внутри комплексной структуры (значение по умолчанию задает характеристики типа параметра):
Код:
// Определение типа:
function f(s: string; pos: integer = 0; len: integer = 1000) = integer;
// Несколько реализаций:
function f(s, _, 0) := expression;
function f(s, 0, l) := expression;
function f(s, p, l) := expression;
Выше в примерчике предполагается перегрузка процедур/функций и по константам (некий упрощённый "pattern matching", уместный при наличии кратких форм определений).
Переменные определяются через ":=" как обычно, как внутри кода, так и в секции объявлений перед блоком действий (инициализирующие значения).
То, что есть дефиниции переменных и по месту -- очень даже норм. Главное, чтобы было наличие ключевого слова, выделяющее объявление. В том же Go получилась жесть с допустимостью краткой формы в виде оператора ":=", который без слова "var" вводит новые переменные. Когда присваивания в форме "=" и ":=" возникают однородно вперемешку, между ними едва уловима разница, можно что-то не заметить и не так понять или непреднамеренно ввести новую переменную в текущей синтаксической области вместо изменения значения у существующей переменной, определенной выше уровнем.
Здесь в смежной теме отмечена проблематика объявлений по месту, но такова связана в большей степени именно с формой декларации (в общем, отдельная тема).
Кстати, наткнулся на сопоставление различных форм объявлений переменных в языках программирования, м.б. полезно:
-
Why does the type go after the variable name in modern programming languages?-
What's the rationale behind the ordering of Scala's value/variable declaration when including a type identifier?В общем, такие вот соображения, м.б. будут полезными для какого-нибудь здешнего "Семантика".