Иллюстрированный самоучитель по Mathematica 3/4

Проблемы совместимости

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

Особенно коварны побочные эффекты в конструкциях, содержащих вспомогательные переменные, – например, в итерационных циклах, функциях вычисления суммы и произведения и т. п. Они содержат переменные-итераторы i, .j, k и т. д. Обычно избежать конфликтов можно с помощью механизма локализации итераторов. Вернемся к уже обсуждавшимся примерам. Возьмем пример с вычислением суммы:

i=2
2
Sum[i, {i, 1, 4}]
10
i
2

Ясно, что сумма вычисляется с применением цикла с заданным числом повторений. В его конце итератор i получает значение 4. Но глобальная переменная с тем же именем имеет значение 1=2, которое она получила до вычисления суммы с помощью функции Sum. В данном случае это достигнуто за счет того, что в теле функции переменная-итератор является локальной.

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

func[x_] := Sum[x^i, {i,4} ] {func[y], func[i]}
(y +y2+ y3+y4, 30}
i
2

Результат вычисления func [у] вполне понятен, тогда как вычисление func [i] носит явно обескураживающий характер. Причина его в том, что вместо символьного значения i в данном случае оказались использованы численные значения итератора i. А в этом случае функция Sum просто вычисляет численные значения. Говорят, что она работает по контексту.

А теперь рассмотрим пример с циклом For:

For[i = 1, i <= 4, i++, Print[i]]
1
2
3
4
i
5

На этот раз переменная i изменила свое значение в конце цикла с 2 на 5. Это говорит о том, что пользователю-программисту надо очень внимательно относиться к статусу переменных во всех итерационных, да и других программах.

Разумеется, Mathematica содержит средства для избежания подобного смешения ролей переменных. Одно из них – применение конструкции Module:

i = 2
2
Module[{i},For[i=1, i<=4, i++, Print[i]]]
1
2
3
4
i
2

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

Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.