Использование Уолтером Брайтом слова «избыточность»… или «Черт возьми, это значит?»

Итак, я Я читаю это интервью с Уолтером Брайтом о языке D в Bitwise ( http://www.bitwisemag.com/copy/programming/d/interview/d_programming_language.html ), и я действительно наткнулся на это интересная цитата о синтаксическом разборе языка:

Однако с теоретической точки зрения для создания хорошей диагностики требуется избыточность в синтаксисе. Избыточность используется, чтобы сделать предположение о том, что было задумано, и чем больше избыточность, тем больше вероятность, что это предположение будет правильным. Это похоже на английский язык - если мы время от времени ошибаемся в написании слова или если слово отсутствует, избыточность позволяет нам правильно угадать значение.Если в языке нет избыточности, то любая случайная последовательность символов является допустимой программой.

А теперь я пытаюсь понять, какого черта он имеет в виду, когда говорит «избыточность».

Я едва могу осмыслить последнюю часть,где он упоминает, что можно иметь язык, в котором «любая случайная последовательность символов является допустимой программой». Меня учили, что существует три вида ошибок: синтаксические, ошибки времени выполнения и семантические. Существуют ли языки, в которых возможны только семантические ошибки? Такая сборка? А как насчет машинного кода?

16
задан tel 19 August 2010 в 16:21
поделиться

7 ответов

Язык ассемблера ( большинство языков ассемблера, во всяком случае) совсем не такой - у них довольно жесткий синтаксис, и большинство случайных строк будут диагностированы как ошибки.

Машинный код намного ближе. Поскольку здесь нет перевода из «исходного» в «объектный» код, все ошибки являются семантическими, а не синтаксическими. Большинство процессоров действительно имеют различные входные данные, которые они отклоняют (например, выполняют ловушку / прерывание «неверный код операции»). Вы можете возразить, что в некоторых случаях это будет синтаксическим (например, код операции, который не был распознан вообще), тогда как другие являются семантическими (например, набор операндов, которые не были разрешены для этой инструкции).

Для тех, кто это помнит, TECO был известен (печально известен?) Тем, что приписывал какое-то значение почти любому возможному вводу, так что все было примерно так же. Интересной задачей было выяснить, что произойдет, если вы введете (например) свое имя.

10
ответ дан 30 November 2019 в 15:14
поделиться

Я сосредоточусь на том, почему (я думаю) Вальтер Брайт считает, что резервирование - это хорошо. Возьмем, к примеру, XML. Этот фрагмент:

<foo>...</foo>

имеет избыточность, закрывающий тег избыточен, если вместо этого мы используем S-выражения:

(foo ...)

Он короче, и программисту не нужно набирать foo чаще, чем необходимо, чтобы сделать смысл этого фрагмента. Меньше избыточности. Но у него есть и недостатки, например, из http://www.prescod.net/xml/sexprs.html показано:

(document author: "paul@prescod.net"
    (para "This is a paragraph " (footnote "(better than the one under there)" ".")
    (para "Ha! I made you say \"underwear\"."))


<document author="paul@prescod.net">
<para>This is a paragraph <footnote>(just a little one).</para>
<para>Ha! I made you say "underwear".</para>
</document>

В обоих случаях конечный тег / закрывающая скобка для сноски отсутствует. Версия xml становится недействительной, как только парсер видит . S-выражение недействительно только в конце документа и только в том случае, если у вас нет ненужной закрывающей пары где-то еще. Так что в некоторых случаях избыточность действительно помогает понять, что имел в виду автор (и указать на ошибки в его способе выражения этого).

24
ответ дан 30 November 2019 в 15:14
поделиться

nglsh nclds ll srts xtr ltrs t mk it ezr t read

9
ответ дан 30 November 2019 в 15:14
поделиться

Я думаю, он говорил о синтаксических структурах языка и о том, как их можно интерпретировать. В качестве примера рассмотрим скромное выражение «если», написанное на нескольких языках.

В bash (сценарий оболочки) это выглядит так:

if [ cond ]; then
  stmts;
elif [ other_cond ]; then
  other_stmts;
else
  other_other_stmts;
fi

в C (с отдельными параметрами, без фигурных скобок):

if (cond)
  stmt;
else if (other_cond)
  other_stmt;
else
  other_other_stmt;

Вы можете видеть, что в bash гораздо больше синтаксической структуры для if, чем в C. На самом деле, все управляющие структуры в bash имеют свои закрывающие ограничители (например, if / then / fi , for / do / done , case / in / esac , ...), тогда как в C фигурная скобка используется везде. Эти уникальные разделители устраняют неоднозначность кода и тем самым обеспечивают контекст, в котором интерпретатор / компилятор может диагностировать условия ошибки и сообщать о них пользователю.

Однако есть компромисс. Программисты обычно предпочитают лаконичный синтаксис (а-ля C, Lisp и т. Д.) Подробному синтаксису (а-ля Pascal, Ada и т. Д.). Однако они также предпочитают описательные сообщения об ошибках, содержащие номера строк / столбцов и предлагаемые решения. Эти цели, конечно, расходятся друг с другом - вы не можете съесть свой пирог и съесть его (по крайней мере, сохраняя простую внутреннюю реализацию компилятора / интерпретатора).

5
ответ дан 30 November 2019 в 15:14
поделиться

Это означает, что синтаксис содержит больше информации, чем необходимо для кодирования работающей программы. Примером могут служить прототипы функций. Как показывает нам K&R C, они избыточны, потому что компилятор может просто позволить вызывающей стороне протолкнуть любые аргументы, которые вы хотите, а затем позволить функции выдать правильные аргументы. Но C ++ и другие языки требуют их, потому что они помогают компилятору проверить, правильно ли вы вызываете функцию.

Другой пример - требование объявить переменные перед их использованием. В некоторых языках это есть, в других - нет. Это явно избыточно, но часто помогает предотвратить ошибки (например, орфографические ошибки, использование переменной, которая была удалена).

4
ответ дан 30 November 2019 в 15:14
поделиться

Я думаю, что лучший пример избыточности - это что-то вроде int a [10] = . На этом этапе компилятор знает, что должно быть дальше, инициализатор массива int, и может выдать соответствующее сообщение об ошибке, если то, что следует далее, не является инициализатором массива int. Если бы в синтаксисе языка говорилось, что все может следовать за int a [10] , компилятору было бы намного сложнее решить проблемы с одним.

3
ответ дан 30 November 2019 в 15:14
поделиться

Хорошо, если использовать пример из C # (поскольку я не знаю D). Если у вас есть класс с абстрактным методом, сам класс должен быть помечен как абстрактный:

public abstract class MyClass
{
    public abstract MyFunc();
}

Теперь для компилятора было бы тривиально автоматически пометить MyClass как абстрактный (именно так C ++ обрабатывает его), но в C #, вы должны делать это явно, чтобы ваши намерения были ясны.

Аналогично виртуальным методам. В C ++ при объявлении виртуального в базовом классе метод автоматически становится виртуальным во всех производных классах. В C #, тем не менее, метод должен быть явно помечен override , чтобы не было путаницы в том, что вам нужно.

8
ответ дан 30 November 2019 в 15:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: