Logo

28 ноября 2013 г.

Цикл «пока» и цикл Дейкстры

В процессе развития концепции объектной алгебры циклы были исключены из Кантора. Записи в блоге оставлены ради истории.

Развитие оператора цикла while до варианта с несколькими ветвями дает цикл Дейкстры, введенный в язык Кантор под влиянием Оберона-07.

На момент написания статьи принято, что операторы цикла имеются только в декларативном синтаксисе.

Цикл «пока»

В варианте с одной ветвью цикл Дейкстры имеет форму обычного цикла «пока»:
while условие do
  ветвь;
end;
Единственная ветвь цикла выполняется, пока условие истинно. Цикл — блочный оператор, поэтому операторы ветви разделяются точкой с запятой, и завершающий end обязателен.

Цикл Дейкстры

В полной форме оператор цикла «пока» становится циклом Дейкстры. Его особенность в языке Кантор — наличие эпилога:
while условие do
  ветвь;
elsif условие do
  ветвь;
elsif условие do
  ветвь;
else
  эпилог;
end;
Логика цикла:
  • На каждой итерации:
    • Последовательно вычисляются условия while и elsif.
    • При истинности условия соответствующая ветвь выполняется — одна ветвь на каждой итерации.
  • Если выполнена хоть одна итерация, перед выходом из цикла выполняется эпилог.
На момент написания статьи предполагается, что введение полноценного цикла Дейкстры и концепции эпилога избавляет от надобности в операторах досрочного выхода и продолжения цикла — break и continue. Эти операторы в языке Кантор отсутствуют.

После исключения циклов и elsif из синтаксиса ключевые слова while и elsif больше не подсвечиваются.

Ветвление и выбор

В языке Кантор учитывается не только опыт Паскаля и Си, но и Ады с PL/SQL, что влияет на синтаксис. Влияние заметно в операторах if и case.

В этой статье рассматривается только декларативный синтаксис.

Оператор ветвления

Принятый в Канторе оператор ветвления считается уже классическим:
if условие then
  ветвь;
elsif условие then
  ветвь;
elsif условие then
  ветвь;
else
  ветвь;
end;
Ветви elsif и else могут отсутствовать, завершающий end обязателен.

Оператор if может использоваться в форме выражения — тогда вместо ветвей стоят одиночные выражения или кортежи, соответствующие возвращаемым значениям, а точка с запятой внутри ветвей не ставится:
a, b = if условие then
  выражение_a, выражение_b
elsif условие then
  выражение_a, выражение_b
elsif условие then
  выражение_a, выражение_b
else
  выражение_a, выражение_b
end;
В таком виде оператор if ближе всего к case when из SQL.

После исключения elsif из синтаксиса ключевое слово elsif в коде больше не подсвечивается.

Оператор выбора

Отличительная особенность оператора case в Канторе — наличие пролога:
case выражение1, выражение2 of
  пролог;
when значение1, значение2 then
  ветвь;
when значение1, значение2 then
  ветвь;
else
  ветвь;
end;
Условием выбора может быть кортеж, то есть несколько выражений, как ключ в БД. Работает оператор следующим образом:
  • Выражения case вычисляются один раз.
  • Если значения совпадают с одним из when, выполняется пролог и эта ветвь.
  • Если значения ни с одним when не совпадают, выполняется только блок else, без пролога.
Наличие хотя бы одного when обязательно, иначе оператор вырождается if без условия, чего быть не может. Блок else может отсутствовать, завершающий end обязателен.

Имеется и выражение case:
a, b = case выражение1, выражение2, выражение3 [of]
  when значение1, значение2, значение3 then
    значение_a, значение_b
  when значение1, значение2, значение3 then
    значение_a, значение_b
else
  значение_a, значение_b
end;
В выражении case пролог отсутствует, поэтому of не обязателен. Точка с запятой внутри ветвей также не ставится. Из-за поддержки кортежей выражением case удобно расписывать таблицы трансляции или подстановки значений.

Ключевые слова when и then введены в case ради кортежей и единообразия: ветви сложных операторов должны начинаться ключевым словом, иначе и синтаксис неоднозначен, и глазу не за что зацепиться. Двоеточие зарезервировано в языке для других целей.

Выражение как строчный оператор

Выражения if и case относятся к разновидности строчных операторов в терминах языка Кантор, обладая следующими признаками:
  • Содержат в ветвях только выражения или кортежи, поэтому могут встраиваться в другие выражения и кортежи подходящего типа.
  • Не имеют побочных эффектов — являются чистыми.
  • Не содержат внутри себя разделителя «точка с запятой» — общий признак всех строчных операторов. 

27 ноября 2013 г.

Строчные и блочные объявления

Операторы в языке Кантор могут иметь строчную или блочную запись. В строчной форме записываются простые выражения и кортежи, а в блочной — все остальные операторы. Вне зависимости от формы записи операторы разделяются точкой с запятой.

В этой статье рассматривается только декларативный синтаксис.

Выражения и кортежи

Во многих случаях строчная форма является естественной для выражений и кортежей. Чаще всего это описания простых функций, в том числе переменных, рассматриваемых в языке Кантор как функции:
a = 5;                     // простая функция
[c, d] = [100, 'пятьсот']; // кортеж
plus2[int val] = val + 2;  // с параметром

var s = 'строка', x = 100; // кортеж инициализированных переменных
Строка в строчной записи — понятие условное. Строчный оператор может занимать сколько угодно строк исходного текста, завершаясь точкой с запятой. Несколько объявлений, разделенных запятой, превращают оператор в кортеж (в терминах языка Кантор). Объявление параметров функций — особый вид кортежа, он будет рассмотрен отдельно.

Блочные объявления

Бывает так, что идущие друг за другом объявления образуют логический блок, который хотелось бы выделить синтаксически, но строчная запись, наоборот, только усложняет восприятие, вытягивая описание в строку и делая его невыразительным. Если оператор разбить на строки и в строчном синтаксисе, отдельные объявления будут завершаться запятой, а последнее объявление — точкой с запятой, что нелогично:
var Byte HeaderVersion = 1;
var Word[32] ImageStart = 16, ImageEnd = 768,
  MemSize = 8192, StackSize = 4096,
  ParamCount = 0;
var HasIcon = false;
Для таких случаев в Канторе предусмотрена блочная форма объявления, объединяющая функции одного типа и/или с одним набором модификаторов в блок of..end, внутри которого отдельные объявления единообразно разделяются точкой с запятой:
var of
  Byte HeaderVersion = 1;
  Word[32] of
    ImageStart = 16;
    ImageEnd = 768;
    MemSize = 8192;
    StackSize = 4096;
    ParamCount = 0;
  end;
  HasIcon = false;
end;
Блоки могут произвольно вкладываться друг в друга, модификаторы при этом суммируются, а взаимоисключающие — перекрываются (еще не решено окончательно).

Несмотря на разность записи, в обоих случаях объявляется несколько самостоятельных функций-переменных, не объединенных ни в какую структуру: HeaderVersion, ImageStart, ImageEnd, MemSize, StackSize, ParamCount, HasIcon.

Запланировано, что на уровне байт-кода оба описания будут абсолютно идентичны, и при отекстовке байт-кода можно будет выбрать предпочитаемую форму — строчную или блочную.

Блоки локальных функций

Другой случай, когда полезен блок объявлений — ограничение видимости локальных имен. Для этого служит оператор-префикс with. Он может предшествовать любому блочному оператору, ограничивая область видимости объявленных в нем имен только этим оператором. С ключевым словом do блок with можно использовать и со строчными объявлениями:
a = 50;
with
  a = 2;
  b = 20;
do
  rslt = a * b;  // = 40
end;
В данном примере на внешнем уровне видны только две функции-константы: a, равная 50, и rslt, равная 40.

Блоки with также могут вкладываться друг в друга.

Синтаксис блочных операторов

Блочные операторы могут быть «многоэтажными», при этом каждая часть имеет блочную запись с разделением вложенных операторов точкой с запятой. Завершается блочный оператор ключевым словом end, после которого ставится точка с запятой — разделитель операторов.

22 ноября 2013 г.

11-я линия В. О., 24

Анонсированный памятник Стиву Джобсу на Embedded Meetup нам так не показали, а вот я до начала меропрятия прошелся до 11-й линии, где в доме №24 жил будущий немецкий математик Георг Кантор.

20 ноября 2013 г.

Тезисы к семинару на Embedded Meetup #2: Связь ООП и ФП

Статьи по теме

Развитие ПО отстает от железа

  • Развитие ПО экстенсивно, требует много рутинного труда.
  • Потеря бинарной совместимости из-за распространения скриптовых языков и платформ JVM и .NET.
  • При этом всё системное и системообразующее ПО написано на одном языке (и в одной стране).
  • Пример: большие накладные расходы WebSVN.

ООП, ФП и СУБД

  • Классы — это функции от состояния , объекты — само состояние.
  • Переменная (объект) — функция, имеющая реализацию памятью.
  • Свойство — функция, имеющая реализацию либо кодом, либо памятью, либо и кодом, и памятью.
  • Всё это похоже на СУБД:
    • Представление → функция.
    • Таблица → объект → переменная.
    • Материализованное представление → представление и таблица одновременно → свойство.

Реализация

  • Язык имеет синтаксические средства для описания, как будет использоваться объект (чтение, запись, мутация, not null и пр.). Это работает для всех объектов без исключения (без «дырявых абстракций»), давая возможность строить граф достижимости.
  • Размещение объектов (переменных) в стеке или в куче выбирается компилятором на основе графа достижимости.
  • Суперкомпиляция нужна для избавления от сборщика мусора при сохранении автоматического управления памятью. Суперкомпилятор строит код на основе графов достижимости.

Постулаты

  • Точкой схождения всех абстракций является null.
  • Общий базовый класс (TObject) является обобщением (generic).
  • Условные типы TObject и Variant — одно и то же.

Тезисы к семинару на Embedded Meetup #2

Вводная

Бизнес-план Гордона Мура изменил направление и теперь по-другому влияет на развитие технологий. На одном из выступлений докладчик Intel назвал закон Мура бизнес-планом Мура, а потом продемонстрировал график, на котором монотонный рост вычислительной мощности преломляется в момент появления первого двухъядерного процессора, после чего фактическое увеличение быстродействия ПО отстает от номинальной производительности процессоров: программы не могут использовать возможности железа, график делится надвое.

Кроме того, есть множество технологий, появившихся еще в 70-е годы XX века, но так и не нашедших воплощения на системном уровне. Было много попыток разработать объектно-ориентированную ОС, но все они так и остались в лабораториях. Почему? Неужели по-прежнему не хватает вычислительной мощности? А кто помнит слова Алана Кея: "Создавая ООП, я не имел в виду C++"?

Западные проектировщики интерфейсов уже пришли к единому мнению по поводу трехмерного интерфейса, в западных источниках уже устоялся термин ZUI по отношению к нему. Почему он до сих пор не реализован в реальных ОС? Нет потребности? Снова недостаточно вычислительной мощности? Может быть, проблема всё же в чем-то другом?