aboutsummaryrefslogtreecommitdiffstats
path: root/docs/reference
diff options
context:
space:
mode:
Diffstat (limited to 'docs/reference')
-rw-r--r--docs/reference/02_evaltime-and-runtime.md45
-rw-r--r--docs/reference/03-1_symbol-resolution.md82
-rw-r--r--docs/reference/03-3_functions.md54
-rw-r--r--docs/reference/index.md26
4 files changed, 207 insertions, 0 deletions
diff --git a/docs/reference/02_evaltime-and-runtime.md b/docs/reference/02_evaltime-and-runtime.md
new file mode 100644
index 0000000..e718cf3
--- /dev/null
+++ b/docs/reference/02_evaltime-and-runtime.md
@@ -0,0 +1,45 @@
+So far, `alv` may seem a lot like any other programming language - you write
+some code, save the file, and it runs, printing some output. "What about the
+'continuously running' aspect from the introduction?", you may ask yourself.
+
+So far, we have only seen *evaltime* execution in alv - but there is also
+*runtime* behavior. At *evaltime*, that is whenever there is change to the
+source code, `alv` behaves similar to a Lisp. This is the part we have seen
+so far. But once one such *eval cycle* has executed, *runtime* starts, and
+`alv` behaves like a dataflow system like [PureData][pd], [Max/MSP][max] or
+[vvvv][vvvv].
+
+What looked so far like static constants are actually *streams* of values.
+Whenever an input to an operator changes, the operator (may) update and respond
+with a change to its output as well. To see this in action, we need to start
+with a changing value. Number literals like `1` and `2`, which we used so far,
+are *evaltime constant*, which means simply that they will never update. Since
+all inputs to our [math/+][] operator are *evaltime constant*, the result is
+constant as well. To get some *runtime* activity, we have to introduce a
+side-effect input from somewhere outside the system.
+
+The [time/][] module contains a number of operators whose outputs update
+over time. Lets take a look at [time/tick][]:
+
+ (import* time)
+ (trace (tick 1))
+
+This will print a series of numbers, incrementing by 1 every second. The
+parameter to [time/tick][] controls how quickly it counts - try changing it to
+`0.5` or `2`. As you can see, we can change [time/tick][] *while it is
+running*, but it doesn't lose track of where it was!
+
+All of the other things we learned above apply to streams of values as well -
+we can use [def][] to store them in the scope, transform them using the ops
+from the [math/][] module and so on:
+
+ (import* time math)
+ (def tik (tick 0.25))
+ (trace (/ tik 4))
+
+Note that if you leave the [time/tick][]'s *tag* in place when you move it into
+the [def][] expression, it will keep on running steadily even then.
+
+[pd]: http://puredata.info/
+[max]: https://cycling74.com/products/max
+[vvvv]: https://vvvv.org/
diff --git a/docs/reference/03-1_symbol-resolution.md b/docs/reference/03-1_symbol-resolution.md
new file mode 100644
index 0000000..87568ef
--- /dev/null
+++ b/docs/reference/03-1_symbol-resolution.md
@@ -0,0 +1,82 @@
+Both [import][] and [import*][] are actually shorthands and what they
+accomplish can be done using the lower-level builtins [def][], [use][] and
+[require][]. Here is how you could replace [import][]:
+
+ #(with import:)
+ (import math)
+ (trace (math/+ 1 2))
+
+ #(with def and require:)
+ (def math (require "math"))
+ (trace (math/+ 1 2))
+
+[require][] returns a *scope*, which is defined as the symbol `math`.
+Then `math/+` is resolved by looking for `+` in this nested scope. Note that
+the symbol that the scope is defined as and the name of the module that is
+loaded do not have to be the same, you could call the alias whatever you want:
+
+ #(this not possible with import!)
+ (def fancy-math (require "math"))
+ (trace (fancy-math/+ 1 2))
+
+Most of the time the name of the module makes a handy prefix already, so
+[import][] can be used to save a bit of typing and make the code look a bit
+cleaner. [import*][], on the other hand, defines every symbol from the imported
+module individually. It could be implemented with [use][] like this:
+
+ (use (require "math"))
+ (trace (+ 1 2))
+
+[use][] copies all symbol definitions from the scope it is passed to the
+current scope.
+
+Note that [import][], [import*][], [def][], and [use][] all can take multiple
+arguments:
+
+ #(using the shorthands:)
+ (import* math logic)
+ (import midi osc)
+
+ #(using require, use and def:)
+ (use (require "math") (require "logic"))
+ (def midi (require "midi")
+ osc (require "osc"))
+
+It is common to have an [import][] and [import*][] expression at the top of an
+`alv` program to load all of the modules that will be used later, but the
+modules don't necessarily have to be loaded at the very beginning, as long as
+all symbols are defined before they are being used.
+
+## nested scopes
+Once a symbol is defined, it cannot be changed or removed:
+
+ (def a 3)
+ (def a 4) #(error!)
+
+It is, however, possible to 'shadow' a symbol by re-defining it in a nested
+scope: So far, all symbols we have defined - using `def`, [import][] and
+[import*][] - have been defined in the *global scope*, the scope that is active
+in the whole `alv` program. The [do][] builtin can be used to create a new
+scope and evaluate some expressions in it:
+
+ (import string)
+
+ (def a 1
+ b 2)
+
+ (trace (.. "first: " a " " b))
+ (do
+ (def a 3)
+ (trace (.. "second: " a " " b))
+ (trace (.. "third: " a " " b))
+
+This example prints the following:
+
+ trace (.. "first: " a " " b): <Value str: first: 1 2>
+ trace (.. "second: " a " " b): <Value str: second: 3 2>
+ trace (.. "third: " a " " b): <Value str: third: 1 2>
+
+As you can see, within a nested scope it is possible to overwrite a definition
+from the parent scope. Symbols that are not explicitly redefined in a nested
+scope keep their values, and changes in the nested scope do not impact the
+parent scope.
diff --git a/docs/reference/03-3_functions.md b/docs/reference/03-3_functions.md
new file mode 100644
index 0000000..917b8d4
--- /dev/null
+++ b/docs/reference/03-3_functions.md
@@ -0,0 +1,54 @@
+Another builtin that creates a nested scope is [fn][], which is used to
+create a *user-defined function*, which can be used to simplify repetitive
+code, amongst other things:
+
+ (import* math)
+
+ (def add-and-trace
+ (fn
+ (a b)
+ (trace (+ a b))))
+
+ (add-and-trace 1 2)
+ (add-and-trace 3 4)
+
+Here a *function* `add-and-trace` is defined. When defining a function, first
+the names of the parameters have to be given. The function defined here takes
+two parameters, `a` and `b`. The last part of the function definition is called
+the *function body*.
+
+A function created using [fn][] can be called just like an operator. When a
+function is called, the parameters to the function are defined with the names
+given in the definition, and then the function body is executed. The previous
+example is equivalent to the following:
+
+ (import* math)
+
+ (def add-and-trace
+ (fn
+ (a b)
+ (trace (+ a b)))
+
+ (do
+ (let a 1
+ b 2)
+ (trace (+ a b)))
+
+ (do
+ (let a 3
+ b 4)
+ (trace (+ a b)))
+
+and the output of both is:
+
+ trace (+ a b): <num= 3>
+ trace (+ a b): <num= 7>
+
+In `alv`, functions are first-class values and can be passed around just like
+numbers, strings, etc. However it is very common to define a function with a
+name, so there is the `defn` shorthand, which combines the `def` and `fn`
+builtins into a single expression. Compare this equivalent definition of the
+`add-and-trace` function:
+
+ (defn add-and-trace (a b)
+ (trace (+ a b)))
diff --git a/docs/reference/index.md b/docs/reference/index.md
new file mode 100644
index 0000000..cfa8fdc
--- /dev/null
+++ b/docs/reference/index.md
@@ -0,0 +1,26 @@
+__This section is currently under construction.__
+
+This reference manual documents the `alv` langauge and its standard facilities
+in detail. If you are new to alive, the [getting started guide][guide] is the
+recommended place to start. If you are looking for information on adding your
+own module or contributing to alive, check out the
+[developer documentation](../internals/index.html).
+
+[guide]: (../guide/index.html)
+
+## contents
+
+1. syntax
+2. [evaltime and runtime](02_evaltime-and-runtime.html)
+3. evaltime
+ 1. [symbol resolution](03-1_symbol-resolution.html)
+ 2. if and switch
+ 3. [functions](03-3_functions.html)
+ 4. dynamic symbols
+ 5. loops
+ 6. modules and loading
+4. runtime
+ 1. result kinds
+ 2. pure operators
+5. [builtin listing](builtins.html)
+6. included modules