Scilab Website | Contribute with GitLab | Mailing list archives | ATOMS toolboxes
Scilab Online Help
2024.1.0 - English


deff

in-line definition of a (anonymous) function in Scilab language

Syntax

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")

Arguments

x, y, in1, in2, ...
input arguments of the defined function. This one can have any number of input arguments, from 0 to any N.

r, r1, r2, ...
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.

funcHeadline
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:
  • "myFunction(x,y)" : no output
  • "r = myFunction(x,y)" : single output
  • "[a,b] = myFunction(x,y)" : two outputs. Etc..
Please note that a) the function keyword must not be provided. b) If any, writting output arguments in the left-hand-side part of the headline is mandatory.

funcBody
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.

This vector is expected when deff(…) is called with two input arguments.

Single or double quotes included in instructions must be doubled to be protected.

definition
Single text or vector of texts, including both the function's headline and body.
  • If it's a vector, it is equivalent to definition = [funcHeadline ; funcBody].
  • Otherwise, the one-string definition is equivalent to funcHeadline + " " + strcat(funcBody,"; ").
Please see the Description and Examples sections.

myFunc
Public name and identifier of the defined function, as implicitly returned in the current environment, or explicitly assigned to the deff(…)'s output variable.

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 anonymous function. Example:

L = list(3, deff("r=noName(x) x.^2+1"), "Hello");. The result of deff(…) is assigned to L(2). Then, L(2)(3.5) // ➜ 13.25.

Description

deff(…) can be used to define a single function from Scilab instructions provided through a matrix of text, instead of through any external text file of instructions written in a function … endfunction block to be executed.

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 function … endfunction blocks defining some nested private functions.

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.

Providing the source code

deff(funcHeadline, funcBody) (2 inputs) and deff([funcHeadline ; funcBody]) (single concatenated input) are equivalent.

When funcBody is made of only one (short) string, it may be glued to and passed with the funcHeadline, as a one-line function definition. Examples:

deff("[a,b] = myFunction(x,y) a = x.^2; b = x-y;")
deff("r = myFunction(x,y) r = (x-y).^2"). This can even be simplified into
deff("r = myFunction(x,y) (x-y).^2")
deff("myFunction(x,y) disp(x.^2 - b)")

When the result of deff(…) is assigned to or inserted into any anonymous element of a container, then it comes that the pseudo-name fakeName defined in the funcHeadline 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 funcHeadline, to highlight that the defined function becomes anonymous.

Identifier of the defined function

The identifier is the actual word (name) to use to call the defined function. The 3 following cases are illustrated in examples.

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.

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.

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 deff(…) call is an expression. The defined function then becomes really anonymous.

Examples

Unassigned functions

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)
--> 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.

With some single input and output:

clear myFunc
source = ["r = myFunc(x,y)" ; "r = x.*(x-y)"]
deff(source)
myFunc(3, -2)
--> 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.

Same example with a one-line definition, that then allows a console-oriented syntax (without optional deff parentheses, but with still mandatory delimiting quotes):

clear myFunc
deff "r = myFunc(x,y) r = x.*(x-y)"
myFunc(1:3, -2)
--> deff "r = myFunc(x,y) r = x.*(x-y)"
--> myFunc(1:3, -2)
 ans  =
   3.   8.   15.

For a one-line direct definition with a single output, we can even omit the "r = " duplicate in the body:

clear myFunc
deff "r = myFunc(x,y) x.*(x-y)"
myFunc(1:3, -2)
--> deff "r = myFunc(x,y) x.*(x-y)"
--> myFunc(1:3, -2)
 ans  =
   3.   8.   15.

Function with no assignable output: Note also the usage of doubled quotes to protect them in the definition string:

clear myFunc
deff("myFunc(x, y) messagebox(prettyprint(x.*(x-y), ""html"",""""))")
myFunc([1 2 ; 3 4], -2)
Defined function assigned to a recipient

Let's keep similar examples as above:

clear myFunc actualName
actualName = deff("r = myFunc(x,y) x.*(x-y)")
isdef(["myFunc" "actualName"])
actualName(1:3, -2)
myFunc(1:3, -2)
--> 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

Since the "internal" function name is fake, we can use "@" instead (the "@" character is not allowed in actual function names):

clear actualName
actualName = deff("r = @(x,y) x.*(x-y)");
actualName(1:3, -2)
--> actualName = deff("r = @(x,y) x.*(x-y)");
--> actualName(1:3, -2)
 ans  =
   3.   8.   15.

Now, let's directly assign the created function to a nameless recipient. Although the function becomes anonymous, we can still call it:

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)
--> 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

Finally, let's use deff() to directly define and pass a function as an input argument of another function:

function r=test(txt, x, theFunc)
    r = x + theFunc(txt)
endfunction

test(rand(2,3), 0.7, deff("r = @(M) sum(size(M).^2)"))
--> test(rand(2,3), 0.7, deff("r = @(M) sum(size(M).^2)"))
 ans  =
   13.7

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.

See also

  • function — opens a function definition
  • exec — script file execution
  • getd — Load all functions defined in a directory
  • genlib — builds a library from a set of *.sci files defining functions in a given directory
  • jdeff — Map a static Java method onto a Scilab macro
  • jcompile — Compile Java code or file

History

VersionDescription
6.0.0
  • The input option opt="c"|"p"|"n" is no longer available.
  • The defined newfunction is now of type 13 (instead of 11).
6.1.1
  • Output optional argument added. Anonymous functions can be defined.
  • Single input argument supported, concatenating the function headline and body.
  • Single string syntax supported, like deff "r = myFun(x,y) x.^2-y"
  • "@" function's pseudo-name supported.
Report an issue
<< argn Advanced functions exec >>

Copyright (c) 2022-2024 (Dassault Systèmes)
Copyright (c) 2017-2022 (ESI Group)
Copyright (c) 2011-2017 (Scilab Enterprises)
Copyright (c) 1989-2012 (INRIA)
Copyright (c) 1989-2007 (ENPC)
with contributors
Last updated:
Mon Jun 17 17:49:22 CEST 2024