reorganize module
This commit is contained in:
75
_archive/rhai_engine/rhaibook/engine/optimize/eager.md
Normal file
75
_archive/rhai_engine/rhaibook/engine/optimize/eager.md
Normal file
@@ -0,0 +1,75 @@
|
||||
Eager Function Evaluation When Using Full Optimization Level
|
||||
============================================================
|
||||
|
||||
{{#include ../../links.md}}
|
||||
|
||||
When the optimization level is [`OptimizationLevel::Full`], the [`Engine`] assumes all functions to
|
||||
be _pure_ and will _eagerly_ evaluated all function calls with constant arguments, using the result
|
||||
to replace the call.
|
||||
|
||||
This also applies to all operators (which are implemented as functions).
|
||||
|
||||
```rust
|
||||
// When compiling the following with OptimizationLevel::Full...
|
||||
|
||||
const DECISION = 1;
|
||||
// this condition is now eliminated because 'sign(DECISION) > 0'
|
||||
if sign(DECISION) > 0 // <- is a call to the 'sign' and '>' functions, and they return 'true'
|
||||
{
|
||||
print("hello!"); // <- this block is promoted to the parent level
|
||||
} else {
|
||||
print("boo!"); // <- this block is eliminated because it is never reached
|
||||
}
|
||||
|
||||
print("hello!"); // <- the above is equivalent to this
|
||||
// ('print' and 'debug' are handled specially)
|
||||
```
|
||||
|
||||
~~~admonish danger "Won't this be dangerous?"
|
||||
|
||||
Yes! _Very!_
|
||||
|
||||
```rust
|
||||
// Nuclear silo control
|
||||
if launch_nukes && president_okeyed {
|
||||
print("This is NOT a drill!");
|
||||
update_defcon(1);
|
||||
start_world_war(3);
|
||||
launch_all_nukes();
|
||||
} else {
|
||||
print("This is a drill. Thank you for your cooperation.");
|
||||
}
|
||||
```
|
||||
|
||||
In the script above (well... as if nuclear silos will one day be controlled by Rhai scripts),
|
||||
the functions `update_defcon`, `start_world_war` and `launch_all_nukes` will be evaluated
|
||||
during _compilation_ because they have constant arguments.
|
||||
|
||||
The [variables] `launch_nukes` and `president_okeyed` are never checked, because the script
|
||||
actually has not yet been run! The functions are called during compilation.
|
||||
This is, _obviously_, not what you want.
|
||||
|
||||
**Moral of the story: compile with an [`Engine`] that does not have any functions registered.
|
||||
Register functions _AFTER_ compilation.**
|
||||
~~~
|
||||
|
||||
~~~admonish question "Why would I ever want to do this then?"
|
||||
|
||||
Good question! There are two reasons:
|
||||
|
||||
* A function call may result in cleaner code than the resultant value.
|
||||
In Rust, this would have been handled via a `const` function.
|
||||
|
||||
* Evaluating a value to a [custom type] that has no representation in script.
|
||||
|
||||
```rust
|
||||
// A complex function that returns a unique ID based on the arguments
|
||||
let id = make_unique_id(123, "hello", true);
|
||||
|
||||
// The above is arguably clearer than:
|
||||
// let id = 835781293546; // generated from 123, "hello" and true
|
||||
|
||||
// A custom type that cannot be represented in script
|
||||
let complex_obj = make_complex_obj(42);
|
||||
```
|
||||
~~~
|
Reference in New Issue
Block a user