From 697bb39a7f30db37f4bb16b2bca5b8d877327476 Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Sun, 31 May 2020 15:55:02 +0800 Subject: [PATCH] Add writeup on Rhai usage scenarios. --- README.md | 20 ++++++++++++++++---- RELEASES.md | 6 +++--- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 50792756..a127d857 100644 --- a/README.md +++ b/README.md @@ -19,8 +19,8 @@ Features including [getters/setters](#getters-and-setters), [methods](#members-and-methods) and [indexers](#indexers). * Freely pass Rust variables/constants into a script via an external [`Scope`]. * Easily [call a script-defined function](#calling-rhai-functions-from-rust) from Rust. -* Low compile-time overhead (~0.6 sec debug/~3 sec release for `rhai_runner` sample app). -* Fairly efficient evaluation (1 million iterations in 0.75 sec on my 5 year old laptop). +* Fairly low compile-time overhead. +* Fairly efficient evaluation (1 million iterations in 0.25 sec on a single core, 2.3 GHz Linux VM). * Relatively little `unsafe` code (yes there are some for performance reasons, and most `unsafe` code is limited to one single source file, all with names starting with `"unsafe_"`). * Re-entrant scripting [`Engine`] can be made `Send + Sync` (via the [`sync`] feature). @@ -47,10 +47,22 @@ It doesn't attempt to be a new language. For example: * No classes. Well, Rust doesn't either. On the other hand... * No traits... so it is also not Rust. Do your Rusty stuff in Rust. -* No structures - define your types in Rust instead; Rhai can seamlessly work with _any Rust type_. +* No structures/records - define your types in Rust instead; Rhai can seamlessly work with _any Rust type_. + There is, however, a built-in [object map] type which is adequate for most uses. * No first-class functions - Code your functions in Rust instead, and register them with Rhai. +* No garbage collection - this should be expected, so... * No closures - do your closure magic in Rust instead; [turn a Rhai scripted function into a Rust closure](#calling-rhai-functions-from-rust). -* It is best to expose an API in Rhai for scripts to call. All your core functionalities should be in Rust. +* No byte-codes/JIT - Rhai has an AST-walking interpreter which will not win any speed races. The purpose of Rhai is not + to be extremely _fast_, but to make it as easy as possible to integrate with native Rust programs. + +Due to this intended usage, Rhai deliberately keeps the language simple and small by omitting advanced language features +such as classes, inheritance, first-class functions, closures, concurrency, byte-codes, JIT etc. +Avoid the temptation to write full-fledge program logic entirely in Rhai - that use case is best fulfilled by +more complete languages such as JS or Lua. + +Therefore, in actual practice, it is usually best to expose a Rust API into Rhai for scripts to call. +All your core functionalities should be in Rust. +This is similar to some dynamic languages where most of the core functionalities reside in a C/C++ standard library. Installation ------------ diff --git a/RELEASES.md b/RELEASES.md index d0a50a9a..1208c720 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -13,13 +13,13 @@ Bug fixes --------- * Indexing with an index or dot expression now works property (it compiled wrongly before). - For example, `let s = "hello"; s[s.len-1] = 'x';` now works property instead of an error. + For example, `let s = "hello"; s[s.len-1] = 'x';` now works property instead of causing a runtime error. Breaking changes ---------------- * `Engine::compile_XXX` functions now return `ParseError` instead of `Box`. -* The `RegisterDynamicFn` trait is merged into the `RegisterResutlFn` trait which now always returns +* The `RegisterDynamicFn` trait is merged into the `RegisterResultFn` trait which now always returns `Result>`. * Default maximum limit on levels of nested function calls is fine-tuned and set to a different value. * Some operator functions are now built in (see _Speed enhancements_ below), so they are available even @@ -62,7 +62,7 @@ Speed enhancements in a full clone of `a` before taking the length and throwing the copy away. Now, `a` is simply passed by reference, avoiding the cloning altogether. * A custom hasher simply passes through `u64` keys without hashing to avoid function call hash keys - (which as by themselves `u64`) being hashed twice. + (which are by themselves `u64`) being hashed twice. Version 0.14.1