Maxima Manual: Функции и переменные для определения функций

Previous: Макросы, Up: Определение функций [Contents][Index]

### 37.4 Функции и переменные для определения функций

Функция: apply (F, [x_1, ..., x_n])

  Составляет и вычисляет выражение `F(arg_1, ..., arg_n)`.

  Функция `apply` не пытается различить функцию-массив и обычную функцию, и если F есть имя функции-массива, то `apply` вычисляет `F(...)` (т.е. обычный вызов функции с круглыми а не с квадратными скобками). Функция `arrayapply` вычисляет вызов функции с квадратными скобками.

  Примеры:

  Функция `apply` вычисляет свои аргументы. В этом примере, `min` применяется к значению `L`.

      (%i1) L : [1, 5, -10.2, 4, 3];
      (%o1)                 [1, 5, - 10.2, 4, 3]
      (%i2) apply (min, L);
      (%o2)                        - 10.2

  Функция `apply` вычисляет свои аргументы даже если функция F не вычисляет их.

      (%i1) F (x) := x / 1729;
                                         x
      (%o1)                     F(x) := ----
                                        1729
      (%i2) fname : F;
      (%o2)                           F
      (%i3) dispfun (F);
                                         x
      (%t3)                     F(x) := ----
                                        1729

      (%o3)                         [%t3]
      (%i4) dispfun (fname);
      fname is not the name of a user function.
       -- an error.  Quitting.  To debug this try debugmode(true);
      (%i5) apply (dispfun, [fname]);
                                         x
      (%t5)                     F(x) := ----
                                        1729

      (%o5)                         [%t5]

  Функция `apply` вычисляет имя функции F. Одиночная кавычка `'` блокирует это вычисление. `demoivre` является именем глобальной переменной и, одновременно, именем функции.

      (%i1) demoivre;
      (%o1)                         false
      (%i2) demoivre (exp (%i * x));
      (%o2)                  %i sin(x) + cos(x)
      (%i3) apply (demoivre, [exp (%i * x)]);
      demoivre evaluates to false
      Improper name or value in functional position.
       -- an error.  Quitting.  To debug this try debugmode(true);
      (%i4) apply ('demoivre, [exp (%i * x)]);
      (%o4)                  %i sin(x) + cos(x)

  Категории:Применение функций ·

Функция: block ([v_1, ..., v_m], expr_1, ..., expr_n)
Функция: block (expr_1, ..., expr_n)

  Функция `block` последовательно вычисляет expr_1, ..., expr_n и возвращает значение последнего вычисленного выражения. Последовательность вычисления может быть изменена при помощи функций `go`, `throw` и `return`. Последнее выражение expr_n вычисляется если не используется `return` или вычисляется выражение, содержащие `throw`. Некоторые переменные v_1, ..., v_m могут быть объявлены локальными в блоке, и они отличаются от глобальных переменных с теми же именами. Если не требуется определять локальные переменные, то список может быть опущен. Внутри блока, все другие переменные, отличные от v_1, ..., v_m, являются глобальными.

  `block` сохраняет текущие значения переменных v_1, ..., v_m (если таковые существуют) при входе в блок, и затем удаляет их значения, так чтобы эти переменные вычислялись сами в себя. Локальные переменные могут принимать любые значения внутри блока, но пр выходе из него сохраненные значения восстанавливаются, а локальные в блоке значения теряются.

  Блок может существовать внутри другого блока. Локальные переменные определяются всякий раз как вычисляется новый `block`. Локальные переменные объемлющего блока выглядят как глобальные для внутреннего блока. Если переменная не локальна в блоке, то ее значение равно последнему, присвоенному в объемлющем блоке, если таковое существует, и значению переменной в глобальном окружении в противном случае. Эта политика совпадает с обычным понятием "динамической области определения".

  Если необходимо сохранять и восстанавливать другие локальные свойства, кроме `value`, такие как `array` (кроме полных массивов), `function`, `dependencies`, `atvalue`, `matchdeclare`, `atomgrad`, `constant` и `nonscalar`, то следует использовать функцию `local` внутри блока с именем функции в качестве параметра.

  Значением блока является значение последнего выражения или значение аргумента функции `return`, которая может быть использована для явного выхода из блока. Функция `go` используется для передачи управления на команду блока, помеченную аргументом `go`. Для того, чтобы пометить команду нужно поместить перед ней метку в виде атома. Например: `block ([x], x:1, loop, x: x+1, ..., go(loop), ...)`. Аргументом `go` должна быть метка, определенная в текущем блоке. Невозможно использовать `go` для передачи управления в блок отличный от того, в котором находится вызов `go`.

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

  Категории:Выражения ·Программирование ·

Функция: break (expr_1, ..., expr_n)

  Вычисляет и печатает выражения expr_1, ..., expr_n и затем вызывает прерывание Maxima с тем, чтобы пользователь мог исследовать и изменить окружение. Ввод `exit;` возобновляет вычисление.

  Категории:Отладка ·

Функция: catch (expr_1, ..., expr_n)

  Вычисляет expr_1, ..., expr_n одно за другими и, если одно из них приводит к вычислению выражения `throw (arg)`, то значением `catch` становится значение аргумента `throw (arg)`, и дальнейшее вычисление не производится. Такой "нелокальный возврат" осуществляется из любого уровня вложенности до первого объемлющего `catch`. Если нет объемлющего `catch`, то `throw` вызывает ошибку.

  Если вычисление аргументов не приводит к вычислению `throw`, то значение `catch` равно значению expr_n.

      (%i1) lambda ([x], if x < 0 then throw(x) else f(x))$
      (%i2) g(l) := catch (map (''%, l))$
      (%i3) g ([1, 2, 3, 7]);
      (%o3)               [f(1), f(2), f(3), f(7)]
      (%i4) g ([1, 2, -3, 7]);
      (%o4)                          - 3

  Здесь, если список `l` содержит только неотрицательные числа, то функция `g` возвращает список функций `f`, примененных к элементам `l`, иначе, `g` "ловит" первое отрицательное число в `l` и "бросает" его вверх.

  Категории:Программирование ·

Функция: compfile (filename, f_1, ..., f_n)
Функция: compfile (filename, functions)
Функция: compfile (filename, all)

  Транслирует функции Maxima в Lisp и записывает полученный код в файл filename.

  Вызов `compfile(filename, f_1, ..., f_n)` транслирует только заданные функции. Вызов `compfile(filename, functions)` или вызов `compfile(filename, all)` транслирует все определенные пользователем функции.

  Код Lisp не вычисляется, а результирующий файл не обрабатывается компилятором Lisp. Функция `translate` создает и вычисляет Lisp код. Функция `compile_file` транслирует код Maxima в Lisp, и затем выполняет компилятор Lisp.

  См. также `translate`, `translate_file` и `compile_file`.

  Категории:Трансляция и компиляция ·

Функция: compile (f_1, ..., f_n)
Функция: compile (functions)
Функция: compile (all)

  Транслирует определения Maxima функций f_1, ..., f_n в Lisp, вычисляет Lisp код и вызывает Lisp функцию `COMPILE` на каждую транслированную функцию. Функция `compile` возвращает список скомпилированных функций.

  Вызов `compile (all)` или `compile (functions)` компилирует все определенные пользователем функции.

  Функция `compile` не вычисляет свои аргументы. Оператор кавычка-кавычка `''` может быть использован для их вычисления.

  Категории:Трансляция и компиляция ·

Функция: define (f(x_1, ..., x_n), expr)
Функция: define (f[x_1, ..., x_n], expr)
Функция: define (funmake (f, [x_1, ..., x_n]), expr)
Функция: define (arraymake (f, [x_1, ..., x_n]), expr)
Функция: define (ev (expr_1), expr_2)

  Определяет функцию с именем f, аргументами x_1, ..., x_n и телом функции expr. Функция `define` всегда вычисляет свой второй аргумент (если вычисление не экранировано, т.е. блокировано явным образом). Функция, определенная данным образом, может быть обычной функцией Maxima (с аргументами в круглых скобках) или функцией-массивом (с аргументам в квадратных скобках).

  Если последний аргумент x_n является одноэлементным списком, то функция, определенная `define`, принимает произвольное число аргументов. Фактические параметры присваиваются по одному формальным параметрам x_1, ..., x_(n - 1), а все последующие фактические параметры, если таковые есть, присваиваются x_n одним списком.

  Если первый параметр `define` имеет форму `f(x_1, ..., x_n)` или `f[x_1, ..., x_n]`, то аргументы функции вычисляются, а f нет, даже если уже есть функция или переменная с таким именем.

  Если же первый параметр является выражением с оператором `funmake`, `arraymake` или `ev`, то первый аргумент вычисляется. Это позволяет вычислять как имя функции так и ее тело.

  Все определяемые функции действуют в одном пространстве имен, т.е. если функция `f` определена внутри другой функции `g`, то действие `f` не ограничено функцией `g`.

  Если некоторый формальный параметр x_k является экранированным символом (после вычисления), то функция, определенная `define`, не будет вычислять соответствующий фактический параметр. Все остальные фактические параметры вычисляются.

  См. также `:=` и `::=`.

  Примеры:

  Функция `define` всегда вычисляет свой второй аргумент (если вычисление не блокировано явным образом).

      (%i1) expr : cos(y) - sin(x);
      (%o1)                    cos(y) - sin(x)
      (%i2) define (F1 (x, y), expr);
      (%o2)              F1(x, y) := cos(y) - sin(x)
      (%i3) F1 (a, b);
      (%o3)                    cos(b) - sin(a)
      (%i4) F2 (x, y) := expr;
      (%o4)                   F2(x, y) := expr
      (%i5) F2 (a, b);
      (%o5)                    cos(y) - sin(x)

  Функция, определяемая `define`, может быть обычной функцией Maxima или функцией-массивом.

      (%i1) define (G1 (x, y), x.y - y.x);
      (%o1)               G1(x, y) := x . y - y . x
      (%i2) define (G2 [x, y], x.y - y.x);
      (%o2)                G2     := x . y - y . x
                             x, y

  Если последний аргумент x_n является одноэлементным списком, то определенная `define` функция принимает произвольное число аргументов.

      (%i1) define (H ([L]), '(apply ("+", L)));
      (%o1)                H([L]) := apply("+", L)
      (%i2) H (a, b, c);
      (%o2)                       c + b + a

  Если первый параметр является выражением с оператором `funmake`, `arraymake` или `ev`, то первый аргумент вычисляется.

      (%i1) [F : I, u : x];
      (%o1)                        [I, x]
      (%i2) funmake (F, [u]);
      (%o2)                         I(x)
      (%i3) define (funmake (F, [u]), cos(u) + 1);
      (%o3)                  I(x) := cos(x) + 1
      (%i4) define (arraymake (F, [u]), cos(u) + 1);
      (%o4)                   I  := cos(x) + 1
                               x
      (%i5) define (foo (x, y), bar (y, x));
      (%o5)                foo(x, y) := bar(y, x)
      (%i6) define (ev (foo (x, y)), sin(x) - cos(y));
      (%o6)             bar(y, x) := sin(x) - cos(y)

  Категории:Определение функций ·

Функция: define_variable (name, default_value, mode)

  Определяет глобальную переменную. `define_variable` полезна в пользовательских пакетах, которые часто транслируются или компилируются.

  Функция `define_variable` выполняет следующие шаги:

  1. `mode_declare (name, mode)` декларирует тип переменной name для транслятора. См. `mode_declare` для списка возможных типов.
  2. Если переменная не имеет значения, то default_value устанавливается равным name.
  3. `declare (name, special)` объявляет переменную специальной.
  4. Ассоциирует имя name с тестовой функцией, чтобы обеспечить, что name будут присваиваться значения только объявленного типа.

  Свойство `value_check` может быть установлено для любой переменной, определенной при помощи `define_variable` с типом отличным от `any`. Значение свойства `value_check` является лямбда-выражением или именем функции одной переменной. Эта функция вызывается всякий раз, как производится попытка присвоить значение данной переменной. Параметром функции `value_check` является предполагаемое новое значение переменной.

  Функция `define_variable` вычисляет `default_value` и не вычисляет `name` и `mode`. Функция `define_variable` возвращает текущее значение `name`, что есть `default_value` если `name` не имела значения до декларации и значение `name` в противном случае.

  Примеры:

  `foo` – логическая переменная с начальным значением `true`.

      (%i1) define_variable (foo, true, boolean);
      (%o1)                         true
      (%i2) foo;
      (%o2)                         true
      (%i3) foo: false;
      (%o3)                         false
      (%i4) foo: %pi;
      Error: foo was declared mode boolean, has value: %pi
       -- an error.  Quitting.  To debug this try debugmode(true);
      (%i5) foo;
      (%o5)                         false

  `bar` – целочисленная переменная, которая должна быть простым числом.

      (%i1) define_variable (bar, 2, integer);
      (%o1)                           2
      (%i2) qput (bar, prime_test, value_check);
      (%o2)                      prime_test
      (%i3) prime_test (y) := if not primep(y) then
                                 error (y, "is not prime.");
      (%o3) prime_test(y) := if not primep(y)

                                         then error(y, "is not prime.")
      (%i4) bar: 1439;
      (%o4)                         1439
      (%i5) bar: 1440;
      1440 is not prime.
      #0: prime_test(y=1440)
       -- an error.  Quitting.  To debug this try debugmode(true);
      (%i6) bar;
      (%o6)                         1439

  `baz_quux` – переменная, которой нельзя присвоить значение. Тип `any_check` аналогичен `any`, но позволяет применять механизм `value_check`, в то время как тип `any` этого не позволяет.

      (%i1) define_variable (baz_quux, 'baz_quux, any_check);
      (%o1)                       baz_quux
      (%i2) F: lambda ([y], if y # 'baz_quux then
                       error ("Cannot assign to `baz_quux'."));
      (%o2) lambda([y], if y # 'baz_quux

                              then error(Cannot assign to `baz_quux'.))
      (%i3) qput (baz_quux, ''F, value_check);
      (%o3) lambda([y], if y # 'baz_quux

                              then error(Cannot assign to `baz_quux'.))
      (%i4) baz_quux: 'baz_quux;
      (%o4)                       baz_quux
      (%i5) baz_quux: sqrt(2);
      Cannot assign to `baz_quux'.
      #0: lambda([y],if y # 'baz_quux then
                       error("Cannot assign to `baz_quux'."))(y=sqrt(2))
       -- an error.  Quitting.  To debug this try debugmode(true);
      (%i6) baz_quux;
      (%o6)                       baz_quux

  Категории:Трансляция и компиляция ·

Функция: dispfun (f_1, ..., f_n)
Функция: dispfun (all)

  Выводит определения пользовательских функций f_1, ..., f_n. Каждый аргумент должен быть именем: макроса (определенного при помощи `::=`), обычной функции (определенной `:=` или `define`), функции-массива (определенной `:=` или `define`, но с аргументами в квадратных скобках `[ ]`), функцией с индексом (определенной `:=` или `define`, но с частью аргументов в квадратных скобках а с другими в круглых `( )`), одним из элементов функции с индексом с определенным значением индекса, или функцией с постоянным индексом.

  Вызов `dispfun (all)` выводит все пользовательские функции, которые определяются списками `functions`, `arrays` и `macros`, кроме функций с постоянным индексом.

  Функция `dispfun` создает метки промежуточных выражений (`%t1`, `%t2` и т.д.) для каждой выводимой функции и присваивает определения функций этим меткам. В отличии от этого, `fundef` возвращает определение функции.

  Функция `dispfun` не вычисляет свои аргументы. Оператор кавычка-кавычка `''` может быть использован для их вычисления. Функция `dispfun` возвращает список меток промежуточных выражений, соответствующих выведенным функциям.

  Примеры:

      (%i1) m(x, y) ::= x^(-y);
                                           - y
      (%o1)                   m(x, y) ::= x
      (%i2) f(x, y) :=  x^(-y);
                                           - y
      (%o2)                    f(x, y) := x
      (%i3) g[x, y] :=  x^(-y);
                                          - y
      (%o3)                     g     := x
                                 x, y
      (%i4) h[x](y) :=  x^(-y);
                                          - y
      (%o4)                     h (y) := x
                                 x
      (%i5) i[8](y) :=  8^(-y);
                                          - y
      (%o5)                     i (y) := 8
                                 8
      (%i6) dispfun (m, f, g, h, h[5], h[10], i[8]);
                                           - y
      (%t6)                   m(x, y) ::= x

                                           - y
      (%t7)                    f(x, y) := x

                                          - y
      (%t8)                     g     := x
                                 x, y

                                          - y
      (%t9)                     h (y) := x
                                 x

                                          1
      (%t10)                     h (y) := --
                                  5        y
                                          5

                                           1
      (%t11)                    h  (y) := ---
                                 10         y
                                          10

                                          - y
      (%t12)                    i (y) := 8
                                 8

      (%o12)       [%t6, %t7, %t8, %t9, %t10, %t11, %t12]
      (%i12) ''%;
                           - y              - y            - y
      (%o12) [m(x, y) ::= x   , f(x, y) := x   , g     := x   ,
                                                  x, y
                        - y           1              1             - y
              h (y) := x   , h (y) := --, h  (y) := ---, i (y) := 8   ]
               x              5        y   10         y   8
                                      5             10

  Категории:Определение функций ·Функции вывода ·

Системная переменная: functions

  Значение по умолчанию: `[]`

  Переменная `functions` есть список всех обычных функций Maxima в текущей сессии. Обычные функции – это функции, определенные при помощи `define` или `:=`, и вызываемые с аргументами в круглых скобках `()`. Функция может быть определена в командной строке Maxima или в файле, загруженном при помощи `load` или `batch`.

  Функции-массивы (вызываемые с квадратными скобками, т.е. `F[x]`) и функции с индексом (вызываемые с круглыми и квадратными скобками, т.е. `F[x](y)`) перечислены в глобальной переменной `arrays`, а не в `functions`.

  Lisp функции не включаются в список.

  Примеры:

      (%i1) F_1 (x) := x - 100;
      (%o1)                   F_1(x) := x - 100
      (%i2) F_2 (x, y) := x / y;
                                            x
      (%o2)                    F_2(x, y) := -
                                            y
      (%i3) define (F_3 (x), sqrt (x));
      (%o3)                   F_3(x) := sqrt(x)
      (%i4) G_1 [x] := x - 100;
      (%o4)                    G_1  := x - 100
                                  x
      (%i5) G_2 [x, y] := x / y;
                                           x
      (%o5)                     G_2     := -
                                   x, y    y
      (%i6) define (G_3 [x], sqrt (x));
      (%o6)                    G_3  := sqrt(x)
                                  x
      (%i7) H_1 [x] (y) := x^y;
                                            y
      (%o7)                     H_1 (y) := x
                                   x
      (%i8) functions;
      (%o8)              [F_1(x), F_2(x, y), F_3(x)]
      (%i9) arrays;
      (%o9)                 [G_1, G_2, G_3, H_1]

  Категории:Определение функций ·Глобальные переменные ·

Функция: fundef (f)

  Возвращает определение функции f.

  Аргумент должен быть именем: макроса (определенного при помощи `::=`), обычной функции (определенной `:=` или `define`), функции-массива (определенной `:=` или `define`, но с аргументами в квадратных скобках `[ ]`), функцией с индексом (определенной `:=` или `define`, но с частью аргументов в квадратных скобках а с другими в круглых `( )`), одним из элементов функции с индексом с определенным значением индекса, или функцией с постоянным индексом.

  Функция `fundef` не вычисляет свои аргументы. Оператор кавычка-кавычка `''` может быть использован для их вычисления.

  Вызов `fundef (f)` возвращает определение функции f. В отличии от этого, `dispfun (f)` присваивает определения функций меткам промежуточных выражений.

  Категории:Определение функций ·

Функция: funmake (F, [arg_1, ..., arg_n])

  Возвращает выражение `F(arg_1, ..., arg_n)`. Это выражение упрощается но не вычисляется, т.е. функция F не вызывается, даже если она определена.

  Функция `funmake` не различает обычные функции и функции-массивы. Если F есть имя функции-массива, то `funmake` все равно возвращает `F(...)` (т.е вызов функции с круглыми а не с квадратными скобками). Для функций-массивом следует использовать `arraymake`.

  Функция `funmake` вычисляет свои аргументы.

  Примеры:

  Функция `funmake`, примененная к обычной Maxima функции.

      (%i1) F (x, y) := y^2 - x^2;
                                         2    2
      (%o1)                  F(x, y) := y  - x
      (%i2) funmake (F, [a + 1, b + 1]);
      (%o2)                    F(a + 1, b + 1)
      (%i3) ''%;
                                    2          2
      (%o3)                  (b + 1)  - (a + 1)

  Функция `funmake`, примененная к макросу.

      (%i1) G (x) ::= (x - 1)/2;
                                        x - 1
      (%o1)                    G(x) ::= -----
                                          2
      (%i2) funmake (G, [u]);
      (%o2)                         G(u)
      (%i3) ''%;
                                    u - 1
      (%o3)                         -----
                                      2

  Функция `funmake`, примененная к функции с индексом.

      (%i1) H [a] (x) := (x - 1)^a;
                                              a
      (%o1)                   H (x) := (x - 1)
                               a
      (%i2) funmake (H [n], [%e]);
                                             n
      (%o2)               lambda([x], (x - 1) )(%e)
      (%i3) ''%;
                                          n
      (%o3)                       (%e - 1)
      (%i4) funmake ('(H [n]), [%e]);
      (%o4)                        H (%e)
                                    n
      (%i5) ''%;
                                          n
      (%o5)                       (%e - 1)

  Функция `funmake`, примененная к символу, не являющемуся функцией какого-либо типа.

      (%i1) funmake (A, [u]);
      (%o1)                         A(u)
      (%i2) ''%;
      (%o2)                         A(u)

  Функция `funmake` вычисляет аргументы, но не результат.

      (%i1) det(a,b,c) := b^2 -4*a*c;
                                          2
      (%o1)              det(a, b, c) := b  - 4 a c
      (%i2) (x : 8, y : 10, z : 12);
      (%o2)                          12
      (%i3) f : det;
      (%o3)                          det
      (%i4) funmake (f, [x, y, z]);
      (%o4)                    det(8, 10, 12)
      (%i5) ''%;
      (%o5)                         - 284

  Maxima упрощает возвращаемое `funmake` значение.

      (%i1) funmake (sin, [%pi / 2]);
      (%o1)                           1

  Категории:Применение функций ·Выражения ·

Функция: lambda ([x_1, ..., x_m], expr_1, ..., expr_n)
Функция: lambda ([[L]], expr_1, ..., expr_n)
Функция: lambda ([x_1, ..., x_m, [L]], expr_1, ..., expr_n)

  Определяет и возвращает лямбда-выражение (т.е. функцию без имени). Функция может иметь обязательные параметры x_1, ..., x_m и/или необязательные параметры L, представляемые в форме списка. Значение, возвращаемое функцией, равно expr_n. Лямбда-выражение может быть присвоено переменной и вычислено, как обычная функция. Лямбда-выражение может использоваться в тех же контекстах, где ожидается имя функции.

  При вычислении функции, создаются неинициализированные локальные переменные x_1, ..., x_m. `lambda` может использоваться внутри `block` или другого `lambda`, и локальные переменные создаются каждый раз, как вычисляется новый блок `block` или `lambda`. Локальные переменные выглядят как глобальные для каждого внутреннего блока `block` или `lambda`. Если переменная не является локальной, то ее значение равно последнему, присвоенному в объемлющем блоке `block` или `lambda`, если таковое существует, и значению переменной в глобальном окружении в противном случае. Эта политика совпадает с обычным понятием "динамической области определения".

  После определения локальных переменных, выражения с expr_1 по expr_n последовательно вычисляются. Специальная переменная `%%` обозначает значение предыдущего выражения. Среди выражение могут применяться `throw` и `catch`.

  Команда возврата `return` не может использоваться в лямбда-выражении если только она не заключена в блоке `block`. В этом случае `return` определяет значение блока а не лямбда-выражения в целом, за исключением случая, когда блок является последним выражением expr_n. Аналогично, `go` не может использоваться в лямбда-выражении без объемлющего блока `block`.

  Функция `lambda` не вычисляет свои параметры. Оператор кавычка-кавычка `''` может быть использован для их вычисления.

  Примеры:

  - Лямбда-выражение может быть присвоено переменной и вычислено, как обычная функция.

      (%i1) f: lambda ([x], x^2);
                                            2
      (%o1)                    lambda([x], x )
      (%i2) f(a);
                                      2
      (%o2)                          a

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

      (%i3) lambda ([x], x^2) (a);
                                      2
      (%o3)                          a
      (%i4) apply (lambda ([x], x^2), [a]);
                                      2
      (%o4)                          a
      (%i5) map (lambda ([x], x^2), [a, b, c, d, e]);
                              2   2   2   2   2
      (%o5)                 [a , b , c , d , e ]

  - Параметры являются локальными переменными. Все остальные переменные глобальны. Глобальные переменные вычисляются в момент вычисления лямбда-выражения, за исключением случая, когда вычисление специально вызвано каким-либо способом, например, оператором `''`.

      (%i6) a: %pi$
      (%i7) b: %e$
      (%i8) g: lambda ([a], a*b);
      (%o8)                   lambda([a], a b)
      (%i9) b: %gamma$
      (%i10) g(1/2);
                                   %gamma
      (%o10)                       ------
                                     2
      (%i11) g2: lambda ([a], a*''b);
      (%o11)                lambda([a], a %gamma)
      (%i12) b: %e$
      (%i13) g2(1/2);
                                   %gamma
      (%o13)                       ------
                                     2

  - Лямбда-выражения могут быть вложены. Локальные переменные объемлющего лямбда-выражения выглядят глобальными для внутреннего, если только во внутреннем лямбда-выражении не определены локальные переменные с теми же именами.

      (%i14) h: lambda ([a, b], h2: lambda ([a], a*b), h2(1/2));
                                                         1
      (%o14)    lambda([a, b], h2 : lambda([a], a b), h2(-))
                                                         2
      (%i15) h(%pi, %gamma);
                                   %gamma
      (%o15)                       ------
                                     2

  - Поскольку `lambda` не вычисляет аргументы, нижеприведенное лямбда-выражение `i` не определяет функцию "умножить на `a`". Такая функция может быть определена с помощью `buildq`, как сделано в лямбда-выражении `i2`.

      (%i16) i: lambda ([a], lambda ([x], a*x));
      (%o16)            lambda([a], lambda([x], a x))
      (%i17) i(1/2);
      (%o17)                  lambda([x], a x)
      (%i18) i2: lambda([a], buildq([a: a], lambda([x], a*x)));
      (%o18)    lambda([a], buildq([a : a], lambda([x], a x)))
      (%i19) i2(1/2);
                                           x
      (%o19)                   lambda([x], -)
                                           2
      (%i20) i2(1/2)(%pi);
                                     %pi
      (%o20)                         ---
                                      2

  - Лямбда-выражение может иметь переменное число аргументов, что обозначается `[L]` в качестве единственного или последнего параметра. Фактические параметры представлены внутри функции в виде списка.

      (%i1) f : lambda ([aa, bb, [cc]], aa * cc + bb);
      (%o1)          lambda([aa, bb, [cc]], aa cc + bb)
      (%i2) f (foo, %i, 17, 29, 256);
      (%o2)       [17 foo + %i, 29 foo + %i, 256 foo + %i]
      (%i3) g : lambda ([[aa]], apply ("+", aa));
      (%o3)             lambda([[aa]], apply(+, aa))
      (%i4) g (17, 29, x, y, z, %e);
      (%o4)                  z + y + x + %e + 46

  Категории:Определение функций ·

Функция: local (v_1, ..., v_n)

  Объявляет переменные v_1, ..., v_n локальными по отношению ко всем свойствам в выражении, где используется `local`.

  Функция `local` не вычисляет свои аргументы. Функция `local` возвращает `done`.

  Функция `local` может использоваться только внутри блока `block`, в теле функции или лямбда-выражении `lambda`, в функции `ev`, и только один раз в каждом случае.

  `local` независима от `context`.

  Категории:Определение функций ·Программирование ·

Управляющая переменная: macroexpansion

  Значение по умолчанию: `false`

  Переменная `macroexpansion` управляет тем, подставляется ли макро-расширение (т.е. возвращаемое значением) вместо вызова макро-функции. Подстановка может ускорить последующие вычисления но за счет увеличения памяти для хранения выражений.

  `false`

    Макро-расширение не подставляется вместо вызова макро-функции.

  `expand`

    При первом вызове макро-функции, макро-расширение сохраняется. Для последующих вызовов, макро-расширение не перевычисляется. Побочные эффекты (такие как `print` или присваивание глобальных переменных) осуществляются только при первом вычислении макро-функции. Макро-расширение в выражении не влияет на другие выражения, имеющие такой же вызов макро-функции.

  `displace`

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

  Примеры:

  Если `macroexpansion` равна `false`, то макро-функция вызывается всякий раз, как вычисляется вызывающее выражение, и вызывающее выражение не изменяется.

      (%i1) f (x) := h (x) / g (x);
                                        h(x)
      (%o1)                     f(x) := ----
                                        g(x)
      (%i2) g (x) ::= block (print ("x + 99 is equal to", x),
                             return (x + 99));
      (%o2) g(x) ::= block(print("x + 99 is equal to", x),
                                                        return(x + 99))
      (%i3) h (x) ::= block (print ("x - 99 is equal to", x),
                             return (x - 99));
      (%o3) h(x) ::= block(print("x - 99 is equal to", x),
                                                        return(x - 99))
      (%i4) macroexpansion: false;
      (%o4)                         false
      (%i5) f (a * b);
      x - 99 is equal to x
      x + 99 is equal to x
                                  a b - 99
      (%o5)                       --------
                                  a b + 99
      (%i6) dispfun (f);
                                        h(x)
      (%t6)                     f(x) := ----
                                        g(x)

      (%o6)                         done
      (%i7) f (a * b);
      x - 99 is equal to x
      x + 99 is equal to x
                                  a b - 99
      (%o7)                       --------
                                  a b + 99

  Если `macroexpansion` равна `expand`, то макро-функция вызывается один раз, и взывающее выражение не изменяется.

      (%i1) f (x) := h (x) / g (x);
                                        h(x)
      (%o1)                     f(x) := ----
                                        g(x)
      (%i2) g (x) ::= block (print ("x + 99 is equal to", x),
                             return (x + 99));
      (%o2) g(x) ::= block(print("x + 99 is equal to", x),
                                                        return(x + 99))
      (%i3) h (x) ::= block (print ("x - 99 is equal to", x),
                             return (x - 99));
      (%o3) h(x) ::= block(print("x - 99 is equal to", x),
                                                        return(x - 99))
      (%i4) macroexpansion: expand;
      (%o4)                        expand
      (%i5) f (a * b);
      x - 99 is equal to x
      x + 99 is equal to x
                                  a b - 99
      (%o5)                       --------
                                  a b + 99
      (%i6) dispfun (f);
                                        h(x)
      (%t6)                     f(x) := ----
                                        g(x)

      (%o6)                         done
      (%i7) f (a * b);
                                  a b - 99
      (%o7)                       --------
                                  a b + 99

  Если `macroexpansion` равна `expand`, то макро-функция вызывается один раз, и взывающее выражение изменяется.

      (%i1) f (x) := h (x) / g (x);
                                        h(x)
      (%o1)                     f(x) := ----
                                        g(x)
      (%i2) g (x) ::= block (print ("x + 99 is equal to", x),
                             return (x + 99));
      (%o2) g(x) ::= block(print("x + 99 is equal to", x),
                                                        return(x + 99))
      (%i3) h (x) ::= block (print ("x - 99 is equal to", x),
                             return (x - 99));
      (%o3) h(x) ::= block(print("x - 99 is equal to", x),
                                                        return(x - 99))
      (%i4) macroexpansion: displace;
      (%o4)                       displace
      (%i5) f (a * b);
      x - 99 is equal to x
      x + 99 is equal to x
                                  a b - 99
      (%o5)                       --------
                                  a b + 99
      (%i6) dispfun (f);
                                       x - 99
      (%t6)                    f(x) := ------
                                       x + 99

      (%o6)                         done
      (%i7) f (a * b);
                                  a b - 99
      (%o7)                       --------
                                  a b + 99

  Категории:Применение функций ·Глобальные переменные ·

Управляющая переменная: mode_checkp

  Значение по умолчанию: `true`

  Если `mode_checkp` равна `true`, то `mode_declare` проверяет типы переменных, имеющих значение до вызова `mode_declare`.

  Категории:Переменные и флаги трансляции ·

Управляющая переменная: mode_check_errorp

  Значение по умолчанию: `false`

  Если `mode_check_errorp` равна `true`, то `mode_declare` вызывает ошибку.

  Категории:Переменные и флаги трансляции ·

Управляющая переменная: mode_check_warnp

  Значение по умолчанию: `true`

  Если `mode_check_warnp` равна `true`, то выводятся предупреждения о ошибках типизации.

  Категории:Переменные и флаги трансляции ·

Функция: mode_declare (y_1, mode_1, ..., y_n, mode_n)

  Функция `mode_declare` используется для определения типов переменных или функций для последующей трансляции и компиляции. Вызов `mode_declare` обычно располагается в начале определения функции, в начале Maxima-программы или выполняется интерактивно в командной строке.

  Параметры `mode_declare` являются парами, состоящими из переменной и ее типа, который может быть `boolean`, `fixnum`, `number`, `rational` или `float`. Вместо переменной можно использовать список переменных, которые все будут объявлены однотипными.

  Если переменная является массивом, и каждый элемент этого массива, на который будут ссылаться, имеет значение, то для первой декларации границ массива следует использовать `array (yi, complete, dim1, dim2, ...)` а не

      array(yi, dim1, dim2, ...)

  Если все элементы массива имеют тип `fixnum` (`float`), то следует использовать `fixnum` (`float`) вместо `complete`. Кроме того, если все элементы массива имеют один тип, скажем `m`, то для эффективной трансляции следует использовать

      mode_declare (completearray (yi), m))

  Численный код с использованием массивов может работать быстрее при объявлении ожидаемого размера массива, как сделано в

      mode_declare (completearray (a [10, 10]), float)

  для массива с плавающей точкой размера 10 x 10.

  Можно определить тип результата функции при помощи `function (f_1, f_2, ...)`, где `f_1`, `f_2`, ... есть имена функций. Например, выражение

      mode_declare ([function (f_1, f_2, ...)], fixnum)

  объявляет значения, возвращаемые функциями `f_1`, `f_2`, ..., целыми числами длиной одно слово.

  Функция `modedeclare` является синонимом `mode_declare`.

  Категории:Трансляция и компиляция ·

Функция: mode_identity (arg_1, arg_2)

  Специальная форма, используемая вместе с `mode_declare` и `macros` для объявления, например, списка списков чисел с плавающей точкой или других подобных составных объектов. Первый аргумент `mode_identity` есть имя типа, как в `mode_declare` (т.е. одно из `float`, `fixnum`, `number`, `list` или `any`), а второй аргумент есть выражение, которое вычисляется и возвращается как значение `mode_identity`. Если возвращаемое значение недопустимо для декларации типа, указанного в первом аргументе, то случается ошибка или печатается предупреждение. Важно то, что тип выражения для транслятора Maxima в Lisp будет всегда определяться первым аргументом, вне зависимости от того, что происходит со вторым. Например, `x: 3.3; mode_identity (fixnum, x);` дает ошибку а `mode_identity (flonum, x)` возвращает 3.3. С этим связан ряд проблем, например, если известно, что `first (l)` возвращает число, то можно написать `mode_identity (number, first (l))`. Но более эффективно будет определить новый примитив

      firstnumb (x) ::= buildq ([x], mode_identity (number, first(x)));

  и использовать `firstnumb` всякий раз при обращении к первому элементу списка чисел.

  Категории:Трансляция и компиляция ·

Управляющая переменная: transcompile

  Значение по умолчанию: `true`

  Если `transcompile` равно `true`, то `translate` и `translate_file` создают декларации, которые делают транслируемый код более удобным для компиляции.

  Функция `compfile` устанавливает `transcompile: true` на время своей работы.

  Категории:Переменные и флаги трансляции ·

Функция: translate (f_1, ..., f_n)
Функция: translate (functions)
Функция: translate (all)

  Транслирует определенные пользователем функции f_1, ..., f_n из языка Maxima в Lisp и вычисляет результат трансляции. Обычно, транслированные функции работают быстрее оригиналов.

  Вызов `translate (all)` или `translate (functions)` транслирует все определенные пользователем функции.

  Транслируемые функции должны, где это возможно, содержать в начале кода вызовы `mode_declare`, для генерации более эффективного кода.

  Например:

      f (x_1, x_2, ...) := block ([v_1, v_2, ...],
          mode_declare (v_1, mode_1, v_2, mode_2, ...), ...)

  где x_1, x_2, ... – параметры функции, а v_1, v_2, ... – локальные переменные.

  Имена транслированных функций удаляются из списка `functions` если значение `savedef` равно `false` (см. ниже) и добавляются к списку `props`.

  Не следует транслировать недостаточно отлаженные функции.

  При трансляции, выражения предполагаются уже упрощенными. Если это не так, то будет сгенерирован правильный но неоптимальный код. Таким образом, не следует устанавливать переключатель `simp` равным `false`, что подавляет упрощение транслируемых выражений.

  Если переключатель `translate` равен `true`, то все определяемые пользователем функции автоматически транслируются в Lisp.

  Отметим, что транслируемые функции могут работать не совсем так, как до трансляции, т.к. существуют некоторые несовместимости между Lisp и Maxima версиями функции. Главным образом, функция `rat`, имеющая более одного параметра, и функция `ratvars` не должны использоваться, если некоторые переменные объявлены `mode_declare` каноническими рациональными выражениями (КРВ). Кроме того, `prederror: false` не транслируется.

  Если `savedef` равна `true`, то Maxima версия сохраняется при трансляции. Это позволяет выводить определение функции при помощи `dispfun` и редактировать его.

  Если `transrun` равна `false`, то интерпретируемые варианты будут выполняться (если они еще доступны) вместо транслированных для всех вызовов функций.

  Функция `translate` возвращает список транслированных функций.

  Категории:Трансляция и компиляция ·

Функция: translate_file (maxima_filename)
Функция: translate_file (maxima_filename, lisp_filename)

  Транслирует файл кода Maxima в файлд кода Lisp. Функция `translate_file` возвращает список трех имен файлов: имя файла Maxima, имя файла Lisp и имя файла, содержащего дополнительную информацию о трансляции. Функция `translate_file` вычисляет свои аргументы.

  Команды `translate_file ("foo.mac"); load("foo.LISP")` дают тот же результат, что и `batch ("foo.mac")` за исключением некоторых ограничений, например, на использование `''` и `%`.

  Вызов `translate_file (maxima_filename)` транслирует файл Maxima maxima_filename в Lisp файл с аналогичным именем. Например, `foo.mac` транслируется в `foo.LISP`. Имя файла Maxima может включать имена директорий, и результирующий Lisp файл будет записан в ту же директорию, где располагается исходный файл Maxima.

  Вызов `translate_file (maxima_filename, lisp_filename)` транслирует файл Maxima maxima_filename в Lisp файл lisp_filename. `translate_file` игнорирует расширение имени файла для `lisp_filename`, если таковое задано. Расширение Lisp файла всегда будет `LISP`. Имя Lisp файла может содержать имена директорий, и в этом случае файл будет записан в заданную директорию.

  `translate_file` также записывает файл предупреждений транслятора, разной степени важности. Расширение имени этого файла – `UNLISP`. Этот файл может содержать ценную информацию, возможно туманную, для обнаружения ошибок в транслированном коде. Файл `UNLISP` всегда записывается в ту же директорию, где расположен исходный файл Maxima.

  `translate_file` генерирует код, в котором некоторые декларации и определения вступают в силу сразу в процессе компиляции Lisp кода. См. также `compile_file` по этому поводу.

  См. также `tr_array_as_ref`, `tr_bound_function_applyp`, `tr_exponent`, `tr_file_tty_messagesp`, `tr_float_can_branch_complex`, `tr_function_call_default`, `tr_numer`, `tr_optimize_max_loop`, `tr_semicompile`, `tr_state_vars`, `tr_warnings_get`, `tr_warn_bad_function_calls`, `tr_warn_fexpr`, `tr_warn_meval`, `tr_warn_mode`, `tr_warn_undeclared`, `tr_warn_undefined_variable` и `tr_windy`.

  Категории:Трансляция и компиляция ·

Управляющая переменная: transrun

  Значение по умолчанию: `true`

  Если `transrun` равна `false`, то для всех функций интерпретируемые варианты будут выполняться (если они еще доступны) вместо транслированных.

  Категории:Переменные и флаги трансляции ·

Управляющая переменная: tr_array_as_ref

  Значение по умолчанию: `true`

  Если `translate_fast_arrays` равна `false`, то ссылки на массивы в Lisp коде, созданном `translate_file`, зависят от `tr_array_as_ref`. Если `tr_array_as_ref` равна `true`, то имена массивов вычисляются, иначе они рассматриваются в транслированном коде как буквальные символы.

  `tr_array_as_ref` не действует если `translate_fast_arrays` равна `true`.

  Категории:Переменные и флаги трансляции ·

Управляющая переменная: tr_bound_function_applyp

  Значение по умолчанию: `true`

  Если `tr_bound_function_applyp` равна `true`, то Maxima выдает предупреждение, если имеющая значение переменная (такая, как аргумент функции) используется как имя функции.

  Например, выражение `g (f, x) := f (x+1)` вызовет предупреждение.

  Категории:Переменные и флаги трансляции ·

Управляющая переменная: tr_file_tty_messagesp

  Значение по умолчанию: `false`

  Если `tr_file_tty_messagesp` равна `true`, то сообщения, генерируемые `translate_file` в процессе трансляции, отображаются на консоли и выводятся в UNLISP файл. Если `false`, то сообщения выводятся только в UNLISP файл.

  Категории:Переменные и флаги трансляции ·

Управляющая переменная: tr_float_can_branch_complex

  Значение по умолчанию: `true`

  Сообщает Maxima-Lisp транслятору, что функции `acos`, `asin`, `asec` и `acsc` могут возвращать комплексные значения.

  Эффект `tr_float_can_branch_complex` заключается в следующем. Хотя, явного влияния на результат трансляции нет, но если этот флаг равен `true`, то `acos(x)` имеет тип `any`, даже если `x` имеет тип `float` (как определено `mode_declare`). Если ли же он равен `false`, то `acos(x)` имеет тип `float` тогда и тоько тогда, когда `x` имеет тип `float`.

  Категории:Переменные и флаги трансляции ·

Управляющая переменная: tr_function_call_default

  Значение по умолчанию: `general`

  Если равна `false`, то следует вызывать `meval`; если `expr`, то предполагать Lisp функцию с фиксированными аргументами; если `general`, то генерируется код, подходящий для `mexprs` и `mlexprs` но не `macros`. `general` обеспечивает правильное связывание переменных в компилируемом коде. В режиме `general`, при трансляции F(X), если F является связанной переменной, то предполагается `apply (f, [x])`, и в таком виде транслируется с печатью соответствующего предупреждения. Нет необходимости выключать этот механизм. С установками по умолчанию, отсутствие предупреждений не означает полную совместимость транслированного и интерпретируемого кода.

  Категории:Переменные и флаги трансляции ·

Управляющая переменная: tr_numer

  Значение по умолчанию: `false`

  Если `tr_numer` равна `true`, то для атомов, имеющих свойство `numer`, например, `%pi`, это свойство принимается во внимание транслятором.

  Категории:Переменные и флаги трансляции ·

Управляющая переменная: tr_optimize_max_loop

  Значение по умолчанию: 100

  `tr_optimize_max_loop` есть максимальное число раз, которое цикл макро-расширения и оптимизации транслятора будет повторен при трансляции формы. Данный предел установлен для обнаружения ошибок макро-расширения и зацикливания оптимизатора.

  Категории:Переменные и флаги трансляции ·

Управляющая переменная: tr_semicompile

  Значение по умолчанию: `false`

  Если `tr_semicompile` равна `true`, то `translate_file` и `compfile` генерируют формы, которые будут макро-расширены но не скомпилированы в машинный код Lisp компилятором.

  Категории:Переменные и флаги трансляции ·

Системная переменная: tr_state_vars

  Значение по умолчанию:

      [transcompile, tr_semicompile, tr_warn_undeclared, tr_warn_meval,
      tr_warn_fexpr, tr_warn_mode, tr_warn_undefined_variable,
      tr_function_call_default, tr_array_as_ref,tr_numer]

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

  Категории:Переменные и флаги трансляции ·

Функция: tr_warnings_get ()

  Печатает список предупреждений, сгенерированных транслятором в процессе текущей трансляции.

  Категории:Трансляция и компиляция ·

Управляющая переменная: tr_warn_bad_function_calls

  Значение по умолчанию: `true`

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

  Категории:Переменные и флаги трансляции ·

Управляющая переменная: tr_warn_fexpr

  Значение по умолчанию: `compfile`

  – выдает предупреждение если встречается FEXPR. Обычно, FEXPR не должны присутствовать в транслированном коде.

  Категории:Переменные и флаги трансляции ·

Управляющая переменная: tr_warn_meval

  Значение по умолчанию: `compfile`

  – выдает предупреждение при вызове функции `meval`. Вызов `meval` означает проблему в транслированном коде.

  Категории:Переменные и флаги трансляции ·

Управляющая переменная: tr_warn_mode

  Значение по умолчанию: `all`

  – выдает предупреждение, когда переменной присваивается значение, несовместимое с ее типом.

  Категории:Переменные и флаги трансляции ·

Управляющая переменная: tr_warn_undeclared

  Значение по умолчанию: `compile`

  – управляет тем, когда печатать сообщения о необъявленных переменных.

  Категории:Переменные и флаги трансляции ·

Управляющая переменная: tr_warn_undefined_variable

  Значение по умолчанию: `all`

  – печатает предупреждение, когда встречается необъявленная переменная.

  Категории:Переменные и флаги трансляции ·

Управляющая переменная: tr_windy

  Значение по умолчанию: `true`

  – вызывает печать полезных комментариев и советов по программированию.

  Категории:Переменные и флаги трансляции ·

Функция: compile_file (filename)
Функция: compile_file (filename, compiled_filename)
Функция: compile_file (filename, compiled_filename, lisp_filename)

  Транслирует файл Maxima filename в Lisp, выполняет компилятор Lisp и, если трансляция и компиляция успешны, то загружает скомпилированный код в Maxima.

  `compile_file` возвращает список имен четырех файлов: изначального файла кода Maxima, транслированного Lisp файла, файла замечаний по трансляции и файла скомпилированного кода. Если компиляция неуспешна, то последний элемент равен `false`.

  Некоторые декларации и определения активизируются сразу в процессе компиляции Lisp кода (без загрузки скомпилированного кода). Сюда относятся функции, определенные при помощи оператора `:=`, макросы, определенные при помощи `::=`, `alias`, `declare`, `define_variable`, `mode_declare` и `infix`, `matchfix`, `nofix`, `postfix`, `prefix` а также `compfile`.

  Присваивания и вызовы функций не вычисляются до загрузки скомпилированного файла. В частности, присваивания флагам трансляции (`tr_numer` и т.п.) внутри Maxima файла не оказывают влияния на результат трансляции.

  Файл filename не может содержать специальные `:lisp` команды.

  Функция `compile_file` вычисляет свои аргументы.

  Категории:Трансляция и компиляция ·

Функция: declare_translated (f_1, f_2, ...)

  При трансляции кода Maxima в код Lisp, транслятору важно знать, какие функции следует вызывать как транслированные или компилированные, а какие как обычные Maxima функции или неопределенные. Данная декларация, помещенная в начале транслируемого файла, дает транслятору информацию, что хотя f_n и не имеет свойство Lisp функции во время трансляции, но будет иметь таковое в момент вызова. Если транслятор не знает, что `fn` будет Lisp функцией, то генерируется код `(MFUNCTION-CALL fn arg1 arg2 ...)`.

  Категории:Трансляция и компиляция ·

Previous: Макросы, Up: Определение функций [Contents][Index]