From a9238b991846bdba16f3dc7ac29821aa07cbdfe0 Mon Sep 17 00:00:00 2001 From: gnembon Date: Tue, 19 Nov 2019 22:53:26 -0400 Subject: [PATCH] docs --- src/main/java/carpet/script/Expression.java | 30 ++++++++++++--------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/src/main/java/carpet/script/Expression.java b/src/main/java/carpet/script/Expression.java index 993823aa..7a2b1305 100644 --- a/src/main/java/carpet/script/Expression.java +++ b/src/main/java/carpet/script/Expression.java @@ -191,8 +191,11 @@ import static java.lang.Math.min; *

Functions and scoping

*

* Users can define functions in the form fun(args....) -> expression and they are compiled and saved - * for further execution in this but also subsequent calls of /script command. This means that once defined functions - * are saved with the world for further use. There are two types of variables, + * for further execution in this but also subsequent calls of /script command. Functions can also be assigned to variables, + * passed as arguments, called with call function, but in most cases you would want to call them directly + * by name, in the form of fun(args...). + * This means that once defined functions + * are saved with the world for further use. For variables, there are two types of them, * global - which are shared anywhere in the code, and those are all which name starts with 'global_', and * local variables which is everything else and those are only visible inside each function. * This also means that all the parameters in functions are passed 'by value', not 'by reference'. @@ -200,12 +203,12 @@ import static java.lang.Math.min; * *

Outer variables

*

Functions can still 'borrow' variables from the outer scope, - * by adding them to the function signature wrapped around built-in function outer. What this does is - * it borrows the reference to that variable from the outer scope to be used inside the function and any modifications to that outer - * variable would result in changes of that value in the outer scope as well. Its like passing the parameters by reference, - * except the calling function itself decides what variables its borrowing. Variables are borrowed from the local scope - * when the function is defined, not used, so this can be used to modify static mutable values, without using global - * variables. Check outer(var) for details.

+ * by adding them to the function signature wrapped around built-in function outer. + * It adds the specified value to the function call stack so they behave exactly like capturing lambdas in Java, but + * unlike java captured variables don't need to be final. Scarpet will just attach their new values at the time of the + * function definition, even if they change later. Most value will be copied, but mutable values, like maps or lists, allow + * to keep the 'state' with the function, allowing them to have memory and act like objects so to speak. + * . Check outer(var) for details.

* * *

Code delivery, line indicators

@@ -784,8 +787,8 @@ public class Expression implements Cloneable * scope, but not global, it needs to use outer function in function signature

*

outer(arg)

*

outer function can only be used in the function signature, and it will - * cause an error everywhere else. It borrows the reference to that variable from the outer scope and allows - * its modification in the inner scope. This is a similar behaviour to using local variables in lambda function definitions + * cause an error everywhere else. It saves the value of that variable from the outer scope and allows + * its use in the inner scope. This is a similar behaviour to using outer variables in lambda function definitions * from Java, except here you have to specify which variables you want to use, and borrow

*

This mechanism can be used to use static mutable objects without the need of using global_... variables

*
@@ -800,9 +803,9 @@ public class Expression implements Cloneable
      * scoping allow to organize even larger scripts

*

call(function, args.....)

*

calls a user defined function with specified arguments. It is equivalent to calling function(args...) - * directly except you can use it with function name instead. This means you can pass functions to other user defined + * directly except you can use it with function value, or name instead. This means you can pass functions to other user defined * functions as arguments and call them with call internally. And since function definitions return the - * defined function name, they can be defined in place

+ * defined function, they can be defined in place as anonymous functions.

*

Little technical note: the use of _ in expression passed to built in functions is much more efficient due to * not creating new call stacks for each invoked function, but anonymous functions is the only mechanism available * for programmers with their own lambda arguments

@@ -811,7 +814,8 @@ public class Expression implements Cloneable * my_map(l(1,2,3), _(x) -> x*x); // => [1,4,9] * * profile_expr(my_map(l(1,2,3), _(x) -> x*x)); // => ~32000 - * sq(x) -> x*x; profile_expr(my_map(l(1,2,3),'sq')); // => ~38000 + * sq(x) -> x*x; profile_expr(my_map(l(1,2,3), 'sq')); // => ~36000 + * sq = (_(x) -> x*x); profile_expr(my_map(l(1,2,3), sq)); // => ~36000 * profile_expr(map(l(1,2,3), _*_)); // => ~80000 * *