fbed99da

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



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


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

Особенно коварны побочные эффекты в конструкциях, содержащих вспомогательные переменные, — например, в итерационных циклах, функциях вычисления суммы и произведения и т. п. Они содержат переменные-итераторы 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 удалось избежать. Однако этот пример носит не более чем частный характер. Вообще говоря, если переменная-итератор задается в теле функции, то она будет локальной, а если она задается за пределами функций, то глобальной.



Содержание раздела