Tutorial: First evaluations

  • 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