Когда я слышу фразу "символическое программирование", LISP, Prolog и (да) Mathematica сразу же приходят на ум.Я бы охарактеризовал символическую среду программирования как среду, в которой выражения, используемые для представления текста программы, также являются основной структурой данных.В результате становится очень легко создавать абстракции на основе абстракций, поскольку данные могут быть легко преобразованы в код и наоборот.
Mathematica активно использует эту возможность.Даже в большей степени, чем LISP и Prolog (IMHO).
В качестве примера символического программирования рассмотрим следующую последовательность событий.У меня есть файл CSV, который выглядит следующим образом:
r,1,2
g,3,4
Я прочитал этот файл в:
Import["somefile.csv"]
--> {{r,1,2},{g,3,4}}
Являются ли данные результата или код?Это оба.Это данные, которые получаются при чтении файла, но это также и выражение, которое будет создавать эти данные.Однако, как показывает код, это выражение является инертным, поскольку результатом его оценки является просто само по себе.
Поэтому теперь я применяю преобразование к результату:
% /. {c_, x_, y_} :> {c, Disk[{x, y}]}
--> {{r,Disk[{1,2}]},{g,Disk[{3,4}]}}
Не останавливаясь на деталяхвсе, что произошло, это то, что Disk[{...}]
обернуто вокруг двух последних чисел в каждой строке ввода.Результат все еще данные / код, но все еще инертен.Еще одно преобразование:
% /. {"r" -> Red, "g" -> Green}
--> {{Red,Disk[{1,2}]},{Green,Disk[{3,4}]}}
Да, все еще инертно.Однако, по удивительному стечению обстоятельств, этот последний результат оказался списком допустимых директив во встроенном в Mathematica доменно-ориентированном языке для графики.Последнее преобразование, и вещи начинают происходить:
% /. x_ :> Graphics[x]
--> Graphics[{{Red,Disk[{1,2}]},{Green,Disk[{3,4}]}}]
На самом деле, вы не увидите этот последний результат.В эпическом представлении синтаксического сахара Mathematica показала бы эту картину с красными и зелеными кружками:
Но веселье на этом не заканчивается.Под всем этим синтаксическим сахаром у нас все еще есть символическое выражение.Я могу применить другое правило преобразования:
% /. Red -> Black
Presto!Красный круг стал черным.
Именно этот вид «проталкивания символов» характеризует символическое программирование.Подавляющее большинство программ Mathematica имеет такую природу.
Функциональное или символическое
Я не буду подробно останавливаться на различиях между символическим и функциональным программированием, но приведу несколько замечаний.
Можно рассматривать символическое программирование как ответ на вопрос: «Что бы произошло, если бы я попытался смоделировать все, используя только преобразования выражений?»Функциональное программирование, напротив, можно рассматривать как ответ на вопрос: «Что бы произошло, если бы я попытался смоделировать все, используя только функции?»Функциональное программирование, как и символическое программирование, позволяет быстро создавать слои абстракций.Пример, который я привел здесь, может быть легко воспроизведен, скажем, в Haskell с использованием подхода функциональной реактивной анимации.Функциональное программирование - это все о композиции функций, функциях более высокого уровня, комбинаторах - все эти изящные вещи, которые вы можете делать с функциями.
Mathematica явно оптимизирована для символического программирования.Можно написать код в функциональном стиле, но функциональные возможности в Mathematica на самом деле являются лишь тонким слоем по сравнению с преобразованиями (и в этом утечку, см. Сноску ниже).
Haskell явно оптимизирован для функциональныхпрограммирование.Можно писать код в символическом стиле, но я бы сказал, что синтаксическое представление программ и данных довольно различно, что делает опыт неоптимальным.
Заключительные замечания
В заключение я защищаю, что есть различие между функциональным программированием (как воплощено в Haskell) и символическим программированием (как воплощено в Mathematica).Я думаю, что если изучать оба, то вы узнаете значительно больше, чем изучаете только один - окончательный тест на отличимость.
Утечка функциональной абстракции в Mathematica?,Попробуйте это, например: f[x_] := g[Function[a, x]];
g[fn_] := Module[{h}, h[a_] := fn[a]; h[0]];
f[999]
Должным образом доложено и подтверждено WRI. Ответ: избегайте использования Function[var, body]
(Function[body]
в порядке).