О подражании Кнуту

May 29, 2007 17:08


Один из распространенных сюжетов в фантастике - это землянин за штурвалом корабля пришельцев. Или наоборот - пришелец за штурвалом корабля землян. Решался он по-разному: от космической оперы ("Джон слегка нажал на педаль, и мощный корабль послушно лег на курс к далекой Земле") до юмористических вещей (масса примеров есть у Шекли, Пола Андерсона и других классиков "золотого века"). Гораздо меньше фантастов задумывалось над тем, что система управления - это отражение нашего мозга, нашей биологии, физиологии, нашей истории. Чужая машина нам будет прежде всего непонятна. Даже если мы сможем как-то заставить её слушаться наших приказов, это будет сопряжено с ежеминутным насилием над собственным мыслительным аппаратом. Нам нужно будет заставлять себя думать как какой-нибудь марсианский богомол.

Но зачем обращаться к фантастике? Разница между людьми тоже немала. В особенности когда речь идёт об "обычных людях" и гениях; я иногда подозреваю, что гении думают не просто лучше нас - а по-другому. Есть тонкая грань между талантом и гением. Талант - это "как мы, только лучше", а гений - это совсем другое, это иное существо. Было бы очень интересно понять, как отличается мое мышление от мышления другого (тем более - гения!) - хоть одним глазом подсмотреть. Но тут есть большая проблема. Дело в том, что каждый человек значительную часть творческих усилий тратит на то, чтобы сделать свою работу понятной для других. По сути убрать особенности своего мышления, привести всё к общему знаменателю. Это очевидно, когда речь идёт об искусстве, о литературе, о преподавании - но это верно и для любой другой творческой деятельности. Когда человек занимается наукой, он пишет статью - то есть "переводит" свои мысли с внутреннего языка на "общечеловеческий". Хороший пример тут - Ньютон, который получал свои результаты при помощи созданного (частично) им же анализа, но излагал их на языке синтетической греческой математики. Это иногда объясняют тем, что Ньютон "не доверял" новым методам. Я позволю себе не поверить в такое объяснение: прекрасно он им доверял - но ему приходилось подлаживаться под стиль мышления аудитории. Позже эти способы стали общим достоянием - но потребовалось несколько веков усилий преподавателей и методистов, чтобы стало возможным излагать их обычным людям. Мы по сути овладели парой правил "грамматики Ньютона" - ценой огромных усилий. Но это, скорее всего, только малая часть того, что понимал Ньютон. Я прошу прощения за избитую ещё в прошлом веке фразу, но наука - это не взаимодействие объекта исследования и его субъекта, это взаимодействие объекта, субъекта и третьего - студента, ученика, читателя. Как и литература, искусство. И поэтому заглянуть в мозг автора сложно: он показывает не то, что он думает, а то, что он хочет показать.

На первый взгляд кажется, что с компьютерным программированием иначе. Программирование - это ведь взаимодействие человека с машиной, так? Но на самом деле программисты уже очень давно пишут в основном для других программистов. Собственно, технологии программирования направлены на облегчение понимания программ людьми. Это - целевая аудитория программиста; а то, что машины тоже понимают эти тексты - эффект, скорее, побочный. Так что из из программ мы не поймём, как "на самом деле" думает программист.

У меня очень давно зреет мысль, что TeX - одно из исключений из этого правила. Дональд Кнут - один из последних великих программистов героического периода. В те времена писали "для машины", оптимизируя код (см. знаменитую "Историю Мела, настоящего программиста"). Кнут поначалу с подозрением отнесся к идее Дейкстры о структурном программировании. Позже он занялся проблемой понимания кода человеком и предложил своё решение: literate programming. Это очень интересная идея; как-нибудь я напишу о том, почему она не получила большого распространения. И самое главное - Кнут, на мой взгляд, ЗА той гранью, которая отделяет талант от гения.

Статьи Кнута о ранней истории TeXа несколько противоречивы. С одной стороны, он подчеркивает, что изначально писал TeX для себя, точнее, для набора одной книги (The Art of Computer Programming), и что его не перестаёт удивлять, что так много людей использует его программы. С другой - программа написана в стиле literate programming (собственно, TeX и Metafont - это два наиболее характерных примера lp), то есть он заботился о том, чтобы программа была понятна другим?

Моя гипотеза состоит в том, что изначально TeX предназначался для "внутреннего пользования". Ещё в то время, когда Кнут полагал, что ему хватит одного sabbatical, чтобы написать систему. Но потом, когда этот проект занял на порядок больше усилий, а масса людей заинтересовалась, Кнут переориентировал его на систему общего назначения. Это иллюстрирует история перехода к TeX3, когда Кнута убедили добавить серьёзную интернационализацию к системе.

Если это так, то дизайн TeXа отражает способ мышления Кнута более точно, чем другие его вещи. И боже мой, насколько этот дизайн не похож на "нормальное человеческое" мышление!

Оговорюсь, что следует различать две вещи: интерфейс TeXа для авторов (математик, пишущий статью в TeXе) и интерфейс для TeXников (программист, создающий стиль верстки для журнала). Первый довольно естественен. Хотя мне больше нравится LaTeXовский стиль в тех местах, где он отличается от TeXовского: почему-то \frac{a}{b} мне кажется понятнее, чем {a \over b}. Но второй - это совсем другое дело. Некоторые думают, что всё дело в том, что Кнут выбрал расширяемый макроязык. Возможно, это и правда. Но есть разные макроязыки. Я программировал в maximе и lispе - нельзя сказать, чтобы это было просто, но это неизмеримо яснее, чем TeX - и это при том, что я очень неплохо знаю TeX. Чисто программистские примитивы в TeXе поражают. Почему автор выбрал эти \futurelet, \afterassignment и т.д.? С другой стороны, почему цикл - не примитив, а вовсе макро (кстати, слегка по-разному определенный в plain и в LaTeXе)? И совсем безумная идея поиска закрывающего \fi - см. раздел 13.8.4 в книге Victor Eijkhout, Tex by Topic. Я позволю себе привести цитату из этой книги:
TeX's matching of \if, \else, and \fi is easily upset. For instance, the TеXbook warns you that you should not say
\let\ifabc=\iftrue inside a conditional, because if this text is skipped TеX sees at least one \if to be matched.

The reason for this is that when TеX is skipping it recognizes all \if..., \or, \else, and \fi tokens, and everything that has been declared a synonym of such a token by \let. In \let\ifabc=\iftrue TеX will therefore at least see the \iftrue as the opening of a conditional, and, if the current meaning of \ifabc was for instance \iffalse, it will also be considered as the opening of a conditional statement.

As another example, if
\csname if\sometest\endcsname \someaction \fi is skipped as part of conditional text, the \fi will unintentionally close the outer conditional. It does not help to enclose such potentially dangerous constructs inside a group, because grouping is independent of conditional structure. Burying such commands inside macros is the safest approach.

В результате вот как выглядит программа, делающая "лексикографическое сравнение" двух строк (из той же книжки):
\let\ex=\expandafter \def\ifbefore #1#2{\ifallchars#1$\are#2$\before} \def\ifallchars#1#2\are#3#4\before {\if#1$\say{true\ex}\else \if#3$\say{false\ex\ex\ex}\else \ifnum#1>#3 \say{false% \ex\ex\ex\ex\ex\ex\ex}\else \ifnum#1<#3 \say{true% \ex\ex\ex\ex\ex\ex\ex \ex\ex\ex\ex\ex\ex\ex\ex}\else \ifrest#2\before#4\fi\fi\fi\fi} \def\ifrest#1\before#2\fi\fi\fi\fi {\fi\fi\fi\fi \ifallchars#1\are#2\before} \def\say#1{\csname if#1\endcsname} Человек, для которого такое естественно, определенно мыслит иначе, чем мы. И это НЕ особенно патологический образчик; посмотрите на продвинутые пакеты на CTAN! Собственно, совершенно неудивительно, что эти пакеты часто написаны в стиле, близком к literate programming (единственное известное мне массовое применение этого метода - а по-другому писать их будет совсем непонятно!)

Мне приходилось писать программы (не тексты, а именно программы!) на TeXе. И всякий раз начиная это делать после долгого перерыва, ощущаешь всю неестественность этого занятия. Как сесть за штурвал звездолета пришельцев с Альфы Водолея. Потом начинаешь работать быстрее: мозг переходит на другие рельсы. В какой-то момент вдруг TeXовские хаки кажутся самоочевидными. Естественными. Хочется думать, что в этот момент ты видишь что-то, что видит Кнут. Но у меня это состояние редко, и его надо вызывать специальными методами. Если моя гипотеза верна, то Кнут в таком находится если не всегда, то часто. Это его образ мышления.

psychology, tex, science, computers

Previous post Next post
Up