aboutsummaryrefslogtreecommitdiffstats
path: root/docs
diff options
context:
space:
mode:
authors-ol <s+removethis@s-ol.nu>2022-01-27 12:58:25 +0000
committers-ol <s+removethis@s-ol.nu>2025-03-02 14:24:49 +0000
commite8219e6ef5422d5906d16d99ea259f59033ddf6d (patch)
tree8328e50c024c4d099b3dc3ac723de768599a2188 /docs
parentlib: tidy up unecessary parameters (diff)
downloadalive-e8219e6ef5422d5906d16d99ea259f59033ddf6d.tar.gz
alive-e8219e6ef5422d5906d16d99ea259f59033ddf6d.zip
docs: update extension guide (PureOp)
Diffstat (limited to 'docs')
-rw-r--r--docs/internals/writing_extensions.md68
1 files changed, 64 insertions, 4 deletions
diff --git a/docs/internals/writing_extensions.md b/docs/internals/writing_extensions.md
index bcc3815..bf4ff05 100644
--- a/docs/internals/writing_extensions.md
+++ b/docs/internals/writing_extensions.md
@@ -337,6 +337,65 @@ write to an internally-created `Result` instance to mark itself as "dirty":
tick: =>
@out\set external_state
+## PureOps
+[*Pure Operators*][ref-04-2-pop] share common semantics for input *kinds*.
+To implement them, the base class `PureOp` is provided and takes care of any
+boilerplate (argument parsing, kind validation, output setup).
+
+To implement a PureOp, you need to specify three parts:
+
+1. the argument types `PureOp.pattern`
+2. the output type `PureOp:type`
+3. the tick logic `PureOp:tick`
+
+
+The argument types are specified as a class member `PureOp.pattern` with a
+pattern value from `base.match`. `Op.inputs` (and therefore `Op:unwrap_all`'s
+result) will follow the shape of the match:
+
+ class PowOp extends PureOp
+ pattern: any.num + any.num
+ type: T.num
+ tick: => @out\set math.pow unpack @unwrap_all!
+
+
+The output type can either by specified directly as a class member, or
+implemented as a method that returns the type value. If `PureOp:type` is a
+method, it will receive the Op inputs as parsed by `PureOp.pattern`:
+
+ class MakeArrayOp extends PureOp
+ pattern: any!*0
+ type: (args) => Array #args, args[1]\type!
+ tick: =>
+ args = @unwrap_all!
+ @out\set args
+
+`Op:tick` is implemented just like for regular Ops. Because of the PureOp
+semantics, there is no need to check which inputs are dirty, so it's
+recommended to use `Op:unwrap_all` to access the inputs.
+
+### overriding `PureOp:setup`
+For more control, it is possible to override `PureOp:setup`. When calling
+`super`, the first argument should be a table of results that are treated
+according `PureOp.pattern` as usual. The second parameter should be
+forwarded. In the third parameter, extra `Input`s can be specified that will
+be merged into `Op.inputs`:
+
+ class LogAll extends PureOp
+ pattern: any.num*0
+
+ full_pattern = -sig.str + any.num*0
+ setup: (inputs, scope) =>
+ { name, values } = full_pattern\match inputs
+ super values, scope, {
+ name: Input.cold name or scope\get '*name*'
+ }
+
+ tick: =>
+ args = @unwrap_all!
+ for i=1,#args
+ print args.name, args[i]
+
## defining `Builtin`s
Builtins are more powerful than Ops because they control whether, how and
when their arguments are evaluated. They roughly correspond to *macros* in Lisps.
@@ -349,8 +408,9 @@ familiar with the relevant internal interfaces (especially `AST`, `Result`, and
[lua]: https://www.lua.org/
[moonscript]: http://moonscript.org/
-[builtins-req]: ../../reference/index.html#require
-[builtins-imp]: ../../reference/index.html#import
-[builtins-im_]: ../../reference/index.html#import*
-[builtins-doc]: ../../reference/index.html#doc
+[builtins-req]: ../../reference/builtins.html#require
+[builtins-imp]: ../../reference/builtins.html#import
+[builtins-im_]: ../../reference/builtins.html#import*
+[builtins-doc]: ../../reference/builtins.html#doc
[modules-midi]: ../../reference/midi.html
+[ref-04-2-pop]: ../../reference/04-2_pure-operators.html