Вопрос. В Оксфорде первым языком программирования берут функциональный язык Haskell, а Оберон ставят лишь вторым. Почему?
Ответ. На "почему?" ответить трудно, т.к. здесь велики субъективные факторы: вспомним о "религиозных войнах" в отношении языков программирования; приверженцы ФЯ там "бойцы" не из последних, а университет вроде Оксфорда не может позволить себе быть как все
) Но во всяком случае можно выяснить, в каком отношении стоят Оберон/Компонентный Паскаль к ФЯ. Вот суть:
Когда мы пишем a := b + c*d, то не озабачиваемся тем, где будет храниться промежуточный результат умножения c*d. Чистые ФЯ распространяют этот принцип на всю программу, т.е. оставляют (скрытое) присваивание лишь в одном месте — при назначении фактических параметров. Все остальные прелести ФЯ — либо вторичны к этому (например, возможность параллельного вычисления разных фактических аргументов, гарантированно "развязанных" по памяти), либо, строго говоря, не специфичны для ФЯ (как автоматическое распознавание типов, которое, кстати говоря, иногда приводит к тяжелейшим ошибкам; здесь как раз полезна избыточность, вводимая явным описанием типов переменных, — не говоря про большое упрощение компилятора со всеми вытекающими долгосрочными последствиями).
Можно пояснить и так. Строгая статическая типизация Оберонов — это запрет программисту решать, какие данные можно записать в ячейку памяти по такому-то адресу. Запрет следующего уровня, вводимый чистыми ФЯ, — это запрет программисту вообще выбирать ячейку, в которую будет записан результат. (Впрочем, некорректные присваивания в императивных языках имеют аналог и в ФЯ: если у функции, например, два целых параметра, то программист запросто может их перепутать.) Запрет "ручного" управления динамической памятью в Обероне, например, есть запрет ровно той же категории. В эту же сторону работают и настоящая модульность с упрятыванием глобальных переменных. Поэтому можно говорить о синтетической, императивно-функциональной природе Оберона, хотя и с подчеркиванием императивного аспекта (что согласуется с реальными механизмами работы реального "железа").
Но и практически применяемые ФЯ — вынуждены быть синтетическими, с переменными и присваиваниями: состояние окошка на экране, в котором меняется текст при нажатии клавиш — это не что иное как переменная, в которой меняется хранимое значение после каждого нажатия, и избежать этого понятия в такой ситуации невозможно. А введение переменных тянет за собой весь хвост соответствующих проблем. За что же боролись?
Локализуйте присваивания в фабричных функциях в Обероне, собранных в отдельные модули, запретите их во всех других местах, и вот вам ФЯ с полностью динамическими списками без принципиальных изъятий. Контролировать наличие в тексте модуля комбинации литер := не труднее, чем контролировать наличие комбинации литер SYSTEM в списке импорта.
Что касается автоматического распараллеливания, то это такого же уровня проблема, как автоматический синтез или верификация программ: обсуждать автоматическое распараллеливание умножений в a*b+c*d — неинтересно, а в реальных случаях все равно нужно сначала хорошо распараллелить алгоритм головой. Но тогда вся остальная организация распараллеливания в том же Обероне — отнюдь не квантовая гравитация.
Остаются, конечно, различия в "духе синтаксиса" между паскалеобразными языками и ФЯ. Но такие вещи вряд ли возможно оценивать объективно.
Вывод такой, что при обучении профессиональных программистов, несомненно, полезно в качестве обязательного второго взять какой-нибудь ФЯ (тот же Haskell; и еще марковский язык в качестве третьего — заметим попутно, что подавлюящее большинство профессиональных программистов затруднятся ответить, что такое "марковские языки").
Но первое место однозначно должен занять Оберон/Компонентный Паскаль, особенно если мы хотим сохранить связь и единое образовательное пространство как со средней школой, так и с обучением программистов-"непрофессионалов".