Я спрашиваю относительно c #, но я предполагаю, что то же самое в большинстве других языков.
У кого-нибудь есть хорошее определение выражений и утверждений и в чем различия?
Выражение: что-то, что оценивает значение. Пример: 1 + 2 / x
Заявление: строка кода, которая что-то делает. Пример: GOTO 100
В самых ранних языках программирования общего назначения, таких как FORTRAN, различие было кристально ясным. В FORTRAN оператор был одной единицей исполнения, то, что вы сделали. Единственная причина, по которой его не называли «линией», заключалась в том, что иногда он занимал несколько строк. Выражение само по себе ничего не может сделать ... вы должны были присвоить его переменной.
1 + 2 / X
ошибка в Фортране, потому что она ничего не делает Вы должны были что-то сделать с этим выражением:
X = 1 + 2 / X
У Фортрана не было грамматики в том виде, в каком мы ее знаем сегодня - эта идея была изобретена вместе с формой Бэкуса-Наура (БНФ), как часть определения Алгол-60. В этот момент семантическое различие («иметь значение» и «делать что-то») было закреплено в синтаксисе : один вид фразы был выражением, а другой - выражением, и синтаксический анализатор мог их различать.
Разработчики более поздних языков размыли различие: они позволяли синтаксическим выражениям делать что-то, и они допускали синтаксические выражения, которые имели значения. Самый ранний популярный пример языка, который до сих пор сохранился, - C. Разработчики C поняли, что никакого вреда не было, если вам позволили оценить выражение и выбросить результат. В C каждое синтаксическое выражение может быть преобразовано в утверждение, просто ставя точку с запятой в конце:
1 + 2 / x;
это абсолютно законное заявление, хотя абсолютно ничего не произойдет. Аналогично, в C выражение может иметь побочные эффекты - оно может что-то изменить.
1 + 2 / callfunc(12);
потому что callfunc
может просто сделать что-то полезное.
Раз вы позволите любому выражению быть оператором, вы можете также разрешить оператор присваивания (=) внутри выражений. Вот почему С позволяет вам делать такие вещи, как
callfunc(x = 2);
Это вычисляет выражение x = 2 (присваивая значение от 2 до x) и затем передает это (2) в функцию callfunc
.
Это размывание выражений и операторов происходит во всех C-производных (C, C ++, C # и Java), которые все еще имеют некоторые операторы (например while
), но которые позволяют использовать практически любое выражение в качестве оператора (в присваивании только C #, Выражения вызова, приращения и декремента могут использоваться в качестве операторов (см . ответ Скотта Вишневского ).
Наличие двух «синтаксических категорий» (так называемых технических терминов для операторов и выражений такого рода) может привести к дублированию усилий. Например, C имеет две формы условного выражения:
if (E) S1; else S2;
и форма выражения
E ? E1 : E2
И иногда люди хотят дублирования, которого нет: например, в стандартном C только оператор может объявить новую локальную переменную, но эта возможность достаточно полезна, так как компилятор GNU C предоставляет расширение GNU, которое позволяет выражению объявлять локальная переменная также.
Проектировщикам других языков не понравился такой тип дублирования, и они рано поняли, что если выражения могут иметь побочные эффекты, а также значения, то синтаксическое различие между утверждениями и выражениями не так уж и полезно, поэтому они избавились от него. , Haskell, Icon, Lisp и ML - все языки, которые не имеют синтаксических операторов - они имеют только выражения. Даже структурированные циклы класса и условные формы считаются выражениями, и они имеют значения, но не очень интересные.
callfunc(x = 2);
переходит x
на callfunc
нет 2
. Если x
это поплавок, callfunc(float)
будет называться, а не callfunc(int)
. И в C ++, если вы передаете x=y
к func
и func
принимает ссылку и изменяет его, она меняется x
, не y
. where
предложение в haskell считается выражением, а не утверждением. learnyouahaskell.com/syntax-in-functions#whereВыражения могут быть оценены, чтобы получить значение, тогда как операторы не возвращают значение (они имеют тип void ).
Выражения вызова функций также можно рассматривать как операторы, но, если в среде выполнения нет специальной встроенной переменной для хранения возвращаемого значения, его невозможно получить.
Языки, ориентированные на операторы, требуют, чтобы все процедуры были списком операторов. Ориентированные на выражения языки, которые, вероятно, являются всеми функциональными языками, представляют собой списки выражений или, в случае LISP, одно длинное S-выражение, представляющее список выражений.
Хотя оба типа могут быть составлены, большинство выражений может быть составлено произвольно, если типы совпадают. Каждый тип оператора имеет свой собственный способ составления других операторов, если они могут делать все это. Foreach, и если для операторов требуется либо одна инструкция, либо чтобы все подчиненные операторы помещались в блоке операторов один за другим, если только подзаголовки не допускают своих подзаголовков.
Выражения могут также включать выражения, где выражение на самом деле не включает никаких утверждений. Однако одним исключением может быть лямбда-выражение, представляющее функцию, и поэтому оно может включать в себя все, что функция может исключить, если язык не допускает только ограниченные лямбды, такие как лямбды Python с одним выражением.
В языке на основе выражений все, что вам нужно, - это одно выражение для функции, поскольку все управляющие структуры возвращают значение (многие из них возвращают NIL). Нет необходимости в операторе возврата, так как последнее вычисленное выражение в функции является возвращаемым значением.
Void
это не нижний тип. Смотри мой ответ . null
)? Не будет void
ли больше похож на тип устройства (но с единственным недоступным значением)? void
это тип возврата функции, которая никогда не возвращается (например, функция, которая throw
является ошибкой), это тип снизу . В противном случае void
это тип устройства . Вы правы, что утверждение, которое не может расходиться, имеет тип единицы измерения. Но утверждение, которое может расходиться, является типом дна. Из-за теоремы Остановки мы обычно не можем доказать, что функция не расходится, поэтому я думаю, что единица - это выдумка. Нижний тип не может иметь значения, поэтому он не может иметь единственного значения null
. null
Значение действительно pseudovalue обозначая , что ссылка указывает на то , что не существует. Выражение - это то, что возвращает значение, а выражение - нет.
Например:
1 + 2 * 4 * foo.bar() //Expression
foo.voidFunc(1); //Statement
Большая сделка между ними заключается в том, что вы можете связывать выражения вместе, тогда как операторы не могут быть связаны.
foo.voidFunc(1);
является выражением со значением void. while
и if
являются заявлениями. return
считается подзаголовком. Проще говоря: выражение оценивает значение, а утверждение - нет.
{}
это утверждение. Помещение слова в кавычки не меняет этого. Заявления являются синтаксическими конструкциями с семантикой. Нет такого понятия, как «уровень семантики» - вы, похоже, имеете в виду выполнение . Вы говорите, что пытаетесь быть точным, но у вас ничего не получилось. Ваша жалоба о "невежестве недовольных избирателей" - это чистый ad hominem; у вас нет информации о психических состояниях downvoters. {}
определяется как оператор в спецификации языка C #. Вы можете найти это в википедии , но выражения оцениваются до некоторого значения, в то время как операторы не имеют оцененного значения.
Таким образом, выражения могут использоваться в выражениях, но не наоборот.
Обратите внимание, что некоторые языки (такие как Lisp, и, я полагаю, Ruby и многие другие) не различают оператор и выражение ... в таких языках все является выражением и может быть связано с другими выражениями.
- выражение - это все, что дает значение: 2 + 2
- оператор является одним из основных «блоков» выполнения программы.
Обратите внимание, что в C "=" на самом деле является оператором, который выполняет две вещи:
- возвращает значение подвыражения правой руки.
- копирует значение правого подвыражения в переменную слева.
Вот выдержка из грамматики ANSI C. Вы можете видеть, что C не имеет много разных видов операторов ... большинство операторов в программе являются выражениями, то есть выражением с точкой с запятой в конце.
statement
: labeled_statement
| compound_statement
| expression_statement
| selection_statement
| iteration_statement
| jump_statement
;
expression_statement
: ';'
| expression ';'
;
Некоторые вещи о языках, основанных на выражениях:
Самое главное: все возвращает значение
Нет никакой разницы между фигурными скобками и фигурными скобками для разграничения блоков кода и выражений, поскольку все является выражением. Это не мешает лексическому ограничению: локальная переменная может быть определена для выражения, в котором содержится ее определение, и для всех операторов, содержащихся в нем, например.
На языке выражений все возвращает значение. Поначалу это может показаться немного странным - что (FOR i = 1 TO 10 DO (print i))
возвращает?
Несколько простых примеров:
(1)
возвращается1
(1 + 1)
возвращается2
(1 == 1)
возвращаетсяTRUE
(1 == 2)
возвращаетсяFALSE
(IF 1 == 1 THEN 10 ELSE 5)
возвращается10
(IF 1 == 2 THEN 10 ELSE 5)
возвращается5
Пара более сложных примеров:
- Некоторые вещи, такие как вызовы некоторых функций, на самом деле не имеют значимого значения для возврата (Вещи, которые вызывают только побочные эффекты?). Вызов
OpenADoor(), FlushTheToilet()
илиTwiddleYourThumbs()
вернет какое-то обычное значение, например OK, Done или Success. - Когда несколько несвязанных выражений вычисляются в одном большем выражении, значение последней вещи, вычисленной в большом выражении, становится значением большого выражения. Чтобы взять пример
(FOR i = 1 TO 10 DO (print i))
, значение цикла for равно 10, это заставляет(print i)
выражение вычисляться 10 раз, каждый раз возвращая i в виде строки. Последний раз через возвращение10
, наш окончательный ответ
Часто требуется небольшое изменение мышления, чтобы извлечь максимальную пользу из языка, основанного на выражениях, поскольку тот факт, что все является выражением, позволяет «встроить» многие вещи
В качестве быстрого примера:
FOR i = 1 to (IF MyString == "Hello, World!" THEN 10 ELSE 5) DO ( LotsOfCode )
является вполне допустимой заменой не на основе выражений
IF MyString == "Hello, World!" THEN TempVar = 10 ELSE TempVar = 5 FOR i = 1 TO TempVar DO ( LotsOfCode )
В некоторых случаях макет, который позволяет код на основе выражений, кажется мне более естественным
Конечно, это может привести к безумию. Как часть хобби-проекта на языке сценариев на основе выражений под названием MaxScript, мне удалось придумать эту линию монстров
IF FindSectionStart "rigidifiers" != 0 THEN FOR i = 1 TO (local rigidifier_array = (FOR i = (local NodeStart = FindsectionStart "rigidifiers" + 1) TO (FindSectionEnd(NodeStart) - 1) collect full_array[i])).count DO
(
LotsOfCode
)
Оператор - это особый случай выражения, один с void
типом. Тенденция языков по-разному относиться к утверждениям часто вызывает проблемы, и было бы лучше, если бы они были должным образом обобщены.
Например, в C # у нас есть очень полезный Func<T1, T2, T3, TResult>
перегруженный набор общих делегатов. Но у нас также должен быть соответствующий Action<T1, T2, T3>
набор, и постоянно нужно дублировать программирование более высокого порядка общего назначения, чтобы справиться с этой неудачной бифуркацией.
Тривиальный пример - функция, которая проверяет, является ли ссылка нулевой, перед вызовом другой функции:
TResult IfNotNull<TValue, TResult>(TValue value, Func<TValue, TResult> func)
where TValue : class
{
return (value == null) ? default(TValue) : func(value);
}
Может ли компилятор иметь дело с возможностью TResult
существования void
? Да. Все, что нужно сделать, это потребовать, чтобы за возвращением следовало выражение, имеющее тип void
. Результат default(void)
будет иметь тип void
, и передаваемая функция должна иметь форму Func<TValue, void>
(которая будет эквивалентна Action<TValue>
).
Ряд других ответов подразумевает, что вы не можете связывать утверждения, как вы, с выражениями, но я не уверен, откуда взялась эта идея. Мы можем думать о том, ;
что появляется после операторов, как бинарный инфиксный оператор, принимая два выражения типа void
и объединяя их в одно выражение типа void
.
Для объяснения важных различий в сочетаемости (цепочечности) выражений и выражений моя любимая ссылка - дипломная работа Тьюринга Джона Бэкуса: Можно ли освободить программирование от стиля фон Неймана? ,
В императивных языках (Fortran, C, Java, ...) подчеркиваются операторы для структурирования программ, а выражения являются своего рода запоздалым размышлением. Функциональные языки подчеркивают выражения. Чисто функциональные языки имеют такие мощные выражения, что операторы могут быть полностью исключены.
Заявления являются грамматически законченными предложениями. Выражения нет. Например
x = 5
читается как "х получает 5" Это полное предложение. Код
(x + 5)/9.0
гласит: «х плюс 5 все делится на 9,0». Это не полное предложение. Заявление
while k < 10:
print k
k += 1
это полное предложение. Обратите внимание, что заголовок цикла не является; «в то время как k <10» является подчиненным предложением.
while
Это выражение некоторых языков, таких как Scala. Вы смешиваете грамматику с набором текста. Смотри мой ответ . while
с телом это еще выражение в Скале. Это также может быть утверждение, если оно создает побочные эффекты, что допускает мой сильно опущенный ответ (выражение также может быть утверждением). Мой ответ - единственный правильный. Извините всех тех читателей, которые не могут понять. Наиболее точно, оператор должен иметь «побочный эффект» (т.е. будет императивным ) и выражение должно иметь в значении типа (т.е. не нижний тип).
Типа заявления является типом блока, но из - за останавливая теоремы блока выдумки так что позволяет сказать нижний тип .
Void
это не совсем нижний тип (это не подтип всех возможных типов). Он существует в языках, которые не имеют полностью звуковой системы типов . Это может звучать как снобистское утверждение, но полнота, такая как аннотации отклонений, имеет решающее значение для написания расширяемого программного обеспечения.
Давайте посмотрим, что Википедия должна сказать по этому вопросу.
https://en.wikipedia.org/wiki/Statement_(computer_science)
В компьютерном программировании оператор - это наименьший автономный элемент императивного языка программирования, который выражает некоторые действия, которые необходимо выполнить.
Многие языки (например, C) различают операторы и определения, причем оператор содержит только исполняемый код и определение, объявляющее идентификатор, тогда как выражение оценивается только как значение.
pass
есть утверждение. Это неоперация, и это ни к чему не приводит. Заявления -> Инструкции для последовательного следования
выражений -> Оценка, которая возвращает значение
Утверждения в основном похожи на шаги или инструкции в алгоритме, результатом выполнения оператора является актуализация указателя инструкции (так называемого в ассемблере)
Выражения не подразумевают и порядок исполнения с первого взгляда, их цель - оценить и вернуть значение. В императивных языках программирования оценка выражения имеет порядок, но это только из-за императивной модели, но не в их сущности.
Примеры заявлений:
for
goto
return
if
(все они подразумевают переход строки (оператора) выполнения к другой строке)
Пример выражения:
2+2
(это подразумевает не идею исполнения, а оценку)
Оператор - это процедурный строительный блок, из которого создаются все программы на C #. Оператор может объявить локальную переменную или константу, вызвать метод, создать объект или присвоить значение переменной, свойству или полю.
Серия операторов, окруженная фигурными скобками, образует блок кода. Тело метода является одним из примеров блока кода.
bool IsPositive(int number)
{
if (number > 0)
{
return true;
}
else
{
return false;
}
}
Выражения в C # часто содержат выражения. Выражение в C # - это фрагмент кода, содержащий буквальное значение, простое имя или оператор и его операнды.
Выражение - это фрагмент кода, который может быть оценен для одного значения, объекта, метода или пространства имен. Два самых простых типа выражений - литералы и простые имена. Литерал - это постоянное значение, которое не имеет имени.
int i = 5;
string s = "Hello World";
И i, и s - простые имена, идентифицирующие локальные переменные. Когда эти переменные используются в выражении, значение переменной извлекается и используется для выражения.
if(number >= 0) return true; else return false;
или даже лучше bool? IsPositive(int number) { if(number > 0) return true; else if(number < 0) return false; else return null;}
:)Я предпочитаю значение statement
в формально-логическом смысле этого слова. Это та, которая изменяет состояние одной или нескольких переменных в вычислении, позволяя сделать истинное или ложное утверждение об их значениях.
Я предполагаю, что всегда будет путаница в вычислительном мире и науке в целом, когда вводится новая терминология или слова, существующие слова «перепрофилируются» или пользователи не знают о существующей, установленной или «правильной» терминологии в отношении того, что они описывают.
Вот краткое изложение одного из самых простых ответов, которые я нашел.
Первоначально ответил Anders Kaseorg
Оператор - это полная строка кода, которая выполняет какое-то действие, а выражение - это любой раздел кода, который оценивает значение.
Выражения могут быть объединены «горизонтально» в более крупные выражения с использованием операторов, тогда как выражения могут быть объединены «вертикально» только путем записи одного за другим или с блочными конструкциями.
Каждое выражение может быть использовано как оператор (чей эффект заключается в оценке выражения и игнорировании полученного значения), но большинство операторов нельзя использовать в качестве выражений.
Я не очень удовлетворен ни одним из ответов здесь. Я посмотрел на грамматику для C ++ (ISO 2008) . Однако, возможно, ради дидактики и программирования ответов может быть достаточно, чтобы различить два элемента (хотя реальность выглядит более сложной).
Оператор состоит из нуля или более выражений, но также может быть и другими языковыми концепциями. Это расширенная форма Backus Naur для грамматики (выдержка для утверждения):
statement:
labeled-statement
expression-statement <-- can be zero or more expressions
compound-statement
selection-statement
iteration-statement
jump-statement
declaration-statement
try-block
Мы можем видеть другие понятия, которые считаются утверждениями в C ++.
- выражение-утверждение s самоочевидно (утверждение может состоять из нуля или более выражений, внимательно прочитайте грамматику, это сложно)
case
например, это помеченное заявление- Выбор-заявление s является
if
if/else
,case
- итерация-заявление s являются
while
,do...while
,for (...)
- перепрыжка заявление s являются
break
,continue
,return
(может возвращать выражение),goto
- объявление-заявление является набором объявлений
- try-block это оператор, представляющий
try/catch
блоки - и там может быть еще немного вниз по грамматике
Это отрывок, показывающий часть выражений:
expression:
assignment-expression
expression "," assignment-expression
assignment-expression:
conditional-expression
logical-or-expression assignment-operator initializer-clause
throw-expression
- выражения являются или содержат часто присваивания
- условно-выражение (звуки , вводит в заблуждение) относится к использованию операторов (
+
,-
,*
,/
,&
,|
,&&
,||
, ...) - бросающее выражение - а?
throw
положение является выражением слишком
Чтобы улучшить и подтвердить мой предыдущий ответ, определения терминов языка программирования должны быть объяснены из теории типов компьютерных наук, когда это применимо.
Выражение имеет тип, отличный от типа Bottom, то есть имеет значение. Оператор имеет тип Unit или Bottom.
Из этого следует, что оператор может иметь какой-либо эффект в программе только тогда, когда он создает побочный эффект, поскольку он либо не может вернуть значение, либо возвращает только значение типа Unit, которое либо не присваивается (в некоторых языках, например, C void
) или (например, в Scala) могут быть сохранены для отложенной оценки оператора.
Очевидно, что a @pragma
или a не /*comment*/
имеют типа и поэтому отличаются от утверждений. Таким образом, единственным типом заявления, которое не будет иметь побочных эффектов, будет неоперация. Неоперация полезна только в качестве заполнителя для будущих побочных эффектов. Любое другое действие из-за заявления будет побочным эффектом. Снова подсказка компилятора, например @pragma
, не является оператором, потому что у него нет типа.
@pragma
или /*comment*/
логически несовместимы. Де-факто основой этих понятий является:
Выражения : синтаксическая категория, экземпляр которой может быть оценен по значению.
Утверждение : синтаксическая категория, экземпляр которой может быть связан с оценками выражения, и результирующее значение оценки (если есть) не гарантировано доступно.
Помимо самого начального контекста ФОРТРАНА в первые десятилетия, оба определения выражений и утверждений в принятом ответе явно неверны:
- Выражения могут быть неоцененными операндами. Ценности никогда не производятся от них.
- Субэкспрессия в нестрогих оценках может быть определенно недооценена.
- Большинство C-подобных языков имеют так называемые правила оценки короткого замыкания, чтобы условно пропустить некоторые оценки подвыражения, не изменяя конечный результат, несмотря на побочные эффекты.
- C и некоторые C-подобные языки имеют понятие неоцененного операнда, который может быть даже нормативно определен в спецификации языка. Такие конструкции используются, чтобы избежать определенных оценок, поэтому оставшаяся контекстная информация (например, типы или требования выравнивания) может быть статически выделена без изменения поведения после перевода программы.
- Например, выражение, используемое в качестве операнда
sizeof
оператора, никогда не вычисляется.
- Например, выражение, используемое в качестве операнда
- Субэкспрессия в нестрогих оценках может быть определенно недооценена.
- Утверждения не имеют ничего общего с линейными конструкциями. Они могут делать что-то большее, чем выражения, в зависимости от языковых спецификаций.
- Современный Fortran, как прямой потомок старого FORTRAN, имеет концепции исполняемого оператора s и неисполнимого оператора s.
- Точно так же C ++ определяет объявления как подкатегорию верхнего уровня единицы перевода. Объявление в C ++ - это утверждение. (Это не так в C.) Существуют также операторы выражений, такие как исполняемые операторы Фортрана.
- Для сравнения выражений важны только «исполняемые» операторы. Но нельзя игнорировать тот факт, что операторы уже обобщены, чтобы быть конструкциями, формирующими единицы перевода на таких императивных языках. Итак, как вы можете видеть, определения категории сильно различаются. (Возможно) единственное оставшееся общее свойство, сохраняемое среди этих языков, заключается в том, что операторы должны интерпретироваться в лексическом порядке (для большинства пользователей слева направо и сверху вниз).
(Кстати, я хочу добавить [цитата нужна] к этому ответу относительно материалов о C, потому что я не могу вспомнить, есть ли у DMR такие мнения. Кажется, нет, в противном случае не должно быть никаких причин сохранять дублирование функциональности в дизайне C : в частности, оператор запятой против операторов.)
(Следующее обоснование не является прямым ответом на первоначальный вопрос, но я считаю необходимым уточнить кое-что, на что здесь уже дан ответ.)
Тем не менее, сомнительно, что нам нужна особая категория «операторов» в языках программирования общего назначения:
- Утверждения не гарантируют, чтобы иметь больше семантических возможностей по сравнению с выражениями в обычных проектах.
- Многие языки уже успешно отказались от понятия утверждений, чтобы получить чистый, аккуратный и согласованный общий дизайн.
- В таких языках выражения могут делать все, что могут делать операторы старого стиля: просто отбрасывать неиспользуемые результаты при оценке выражений, либо оставляя результаты явно неуказанными (например, в схеме R n RS), либо имея специальное значение (как значение типа единицы) не может быть получено из вычислений нормального выражения.
- Правила лексического порядка вычисления выражений могут быть заменены оператором явного контроля последовательности (например,
begin
на схеме) или синтаксическим сахаром монадных структур. - Правила лексического порядка других видов «операторов» могут быть получены как синтаксические расширения (например, с использованием гигиенических макросов), чтобы получить аналогичную синтаксическую функциональность. (И это действительно может сделать больше .)
- Напротив, у заявлений не может быть таких общепринятых правил, потому что они не сочетаются с оценкой: просто нет такого распространенного понятия «оценка подзаголовка». (Даже если таковые имеются, я сомневаюсь, что может быть нечто гораздо большее, чем копирование и вставка из существующих правил оценки выражений.)
- Как правило, операторы, сохраняющие языки, также будут иметь выражения для выражения вычислений, и существует подкатегория верхнего уровня операторов, сохраненная для вычислений выражений для этой подкатегории. Например, C ++ имеет так называемый оператор выражения в качестве подкатегории и использует правила оценки выражения с отброшенными значениями для определения общих случаев оценки полного выражения в таком контексте. Некоторые языки, такие как C #, выбирают для уточнения контекстов, чтобы упростить варианты использования, но это больше раздувает спецификацию.
- Многие языки уже успешно отказались от понятия утверждений, чтобы получить чистый, аккуратный и согласованный общий дизайн.
- Для пользователей языков программирования значение утверждений может еще больше запутать их.
- Разделение правил выражений и утверждений на языках требует больше усилий для изучения языка.
- Наивная интерпретация лексического порядка скрывает более важное понятие: оценка выражения. (Это, вероятно, наиболее проблематично из всех.)
- Даже вычисления полных выражений в выражениях ограничены лексическим порядком, а подвыражения - нет (обязательно). Пользователи должны в конечном счете изучить это помимо любых правил, связанных с утверждениями. (Подумайте, как заставить новичка понять, что
++i + ++i
для C. бессмысленно) - Некоторые языки, такие как Java и C #, еще более ограничивают порядок вычислений подвыражений, чтобы разрешить игнорирование правил оценки. Это может быть еще более проблематичным.
- Это кажется чрезмерным для пользователей, которые уже изучили идею оценки выражений. Это также побуждает сообщество пользователей следовать размытой ментальной модели языкового дизайна.
- Это еще больше расширяет спецификацию языка.
- Это вредно для оптимизации, так как пропускает выразительность недетерминизма в оценках, прежде чем вводятся более сложные примитивы.
- Некоторые языки, такие как C ++ (в частности, C ++ 17), задают более тонкий контекст правил оценки в качестве компромисса вышеперечисленных проблем.
- Это сильно раздувает спецификацию языка.
- Это полностью противоречит простоте для средних пользователей ...
- Даже вычисления полных выражений в выражениях ограничены лексическим порядком, а подвыражения - нет (обязательно). Пользователи должны в конечном счете изучить это помимо любых правил, связанных с утверждениями. (Подумайте, как заставить новичка понять, что
Так почему заявления? Во всяком случае, история уже беспорядок. Кажется, большинство языковых дизайнеров не принимают свой выбор тщательно.
Хуже того, он даже дает некоторым энтузиастам систем типов (которые недостаточно знакомы с историей PL) некоторые заблуждения о том, что системы типов должны иметь важные вещи, связанные с более существенными разработками правил операционной семантики.
Серьезно, рассуждение в зависимости от типов не так уж плохо во многих случаях, но особенно неконструктивно в этом особом. Даже эксперты могут все испортить.
Например, кто-то подчеркивает типизирующую природу как центральный аргумент против традиционного подхода к неограниченным продолжениям . Хотя этот вывод несколько обоснован, и понимание составных функций в порядке ( но все же слишком наивно для сути ), этот аргумент не верен, поскольку на практике он полностью игнорирует подход «побочного канала», такой как _Noreturn any_of_returnable_types
(в C11) для кодирования Falsum
. И, строго говоря, абстрактная машина с непредсказуемым состоянием не идентична «разбитому компьютеру».