Add docs for auto-currying.
This commit is contained in:
@@ -49,9 +49,13 @@ fn anon_fn_1001(x) { this.data -= x; }
|
||||
fn anon_fn_1002() { print this.data; }
|
||||
```
|
||||
|
||||
|
||||
WARNING - NOT Closures
|
||||
----------------------
|
||||
|
||||
Remember: anonymous functions, though having the same syntax as Rust _closures_, are themselves
|
||||
**not** closures. In particular, they do not capture their running environment. They are more like
|
||||
Rust's function pointers.
|
||||
|
||||
They do, however, _capture_ variable _values_ from their execution environment, unless the [`no_capture`]
|
||||
feature is turned on. This is accomplished via [automatic currying][capture].
|
||||
|
54
doc/src/language/fn-closure.md
Normal file
54
doc/src/language/fn-closure.md
Normal file
@@ -0,0 +1,54 @@
|
||||
Capture External Variables via Automatic Currying
|
||||
================================================
|
||||
|
||||
Poor Man's Closures
|
||||
-------------------
|
||||
|
||||
Since [anonymous functions] de-sugar to standard function definitions, they retain all the behaviors of
|
||||
Rhai functions, including being _pure_, having no access to external variables.
|
||||
|
||||
The anonymous function syntax, however, automatically _captures_ variables that are not defined within
|
||||
the current scope, but are defined in the external scope - i.e. the scope where the anonymous function
|
||||
is created.
|
||||
|
||||
Variables that are accessible during the time the [anonymous function] is created can be captured,
|
||||
as long as they are not shadowed by local variables defined within the function's scope.
|
||||
The values captured are the values of those variables at the time of the [anonymous function]'s creation.
|
||||
|
||||
|
||||
New Parameters For Captured Variables
|
||||
------------------------------------
|
||||
|
||||
In actual implementation, this de-sugars to:
|
||||
|
||||
1. Keeping track of what variables are accessed inside the anonymous function,
|
||||
|
||||
2. If a variable is not defined within the anonymous function's scope, it is looked up _outside_ the function and in the current execution scope - where the anonymous function is created.
|
||||
|
||||
3. The variable is added to the parameters list of the anonymous function, at the front.
|
||||
|
||||
4. The current value of the variable is then [curried][currying] into the [function pointer] itself, essentially carrying that value and inserting it into future calls of the function.
|
||||
|
||||
Automatic currying can be turned off via the [`no_capture`] feature.
|
||||
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
```rust
|
||||
let x = 40;
|
||||
|
||||
let f = |y| x + y; // current value of variable 'x' is auto-curried
|
||||
// the value 40 is curried into 'f'
|
||||
|
||||
x = 1; // 'x' can be changed but the curried value is not
|
||||
|
||||
f.call(2) == 42; // the value of 'x' is still 40
|
||||
|
||||
// The above de-sugars into this:
|
||||
fn anon$1001(x, y) { x + y } // parameter 'x' is inserted
|
||||
|
||||
let f = Fn("anon$1001").curry(x); // current value of 'x' is curried
|
||||
|
||||
f.call(2) == 42;
|
||||
```
|
@@ -28,3 +28,12 @@ let curried = curry(func, 21); // function-call style also works
|
||||
curried.call(2) == 42; // <- de-sugars to 'func.call(21, 2)'
|
||||
// only one argument is now required
|
||||
```
|
||||
|
||||
|
||||
Automatic Currying
|
||||
------------------
|
||||
|
||||
[Anonymous functions] defined via a closure syntax _capture_ external variables that are not shadowed inside
|
||||
the function's scope.
|
||||
|
||||
This is accomplished via [automatic currying].
|
||||
|
@@ -21,6 +21,18 @@ When a property of an [object map] is called like a method function, and if it h
|
||||
a valid [function pointer] (perhaps defined via an [anonymous function]), then the call will be
|
||||
dispatched to the actual function with `this` binding to the [object map] itself.
|
||||
|
||||
|
||||
Use Anonymous Functions to Define Methods
|
||||
----------------------------------------
|
||||
|
||||
[Anonymous functions] defined as values for [object map] properties take on a syntactic shape
|
||||
that resembles very closely that of class methods in an OOP language.
|
||||
|
||||
Anonymous functions can also _capture_ variables from the defining environment, which is a very
|
||||
common OOP pattern. Capturing is accomplished via a feature called _[automatic currying]_ and
|
||||
can be turned off via the [`no_capture`] feature.
|
||||
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
|
Reference in New Issue
Block a user