* `polyint` is introduced to compute polynomial antiderivatives.
* Listbox uicontrol callback is now triggered by item click in single selection mode. For example, it allows successive execution of a demo in the demonstrations gui.
* `det` is now actually extended to sparse matrices.
+* `deff` is upgraded:
+ - The created function may be returned as output argument.
+ - Providing the function headline and body concatenated in a single input text vector is possible.
+ - For a simple function, a single string input definition can be provided.
+ - For assignable calls to `deff`, the `@` symbol can be used as function pseudo-name.
Help pages:
* [#16458](https://bugzilla.scilab.org/16458): `mean()` did not handle sparse numerical matrices.
* [#16465](https://bugzilla.scilab.org/16465): Scinotes OpenRecent menu was not updated when it should.
* [#16473](https://bugzilla.scilab.org/16473): Deleting rows in a sparse squared the matrix with padding zeros (Scilab 6 regression).
+<<<<<<< HEAD
* [#16474](https://bugzilla.scilab.org/16474): `imult(%z)` crashed Scilab.
* [#16476](https://bugzilla.scilab.org/16476): `issquare` was not overloaded.
* [#16488](https://bugzilla.scilab.org/16488): Concatenations mixing boolean and double with at least one operand being sparse were not supported.
=======
>>>>>>> afb92ac5368 (* Bug 16614 fixed: replot() could fail out of gcf())
+=======
+* [#16529](https://bugzilla.scilab.org/16529): `deff` could not return the created function as output argument, preventing to cretae and use anonymous functions. The function's headline and body had to be provided separately. For Simple functions, a one-string input (possibly console-oriented) definition was not supported.
+
+>>>>>>> 75a0ccd0638 (* Bug 16529 fixed: deff() upgraded: output arg added, one-string def, etc)
### Bugs fixed in 6.1.0:
* [#2694](https://bugzilla.scilab.org/2694): `bitget` did not accept positive integers of types int8, int16 or int32.
<!--
* Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
* Copyright (C) XXXX-2008 - INRIA
- * Copyright (C) 2018 - Samuel GOUGEON
- *
* Copyright (C) 2012 - 2016 - Scilab Enterprises
+ * Copyright (C) 2018 - 2020 - Samuel GOUGEON
*
* This file is hereby licensed under the terms of the GNU GPL v2.0,
* pursuant to article 5.3.4 of the CeCILL v.2.1.
xml:lang="en" xml:id="deff">
<refnamediv>
<refname>deff</refname>
- <refpurpose>in-line definition of a function in Scilab language</refpurpose>
+ <refpurpose>in-line definition of a (anonymous) function in Scilab language</refpurpose>
</refnamediv>
<refsynopsisdiv>
<title>Syntax</title>
- <synopsis>deff('[s1, s2, ...] = newfunction(e1, e2, ...)',text)</synopsis>
+ <synopsis>
+ deff(funcHeadline, funcBody)
+ deff(definition)
+ deff("[r1, r2, ...] = myFunc(in1, in2, ...)", funcBody)
+ deff "r = myFunc(x,y) r = x^2 - y"
+ deff "r = myFunc(x,y) x^2 - y"
+ deff("r = @(x,y) x^2 - y") // as anonymous container's element
+
+ myFunc = deff(funcHeadline, funcBody)
+ myFunc = deff(definition)
+ myFunc = deff("[r1, r2, ...] = fakeName(in1, in2, ...)", funcBody)
+ myFunc = deff("r = fakeName(x,y) r = x^2 - y")
+ myFunc = deff("r = fakeName(x,y) x^2 - y")
+ myFunc = deff("r = @(x,y) x^2 - y")
+ </synopsis>
</refsynopsisdiv>
<refsection>
<title>Arguments</title>
<variablelist>
<varlistentry>
- <term>e1, e2, ...</term>
+ <term>x, y, in1, in2, ...</term>
+ <listitem>
+ input arguments of the defined function. This one can have any number
+ of input arguments, from 0 to any N.
+ <para/>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>r, r1, r2, ...</term>
<listitem>
- <para>input variables.</para>
+ Output results of the defined function. This one can have any number
+ of output results, from 0 to any M. If any, all output arguments
+ must be explicit = written on the left-hand-side of the function name.
+ <para/>
</listitem>
</varlistentry>
<varlistentry>
- <term>s1, s2, ...</term>
+ <term>funcHeadline</term>
<listitem>
- <para>output variables.</para>
+ Single string: Function's headline = its first line giving the local
+ function's name and the lists of its right-hand-side input arguments
+ and left-hand-side output arguments. Examples:
+ <itemizedlist>
+ <listitem>
+ <literal>"myFunction(x,y)"</literal> : no output
+ </listitem>
+ <listitem>
+ <literal>"r = myFunction(x,y)"</literal> : single output
+ </listitem>
+ <listitem>
+ <literal>"[a,b] = myFunction(x,y)"</literal> : two outputs. Etc..
+ </listitem>
+ </itemizedlist>
+ Please note that a) the <literal>function</literal> keyword
+ must not be provided. b) If any, writting output arguments in the
+ left-hand-side part of the headline is mandatory.
+ <para/>
</listitem>
</varlistentry>
<varlistentry>
- <term>text</term>
+ <term>funcBody</term>
<listitem>
- <para>a matrix of character strings.</para>
+ a vector of texts = Scilab instructions of the function's body, in the order
+ they must be executed. These instructions must define and assign the value
+ of all output arguments. No trailing "endfunction" keyword is expected.
+ <para/>
+ This vector is expected when deff(…) is called with two input arguments.
+ <para/>
+ <warning>
+ Single or double quotes included in instructions must be doubled to be
+ protected.
+ </warning>
+ <para/>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>definition</term>
+ <listitem>
+ Single text or vector of texts, including both the function's headline and body.
+ <itemizedlist>
+ <listitem>
+ If it's a vector, it is equivalent to
+ <literal>definition = [funcHeadline ; funcBody]</literal>.
+ </listitem>
+ <listitem>
+ Otherwise, the one-string definition is equivalent to
+ <literal>funcHeadline + " " + strcat(funcBody,"; ")</literal>.
+ </listitem>
+ </itemizedlist>
+ Please see the Description and Examples sections.
+ <para/>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>myFunc</term>
+ <listitem>
+ Public name and identifier of the defined function, as implicitly
+ returned in the current environment, or explicitly assigned to the
+ deff(…)'s output variable.
+ <para/>
+ <note>
+ When deff(…) is called without explicit output argument but
+ as an element of a container or as input argument of another function,
+ it is implicitly assigned to this element or argument,
+ which is anonymous. It is then an
+ <emphasis role="bold">anonymous function</emphasis>. Example:
+ <para/>
+ <literal>L = list(3, deff("r=noName(x) x.^2+1"), "Hello");</literal>.
+ The result of deff(…) is assigned to L(2). Then,
+ <literal>L(2)(3.5) // ➜ 13.25</literal>.
+ </note>
+ <para/>
</listitem>
</varlistentry>
</variablelist>
<refsection>
<title>Description</title>
<para>
- <function>deff</function> can be used to define functions from sequences of instructions
- written in text strings. The resulting function object has the same properties
- of any other function defined in a text file and loaded with <function>exec</function>.
+ deff(…) can be used to define a <emphasis>single</emphasis> function from Scilab
+ instructions provided through a matrix of text, instead of through any external
+ text file of instructions written in a <literal>function … endfunction</literal>
+ block to be executed.
</para>
- <warning>
- Quotes included in instructions given in strings must be doubled to be protected.
- </warning>
+ <para>
+ A source file of Scilab code can include the definition of several public functions.
+ This is not possible with deff(…): Only one public function can be defined.
+ However, as with a file, the body of the defined function can include one
+ or several <literal>function … endfunction</literal> blocks defining
+ some nested private functions.
+ </para>
+ <para>
+ Whatever is the deff(…) syntax used to provide the source code (see below), if this one
+ includes a syntax error, deff(…) will yield a compilation error and stop.
+ </para>
+ <refsect3>
+ <title>Providing the source code</title>
+ <para>
+ <emphasis role="bold">deff(funcHeadline, funcBody)</emphasis> (2 inputs) and
+ <emphasis role="bold">deff([funcHeadline ; funcBody])</emphasis>
+ (single concatenated input) are equivalent.
+ </para>
+ <para>
+ When <varname>funcBody</varname> is made of only one (short) string, it may be glued
+ to and passed with the <varname>funcHeadline</varname>, as a one-line function
+ definition. Examples:
+ <table cellpadding="0" cellspacing="0">
+ <tr><td><literal>deff("[a,b] = myFunction(x,y) a = x.^2; b = x-y;")</literal></td>
+ </tr>
+ <tr><td>
+ <literal>deff("r = myFunction(x,y) r = (x-y).^2")</literal>.
+ This can even be simplified into
+ </td>
+ </tr>
+ <tr><td>
+ <literal>deff("r = myFunction(x,y) (x-y).^2")</literal>
+ </td>
+ </tr>
+ <tr><td><literal>deff("myFunction(x,y) disp(x.^2 - b)")</literal></td>
+ </tr>
+ </table>
+ </para>
+ <para>
+ When the result of deff(…) is assigned to or inserted into any anonymous element
+ of a container, then it comes that the pseudo-name <varname>fakeName</varname>
+ defined in the <varname>funcHeadline</varname>
+ has no role at all, and could in no way be used to call the function.
+ This name can then be replaced with the "@" character in the <varname>funcHeadline</varname>,
+ to highlight that the defined function becomes <emphasis>anonymous</emphasis>.
+ </para>
+ </refsect3>
+ <refsect3>
+ <title>Identifier of the defined function</title>
+ <para>
+ The identifier is the actual word (name) to use to call the defined function.
+ The 3 following cases are illustrated in examples.
+ </para>
+ <para>
+ When the defined function is not expected as a assignable result, its identifier
+ is returned directly in the calling environment. Its public name is then the name
+ used in the headline of the provided source code.
+ </para>
+ <para>
+ Otherwise, when deff(…) is called with an explicit output argument, the name
+ of this one becomes the only actual public function's identifier. As a consequence,
+ the function name used in the source code can't be used to call it. It becomes
+ a pseudo-name. For this reason, the "@" symbol (standing for "anonymous") can then
+ be used in the function code's headline, instead of any valid function's name.
+ Of course, nothing prevents to use an output name identical to any valid
+ function name defined in the headline. But it's not mandatory.
+ </para>
+ <para>
+ The last case is using deff(…) as an element of a container, for instance
+ when defining or inserting into a list, or as input argument of another function.
+ Then deff(…) works in an assignable way. It returns the identifier of the defined
+ function and assigns it to the considered list element or input argument.
+ These ones are nameless, since the <literal>deff(…)</literal> call is an expression.
+ The defined function then becomes really <emphasis>anonymous</emphasis>.
+ </para>
+ </refsect3>
</refsection>
<refsection>
<title>Examples</title>
- <programlisting role="example"><![CDATA[
-deff('x = myplus(y,z)', 'x = y+z')
-myplus(1,%i)
+ <refsect3>
+ <title>Unassigned functions</title>
+ <para/>
+ <programlisting role="example"><![CDATA[
+ deff('x = myplus(y,z)', 'x = y+z')
+ myplus(1,%i)
-deff('[y, z] = mymacro(x)', ['y = 3*x+1'; 'z = a*x + x.^2'])
-a = 3;
-[u, v] = mymacro(2)
- ]]></programlisting>
- <screen><![CDATA[
+ deff('[y, z] = mymacro(x)', ['y = 3*x+1'; 'z = a*x + x.^2'])
+ a = 3;
+ [u, v] = mymacro(2)
+ ]]></programlisting>
+ <screen><![CDATA[
--> deff('x = myplus(y,z)', 'x = y+z')
--> myplus(1,%i)
ans =
u =
7.
]]></screen>
+ <para>
+ With some single input and output:
+ </para>
+ <programlisting role="example"><![CDATA[
+ clear myFunc
+ source = ["r = myFunc(x,y)" ; "r = x.*(x-y)"]
+ deff(source)
+ myFunc(3, -2)
+ ]]></programlisting>
+ <screen><![CDATA[
+--> source = ["r = myFunc(x,y)" ; "r = x.*(x-y)"]
+ source =
+ "r = myFunc(x,y)"
+ "r = x.*(x-y)"
+
+--> deff(source)
+--> myFunc(3, -2)
+ ans =
+ 15.
+]]></screen>
+ <para>
+ Same example with a one-line definition, that then allows a console-oriented
+ syntax (without optional deff parentheses, but with still mandatory delimiting quotes):
+ </para>
+ <programlisting role="example"><![CDATA[
+ clear myFunc
+ deff "r = myFunc(x,y) r = x.*(x-y)"
+ myFunc(1:3, -2)
+ ]]></programlisting>
+ <screen><![CDATA[
+--> deff "r = myFunc(x,y) r = x.*(x-y)"
+--> myFunc(1:3, -2)
+ ans =
+ 3. 8. 15.
+]]></screen>
+ <para>
+ For a one-line direct definition with a single output, we can even omit the "r = " duplicate in the body:
+ </para>
+ <programlisting role="example"><![CDATA[
+ clear myFunc
+ deff "r = myFunc(x,y) x.*(x-y)"
+ myFunc(1:3, -2)
+ ]]></programlisting>
+ <screen><![CDATA[
+--> deff "r = myFunc(x,y) x.*(x-y)"
+--> myFunc(1:3, -2)
+ ans =
+ 3. 8. 15.
+]]></screen>
+ <para>
+ Function with no assignable output: Note also the usage of doubled quotes to protect
+ them in the definition string:
+ </para>
+ <programlisting role="example"><![CDATA[
+ clear myFunc
+ deff("myFunc(x, y) messagebox(prettyprint(x.*(x-y), ""html"",""""))")
+ myFunc([1 2 ; 3 4], -2)
+ ]]></programlisting>
+ </refsect3>
+ <refsect3>
+ <title>Defined function assigned to a recipient</title>
+ <para>
+ Let's keep similar examples as above:
+ </para>
+ <programlisting role="example"><![CDATA[
+ clear myFunc actualName
+ actualName = deff("r = myFunc(x,y) x.*(x-y)")
+ isdef(["myFunc" "actualName"])
+ actualName(1:3, -2)
+ myFunc(1:3, -2)
+ ]]></programlisting>
+ <screen><![CDATA[
+--> actualName = deff("r = myFunc(x,y) x.*(x-y)")
+ actualName =
+[r]=actualName(x,y)
+
+--> isdef(["myFunc" "actualName"])
+ ans =
+ F T
+
+--> actualName(1:3, -2)
+ ans =
+ 3. 8. 15.
+
+--> myFunc(1:3, -2)
+Undefined variable: myFunc
+]]></screen>
+ <para>
+ Since the "internal" function name is fake, we can use "@" instead
+ (the "@" character is not allowed in actual function names):
+ </para>
+ <programlisting role="example"><![CDATA[
+ clear actualName
+ actualName = deff("r = @(x,y) x.*(x-y)");
+ actualName(1:3, -2)
+ ]]></programlisting>
+ <screen><![CDATA[
+--> actualName = deff("r = @(x,y) x.*(x-y)");
+--> actualName(1:3, -2)
+ ans =
+ 3. 8. 15.
+]]></screen>
+ <para>
+ Now, let's directly assign the created function to a nameless recipient.
+ Although the function becomes anonymous, we can still call it:
+ </para>
+ <programlisting role="example"><![CDATA[
+ L = list("abc", deff("r = @(x,y) x.*(x-y)"), %z);
+ L(2)(1.1:4, -2.1)
+ // We can extract and set a name to the anonymous function:
+ Abc = L(2)
+ Abc(1.1:4, -2.1)
+ ]]></programlisting>
+ <screen><![CDATA[
+--> L = list("abc", deff("r = @(x,y) x.*(x-y)"), %z);
+--> L(2)(1.1:4, -2.1)
+ ans =
+ 3.52 8.82 16.12
+
+--> Abc = L(2)
+ Abc =
+[r]=Abc(x,y)
+
+--> Abc(1.1:4, -2.1)
+ ans =
+ 3.52 8.82 16.12
+]]></screen>
+ <para>
+ Finally, let's use deff() to directly define and pass a function
+ as an input argument of another function:
+ </para>
+ <programlisting role="example"><![CDATA[
+ function r = test(txt, x, theFunc)
+ r = x + theFunc(txt)
+ endfunction
+
+ test(rand(2,3), 0.7, deff("r = @(M) sum(size(M).^2)"))
+ ]]></programlisting>
+ <screen><![CDATA[
+--> test(rand(2,3), 0.7, deff("r = @(M) sum(size(M).^2)"))
+ ans =
+ 13.7
+]]></screen>
+ <para>
+ In this example, the passed function is anonymous in the calling environment,
+ but is assigned and gets its "theFunct" name from inside the called function.
+ </para>
+ </refsect3>
</refsection>
<refsection role="see also">
<title>See also</title>
</itemizedlist>
</revdescription>
</revision>
+ <revision>
+ <revnumber>6.1.1</revnumber>
+ <revdescription>
+ <itemizedlist>
+ <listitem>
+ Output optional argument added. Anonymous functions can be defined.
+ </listitem>
+ <listitem>
+ Single input argument supported, concatenating the function headline and body.
+ </listitem>
+ <listitem>
+ Single string syntax supported, like <literal>deff "r = myFun(x,y) x.^2-y"</literal>
+ </listitem>
+ <listitem>
+ "@" function's pseudo-name supported.
+ </listitem>
+ </itemizedlist>
+ </revdescription>
+ </revision>
</revhistory>
</refsection>
</refentry>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- * Copyright (C) XXXX-2008 - INRIA
- * Copyright (C) 2018 - Samuel GOUGEON
- *
- * Copyright (C) 2012 - 2016 - Scilab Enterprises
- *
- * This file is hereby licensed under the terms of the GNU GPL v2.0,
- * pursuant to article 5.3.4 of the CeCILL v.2.1.
- * This file was originally licensed under the terms of the CeCILL v2.1,
- * and continues to be available under such terms.
- * For more information, see the COPYING file which you should have received
- * along with this program.
- *
- -->
-<refentry xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink"
- xmlns:svg="http://www.w3.org/2000/svg" xmlns:mml="http://www.w3.org/1998/Math/MathML"
- xmlns:db="http://docbook.org/ns/docbook" xmlns:scilab="http://www.scilab.org"
- xml:lang="ja" xml:id="deff">
- <refnamediv>
- <refname>deff</refname>
- <refpurpose>関数のオンライン定義</refpurpose>
- </refnamediv>
- <refsynopsisdiv>
- <title>呼び出し手順</title>
- <synopsis>deff('[s1, s2,...] = newfunction(e1, e2,...)',text)</synopsis>
- </refsynopsisdiv>
- <refsection>
- <title>引数</title>
- <variablelist>
- <varlistentry>
- <term>e1, e2, ...</term>
- <listitem>
- <para>入力変数.</para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>s1, s2, ...</term>
- <listitem>
- <para>出力変数.</para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>text</term>
- <listitem>
- <para>文字列行列</para>
- </listitem>
- </varlistentry>
- </variablelist>
- </refsection>
- <refsection>
- <title>説明</title>
- <para>
- <function>deff</function> はテキスト文字列で記述された一連の命令から
- 関数を定義する際に使用されます.
- 得られる関数オブジェクトはテキストファイルで定義され,
- <function>exec</function> または <function>exec</function> で
- 定義された他の関数と同じ特性を有しています.
- </para>
- <warning>>
- 命令の中の引用符(文字列の区切りまたは行列の転置を意味する)は,
- ただしく解釈されるように二重化する必要があります(<link linkend="quote">quote</link>のヘルプを参照).
- この仕様のため,作成作業はやや不便となります.
- </warning>
- </refsection>
- <refsection>
- <title>例</title>
- <programlisting role="example"><![CDATA[
-deff('x = myplus(y,z)', 'x = y+z')
-myplus(1,%i)
-
-deff('[y, z] = mymacro(x)', ['y = 3*x+1'; 'z = a*x + x.^2'])
-a = 3;
-[u, v] = mymacro(2)
- ]]></programlisting>
- <screen><![CDATA[
---> deff('x = myplus(y,z)', 'x = y+z')
---> myplus(1,%i)
- ans =
- 1. + i
-
---> deff('[y, z] = mymacro(x)', ['y = 3*x+1'; 'z = a*x + x.^2'])
---> a = 3;
---> [u, v] = mymacro(2)
- v =
- 10.
-
- u =
- 7.
-]]></screen>
- </refsection>
- <refsection role="see also">
- <title>参照</title>
- <simplelist type="inline">
- <member>
- <link linkend="function">function</link>
- </member>
- <member>
- <link linkend="exec">exec</link>
- </member>
- <member>
- <link linkend="getd">getd</link>
- </member>
- <member>
- <link linkend="genlib">genlib</link>
- </member>
- <member>
- <link linkend="jdeff">jdeff</link>
- </member>
- <member>
- <link linkend="jcompile">jcompile</link>
- </member>
- </simplelist>
- </refsection>
- <refsection role="history">
- <title>履歴</title>
- <revhistory>
- <revision>
- <revnumber>6.0.0</revnumber>
- <revdescription>
- <itemizedlist>
- <listitem>
- The input option
- <ulink url="https://help.scilab.org/docs/5.5.2/ja_JP/deff.html">
- <varname>opt="c"|"p"|"n"</varname>
- </ulink> is no longer available.
- </listitem>
- <listitem>
- The defined <varname>newfunction</varname> is now of type 13 (instead of 11).
- </listitem>
- </itemizedlist>
- </revdescription>
- </revision>
- </revhistory>
- </refsection>
-</refentry>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- * Copyright (C) XXXX-2008 - INRIA
- * Copyright (C) 2018 - Samuel GOUGEON
- *
- * Copyright (C) 2012 - 2016 - Scilab Enterprises
- *
- * This file is hereby licensed under the terms of the GNU GPL v2.0,
- * pursuant to article 5.3.4 of the CeCILL v.2.1.
- * This file was originally licensed under the terms of the CeCILL v2.1,
- * and continues to be available under such terms.
- * For more information, see the COPYING file which you should have received
- * along with this program.
- *
- -->
-<refentry xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink"
- xmlns:svg="http://www.w3.org/2000/svg" xmlns:ns3="http://www.w3.org/1999/xhtml"
- xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:db="http://docbook.org/ns/docbook"
- xmlns:scilab="http://www.scilab.org" xml:id="deff" xml:lang="pt">
- <refnamediv>
- <refname>deff</refname>
- <refpurpose>definição on-line de função</refpurpose>
- </refnamediv>
- <refsynopsisdiv>
- <title>Seqüência de Chamamento</title>
- <synopsis>deff('[s1, s2, ...] = newfunction(e1, e2,...)',text)</synopsis>
- </refsynopsisdiv>
- <refsection>
- <title>Parâmetros</title>
- <variablelist>
- <varlistentry>
- <term>e1, e2, ...</term>
- <listitem>
- <para>variáveis de entrada.</para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>s1, s2, ...</term>
- <listitem>
- <para>variáveis de saída.</para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>text</term>
- <listitem>
- <para>matriz de strings.</para>
- </listitem>
- </varlistentry>
- </variablelist>
- </refsection>
- <refsection>
- <title>Descrição</title>
- <para>
- <function>deff</function> pode ser usada para definir funções de
- seqüências de instruções escritas em strings de textos. Objeto função
- resultante tem as mesmas propriedades que qualquer outra função definida
- em um arquivo de texto e carregada através de <function>exec</function> ou
- <function>exec</function>.
- </para>
- </refsection>
- <refsection>
- <title>Exemplos</title>
- <programlisting role="example"><![CDATA[
-deff('x = myplus(y,z)', 'x = y+z')
-myplus(1,%i)
-
-deff('[y, z] = mymacro(x)', ['y = 3*x+1'; 'z = a*x + x.^2'])
-a = 3;
-[u, v] = mymacro(2)
- ]]></programlisting>
- <screen><![CDATA[
---> deff('x = myplus(y,z)', 'x = y+z')
---> myplus(1,%i)
- ans =
- 1. + i
-
---> deff('[y, z] = mymacro(x)', ['y = 3*x+1'; 'z = a*x + x.^2'])
---> a = 3;
---> [u, v] = mymacro(2)
- v =
- 10.
-
- u =
- 7.
-]]></screen>
- </refsection>
- <refsection role="see also">
- <title>Ver Também</title>
- <simplelist type="inline">
- <member>
- <link linkend="function">function</link>
- </member>
- <member>
- <link linkend="exec">exec</link>
- </member>
- <member>
- <link linkend="getd">getd</link>
- </member>
- <member>
- <link linkend="genlib">genlib</link>
- </member>
- <member>
- <link linkend="jdeff">jdeff</link>
- </member>
- <member>
- <link linkend="jcompile">jcompile</link>
- </member>
- </simplelist>
- </refsection>
- <refsection role="history">
- <title>Histórico</title>
- <revhistory>
- <revision>
- <revnumber>6.0.0</revnumber>
- <revdescription>
- <itemizedlist>
- <listitem>
- The input option
- <ulink url="https://help.scilab.org/docs/5.5.2/pt_BR/deff.html">
- <varname>opt="c"|"p"|"n"</varname>
- </ulink> is no longer available.
- </listitem>
- <listitem>
- The defined <varname>newfunction</varname> is now of type 13 (instead of 11).
- </listitem>
- </itemizedlist>
- </revdescription>
- </revision>
- </revhistory>
- </refsection>
-</refentry>
<!--
* Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
* Copyright (C) XXXX-2008 - INRIA
- * Copyright (C) 2018 - Samuel GOUGEON
- *
* Copyright (C) 2012 - 2016 - Scilab Enterprises
+ * Copyright (C) 2018 - 2020 - Samuel GOUGEON
*
* This file is hereby licensed under the terms of the GNU GPL v2.0,
* pursuant to article 5.3.4 of the CeCILL v.2.1.
*
-->
<refentry xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink"
- xmlns:svg="http://www.w3.org/2000/svg" xmlns:mml="http://www.w3.org/1998/Math/MathML"
- xmlns:db="http://docbook.org/ns/docbook" xmlns:scilab="http://www.scilab.org"
- xml:lang="ru" xml:id="deff">
+ xmlns:svg="http://www.w3.org/2000/svg" xmlns:mml="http://www.w3.org/1998/Math/MathML"
+ xmlns:db="http://docbook.org/ns/docbook" xmlns:scilab="http://www.scilab.org"
+ xml:lang="ru" xml:id="deff">
<refnamediv>
<refname>deff</refname>
<refpurpose>
- определение функции во время выполнения программы
+ вставленное определение (анонимной) функции на языке Scilab
</refpurpose>
</refnamediv>
<refsynopsisdiv>
<title>Синтаксис</title>
- <synopsis>deff('[s1, s2, ...] = newfunction(e1, e2, ...)',text)</synopsis>
+ <synopsis>
+ deff(funcHeadline, funcBody)
+ deff(definition)
+ deff("[r1, r2, ...] = myFunc(in1, in2, ...)", funcBody)
+ deff "r = myFunc(x,y) r = x^2 - y"
+ deff "r = myFunc(x,y) x^2 - y"
+ deff("r = @(x,y) x^2 - y") // в качестве элемента анонимного контейнера
+
+ myFunc = deff(funcHeadline, funcBody)
+ myFunc = deff(definition)
+ myFunc = deff("[r1, r2, ...] = fakeName(in1, in2, ...)", funcBody)
+ myFunc = deff("r = fakeName(x,y) r = x^2 - y")
+ myFunc = deff("r = fakeName(x,y) x^2 - y")
+ myFunc = deff("r = @(x,y) x^2 - y")
+ </synopsis>
</refsynopsisdiv>
<refsection>
<title>Аргументы</title>
<variablelist>
<varlistentry>
- <term>e1, e2, ...</term>
+ <term>x, y, in1, in2, ...</term>
+ <listitem>
+ входные аргументы определяемой функции. Последняя может иметь
+ любое количество входных аргументов, от 0 до любого N.
+ <para/>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>r, r1, r2, ...</term>
<listitem>
- <para>входные переменные.</para>
+ результаты на выходе определяемой функции. Последняя может
+ иметь любое количество результатов на выходе, от 0 до любого
+ M. Все выходные аргументы должны быть явными, то есть,
+ записанными слева от имени функции.
+ <para/>
</listitem>
</varlistentry>
<varlistentry>
- <term>s1, s2, ...</term>
+ <term>funcHeadline</term>
<listitem>
- <para>выходные переменные.</para>
+ одиночная строка: заголовок функции, то есть, её первая строчка,
+ указывающая локальное имя функции и списки её входных аргументов
+ с правой стороны и выходных аргументов с левой стороны. Примеры:
+ <itemizedlist>
+ <listitem>
+ <literal>"myFunction(x,y)"</literal> : нет аргументов на выходе
+ </listitem>
+ <listitem>
+ <literal>"r = myFunction(x,y)"</literal> : один аргумент на выходе
+ </listitem>
+ <listitem>
+ <literal>"[a,b] = myFunction(x,y)"</literal> : два аргумента
+ на выходе. И т.д.
+ </listitem>
+ </itemizedlist>
+ Пожалуйста, обратите внимание, что a) ключевое слово <literal>function</literal>
+ не обязательно указывать. b) запись выходных аргументов, если они есть, на левой
+ части заголовочной строчки является обязательной.
+ <para/>
</listitem>
</varlistentry>
<varlistentry>
- <term>text</term>
+ <term>funcBody</term>
<listitem>
- <para>матрица символьных строк.</para>
+ вектор текстов, то есть Scilab-инструкций тела функции, в том
+ порядке, в котором они должны быть выполнены. Эти инструкции
+ должны определять и назначать значения всех выходных аргументов.
+ Завершающее ключевое слово "endfunction" не ожидается.
+ <para/>
+ Этот вектор ожидается, когда <literal>deff(…)</literal> вызывается
+ с двумя входными аргументами.
+ <para/>
+ <warning>
+ Одинарные или двойные кавычки внутри инструкций должны
+ дублироваться для защиты.
+ </warning>
+ <para/>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>definition</term>
+ <listitem>
+ Отдельный текст или вектор текстов, включая как заголовочную
+ строчку функции, так и тело.
+ <itemizedlist>
+ <listitem>
+ Если это вектор, то это эквивалентно
+ <literal>definition = [funcHeadline ; funcBody]</literal>.
+ </listitem>
+ <listitem>
+ В противном случае одностроковое определение эквивалентно
+ <literal>funcHeadline + " " + strcat(funcBody,"; ")</literal>.
+ </listitem>
+ </itemizedlist>
+ Пожалуйста, смотрите разделы "Описание" и "Примеры".
+ <para/>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>myFunc</term>
+ <listitem>
+ Публичное имя и идентификатор определяемой функции, неявно
+ возвращаемый в текущее окружение, либо явно присваиваемый
+ переменной на выходе <literal>deff(…)</literal>.
+ <para/>
+ <note>
+ Когда <literal>deff(…)</literal> вызывается без явных выходных
+ аргументов, но в качестве элемента контейнера или в качестве
+ входного аргумента другой функции, то она неявно присваивается
+ этому элементу или аргументу, который является анонимным. То
+ тогда она является
+ <emphasis role="bold">анонимной функцией</emphasis>. Например:
+ <para/>
+ <literal>L = list(3, deff("r=noName(x) x.^2+1"), "Hello");</literal>.
+ Результат <literal>deff(…)</literal> присваивается <literal>L(2)</literal>.
+ Тогда <literal>L(2)(3.5) // ➜ 13.25</literal>.
+ </note>
+ <para/>
</listitem>
</varlistentry>
</variablelist>
<refsection>
<title>Описание</title>
<para>
- Функция <function>deff</function> может быть использована для определения функций из
- ряда инструкций, написанных в текстовых строках. Полученный объект функции имеет те же
- свойства, что и любая другая функция, определённая в текстовом файле и загруженная
- с помощью функции <function>exec</function>.
+ <literal>deff(…)</literal> может использоваться для определения
+ <emphasis>отдельной</emphasis> функции из инструкций Scilab, указанных
+ через матрицу текстов, вместо любого внешнего текстового файла с
+ инструкциями для исполнения, записанными в блок <literal>function … endfunction</literal>.
</para>
+ <para>
+ Файл исходного Scilab-кода может включать в себя определение нескольких
+ публичных функций. Это не возможно сделать с помощью <literal>deff(…)</literal>:
+ только одну публичную функцию можно определить. Однако, как и в случае
+ с файлом, тело определяемой функции может включать в себя один или
+ несколько блоков <literal>function … endfunction</literal>, определяющих
+ вложенные приватные функции.
+ </para>
+ <para>
+ Независимо от синтаксиса <literal>deff(…)</literal>, используемого для
+ обеспечения исходного кода (см. ниже), если он содержит синтаксическую
+ ошибку, то <literal>deff(…)</literal> выдаст ошибку компиляции
+ и остановит работу.
+ </para>
+ <refsect3>
+ <title>Указание исходного кода</title>
+ <para>
+ <emphasis role="bold">deff(funcHeadline, funcBody)</emphasis> (2 входа) и
+ <emphasis role="bold">deff([funcHeadline ; funcBody])</emphasis>
+ (единый конкатенированный вход) эквивалентны.
+ </para>
+ <para>
+ Когда <varname>funcBody</varname> сделана только из одной (короткой)
+ строки, она может быть приклеена и передана вместе с
+ <varname>funcHeadline</varname>, как одностроковое определение функции.
+ Примеры:
+ <table cellpadding="0" cellspacing="0">
+ <tr><td><literal>deff("[a,b] = myFunction(x,y) a = x.^2; b = x-y;")</literal></td>
+ </tr>
+ <tr><td>
+ <literal>deff("r = myFunction(x,y) r = (x-y).^2")</literal>.
+ Это можно даже упростить до
+ </td>
+ </tr>
+ <tr><td>
+ <literal>deff("r = myFunction(x,y) (x-y).^2")</literal>
+ </td>
+ </tr>
+ <tr><td><literal>deff("myFunction(x,y) disp(x.^2 - b)")</literal></td>
+ </tr>
+ </table>
+ </para>
+ <para>
+ Когда результат <literal>deff(…)</literal> присваивается или вводится
+ в любой анонимный контейнер, то оказывается, что псевдоимя
+ <varname>fakeName</varname>, определённое в <varname>funcHeadline</varname>
+ не играет роли вообще, и может совсем не использоваться для вызова
+ функции. Это имя может быть тогда заменено символом "@" в
+ <varname>funcHeadline</varname> для указания, что определяемая
+ функция становится <emphasis>анонимной</emphasis>.
+ </para>
+ </refsect3>
+ <refsect3>
+ <title>Идентификатор определяемой функции</title>
+ <para>
+ Идентификатор - это фактическое слово (имя), которое используется
+ для вызова определяемой функции. Следующие три случая представлены
+ для примера.
+ </para>
+ <para>
+ Когда определяемая функция не предполагает присваиваемый результат,
+ то её идентификатор возвращается напрямую в вызывающее окружение.
+ Её публичное имя тогда является именем, используемым в заголовочной
+ строчке представленного исходного кода.
+ </para>
+ <para>
+ В противном случае, когда <literal>deff(…)</literal> вызывается с
+ явным выходным аргументом, то его имя становится единственным
+ фактическим идентификатором публичной функции. В результате, имя
+ функции, используемой в исходном коде, нельзя использовать для её
+ вызова. Оно становится псевдоименем. По этой причине в заголовочной
+ строчке может быть использован символ "@" (ставящийся для "анонимок")
+ вместо какого-либо корректного имени функции, определённой в заголовочной
+ строчке. Но это не обязательно.
+ </para>
+ <para>
+ Последний случай использования <literal>deff(…)</literal> в качестве
+ элемента контейнера, например когда определяется или вводится в список,
+ либо в качестве входного аргумента другой функции. Тогда
+ <literal>deff(…)</literal> работает как присвоение. Она возвращает
+ идентификатор определяемой функции и присваивает его соответствующему
+ элементу списка или входного аргумента. Они безымянны, следовательно
+ вызов <literal>deff(…)</literal> является выражением. Определяемая
+ функция тогда становиться реально <emphasis>анонимной</emphasis>.
+ </para>
+ </refsect3>
</refsection>
<refsection>
<title>Примеры</title>
- <programlisting role="example"><![CDATA[
-deff('x = myplus(y,z)', 'x = y+z')
-myplus(1,%i)
+ <refsect3>
+ <title>Неприсваивающие функции</title>
+ <para/>
+ <programlisting role="example"><![CDATA[
+ deff('x = myplus(y,z)', 'x = y+z')
+ myplus(1,%i)
-deff('[y, z] = mymacro(x)', ['y = 3*x+1'; 'z = a*x + x.^2'])
-a = 3;
-[u, v] = mymacro(2)
- ]]></programlisting>
- <screen><![CDATA[
+ deff('[y, z] = mymacro(x)', ['y = 3*x+1'; 'z = a*x + x.^2'])
+ a = 3;
+ [u, v] = mymacro(2)
+ ]]></programlisting>
+ <screen><![CDATA[
--> deff('x = myplus(y,z)', 'x = y+z')
--> myplus(1,%i)
ans =
u =
7.
]]></screen>
+ <para>
+ С единственным входным и выходным аргументом:
+ </para>
+ <programlisting role="example"><![CDATA[
+ clear myFunc
+ source = ["r = myFunc(x,y)" ; "r = x.*(x-y)"]
+ deff(source)
+ myFunc(3, -2)
+ ]]></programlisting>
+ <screen><![CDATA[
+--> source = ["r = myFunc(x,y)" ; "r = x.*(x-y)"]
+ source =
+ "r = myFunc(x,y)"
+ "r = x.*(x-y)"
+
+--> deff(source)
+--> myFunc(3, -2)
+ ans =
+ 15.
+]]></screen>
+ <para>
+ Тот же пример с одностроковым определением, которое затем позволяет
+ синтаксис, ориентированный на командную строку (без необязательных
+ скобок deff, но с, по-прежнему, обязательными разделительными кавычками):
+ </para>
+ <programlisting role="example"><![CDATA[
+ clear myFunc
+ deff "r = myFunc(x,y) r = x.*(x-y)"
+ myFunc(1:3, -2)
+ ]]></programlisting>
+ <screen><![CDATA[
+--> deff "r = myFunc(x,y) r = x.*(x-y)"
+--> myFunc(1:3, -2)
+ ans =
+ 3. 8. 15.
+]]></screen>
+ <para>
+ Для однострокового прямого определения с единственным выходным аргументом,
+ мы можем даже опустить дубликат "r = " в теле функции:
+ </para>
+ <programlisting role="example"><![CDATA[
+ clear myFunc
+ deff "r = myFunc(x,y) x.*(x-y)"
+ myFunc(1:3, -2)
+ ]]></programlisting>
+ <screen><![CDATA[
+--> deff "r = myFunc(x,y) x.*(x-y)"
+--> myFunc(1:3, -2)
+ ans =
+ 3. 8. 15.
+]]></screen>
+ <para>
+ Функция без присваиваемого выходного аргумента: обратите также внимание
+ на использование удвоенных кавычек для защиты их в строке определения:
+ </para>
+ <programlisting role="example"><![CDATA[
+ clear myFunc
+ deff("myFunc(x, y) messagebox(prettyprint(x.*(x-y), ""html"",""""))")
+ myFunc([1 2 ; 3 4], -2)
+ ]]></programlisting>
+ </refsect3>
+ <refsect3>
+ <title>Определяемая функция, присваиваемая реципиенту</title>
+ <para>
+ Придержимся примеров, похожих на приведённые выше:
+ </para>
+ <programlisting role="example"><![CDATA[
+ clear myFunc actualName
+ actualName = deff("r = myFunc(x,y) x.*(x-y)")
+ isdef(["myFunc" "actualName"])
+ actualName(1:3, -2)
+ myFunc(1:3, -2)
+ ]]></programlisting>
+ <screen><![CDATA[
+--> actualName = deff("r = myFunc(x,y) x.*(x-y)")
+ actualName =
+[r]=actualName(x,y)
+
+--> isdef(["myFunc" "actualName"])
+ ans =
+ F T
+
+--> actualName(1:3, -2)
+ ans =
+ 3. 8. 15.
+
+--> myFunc(1:3, -2)
+Undefined variable: myFunc
+]]></screen>
+ <para>
+ Поскольку имя "внутренней" функции является псевдоименем, то мы
+ можем вместо него использовать "@" (символ "@" нельзя использовать
+ в фактических именах функций):
+ </para>
+ <programlisting role="example"><![CDATA[
+ clear actualName
+ actualName = deff("r = @(x,y) x.*(x-y)");
+ actualName(1:3, -2)
+ ]]></programlisting>
+ <screen><![CDATA[
+--> actualName = deff("r = @(x,y) x.*(x-y)");
+--> actualName(1:3, -2)
+ ans =
+ 3. 8. 15.
+]]></screen>
+ <para>
+ Теперь напрямую присвоим созданную функцию безымянному реципиенту.
+ Хотя функция становится анонимной, мы, по-прежнему, можем вызывать её:
+ </para>
+ <programlisting role="example"><![CDATA[
+ L = list("abc", deff("r = @(x,y) x.*(x-y)"), %z);
+ L(2)(1.1:4, -2.1)
+ // Мы можем извлекать и устанавливать имя анонимной функции:
+ Abc = L(2)
+ Abc(1.1:4, -2.1)
+ ]]></programlisting>
+ <screen><![CDATA[
+--> L = list("abc", deff("r = @(x,y) x.*(x-y)"), %z);
+--> L(2)(1.1:4, -2.1)
+ ans =
+ 3.52 8.82 16.12
+
+--> Abc = L(2)
+ Abc =
+[r]=Abc(x,y)
+
+--> Abc(1.1:4, -2.1)
+ ans =
+ 3.52 8.82 16.12
+]]></screen>
+ <para>
+ Наконец, давайте используем <literal>deff()</literal> для прямого
+ определения и передачи функции в качестве входного элемента другой
+ функции:
+ </para>
+ <programlisting role="example"><![CDATA[
+ function r = test(txt, x, theFunc)
+ r = x + theFunc(txt)
+ endfunction
+
+ test(rand(2,3), 0.7, deff("r = @(M) sum(size(M).^2)"))
+ ]]></programlisting>
+ <screen><![CDATA[
+--> test(rand(2,3), 0.7, deff("r = @(M) sum(size(M).^2)"))
+ ans =
+ 13.7
+]]></screen>
+ <para>
+ В этом примере передаваемая функция является анонимной в вызывающем
+ окружении, но присваивается и получает своё имя "theFunct" внутри
+ вызываемой функции.
+ </para>
+ </refsect3>
</refsection>
<refsection role="see also">
<title>Смотрите также</title>
<itemizedlist>
<listitem>
Входная опция
- <ulink url="https://help.scilab.org/docs/5.5.2/ru_RU/deff.html">
+ <ulink url="https://help.scilab.org/docs/5.5.2/en_US/deff.html">
<varname>opt="c"|"p"|"n"</varname>
- </ulink> более не доступна.
+ </ulink> больше не доступна.
+ </listitem>
+ <listitem>
+ Определяемая <varname>newfunction</varname> теперь имеет
+ тип 13 (вместо 11).
+ </listitem>
+ </itemizedlist>
+ </revdescription>
+ </revision>
+ <revision>
+ <revnumber>6.1.1</revnumber>
+ <revdescription>
+ <itemizedlist>
+ <listitem>
+ Добавлен необязательный выходной аргумент. Могут определяться
+ анонимные функции.
+ </listitem>
+ <listitem>
+ Поддерживаются одиночные входные аргументы, конкатенирующие
+ заголовочную строку функции и её тело.
+ </listitem>
+ <listitem>
+ Поддерживается синтаксис одиночной строки, вроде
+ <literal>deff "r = myFun(x,y) x.^2-y"</literal>
</listitem>
<listitem>
- Определённая новая функция <varname>newfunction</varname> теперь имеет тип 13 (вместо 11).
+ Поддерживается псевдоимя функции "@".
</listitem>
</itemizedlist>
</revdescription>
-function deff(varargin)
- if size(varargin) <> 2 then
- error(msprintf(_("%s: Wrong number of input arguments: %d expected.\n"), "deff", 2));
- end
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) INRIA
+// Copyright (C) 2012 - 2016 - Scilab Enterprises
+// Copyright (C) 2020 - Samuel GOUGEON
+//
+// This file is hereby licensed under the terms of the GNU GPL v2.0,
+// pursuant to article 5.3.4 of the CeCILL v.2.1.
+// This file was originally licensed under the terms of the CeCILL v2.1,
+// and continues to be available under such terms.
+// For more information, see the COPYING file which you should have received
+// along with this program.
- //try to build execstr string
- str = "function " + varargin(1);
- str = [str ; varargin(2)(:); "endfunction"];
+function varargout = deff(varargin)
+ [lhs, rhs] = argn();
+ if rhs < 1 | rhs > 2 then
+ msg = _("%s: Wrong number of input arguments: %d or %d expected.\n")
+ error(msprintf(msg, "deff", 1, 2))
+ end
+ if rhs == 2 then // Usual deff syntax
+ prototype = varargin(1)
+ text = matrix(varargin(2), -1, 1)
+ else
+ text = matrix(varargin(1), -1, 1)
+ if size(text,"*")==1
+ // We must split the input into the prototype and the definition
+ // The prototype is ended with the first ")":
+ [b, e, prototype] = regexp(text,"/.*?\)/", "o")
+ text = part(text,e+1:$)
+ // Case r = fun(x,y) x^2+y (single output, no r= in the definition:
+ if grep(prototype, "=") <> [] & grep(text,"=")==[]
+ outvar = strtok(prototype, "=")
+ if grep(outvar,",")==[]
+ text = outvar + " = " + text
+ end
+ end
+ else
+ prototype = varargin(1)(1)
+ text = varargin(1)(2:$)
+ end
+ end
+ // Detect @ in the prototype and replace it, if any (can't be a function's name):
+ if grep(prototype, "@") <> [] // "/(?:[^(]*?)=\s*(.+?)(?:\s*\()/")
+ prototype = strsubst(prototype, "@", "%funcname");
+ end
+ // try to build execstr string
+ str = ["function " + prototype ; text ; "endfunction"];
execstr(str);
- funcs = funclist();
- if size(funcs, "*") <= 0 then
- return;
- elseif size(funcs, "*") <> 1 then
- return;
+ %deff_func = funclist();
+ if size(%deff_func, "*") <= 0 | size(%deff_func, "*") <> 1 then
+ return
else
- execstr(funcs + "= return(" + funcs + ")");
+ if argn(1) == 0
+ execstr(%deff_func + "= return(" + %deff_func + ")");
+ else
+ execstr("varargout = list(" + %deff_func + ");")
+ end
end
-
endfunction
+++ /dev/null
-// =============================================================================
-// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
-// Copyright (C) 2009 - DIGITEO - Allan CORNET
-//
-// This file is distributed under the same license as the Scilab package.
-// =============================================================================
-// <-- CLI SHELL MODE -->
-deff("[x] = myplus(y,z)","x=y+z");
-assert_checktrue(isdef("myplus"));
-assert_checkequal(myplus(3,2), 5);
-clear myplus;
-assert_checkfalse(isdef("myplus"));
-deff("[x] = mymacro(y,z)",["a=3*y+1"; "x=a*z+y"]);
-assert_checktrue(isdef("mymacro"));
-assert_checkequal(mymacro(5,2), 37);
-clear mymacro;
-assert_checkfalse(isdef("mymacro"));
-deff("[a,b,c] = mymacro(varargin)",["a = varargin(1); b = varargin(2) * a; c = varargin(3) * b"]);
-assert_checktrue(isdef("mymacro"));
-[a,b,c] = mymacro(3,4,5);
-assert_checkequal(a, 3);
-assert_checkequal(b, 12);
-assert_checkequal(c, 60);
-clear mymacro;
-assert_checkfalse(isdef("mymacro"));
-deff("[varargout] = mymacro(varargin)",["for i = 1 : size(varargin)"; " varargout(i) = varargin(i) * 2;";"end"]);
-assert_checktrue(isdef("mymacro"));
-[a,b,c] = mymacro(3,4,5);
-assert_checkequal(a, 6);
-assert_checkequal(b, 8);
-assert_checkequal(c, 10);
-clear mymacro;
-assert_checkfalse(isdef("mymacro"));
-deff("[varargout] = mymacro(varargin)", ["deff(""varargout = mymacro2(varargin)"", [""for i = 1 : size(varargin)""; "" varargout(i) = varargin(i) * 2;"";""end""]);";"[a,b,c] = mymacro2(varargin(:));";"varargout(1) = a*2;";"varargout(2) = b*2;";"varargout(3) = c*2;"]);
-assert_checktrue(isdef("mymacro"));
-assert_checkfalse(isdef("mymacro2"));
-[a,b,c] = mymacro(3,4,5);
-assert_checkequal(a, 12);
-assert_checkequal(b, 16);
-assert_checkequal(c, 20);
-assert_checkfalse(isdef("mymacro2"));
-clear mymacro;
-assert_checkfalse(isdef("mymacro"));
// =============================================================================
// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
// Copyright (C) 2009 - DIGITEO - Allan CORNET
+// Copyright (C) 2020 - Samuel GOUGEON
//
// This file is distributed under the same license as the Scilab package.
// =============================================================================
// <-- CLI SHELL MODE -->
+// <-- NO CHECK REF -->
+
deff("[x] = myplus(y,z)","x=y+z");
assert_checktrue(isdef("myplus"));
clear mymacro;
assert_checkfalse(isdef("mymacro"));
+// Other syntaxes
+clear Fun
+deff(["r = Fun(x)" "r = x.^2 - 3"]); // Only one deff argin, being a vector
+assert_checktrue(isdef("Fun","l"));
+assert_checkequal(Fun(4), 13);
+clear Fun
+deff "r = Fun(x) r = x.^2 - 3"; // Only one deff argin, being a scalar
+assert_checktrue(isdef("Fun","l"));
+assert_checkequal(Fun(4), 13);
+clear Fun
+deff("r = Fun(x) x.^2 - 3"); // Fun argout implicit assignment (missing in definition)
+assert_checktrue(isdef("Fun","l"));
+assert_checkequal(Fun(4), 13);
+
+// output = deff(..)
+// =================
+clear Fun myFun
+myFun = deff("res = Fun(a,b)",["res = a+b" "res = res.^2"]);
+assert_checkequal(myFun(1,1), 4);
+assert_checkfalse(isdef("Fun","l"));
+
+clear myFun
+e = execstr("myFun = deff(""res = Fun(a,b)"",[""res = a+"" ""res = res.^2""]);", "errcatch");
+assert_checktrue(e <> 0); // syntax error ^^^
+assert_checkfalse(isdef("myFun","l"));
+assert_checkfalse(isdef("Fun","l"));
+
+in = list(["r = Fun(x)" "r = x.^2"], .. // Only one deff argin, being a vector
+ "r = Fun(x) r = x.^2", .. // Only one deff scalar argin
+ "r = Fun(x) x.^2",.. // Fun argout implicit assignment (missing in definition):
+ "[a,b] = Fun(x) a=x.^2; b=x-3"); // Only one deff scalar argin. 2 outputs
+for argin = in
+ clear myFun
+ myFun = deff(argin);
+ assert_checktrue(isdef("myFun","l"));
+ assert_checkfalse(isdef("Fun","l"));
+ if grep(argin(1), "[a,b]") <> []
+ [u,v] = myFun(4);
+ assert_checkequal([u v], [16 1]);
+ else
+ assert_checkequal(myFun(4), 16);
+ end
+
+ // Anonymous "@"
+ clear myFun
+ argin = strsubst(argin, "Fun", "@")
+ myFun = deff(argin);
+ assert_checktrue(isdef("myFun","l"));
+ assert_checkequal(myFun(4), 16);
+end