Проблемы совместимости
Проблемы совместимости
Мы уже не раз обращали внимание на то, что при создании документов нередки конфликты между переменными, назначаемыми пользователем, и переменными, входящими в программы ядра, между функциями пользователя и встроенными функциями, между их заголовками и т. д. Ситуация усложняется при использовании пакетов расширения, поскольку в них широко используются переменные и различные функции, причем нередко обозначенные так же, как и встроенные функции. Особенно коварны побочные эффекты в конструкциях, содержащих вспомогательные переменные, — например, в итерационных циклах, функциях вычисления суммы и произведения и т. п. Они содержат переменные-итераторы i,. j, k и т. д. Обычно избежать конфликтов можно с помощью механизма локализации итераторов. Вернемся к уже обсуждавшимся примерам. Возьмем пример с вычислением суммы: i=2 2 Sum[i,{i,l,4}] 10 i 2
Ясно, что сумма вычисляется с применением цикла с заданным числом повторений. В его конце итератор i получает значение 4. Но глобальная переменная с тем же именем имеет значение 1=2, которое она получила до вычисления суммы с помощью функции Sum. В данном случае это достигнуто за счет того, что в теле функции переменная-итератор является локальной. Нетрудно убедиться, что проблемы со статусом переменных возможны и в, казалось бы, изученных функциях суммирования и перемножения. На это явно указывает следующий пример: func[x_] :=Sum[x^i, {i,4} ] {func[y] ,func[i] } (У +У2+ У3+У4, 30} i 2 Результат вычисления func [у] вполне понятен, тогда как вычисление func [i] носит явно обескураживающий характер. Причина его в том, что вместо символьного значения i в данном случае оказались использованы численные значения итератора i. А в этом случае функция Sum просто вычисляет численные значения. Говорят, что она работает по контексту] А теперь рассмотрим пример с циклом For: For [ i=l , i<=4 , i++ , Print [ i ] ] 1 2 3 4 i 5 . На этот раз переменная i изменила свое значение в конце цикла с 2 на 5. Это говорит о том, что пользователю-программисту надо очень внимательно относиться к статусу переменных во всех итерационных, да и других программах. Разумеется, Mathematica содержит средства для избежания подобного смешения ролей переменных. Одно из них — применение конструкции Module: i=2 2 Module[{i},For[i=l,i<=4,i++,Print[i]]] 1 2 3 4 i 2 На этот раз захвата итератором глобальной переменной i удалось избежать. Однако этот пример носит не более чем частный характер. Вообще говоря, если переменная-итератор задается в теле функции, то она будет локальной, а если она задается за пределами функций, то глобальной.