miller/docs6/docs/reference-dsl-user-defined-functions.md.in

53 lines
3.3 KiB
Markdown

# DSL reference: user-defined functions
As of Miller 5.0.0 you can define your own functions, as well as subroutines.
## User-defined functions
Here's the obligatory example of a recursive function to compute the factorial function:
GENMD_INCLUDE_AND_RUN_ESCAPED(data/factorial-example.sh)
Properties of user-defined functions:
* Function bodies start with `func` and a parameter list, defined outside of `begin`, `end`, or other `func` or `subr` blocks. (I.e. the Miller DSL has no nested functions.)
* A function (uniqified by its name) may not be redefined: either by redefining a user-defined function, or by redefining a built-in function. However, functions and subroutines have separate namespaces: you can define a subroutine `log` which does not clash with the mathematical `log` function.
* Functions may be defined either before or after use (there is an object-binding/linkage step at startup). More specifically, functions may be either recursive or mutually recursive. Functions may not call subroutines.
* Functions may be defined and called either within `mlr put` or `mlr put`.
* Functions have read access to `$`-variables and `@`-variables but may not modify them. See also [Memoization with out-of-stream variables](misc-examples.md#memoization-with-out-of-stream-variables) for an example.
* Argument values may be reassigned: they are not read-only.
* When a return value is not implicitly returned, this results in a return value of absent-null. (In the example above, if there were records for which the argument to `f` is non-numeric, the assignments would be skipped.) See also the section on [xxxx](reference-main-null-data.md).
* See the section on [Local variables](reference-dsl-variables.md#local-variables) for information on scope and extent of arguments, as well as for information on the use of local variables within functions.
* See the section on [Expressions from files](reference-dsl-syntax.md#expressions-from-files) for information on the use of `-f` and `-e` flags.
## User-defined subroutines
Example:
GENMD_INCLUDE_AND_RUN_ESCAPED(data/subr-example.sh)
Properties of user-defined subroutines:
* Subroutine bodies start with `subr` and a parameter list, defined outside of `begin`, `end`, or other `func` or `subr` blocks. (I.e. the Miller DSL has no nested subroutines.)
* A subroutine (uniqified by its name) may not be redefined. However, functions and subroutines have separate namespaces: you can define a subroutine `log` which does not clash with the mathematical `log` function.
* Subroutines may be defined either before or after use (there is an object-binding/linkage step at startup). More specifically, subroutines may be either recursive or mutually recursive. Subroutines may call functions.
* Subroutines may be defined and called either within `mlr put` or `mlr put`.
* Subroutines have read/write access to `$`-variables and `@`-variables.
* Argument values may be reassigned: they are not read-only.
* See the section on [local variables](reference-dsl-variables.md#local-variables) for information on scope and extent of arguments, as well as for information on the use of local variables within functions.
* See the section on [Expressions from files](reference-dsl-syntax.md#expressions-from-files) for information on the use of `-f` and `-e` flags.