1 <?xml version="1.0" encoding="UTF-8"?>
3 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
4 * Copyright (C) XXXX-2008 - INRIA
5 * Copyright (C) 2012 - 2016 - Scilab Enterprises
6 * Copyright (C) 2018 - 2020 - Samuel GOUGEON
8 * This file is hereby licensed under the terms of the GNU GPL v2.0,
9 * pursuant to article 5.3.4 of the CeCILL v.2.1.
10 * This file was originally licensed under the terms of the CeCILL v2.1,
11 * and continues to be available under such terms.
12 * For more information, see the COPYING file which you should have received
13 * along with this program.
16 <refentry xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink"
17 xmlns:svg="http://www.w3.org/2000/svg" xmlns:mml="http://www.w3.org/1998/Math/MathML"
18 xmlns:db="http://docbook.org/ns/docbook" xmlns:scilab="http://www.scilab.org"
19 xml:lang="ru" xml:id="deff">
21 <refname>deff</refname>
23 вставленное определение (анонимной) функции на языке Scilab
27 <title>Синтаксис</title>
29 deff(funcHeadline, funcBody)
31 deff("[r1, r2, ...] = myFunc(in1, in2, ...)", funcBody)
32 deff "r = myFunc(x,y) r = x^2 - y"
33 deff "r = myFunc(x,y) x^2 - y"
34 deff("r = @(x,y) x^2 - y") // в качестве элемента анонимного контейнера
36 myFunc = deff(funcHeadline, funcBody)
37 myFunc = deff(definition)
38 myFunc = deff("[r1, r2, ...] = fakeName(in1, in2, ...)", funcBody)
39 myFunc = deff("r = fakeName(x,y) r = x^2 - y")
40 myFunc = deff("r = fakeName(x,y) x^2 - y")
41 myFunc = deff("r = @(x,y) x^2 - y")
45 <title>Аргументы</title>
48 <term>x, y, in1, in2, ...</term>
50 входные аргументы определяемой функции. Последняя может иметь
51 любое количество входных аргументов, от 0 до любого N.
56 <term>r, r1, r2, ...</term>
58 результаты на выходе определяемой функции. Последняя может
59 иметь любое количество результатов на выходе, от 0 до любого
60 M. Все выходные аргументы должны быть явными, то есть,
61 записанными слева от имени функции.
66 <term>funcHeadline</term>
68 одиночная строка: заголовок функции, то есть, её первая строчка,
69 указывающая локальное имя функции и списки её входных аргументов
70 с правой стороны и выходных аргументов с левой стороны. Примеры:
73 <literal>"myFunction(x,y)"</literal> : нет аргументов на выходе
76 <literal>"r = myFunction(x,y)"</literal> : один аргумент на выходе
79 <literal>"[a,b] = myFunction(x,y)"</literal> : два аргумента
83 Пожалуйста, обратите внимание, что a) ключевое слово <literal>function</literal>
84 не обязательно указывать. b) запись выходных аргументов, если они есть, на левой
85 части заголовочной строчки является обязательной.
92 вектор текстов, то есть Scilab-инструкций тела функции, в том
93 порядке, в котором они должны быть выполнены. Эти инструкции
94 должны определять и назначать значения всех выходных аргументов.
95 Завершающее ключевое слово "endfunction" не ожидается.
97 Этот вектор ожидается, когда <literal>deff(…)</literal> вызывается
98 с двумя входными аргументами.
101 Одинарные или двойные кавычки внутри инструкций должны
102 дублироваться для защиты.
108 <term>definition</term>
110 Отдельный текст или вектор текстов, включая как заголовочную
111 строчку функции, так и тело.
114 Если это вектор, то это эквивалентно
115 <literal>definition = [funcHeadline ; funcBody]</literal>.
118 В противном случае одностроковое определение эквивалентно
119 <literal>funcHeadline + " " + strcat(funcBody,"; ")</literal>.
122 Пожалуйста, смотрите разделы "Описание" и "Примеры".
129 Публичное имя и идентификатор определяемой функции, неявно
130 возвращаемый в текущее окружение, либо явно присваиваемый
131 переменной на выходе <literal>deff(…)</literal>.
134 Когда <literal>deff(…)</literal> вызывается без явных выходных
135 аргументов, но в качестве элемента контейнера или в качестве
136 входного аргумента другой функции, то она неявно присваивается
137 этому элементу или аргументу, который является анонимным. То
139 <emphasis role="bold">анонимной функцией</emphasis>. Например:
141 <literal>L = list(3, deff("r=noName(x) x.^2+1"), "Hello");</literal>.
142 Результат <literal>deff(…)</literal> присваивается <literal>L(2)</literal>.
143 Тогда <literal>L(2)(3.5) // ➜ 13.25</literal>.
151 <title>Описание</title>
153 <literal>deff(…)</literal> может использоваться для определения
154 <emphasis>отдельной</emphasis> функции из инструкций Scilab, указанных
155 через матрицу текстов, вместо любого внешнего текстового файла с
156 инструкциями для исполнения, записанными в блок <literal>function … endfunction</literal>.
159 Файл исходного Scilab-кода может включать в себя определение нескольких
160 публичных функций. Это не возможно сделать с помощью <literal>deff(…)</literal>:
161 только одну публичную функцию можно определить. Однако, как и в случае
162 с файлом, тело определяемой функции может включать в себя один или
163 несколько блоков <literal>function … endfunction</literal>, определяющих
164 вложенные приватные функции.
167 Независимо от синтаксиса <literal>deff(…)</literal>, используемого для
168 обеспечения исходного кода (см. ниже), если он содержит синтаксическую
169 ошибку, то <literal>deff(…)</literal> выдаст ошибку компиляции
173 <title>Указание исходного кода</title>
175 <emphasis role="bold">deff(funcHeadline, funcBody)</emphasis> (2 входа) и
176 <emphasis role="bold">deff([funcHeadline ; funcBody])</emphasis>
177 (единый конкатенированный вход) эквивалентны.
180 Когда <varname>funcBody</varname> сделана только из одной (короткой)
181 строки, она может быть приклеена и передана вместе с
182 <varname>funcHeadline</varname>, как одностроковое определение функции.
184 <table cellpadding="0" cellspacing="0">
185 <tr><td><literal>deff("[a,b] = myFunction(x,y) a = x.^2; b = x-y;")</literal></td>
188 <literal>deff("r = myFunction(x,y) r = (x-y).^2")</literal>.
189 Это можно даже упростить до
193 <literal>deff("r = myFunction(x,y) (x-y).^2")</literal>
196 <tr><td><literal>deff("myFunction(x,y) disp(x.^2 - b)")</literal></td>
201 Когда результат <literal>deff(…)</literal> присваивается или вводится
202 в любой анонимный контейнер, то оказывается, что псевдоимя
203 <varname>fakeName</varname>, определённое в <varname>funcHeadline</varname>
204 не играет роли вообще, и может совсем не использоваться для вызова
205 функции. Это имя может быть тогда заменено символом "@" в
206 <varname>funcHeadline</varname> для указания, что определяемая
207 функция становится <emphasis>анонимной</emphasis>.
211 <title>Идентификатор определяемой функции</title>
213 Идентификатор - это фактическое слово (имя), которое используется
214 для вызова определяемой функции. Следующие три случая представлены
218 Когда определяемая функция не предполагает присваиваемый результат,
219 то её идентификатор возвращается напрямую в вызывающее окружение.
220 Её публичное имя тогда является именем, используемым в заголовочной
221 строчке представленного исходного кода.
224 В противном случае, когда <literal>deff(…)</literal> вызывается с
225 явным выходным аргументом, то его имя становится единственным
226 фактическим идентификатором публичной функции. В результате, имя
227 функции, используемой в исходном коде, нельзя использовать для её
228 вызова. Оно становится псевдоименем. По этой причине в заголовочной
229 строчке может быть использован символ "@" (ставящийся для "анонимок")
230 вместо какого-либо корректного имени функции, определённой в заголовочной
231 строчке. Но это не обязательно.
234 Последний случай использования <literal>deff(…)</literal> в качестве
235 элемента контейнера, например когда определяется или вводится в список,
236 либо в качестве входного аргумента другой функции. Тогда
237 <literal>deff(…)</literal> работает как присвоение. Она возвращает
238 идентификатор определяемой функции и присваивает его соответствующему
239 элементу списка или входного аргумента. Они безымянны, следовательно
240 вызов <literal>deff(…)</literal> является выражением. Определяемая
241 функция тогда становиться реально <emphasis>анонимной</emphasis>.
246 <title>Примеры</title>
248 <title>Неприсваивающие функции</title>
250 <programlisting role="example"><![CDATA[
251 deff('x = myplus(y,z)', 'x = y+z')
254 deff('[y, z] = mymacro(x)', ['y = 3*x+1'; 'z = a*x + x.^2'])
259 --> deff('x = myplus(y,z)', 'x = y+z')
264 --> deff('[y, z] = mymacro(x)', ['y = 3*x+1'; 'z = a*x + x.^2'])
266 --> [u, v] = mymacro(2)
274 С единственным входным и выходным аргументом:
276 <programlisting role="example"><![CDATA[
278 source = ["r = myFunc(x,y)" ; "r = x.*(x-y)"]
283 --> source = ["r = myFunc(x,y)" ; "r = x.*(x-y)"]
294 Тот же пример с одностроковым определением, которое затем позволяет
295 синтаксис, ориентированный на командную строку (без необязательных
296 скобок deff, но с, по-прежнему, обязательными разделительными кавычками):
298 <programlisting role="example"><![CDATA[
300 deff "r = myFunc(x,y) r = x.*(x-y)"
304 --> deff "r = myFunc(x,y) r = x.*(x-y)"
310 Для однострокового прямого определения с единственным выходным аргументом,
311 мы можем даже опустить дубликат "r = " в теле функции:
313 <programlisting role="example"><![CDATA[
315 deff "r = myFunc(x,y) x.*(x-y)"
319 --> deff "r = myFunc(x,y) x.*(x-y)"
325 Функция без присваиваемого выходного аргумента: обратите также внимание
326 на использование удвоенных кавычек для защиты их в строке определения:
328 <programlisting role="example"><![CDATA[
330 deff("myFunc(x, y) messagebox(prettyprint(x.*(x-y), ""html"",""""))")
331 myFunc([1 2 ; 3 4], -2)
335 <title>Определяемая функция, присваиваемая реципиенту</title>
337 Придержимся примеров, похожих на приведённые выше:
339 <programlisting role="example"><![CDATA[
340 clear myFunc actualName
341 actualName = deff("r = myFunc(x,y) x.*(x-y)")
342 isdef(["myFunc" "actualName"])
347 --> actualName = deff("r = myFunc(x,y) x.*(x-y)")
351 --> isdef(["myFunc" "actualName"])
355 --> actualName(1:3, -2)
360 Undefined variable: myFunc
363 Поскольку имя "внутренней" функции является псевдоименем, то мы
364 можем вместо него использовать "@" (символ "@" нельзя использовать
365 в фактических именах функций):
367 <programlisting role="example"><![CDATA[
369 actualName = deff("r = @(x,y) x.*(x-y)");
373 --> actualName = deff("r = @(x,y) x.*(x-y)");
374 --> actualName(1:3, -2)
379 Теперь напрямую присвоим созданную функцию безымянному реципиенту.
380 Хотя функция становится анонимной, мы, по-прежнему, можем вызывать её:
382 <programlisting role="example"><![CDATA[
383 L = list("abc", deff("r = @(x,y) x.*(x-y)"), %z);
385 // Мы можем извлекать и устанавливать имя анонимной функции:
390 --> L = list("abc", deff("r = @(x,y) x.*(x-y)"), %z);
391 --> L(2)(1.1:4, -2.1)
404 Наконец, давайте используем <literal>deff()</literal> для прямого
405 определения и передачи функции в качестве входного элемента другой
408 <programlisting role="example"><![CDATA[
409 function r = test(txt, x, theFunc)
413 test(rand(2,3), 0.7, deff("r = @(M) sum(size(M).^2)"))
416 --> test(rand(2,3), 0.7, deff("r = @(M) sum(size(M).^2)"))
421 В этом примере передаваемая функция является анонимной в вызывающем
422 окружении, но присваивается и получает своё имя "theFunct" внутри
427 <refsection role="see also">
428 <title>Смотрите также</title>
429 <simplelist type="inline">
431 <link linkend="function">function</link>
434 <link linkend="exec">exec</link>
437 <link linkend="getd">getd</link>
440 <link linkend="genlib">genlib</link>
443 <link linkend="jdeff">jdeff</link>
446 <link linkend="jcompile">jcompile</link>
450 <refsection role="history">
451 <title>История</title>
454 <revnumber>6.0.0</revnumber>
459 <ulink url="https://help.scilab.org/docs/5.5.2/en_US/deff.html">
460 <varname>opt="c"|"p"|"n"</varname>
461 </ulink> больше не доступна.
464 Определяемая <varname>newfunction</varname> теперь имеет
471 <revnumber>6.1.1</revnumber>
475 Добавлен необязательный выходной аргумент. Могут определяться
479 Поддерживаются одиночные входные аргументы, конкатенирующие
480 заголовочную строку функции и её тело.
483 Поддерживается синтаксис одиночной строки, вроде
484 <literal>deff "r = myFun(x,y) x.^2-y"</literal>
487 Поддерживается псевдоимя функции "@".