From 686d40d4ae10005480e8cb34f827d582dc46483e Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Sun, 19 Jul 2020 21:18:13 +0800 Subject: [PATCH] Move anonymous function to own chapter. --- doc/src/SUMMARY.md | 1 + doc/src/language/fn-anon.md | 57 +++++++++++++++++++++++++++++++++++++ doc/src/language/fn-ptr.md | 55 ----------------------------------- doc/src/links.md | 4 +-- 4 files changed, 60 insertions(+), 57 deletions(-) create mode 100644 doc/src/language/fn-anon.md diff --git a/doc/src/SUMMARY.md b/doc/src/SUMMARY.md index e344c306..d86aae6a 100644 --- a/doc/src/SUMMARY.md +++ b/doc/src/SUMMARY.md @@ -75,6 +75,7 @@ The Rhai Scripting Language 2. [Overloading](language/overload.md) 3. [Namespaces](language/fn-namespaces.md) 4. [Function Pointers](language/fn-ptr.md) + 5. [Anonymous Functions](language/fn-anon.md) 15. [Print and Debug](language/print-debug.md) 16. [Modules](language/modules/index.md) 1. [Export Variables, Functions and Sub-Modules](language/modules/export.md) diff --git a/doc/src/language/fn-anon.md b/doc/src/language/fn-anon.md new file mode 100644 index 00000000..21ceb7a3 --- /dev/null +++ b/doc/src/language/fn-anon.md @@ -0,0 +1,57 @@ +Anonymous Functions +=================== + +{{#include ../links.md}} + +Sometimes it gets tedious to define separate functions only to dispatch them via single [function pointers]. +This scenario is especially common when simulating object-oriented programming ([OOP]). + +```rust +// Define object +let obj = #{ + data: 42, + increment: Fn("inc_obj"), // use function pointers to + decrement: Fn("dec_obj"), // refer to method functions + print: Fn("print_obj") +}; + +// Define method functions one-by-one +fn inc_obj(x) { this.data += x; } +fn dec_obj(x) { this.data -= x; } +fn print_obj() { print(this.data); } +``` + +The above can be replaced by using _anonymous functions_ which have the same syntax as Rust's closures +(but they are **NOT** closures, merely syntactic sugar): + +```rust +let obj = #{ + data: 42, + increment: |x| this.data += x, // one-liner + decrement: |x| this.data -= x, + print_obj: || { print(this.data); } // full function body +}; +``` + +The anonymous functions will be hoisted into separate functions in the global namespace. +The above is equivalent to: + +```rust +let obj = #{ + data: 42, + increment: Fn("anon_fn_1000"), + decrement: Fn("anon_fn_1001"), + print: Fn("anon_fn_1002") +}; + +fn anon_fn_1000(x) { this.data += x; } +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. diff --git a/doc/src/language/fn-ptr.md b/doc/src/language/fn-ptr.md index 1552a46a..833cfaa2 100644 --- a/doc/src/language/fn-ptr.md +++ b/doc/src/language/fn-ptr.md @@ -164,58 +164,3 @@ Beware that this only works for _method-call_ style. Normal function-call style the `this` pointer (for syntactic reasons). Therefore, obviously, binding the `this` pointer is unsupported under [`no_object`]. - - -Anonymous Functions -------------------- - -Sometimes it gets tedious to define separate functions only to dispatch them via single function pointers. -This scenario is especially common when simulating object-oriented programming ([OOP]). - -```rust -// Define object -let obj = #{ - data: 42, - increment: Fn("inc_obj"), // use function pointers to - decrement: Fn("dec_obj"), // refer to method functions - print: Fn("print_obj") -}; - -// Define method functions one-by-one -fn inc_obj(x) { this.data += x; } -fn dec_obj(x) { this.data -= x; } -fn print_obj() { print(this.data); } -``` - -The above can be replaced by using _anonymous functions_ which have the same syntax as Rust's closures -(but they are **NOT** closures, merely syntactic sugar): - -```rust -let obj = #{ - data: 42, - increment: |x| this.data += x, // one-liner - decrement: |x| this.data -= x, - print_obj: || { print(this.data); } // full function body -}; -``` - -The anonymous functions will be expanded into separate functions in the global namespace: - -```rust -let obj = #{ - data: 42, - increment: Fn("anon_fn_1000"), - decrement: Fn("anon_fn_1001"), - print: Fn("anon_fn_1002") -}; - -fn anon_fn_1000(x) { this.data += x; } -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. diff --git a/doc/src/links.md b/doc/src/links.md index 4cdb83e8..a26a34e8 100644 --- a/doc/src/links.md +++ b/doc/src/links.md @@ -78,8 +78,8 @@ [function pointers]: {{rootUrl}}/language/fn-ptr.md [function namespace]: {{rootUrl}}/language/fn-namespaces.md [function namespaces]: {{rootUrl}}/language/fn-namespaces.md -[anonymous function]: {{rootUrl}}/language/fn-ptr.md#anonymous-functions -[anonymous functions]: {{rootUrl}}/language/fn-ptr.md#anonymous-functions +[anonymous function]: {{rootUrl}}/language/fn-anon.md +[anonymous functions]: {{rootUrl}}/language/fn-anon.md [`Module`]: {{rootUrl}}/language/modules/index.md [module]: {{rootUrl}}/language/modules/index.md