- This tutorial expects that you have already completed successfully Tutorial: Initial steps
- Add the following self-descriptive markdown to any Logseq page:
- - **DISCLAIMER:** This tutorial: - doesn't contain many natural expressions - The reason is that it follows a **bottom-up** approach. - is written for both basic and advanced users - It is not ideal for either. - If you are an **advanced** user, feel free to skip some parts. - If you are a **basic** user: - don't worry about the (many) **details** - read through only to get **familiar** - **experiment** a lot, by: - **changing** the various expressions - they are all **safe** - **observing** the results - experiment **even more** - This point cannot be stressed enough. - - To **evaluate** an expression means to produce a **value** out of it. - That value is called the **result** of that evaluation. - **Composite** expressions are: - expressions made of simpler **subexpressions** - evaluated in **steps** - Each step is the evaluation of a subexpression. - The result of a step is called an **intermediate** result. - - Evaluating with **macros** - Macros in Synthesis lab: - expect a single **expression** of arbitrary complexity - are Logseq macros, therefore they don't accept some otherwise valid Synthesis characters: - comma `,` - It separates arguments, but Synthesis reads only the first one. - Usually not needed, but can use instead semicolon `;` - curly braces `{}` and square brackets `[]` - Use instead `Dict()` and `List()` respectively (see lower) - single quotes `'` - Use instead double quotes `"`, although: - they may need escaping with backslash `\` - sometimes may need to be assigned to a variable (see lower) - macro `eval` - evaluates the passed expression and displays the result every time the block is **rendered** - example syntax - ```logseq the cubic root of 27 is {{eval 27 ^ (1 / 3)}} ``` - the spaces around ` ^ ` and ` / ` are necessary - example block - the cubic root of 27 is {{eval 27 ^ (1 / 3)}} - Try editing the parent block to see the macro inside. - macro `evalonce` - same with `eval`, but **replaces** the macro with its result - example syntax - ```logseq the cubic root of 27 is {{evalonce 27 ^ (1 / 3)}} ``` - example block - the cubic root of 27 is 3 - Replace `3` with macro `{{evalonce 27 ^ (1 / 3)}}` - Try editing the block to see that the macro is gone. - macro `cell` - spreadsheet-like **live** cell - example syntax - ```logseq the cubic root of 27 is {{cell 27 ^ (1 / 3)}} ``` - example block - the cubic root of 27 is {{cell 27 ^ (1 / 3)}} - Hover on **3** to see its expression. - Click on the expression to edit it. - e.g. to `64 ^ (1 / 3)` - Press `Enter` to evaluate it. - the value should be updated - e.g. to **3.9999999999999996** - The strange precision: - is a defect inherited from Javascript - because Synthesis lab is implemented in Javascript - can be "fixed" with `round (64 ^ (1 / 3)` - pressing `Enter` again, should show **4** - Press `Escape` to reset it. - - Evaluating with **variables** - A variable is a **name** that within a given **context** points to a **value** for later usage. - Almost all names are accepted and their **initial** value is **void**. - In Synthesis, `void` is: - a **plain** word - also used to represent **empty** values - including low-level so-called nullish values (null, undefined etc.) - To **assign** a value to a variable means to make that variable to point to that value. - **Reading** with prefix `?` - natural forms `that ` / `those ` - example syntaxes - `{{eval ?varname}}` => {{eval ?varname}} - no space after `?` - `{{eval that varname}}` => {{eval that varname}} - `{{eval those varname}}` => {{eval those varname}} - meaningful examples in following sections - **Special** Synthesis variable `$it` - The symbol `$` generally indicates a **s**pecial **S**ynthesis **s**ymbol. - natural forms `it` / `them` - This variable always points to the last **unassigned** intermediate result of an ongoing evaluation. - If a result is assigned to another variable, the variable `$it` keeps its current value. - example - `{{eval 1 + 1; it + them + it}}` => {{eval 1 + 1; it + them + it}} - explanation - 1 + 1 = 2 = $it - $it + $it + $it = 2 + 2 + 2 = 6 = new $it - **Writing** with suffix `= ` - natural form `let ` - All variables are normally **local**. - i.e. they don't maintain their value among different evaluations - examples - `{{eval x= 1; ?x + ?x}}` => {{eval x= 1; ?x + ?x}} - no space before `= ` - `{{eval let x 1; that x plus that x}}` => {{eval let x 1; that x plus that x}} - natural version of the previous example - `{{eval let x yes}} {{eval ?x}} {{eval let x yes; x= no; ?x}}` => {{eval let x yes}} {{eval ?x}} {{eval let x yes; x= no; ?x}} - explanation - The three macros produce three **independent** evaluations. - **first** evaluation for macro `{{eval let x yes}}` - both first `$it` and first `x` have **initial** value **void** - as explained earlier - first `x` gets assigned value **yes** - first evaluation's result = first `$it` = **void** - **second** evaluation for macro `{{eval ?x}}` - both second `$it` and second `x` have initial value **void** - no matter that first `x` had value **yes** - second `$it` gets assigned second `x`'s value, which is **void** - second evaluation's result = second `$it` = **void** - **third** evaluation for macro `{{eval let x yes; x= no; ?x}}` - both third `$it` and third `x` have initial value **void** - no matter the values of previous `$it` and `x` - third `x` gets assigned value **yes** - third `x` gets assigned value **no** - There is no difference between `let` and suffix `= ` - The previous value is practically lost for the current context. - third `$it` gets assigned third `x`'s value, which at this point is **no** - third evaluation's result = third `$it` = **no** - The three results are displayed in place of the macros. - - Evaluating with **functions** - The following are not natural expressions, but accept natural expressions in their arguments. - **Javascript** built-in functions - Many (but not all) of them are available as simple calls. Some examples: - `{{eval Date.now()}}` => {{eval Date.now()}} - `{{eval Date.parse("1970-01-02")}}` => {{eval Date.parse("1970-01-02")}} - `{{eval Math.max(3 Math.min(1 5) 4 2)}}` => {{eval Math.max(3 Math.min(1 5) 4 2)}} - `{{eval Math.cos(Math.PI)}}` => {{eval Math.cos(Math.PI)}} - `{{eval Math.random()}}` => {{eval Math.random()}} - `{{eval String.fromCharCode(10000)}}` => {{eval String.fromCharCode(10000)}} - **Synthesis** convenience functions to **combine parts** - `Number` functions - `Sum` of numbers - for multiple **additions** - example - `{{eval Number.Sum(1 0.2 3 -4 -.5)}}` => {{eval Number.Sum(1 0.2 3 -4 -.5)}} - equivalent to `{{eval 1 + 0.2 + 3 - 4 - .5}}` => {{eval 1 + 0.2 + 3 - 4 - .5}} - fix precision - `{{eval Number.Sum(1 0.2 3 -4 -.5); (round (10 * it)) / 10}}` => {{eval Number.Sum(1 0.2 3 -4 -.5); (round (10 * it)) / 10}} - `Product` of numbers - for multiple **multiplications** - example - `{{eval Number.Product(1 0.2 3 -4 -.5)}}` => {{eval Number.Product(1 0.2 3 -4 -.5)}} - equivalent to `{{eval 1 * 0.2 * 3 * -4 * -.5}}` => {{eval 1 * 0.2 * 3 * -4 * -.5}} - fix precision - `{{eval Number.Product(1 0.2 3 -4 -.5); (round (10 * it)) / 10}}` => {{eval Number.Product(1 0.2 3 -4 -.5); (round (10 * it)) / 10}} - `List` of arbitrary items - an **ordered** collection - a JSON-like Javascript array - examples - `{{eval List(9 8 7 6)}}` => {{eval List(9 8 7 6)}} - items are not sorted - `{{eval List()}}` => {{eval List()}} - an **empty** list - `{{eval item= 1; List(?item ?item)}}` => {{eval item= 1; List(?item ?item)}} - The **same** value can participate **multiple** times. - `Dict`ionary of key-value pairs - a **set** of **unique** keys and their arbitrary values - a JSON-like Javascript object - examples - `{{eval Dict(9 8 7 6)}}` => {{eval Dict(9 8 7 6)}} - **odd** arguments become keys, **even** arguments become values - order of pairs is not guaranteed - `{{eval Dict(9 8 7)}}` => {{eval Dict(9 8 7)}} - **missing** values are considered **void** - `{{eval Dict()}}` => {{eval Dict()}} - an **empty** dictionary - `{{eval key= k; val1= a; val2= b; Dict(?key ?val1 ?key ?val2)}}` => {{eval key= k; val1= a; val2= b; Dict(?key ?val1 ?key ?val2)}} - The later pair **overwrote** the earlier one, because they had the **same** key **k**. - `Text` concatenation - easy and powerful way to form textual values - examples - `{{eval Text(left "< ; >" right)}}` => {{eval Text(left "< ; >" right)}} - Spaces outside literals are not concatenated. - `{{eval Text(left; ; ; "< ; >"; ; ; right)}}` => {{eval Text(left; ; ; "< ; >"; ; ; right)}} - Empty arguments have also no effect. - `{{eval Text("(" 1 + 2 ")" = ( 1 + 2 ))}}` => {{eval Text("(" 1 + 2 ")" = ( 1 + 2 ))}} - Subexpressions are evaluated before being concatenated. - `{{eval Text("( 1 + 2 ) = " ( 1 + 2 ))}}` => {{eval Text("( 1 + 2 ) = " ( 1 + 2 ))}} - Compare to get the idea. - `{{eval a= 1; b= 2; ?a + ?b; Text("a + b = " it)}}` => {{eval a= 1; b= 2; ?a + ?b; Text("a + b = " it)}} - Handy for separating calculations from printing. - `{{eval Text(colon space dash void comma void dash space colon)}}` => {{eval Text(colon space dash void comma void dash space colon)}} - Each argument is replaced with the result of `text from that argument` - - Examples of **reading parts** - The following are very few of the possible combinations. - substrings in **text** - `{{eval text= "test"; ?text first 2}}` => {{eval text= "test"; ?text first 2}} - `{{eval text= "test"; ?text sans prefix "te"}}` => {{eval text= "test"; ?text sans prefix "te"}} - items in **list** - `{{eval List(9 8 7 6); the first of it}}` => {{eval List(9 8 7 6); the first of it}} - `{{eval member "1" of List(9 8 7 6)}}` => {{eval member "1" of List(9 8 7 6)}} - Because the indexing begins from zero. - `{{eval List(9 8 7 6) its 7}}` => {{eval List(9 8 7 6) its 7}} - Because there is no 8th item in a list of only 4. - values in **dictionary** - `{{eval Dict(9 8 7 6)}}` => {{eval Dict(9 8 7 6)}} - A reminder of an earlier example. - `{{eval values of Dict(9 8 7 6)}}` => {{eval values of Dict(9 8 7 6)}} - First-order only. Keys are values of second order. - `{{eval Dict(9 8 7 6); keys of it}}` => {{eval Dict(9 8 7 6); keys of it}} - Keys are actually strings. - `{{eval Dict(9 8 7 6) its 7}}` => {{eval 7 of Dict(9 8 7 6)}} - Because of key-value pair **7: 6**. - `{{eval 8 of Dict(9 8 7 6)}}` => {{eval Dict(9 8 7 6) its 8}} - Because there is no key **8** in this dictionary. -
3 Likes