Чем императивные языки более отличаются друг от друга, чем функциональные языки?

17

Я читаю «Реализацию языков функционального программирования» Саймона Пейтона Джонса, и есть одно утверждение, которое меня немного удивило (на странице 39):

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

Теперь, это было написано в 1987 году, и на мои мысли по этому вопросу могли повлиять более современные языки программирования, которые тогда не были популярны или популярны. Тем не менее, мне трудно в это поверить. Например, я думаю, что описанный язык программирования Miranda (ранний предшественник Haskell) имеет гораздо более различную семантику по сравнению со строгим языком, таким как ML, чем, скажем, C с Pascal или, может быть, даже C с smalltalk (хотя я уступлю, что C ++ обеспечивает некоторую проверку своей точки зрения :-).

Но опять же, я основываю это на своем интуитивном понимании. Саймон Пейтон Джонс в основном прав, говоря это, или это спорный вопрос?

Джейсон
источник

Ответы:

19

Саймон в основном прав, с экстенсиональной точки зрения. Мы достаточно хорошо знаем, какова семантика современных функциональных языков, и они действительно являются относительно небольшими вариациями друг друга - каждый из них представляет несколько разные переводы в монадный метаязык. Даже такой язык, как Scheme (динамически типизированный императивный язык высшего порядка с первоклассным управлением), имеет семантику, довольно близкую к ML и Haskell.

В

Но попасть в категорию, подходящую для интерпретации современных типизированных функциональных языков, становится довольно страшно. По сути, вы в конечном итоге создаете ультраметрически обогащенную категорию отношений частичной эквивалентности над этой областью. (В качестве примера см. Биркедал, Стовринг и Тэмсборг «Семантика реализуемости параметрического полиморфизма, общие ссылки и рекурсивные типы».) Люди, которые предпочитают операционную семантику, знают это как пошаговые индексированные логические отношения. (Например, см. «Независимость представительства в зависимости от государства» Ахмеда, Дрейера и Россберга.) В любом случае используемые методы являются относительно новыми.

a -> baTбaбT(A)aa

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

Разница в ощущениях между ML и Haskell на самом деле проистекает из интенсиональных свойств двух языков - времени выполнения и потребления памяти. ML имеет композиционную модель производительности (т. Е. Затраты времени / пространства программы могут быть вычислены из затрат времени / пространства ее подтерминов), как и настоящий язык вызовов по имени. Actual Haskell реализован с помощью запроса по запросу, своего рода напоминания, и в результате его производительность не является композиционной - сколько времени занимает выражение, связанное с переменной, для оценки зависит от того, использовалось ли оно ранее или нет. Это не смоделировано в семантике, на которую я ссылался выше.

Если вы хотите более серьезно относиться к интенсиональным свойствам, тогда ML и Haskell начинают проявлять более серьезные различия. Вероятно, все еще возможно разработать общий метаязык для них, но интерпретация типов будет отличаться гораздо более систематическим образом, связанным с теоретико-доказательной идеей фокусировки . Хорошее место, чтобы узнать об этом - кандидатская диссертация Ноама Цайлбергера.

Нил Кришнасвами
источник
10

Я чувствую, что SPJ имел в виду чисто функциональные языки - то есть языки, которые являются прозрачными по ссылкам. Это включает в себя, например, Haskell, Miranda, Clean, но не ML. Как правило, если у вас есть чисто функциональный язык, вы можете дать ему довольно чистую и четко определенную денотационную семантику. Эта семантика, в общем, будет выглядеть как лямбда-исчисление с некоторыми изменениями здесь и там. Как правило, у вас будет система типов, которая напоминает вариант системы F - возможно, более мощный в некоторых отношениях, более ограниченный в других. Вот почему извлечение кода в / компиляцию в Haskell, O'Caml и т. Д. Относительно просто из сложных помощников с зависимой типизацией, таких как Agda.

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

Заявление Саймона также вписывается в очень важный исторический контекст. Во время рождения Хаскелла (1987) было множество нестрогих функциональных языков - не только Миранда, но и Ленивый М.Л., Оруэлл, Клин и многие другие. Помимо некоторых синтаксических вариаций, все они были очень похожим языком. Именно это и послужило мотивацией для формирования комитета Хаскелла. Подробнее об этом см. «История Хаскелла: лениться с классом»: http://research.microsoft.com/en-us/um/people/simonpj/papers/history-of-haskell/ .

sclv
источник
5

Я думаю, что SPJ правильно сказал это для базовой семантики.

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

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

Напротив, скажем, что реализация C по сравнению с реализацией той же функции на Smalltalk, вероятно, будет иметь другую структуру (функции и низкоуровневые структуры данных по сравнению с объектами), фокусироваться на разных уровнях детализации (например, ручное управление памятью или сборка мусора). ) и работать на разных уровнях абстракции.

Мировоззрение пространства разработки функциональных языков просто более специфично и согласованно, чем мировоззрение «императивного программирования», которое объединяет ассемблер, C, Smalltalk, Forth и десятки других радикально разных языков в одну универсальную категорию.

Марк Хаманн
источник
4

Я думаю, что цитата Саймона ПиДжея на самом деле немного странная реплика.

Сходство между языками определяется тем, какой консенсус был достигнут в сообществе исследователей и разработчиков языков. Нет сомнений в том, что в сообществе функционального программирования существует более высокая степень консенсуса, чем в сообществе императивного программирования. Но это также тот случай, когда функциональные языки программирования в основном разрабатываются исследователями, а не практиками. Таким образом, естественно, что такой консенсус возник.

Практически во всех функциональных языках используется управление памятью с сборкой мусора и рекурсивные структуры данных (разработанные Lisp), большинство из них используют «алгебраические» типы данных и сопоставление с образцом (разработано Hope), многие из них используют функции более высокого порядка и полиморфные функции ( возникла из ML). Помимо этого, консенсус исчезает. Они различаются по используемым модульным системам, как должны обрабатываться операции изменения состояния и другие вычислительные эффекты, а также порядок оценки (вызов по имени против вызова по значению) и т. Д.

В императивных языках программирования обычно используются вложенные управляющие структуры (созданные Algol 60) и системы типов (созданные Algol 60, но объединенные Algol 68). Как правило, они имеют громоздкий поверхностный синтаксис (снова возвращаясь к Algol 60), делают нерешительные попытки обработать функции и полиморфные типы высшего порядка и отличаются поддержкой блочной структуры и модульных систем. Вероятно, существует больше единообразия в порядке оценки, потому что после 60-х годов вызов по имени практически исчез из императивных языков.

Итак, мне не ясно, что разница между двумя классами языков в их однородности настолько велика.

Было бы действительно целесообразно привести более четкие и единообразные обозначения функционального программирования в императивные языки программирования. Я вижу, что Скала положила начало в этом направлении. Еще неизвестно, сохранится ли тенденция.

Удай Редди
источник
Мне не интересно, почему вы использовали пугающие кавычки в «алгебраических» типах данных?
Стивен Шоу