Мой комментарий
Прочитав сегодня статью Пола Грэма "Языки программирования через сто лет", решил, во-первых, разместить ее на своем сайте, и, во-вторых, дать свои комментарии к этой статье.
Начну со следующей цитаты:
Слово "эссе" происходит от французского глагола "essayer", который в переводе означает "пытаться". Первоначально так назывались тексты, которые писали, для того чтобы в чём-либо разобраться. С программным обеспечением то же самое. Думаю, некоторые из лучших программ представляли собой "эссе", в том смысле, что их авторы начинали работу, не представляя себе в точности, что они пытаются написать.
Почему меня заинтересовала это цитата? Очень просто - она дает мне шанс развивать идеи, которые возникают в процессе работы над проектом TxCalc. К сожалению, гарантий не дает :-)Написание калькуляторов менее всего подходит на роль "глубоких научных изысканий", поэтому читателю этих строк трудно заподозрить меня в подобном намерении. В общем то, я и сейчас далек от этого, но пройти мимо очевидных вещей после случайного столкновения с ними уже не могу.
Очень давно (точно, до 1994 года) после знакомства с книгой Н.Вирта "Алгоритмы+структуры данных=программы" я попробовал написать простейший компилятор. Даже не написать, а переписать из книги. К тому моменту меня обуревал восторг от "персоналок" и от турбо-паскаля. Чтобы облегчить себе работу выкинул генератор кода, оставив только синтаксический анализатор выражений. Через некоторое время выкинул даже введение функций и т.п. В результате получился очень маленький вычислитель выражений. Около 150 строк исходного текста после компиляции превращались в программу менее 9Кб. После сжатия она становилась размером 6446 байт. Для работы с текстами потребовалась минимальная доработка.
После смерти ДОС-а я перестал программировать - последние 10 лет точно не программировал, даже все предыдущие навыки потерял. Конкурировать с молодыми бессмысленно, да и само программирование потеряло свою привлекательность. Заниматься изучением все новых и новых программных продуктов, чтобы выдать строку "Hello World" - что может быть глупее? Иногда компилировал на Delphi несколько строчек, иногда воодушевлялся игрушками типа сокобана, но, в целом, само программирование стало неинтересно. Осталась одна ниша - алгоритмы.
Но в июле этого года понадобилось подготовить что-то, похожее на продаваемый продукт. Писать игру? Хм... только какую-нибудь простенькую в реализации - опыт сокобана дает маленькую надежду на создание логических головоломок. Показалось, что быстрее получится TxCalc, который уже давно откомпилирован в Delphi.
Подготовка внешнего вида оказалась не такой уж простой задачей - это интересная область, но любителю в этой области очень тяжело. Время полетело ...
Наступил момент, когда потребовалось несколько расширить возможности калькулятора, чтобы конкурировать с предыдущими бесплатными версиями. Идея, которая обыгрывалась, должна была остаться прежней - доступность простому инженеру, которому нужен понятный продукт и не требовал бы от него перехода в программисты. Были выбраны операторы loop() и sel(). Теоретически они покрывают все потребности структурного программирования.
Понятно, что эта частная задача пересекается с темой рассматриваемой статьи. Взгляните с позиции этой частной задачи на строки:
Любой язык программирования можно поделить на две части: некий набор
фундаментальных операторов, которые играют роль аксиом, и остаток языка,
который, в принципе, может быть описан в терминах этих фундаментальных
операторов.
Я считаю, что фундаментальные операторы - это самый важный фактор, влияющий на
выживание языка в долгосрочной перспективе. Всё остальное может меняться.
Важен не только хороший подбор аксиом, но и их немногочисленность. Математики
всегда понимали, что аксиом должно быть как можно меньше, а они-то кое-что в этом
смыслят.
- Именно языком человек отличается от прочих животных.
- Разнообразие языков говорит о некотором субъективизме при создании языка.
- Языки развиваются.
- Появляются специальные языки. Например, математика - язык современной науки.
- Язык математики становится мертвым, если из него выкинуть "обычный" язык.
- К языку можно привыкнуть и распространенность некоторого языка не может служить мерилом качества этого языка.
- Язык служит для передачи информации не только от человека к человеку, но и от поколения к поколению.
- Язык влияет на мышление человека, на его сознание.
- И т.д.
Маловероятно, что язык будет только один.
Таким образом, у нас есть две идеи, и если сложить их, обнаружатся интересные возможности. Во-первых, язык программирования будущего, в принципе, может быть изобретён сегодня. Во-вторых, такой язык может годиться для программирования и в наше время. Сложно удержаться и не подумать: так почему бы не попробовать написать язык будущего прямо сейчас?
Раз имеется необходимость, а она имеется, то пробовать писать новые языки программирования обязательно надо.Вернемся к частной задаче, к языку калькулятора TxCalc. Для вычислений можно было использовать и обратную польскую нотацию (язык Форт) и префиксные конструкции (язык Лисп). Были выбраны традиционные формулы, к которым все уже давно привыкли. Конечно, многоэтажные конструкции пришлось выкинуть, но ... "понятность" удалось сохранить. При выборе конструкций ветвления и циклов я стремился к минимуму (на самом деле, достачно было ввести один обобщенный цикл loop(), который может обслуживать и ветвление, но мне это показалось перебором). Почему я отказался от if-then-else, while do и т.д.? Нет, сами конструкции не так уж и плохи, не хуже предложенных. Но при обычном их применении имеется одна легко замечаемая пакость - наборы операторов, вставляемые в эти конструкции, часто по размеру превышают все разумные пределы. Программисты для борьбы с этой бедой используют отступы, но это часто не помогает.
Главным было введение "именованных областей". Понятно, что обойтись без нечто подобного нельзя. Процедуры, функции, подпрограммы и т.п. Неизбежность ввода чего-то "именного" была понятна и, самое главное, естественна (даже для непрограммиста). Оставалось выбрать обозначение. Я вспомнил фортовскую конструкцию:
Дальше просто ввел эти конструкции в интерпретатор - особых проблем не было, кроме одной. У меня активно используется конструкция для комментариев
Я чуть не пропустил одну великолепную вещь. Встал вопрос, что делать, если мы вводим новый блок с уже использованным именем? Можно было выдать ошибку, но я решил попробовать удалять старый блок и вводить новый. А т.к. интерпретатор при исполнении использует только имя, то появилось "позднее связывание" со всеми вытекающими последствиями.
Итак, начало положено. Нет ни одной случайной конструкции. Объеденены формулы и фортовская конструкция, значение которой не нужно объяснять. Остались непроработанными "данные". Фиксировать типы, как в паскале? Пока я склоняюсь к тому, чтобы типы использовать на этапе исполнения. В калькуляторе это не очень нужно, хотя использование комплексных чисел можно попробовать.
Недавно на форуме rsdn произошел следующий диалог:
MC>Я вот вообще не могу вкурить, что тут за текст такой
Вот эквивалентный (и допустимый) текст:
[Интеграл_по_Симпсону
{задаем начальные значения}
I=0
d=(b-a)/(2*n) {размер интервала}
x=a
ФУНКЦИЯ {вычисляем y при x=a}
I=y/2 {понимаем, что оператор I=0 лишний, его можно выкинуть}
x=b
ФУНКЦИЯ {вычисляем y при x=b}
I=I-y/2
x=a
k=0 {индекс инициируем}
{Теперь вычисляем сумму в цикле}
loop(IA,n-k,IB)
{Умножаем сумму на необходимые коэффициенты для получения значения интеграла}
I=I*(b-a)/(3*n) ]
{Теперь все выше написанное можно записать и забыть. Пользуясь "поздним связыванием" для вычисления интеграла от некоторой функции задаем сначала функцию следующим, немного непривычным способом}
[ ФУНКЦИЯ {русские буквы разрешены} y=1/(1+x^2)]
{Задаем интервал a..b и число n}
a=0 b=1 n=12
{Вычисляем интеграл}
Интеграл_по_Симпсону
{Теперь выводим вычисленное значение с 10 знаками после десятичной точки}
I=?10
{УсЁ}