# Partial Application {#partial-application}

Partial application fixes part or all of the parameters of a function to generate a new function with fewer parameters.

## Syntax {#syntax}

&lt;functionName&gt;\{parameters\}

or

Using object methods:

-   *obj* fixed as the first argument of *method*: `obj.method{parameters...}(newArgs...)` \(equivalent to `method{obj, parameters...}(newArgs...)`\)

-   *obj* passed as the first argument to *method*:`obj.{method{parameters...}}(newArgs...)`\(equivalent to `method{parameters...}(obj, newArgs...)`\)


## Details {#details}

For positional parameters,

-   If you only want to fix the first few parameters, the remaining parameters are not required to be indicated.

-   If there are any unfixed parameters before a fixed one, their positions must be indicated.


For keyword parameters, you can only specify the parameters to be fixed.

When generating partial applications, you can use the constant DFLT to fix the parameters to their default values. It is important to note that when fixing optional parameters with an empty default value, DFLT should be used instead of null. For optional parameters with a default value that is not empty, you can use its default value or DFLT.

Partial application can be used with template functions that have certain requirements about function inputs.

## Examples {#examples}

``` {#codeblock_g5l_tzc_s1c}
a=100
g=add{a*a};
g(8)
// output: 10008
```

``` {#codeblock_h5l_tzc_s1c}
add{a*a}(88);
// output: 10088
```

``` {#codeblock_n4t_tzc_s1c}
def f(a,b):a*exp(b)
g=f{10};  // g(b)==f(10,b)
g(0);
// output: 10
```

``` {#codeblock_wzk_5zc_s1c}
g(1);
// output: 27.182818
```

``` {#codeblock_nzq_5zc_s1c}
k=f{,1};  // k(a)==f(a,1)
k(10);
// output: 27.182818
```

If there is a free optional parameter before a fixed parameter, and its position is not indicated, it must be specified when the partially applied function is called.

```
//Calculate the singular value decomposition of matrix m.
m=matrix([[2,1,0],[1,3,1],[0,1,4],[1,2,3]]);
// The syntax of function svd is svd(obj, [fullMatrices=true], [computeUV=true]). Since f1 does not have the optional *fullMatrices* parameter fixed, you must specify *fullMatrices* when executing f1, otherwise an error will be reported.
f1 = svd{m, computeUV=true}
f1(false)   // Successfully executed.
f1()  // An error is reported: The function [svd] expects 1 argument(s), but the actual number of arguments is: 0
```

Examples for using object methods to implement partial application for user-defined function `myFunc`.

``` {#codeblock_cxs_gzc_s1c}
//user-defined function myFunc
def myFunc(a,b,c){
    return a*10+b*5+c*2
}

a1=[1,2,3]
b1=5
c1=9

//fix the first parameter as a1
a1.myFunc{}(c1,b1)  //equivalent to myFunc{a1}(c1,b1)
// output: [65,75,85]
```

``` {#codeblock_e3k_3zc_s1c}
//fix the first and third parameters as b1 and a1
b1.myFunc{,a1}(c1)  //equivalent to myFunc{b1,,a1} (c1)
// output: [97,99,101]
```

``` {#codeblock_rw2_lzc_s1c}
//generate a partial application with only one parameter, myFunc{b1,a1}(c1)
b1.{myFunc{,a1}}(c1)    // equivalent to myFunc(b1,a1,c1)
// output: [73,78,83]
```

Partial application implemented by object methods can be used with higher-order function symbols.

-   Used with `:E`.

    ``` {#codeblock_yy5_zqd_s1c}
    a1.myFunc{b1}:E([4,5,6]) //equivalent to each(a1.myFunc{b1},[4,5,6])
    ```

    Returns a matrix:

<table id="table_dyg_rrd_s1c"><tbody><tr><td align="left">

4

</td><td align="left">

5

</td><td align="left">

6

</td></tr><tr><td align="left">

43

</td><td align="left">

45

</td><td align="left">

47

</td></tr><tr><td align="left">

53

</td><td align="left">

55

</td><td align="left">

57

</td></tr><tr><td align="left">

63

</td><td align="left">

65

</td><td align="left">

67

</td></tr></tbody>
</table>-   Used with `:V` to calculate the skewness by column.

    ``` {#codeblock_vfl_drd_s1c}
    av = array(INT[],0,10).append!([2 6 6 9 3, 0 7 4 7 1, 4 2 4 8 7,0 9 8 9 7])
    av.{skew{,false}}:V()// equivalent to skew{,false}:V(av) or byColumn(skew{,false},av)
    // output: [0.8545,-0.9406,0.8545,-0.8545,-0.3703]
    ```

    In this case, if you do not use "\{\}" to bind *method* and *parameters*, *obj* will be interpreted as the first fixed argument of `skew`. Since the `skew` function can only take two arguments, the following script will throw an exception:

    ``` {#codeblock_mdf_grd_s1c}
    av.skew{,false}:H() // equivalent to skew{av,,false}:H()
    // throw an exception
    ```


The syntax of built-in function `rank` is `rank(X, [ascending=true], [groupNum], [ignoreNA=true], [tiesMethod='min'], [percent=false], [precision]`.

To fix *percent*=true, use positional arguments:

``` {#codeblock_dd1_vkb_bbc}
f1 = rank{,,,,,true}
```

Alternatively, use keyword arguments:

``` {#codeblock_znf_vkb_bbc}
f2 = rank{percent=true}
```

To fix *groupNum*to its default value \(null\), specify DFLT:

``` {#codeblock_r5n_4kb_bbc}
f3 = rank{groupNum=DFLT,percent=true}
```

