Next: Макросы, Previous: Введение в определение функций, Up: Определение функций [Contents][Index]
Для определения функций в Maxima используется оператор :=
.
Например
f(x) := sin(x)
определяет функцию f
.
Функции без имени могут быть созданы при помощи lambda
.
Например
lambda ([i, j], ...)
может быть использовано вместо f
, и
f(i,j) := block ([], ...); map (lambda ([i], i+1), l)
возвращает список с каждым элементом увеличенным на 1.
Можно определить функцию с переменным числом аргументов, присваивая последнему аргументу список дополнительных параметров:
(%i1) f ([u]) := u; (%o1) f([u]) := u (%i2) f (1, 2, 3, 4); (%o2) [1, 2, 3, 4] (%i3) f (a, b, [u]) := [a, b, u]; (%o3) f(a, b, [u]) := [a, b, u] (%i4) f (1, 2, 3, 4, 5, 6); (%o4) [1, 2, [3, 4, 5, 6]]
Правая часть определения функции является выражением. Поэтому, если требуется последовательность выражений, то можно определить правую часть следующим образом
f(x) := (expr1, expr2, ...., exprn);
В этом случае, значение, возвращаемое функцией, будет равно значению exprn.
Использование команды возврата return
возможно тоько внутри программного
блока block
. Блок
block ([], expr1, ..., if (a > 10) then return(a), ..., exprn)
сам по себе является выражением и может использоваться в правой части определения функции. При этом, команда возврата может быть выполнена раньше достижения последнего выражения.
Первый элемент блока []
может содержать список переменных
и присваиваемых им значений, например, такой как [a: 3, b, c: []]
.
В результате, три переменные a
,b
и c
не будут ссылаться на свои глобальные значения, а будут иметь локальные
значения внутри блока или внутри функций, вызываемых из этого блока.
Это называется термином динамическое связывание, поскольку локальные переменные
сохраняются от начала выполнения блока до его завершения.
Как только выполнение возвращается из блока, или его выполнение прерывается,
то старое значения переменных (если существуют) восстанавливаются.
Это хороший метод защиты значения переменных.
Отметим, что присваивание начальных значений переменных в блоке выполняется
параллельно. Это означает, что если сделать c: a
, в вышеизложенном примере,
то значение c
будет равно значению a
до входа в блок и до присваивания
a
локального значения. Поэтому, выполнение кода
block ([a: a], expr1, ... a: a+3, ..., exprn)
защитит внешнее значение переменной a
от изменения внутри блока, и, с другой
стороны, обеспечит доступ к этому значению. Иными словами, правая часть присваивания
вычисляется до выполнения каких-либо присваиваний.
Простое использование block ([x], ...
приводит к тому, что x
внутри блока
равна сама себе, как при запуске новой сессии Maxima.
Фактические параметры функции трактуются точно так же, как локальные переменные в блоке. Таким образом, при определении
f(x) := (expr1, ..., exprn);
и вызове
f(1);
создается контекст, аналогичный
block ([x: 1], expr1, ..., exprn)
Внутри функций, если правая часть определения функции может вычисляться
во время выполнения, полезно использовать define
и, возможно, buildq
.
Функции-массивы сохраняют значение функции при первом вызове с определенными значениями параметров, и возвращают сохраненное значение без перевычисления при последующих вызовах с теми же параметрами. Такие функции часто называются “функции с памятью”.
Имена функций-массивов добавляются к глобальной переменной arrays
(не к глобальной переменной functions
).
Функция arrayinfo
возвращает для таких функций список сохраненных элементов, а
функция listarray
возвращает сохраненные значения.
Функции dispfun
и fundef
возвращают определения функций-массива.
Функция arraymake
создает вызов функции-массива, аналогично тому как
funmake
делает для обычных функций.
Функция arrayapply
применяет функцию-массив к аргументам, аналогично тому
как apply
делает для обычных функций.
Не существует полного аналога функции map
для функций-массивов, но
map(lambda([x], a[x]), L)
или
makelist(a[x], x, L)
, где L – список,
действует очень похоже.
Функция remarray
удаляет определение функции-массива (включая сохраненные значения),
аналогично тому как remfunction
делает для обычных функций.
Вызов kill(a[x])
удаляет сохраненное значение функции-массива a
для аргумента x. При следующем вызове a с аргументом x, функция
будет перевычислена.
Не существует способа сразу удалить все сохраненные значения функции-массива кроме как
вызов kill(a)
или remarray(a)
, что также удаляет определение
функции.
Next: Макросы, Previous: Введение в определение функций, Up: Определение функций [Contents][Index]