introduce haku reference docs
This commit is contained in:
		
							parent
							
								
									a4c18c37dc
								
							
						
					
					
						commit
						b5cdfdb1b6
					
				
					 2 changed files with 521 additions and 0 deletions
				
			
		
							
								
								
									
										520
									
								
								docs/haku.dj
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										520
									
								
								docs/haku.dj
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,520 @@
 | 
			
		|||
# haku reference manual
 | 
			
		||||
 | 
			
		||||
haku is a dynamically typed, pure functional programming language, used for programming brushes in rakugaki.
 | 
			
		||||
 | 
			
		||||
For the layperson, it can be thought of a beefed up calculator.
 | 
			
		||||
It has roots in ordinary school algebra, but has a much more powerful set of features, with the special ability of being able to edit images.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## Overview
 | 
			
		||||
 | 
			
		||||
haku programs are called _brushes_.
 | 
			
		||||
The purpose of a brush is to produce instructions for rakugaki on how the user may interact with the wall (via _reticles_), and what things should be drawn on the wall as a result of those interactions (via _scribbles_).
 | 
			
		||||
Collectively, reticles and scribbles are what we call _effects_.
 | 
			
		||||
 | 
			
		||||
A brush's task is to compute (or in simpler terms, calculate) an effect that rakugaki will then _perform_.
 | 
			
		||||
 | 
			
		||||
In case of reticles, rakugaki will allow the user to interact with the wall, and then ask haku for another effect to perform afterwards (a _continuation_).
 | 
			
		||||
 | 
			
		||||
In case of scribbles, rakugaki will draw the scribble onto the wall, without asking haku for more.
 | 
			
		||||
 | 
			
		||||
Once rakugaki runs through all effects, we say that the brush has _finished executing_.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## Lexical elements
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### Comments
 | 
			
		||||
 | 
			
		||||
haku's most basic lexical element is the _comment_.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
-- This is a comment.
 | 
			
		||||
-- こんにちは!
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Comments introduce human-readable remarks into a brush's code.
 | 
			
		||||
Their only purpose is documentation.
 | 
			
		||||
They serve no semantic meaning, and thus do not affect the result of the brush whatsoever.
 | 
			
		||||
 | 
			
		||||
Comments begin with `--`, and span until the end of the current line of text.
 | 
			
		||||
Once the line ends, the comment does, too.
 | 
			
		||||
 | 
			
		||||
Comments do not necessarily have to appear at the beginning of a line.
 | 
			
		||||
 | 
			
		||||
```haku
 | 
			
		||||
magnitude: \v ->  -- calculate the magnitude of a vector
 | 
			
		||||
  hypot vecX.v vecY.v
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### Literals
 | 
			
		||||
 | 
			
		||||
Literals represent _literal values_ that are input into the brush.
 | 
			
		||||
 | 
			
		||||
haku has a few types of literals, but not all literals are purely lexical elements (some of them can nest)---which is why the different types of literals are covered under the [Expressions](#Expressions) section.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### Identifiers
 | 
			
		||||
 | 
			
		||||
Identifiers are used for naming values inside a brush.
 | 
			
		||||
New names are introduced using [defs](#Structure-of-a-brush) and [lets](#Let-expression).
 | 
			
		||||
Once a name is introduced, it may be referenced using its identifier in its corresponding scope---the whole brush for defs, and the following expression in lets.
 | 
			
		||||
 | 
			
		||||
An identifier starts with a *lowercase* ASCII letter---`a`--`z` or an underscore---`_`, and is followed by zero or more ASCII letters of any case---`a`--`z`, `A`--`Z`, digits---`0`--`9`, and underscores---`_`.
 | 
			
		||||
This then may be followed by an arbitrary number of _suffix characters_ prime symbols---`'` and question marks---`?`.
 | 
			
		||||
 | 
			
		||||
By convention, prime symbols are used in the same way they are used in math notation---for introducing a distinct variable of the same name as another variable, usually derived from the previous.
 | 
			
		||||
For example, given a variable named `position`, an _updated_ position may be named `position'`.
 | 
			
		||||
 | 
			
		||||
The question mark suffix is conventionally used for [boolean](#Boolean-type) variables, as well as boolean-returning functions.
 | 
			
		||||
By convention, only one question mark is always used.
 | 
			
		||||
 | 
			
		||||
Identifiers starting with *uppercase* ASCII letters---`A`--`Z` are not identifiers, but rather [tags](#tag-literal), and therefore cannot be used as def and let names.
 | 
			
		||||
 | 
			
		||||
The following identifiers are reserved as _keywords_, and have special meaning assigned within the language syntax.
 | 
			
		||||
 | 
			
		||||
- `if` --- Introduces an [`if` expression](#if-expression).
 | 
			
		||||
- `else` --- Introduces the `else` clause in an [`if` expression](#if-expression).
 | 
			
		||||
 | 
			
		||||
Additionally, the following identifiers are reserved for future use, and may not be used for naming defs and lets.
 | 
			
		||||
 | 
			
		||||
- `and`
 | 
			
		||||
- `or`
 | 
			
		||||
 | 
			
		||||
By convention, a prime symbol `'` suffix can be used to work around this restriction.
 | 
			
		||||
For example, instead of naming a variable `if`, try naming it `if'` (read as _if prime_, "_the other if_").
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### Operators and punctuation
 | 
			
		||||
 | 
			
		||||
Operators and punctuation share a section in this part of the reference due to their lexical similarity.
 | 
			
		||||
 | 
			
		||||
[Operators](#operators) serve as a terse syntax for calling a small set of built-in functions within the program (described in detail in the [system reference documentation](system.html)), while punctuation serves the purpose of syntactic delimiters.
 | 
			
		||||
 | 
			
		||||
The following symbols are operators:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
+ - * /
 | 
			
		||||
== != < <= > >= !
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
And the following symbols are punctuation:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
<newline>
 | 
			
		||||
( ) [ ] ,
 | 
			
		||||
= :
 | 
			
		||||
. |
 | 
			
		||||
\ ->
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
`<newline>` is literally written down as a line break in programs, which would be invisible in this reference.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## Structure of a brush
 | 
			
		||||
 | 
			
		||||
A brush is structured like so:
 | 
			
		||||
 | 
			
		||||
```haku
 | 
			
		||||
def1: expr1
 | 
			
		||||
def2: expr2
 | 
			
		||||
def3: expr3
 | 
			
		||||
-- ...
 | 
			
		||||
effectExpr
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
That is, there are two parts to a brush: its _defs_, followed by the resulting effect [expression](#Expressions).
 | 
			
		||||
The effect produced by this expression is the effect performed by rakugaki when the user interacts with the wall (clicks on it, touches it, starts a pen stroke).
 | 
			
		||||
 | 
			
		||||
Defs introduce names for values that are available across the entire program.
 | 
			
		||||
They are most commonly used to name constants and functions.
 | 
			
		||||
 | 
			
		||||
Example:
 | 
			
		||||
 | 
			
		||||
```haku
 | 
			
		||||
-- Constant definition
 | 
			
		||||
pi: 3.14159265
 | 
			
		||||
 | 
			
		||||
-- Function definition
 | 
			
		||||
magnitude: \v ->
 | 
			
		||||
  hypot vecX.v vecY.v
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## Expressions
 | 
			
		||||
 | 
			
		||||
haku is a strictly expression-oriented language.
 | 
			
		||||
There is no idea of statements, as would be the case in lower-level languages like C++ or JavaScript.
 | 
			
		||||
This comes from the fact that haku is a _pure_ functional language, which means there aren't any expressions whose result you would want to discard, only for their side effects.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### Nil
 | 
			
		||||
 | 
			
		||||
An empty parenthesis represents a _nil_ value---that is, literally a value that means "no value."
 | 
			
		||||
 | 
			
		||||
```haku
 | 
			
		||||
()
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
It is one of the only values considered [_false_](#Truth) by the language, other than the [`False` boolean](#Tags).
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### Numbers
 | 
			
		||||
 | 
			
		||||
Numbers in haku are written down as a sequence of ASCII digits---`0`--`9`, followed by an optional decimal point `.` with a decimal part.
 | 
			
		||||
 | 
			
		||||
```haku
 | 
			
		||||
0
 | 
			
		||||
123
 | 
			
		||||
3.14159265
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Internally, they are represented by 32-bit floating point numbers.
 | 
			
		||||
This means that they have [fairly limited precision](https://float.exposed/0x42f60000), and do not always behave exactly like math on real numbers.
 | 
			
		||||
For example, there are magical values for ∞ and -∞ (which _can_ exist and can be operated upon), as well as a value called NaN (not a number), which are produced as results of certain operations that aren't well-defined in math (most commonly division by zero).
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### Tags
 | 
			
		||||
 | 
			
		||||
Tags are similar to [identifiers](#Identifiers), but start with an *uppercase* rather than a lowercase ASCII letter (that is, `A`--`Z`).
 | 
			
		||||
They are values which represent _names_.
 | 
			
		||||
 | 
			
		||||
This concept may feel a bit alien.
 | 
			
		||||
As an example, consider how haku implements record types.
 | 
			
		||||
From the perspective of the user, a record type acts like a [function](#Functions) which accepts a tag as an argument---with the tag being the name of the record field.
 | 
			
		||||
 | 
			
		||||
```haku
 | 
			
		||||
withDotter \d ->
 | 
			
		||||
  stroke 8 #000 (line d.From d.To)
 | 
			
		||||
                        ----   --  these are tags
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
There are also two special tags, `True` and `False`, which are used to represent Boolean logic.
 | 
			
		||||
 | 
			
		||||
The boolean `False` is the only [_false_](#Truth) value in the language, other than [nil](#Nil).
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### Colors
 | 
			
		||||
 | 
			
		||||
haku has a literal for representing RGBA colors.
 | 
			
		||||
It takes one of the following four forms, from most explicit to least explicit:
 | 
			
		||||
 | 
			
		||||
```haku
 | 
			
		||||
#RRGGBBAA
 | 
			
		||||
#RRGGBB
 | 
			
		||||
#RGBA
 | 
			
		||||
#RGB
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Each character in a color literal is a hexadecimal digit, with the digits `0`--`9` representing digits 0 to 9, and letters `a`--`f` representing digits 10 to 16 (case insensitive.)
 | 
			
		||||
 | 
			
		||||
For `#RGB` and `#RGBA`, the digits are repeated twice implicitly---that is, `#1234` is the same as `#11223344`.
 | 
			
		||||
 | 
			
		||||
This syntax is designed to be convenient for working with colors coming from external programs.
 | 
			
		||||
For example, you may pick a color from an online palette, and paste its hex code straight into your brush code.
 | 
			
		||||
 | 
			
		||||
Example (rakugaki logo colors):
 | 
			
		||||
 | 
			
		||||
```haku
 | 
			
		||||
white: #FFF
 | 
			
		||||
peach: #FFA6A6
 | 
			
		||||
raspberry: #F44096
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### Lists
 | 
			
		||||
 | 
			
		||||
Lists are fixed-length sequences of values.
 | 
			
		||||
They are written down by listing out a sequence of comma `,` or newline-separated items, enclosed in square brackets `[]`.
 | 
			
		||||
 | 
			
		||||
```haku
 | 
			
		||||
six: [1, 2, 3, 4, 5, 6]
 | 
			
		||||
four: [
 | 
			
		||||
    1
 | 
			
		||||
    2
 | 
			
		||||
    3
 | 
			
		||||
    4
 | 
			
		||||
]
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Lists are allowed to nest, as the values may be of any type---including lists themselves.
 | 
			
		||||
 | 
			
		||||
Lists are most commonly used to compose scribbles.
 | 
			
		||||
A list is also a scribble, which draws the scribbles it contains within itself, from first to last.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### Operators
 | 
			
		||||
 | 
			
		||||
Operators in haku are used mostly for basic mathematical operations.
 | 
			
		||||
They are either unary, written in prefix form `!x`, or binary, written in infix form `a + b`.
 | 
			
		||||
 | 
			
		||||
While order of operations in case of unary operators is unambiguous (innermost to outermost), infix operators are not as simple.
 | 
			
		||||
Certain infix operators have _precedence_ over others.
 | 
			
		||||
 | 
			
		||||
This precedence depends on the operator used, as well as the spacing around it.
 | 
			
		||||
Spacing _only_ matters for infix operators; prefix operators may have any amount of spaces around them, though conventionally they are glued to the expression on the right, like `(-1)`, or `vec -1 0`.
 | 
			
		||||
 | 
			
		||||
Infix operators with spaces around them are classified as _loose_, and those without spaces around them are _tight_.
 | 
			
		||||
An unequal amount of spaces around an infix operator is considered an error (or is parsed as a prefix operator, depending on context).
 | 
			
		||||
 | 
			
		||||
Based on these two groups, the precedence of operators is defined as follows:
 | 
			
		||||
 | 
			
		||||
1. Prefix operators: `-a`, `!a`
 | 
			
		||||
1. Tight
 | 
			
		||||
 | 
			
		||||
    1. Dot: `a.b`
 | 
			
		||||
    1. Arithmetic: `a+b`, `a-b`, `a*b`, `a/b`
 | 
			
		||||
    1. Comparisons: `a==b`, `a!=b`, `a<b`, `a<=b`, `a>b`, `a>=b`
 | 
			
		||||
 | 
			
		||||
1. Function calls: `a b`
 | 
			
		||||
1. Loose
 | 
			
		||||
 | 
			
		||||
    1. Dot: `a . b`
 | 
			
		||||
    1. Arithmetic: `a + b`, `a - b`, `a * b`, `a / b`, `a |b`
 | 
			
		||||
    1. Comparisons: `a == b`, `a != b`
 | 
			
		||||
    1. Variables: `a: b`, `a = b`
 | 
			
		||||
 | 
			
		||||
The operators `+`, `-`, `*`, `/`, `==`, `!=`, `<`, `<=`, `>`, `>=`, `!`, are used for calling functions built into the haku [system library](system.html).
 | 
			
		||||
 | 
			
		||||
Other infix tokens listed above have other semantic meaning.
 | 
			
		||||
 | 
			
		||||
- `a b`, `.`, and `|` --- Used for calling [functions](#Functions).
 | 
			
		||||
- `:` --- Used for introducing [defs](#Structure-of-a-brush).
 | 
			
		||||
- `=` --- Used for introducing [lets](#Let-expression).
 | 
			
		||||
 | 
			
		||||
Examples of how these precedence rules work in practice:
 | 
			
		||||
 | 
			
		||||
```haku
 | 
			
		||||
2 + 2 * 2 == 8  -- left to right
 | 
			
		||||
2 + 2*2   == 6  -- 2*2 goes first
 | 
			
		||||
2+2 * 2   == 8  -- 2+2 goes first
 | 
			
		||||
2+2*2     == 8  -- left to right
 | 
			
		||||
 | 
			
		||||
sin 2 * pi * x == (sin 2) * pi * x  -- function call goes first
 | 
			
		||||
sin 2*pi*x     == sin (2 * pi * x)  -- argument goes first
 | 
			
		||||
 | 
			
		||||
-- unintuitive for users of C-likes:
 | 
			
		||||
-- prefix `-` has higher precedence than `.`
 | 
			
		||||
-vecX.v == (-vecX).v
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
One thing that should be noted about haku's operator precedence is that, unlike math notation and most other programming languages, `+`, `-`, `*`, and `/`, are evaluated from left to right.
 | 
			
		||||
This is because otherwise they would interact unintuitively with the pipe `|` operator, which is effectively used as an operator that turns any function infix.
 | 
			
		||||
 | 
			
		||||
It is not obvious where `|` would sit in the precedence hierarchy if arithmetic was split into separate precedence levels for `+` and `-`, and `*` and `/`, whereas with haku's solution, all arithmetic expressions are simply read from left to right.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### Parentheses
 | 
			
		||||
 | 
			
		||||
In case the tight-loose system is not expressive enough, parentheses can be used as an escape hatch for grouping expressions.
 | 
			
		||||
 | 
			
		||||
```haku
 | 
			
		||||
2 + (2 * 2) == 2 + 2*2
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### Functions
 | 
			
		||||
 | 
			
		||||
Functions in haku follow the definition of mathematical functions: given a set of _arguments_, the arguments are substituted into the function's _parameter variables_, and a result is computed from the resulting expression.
 | 
			
		||||
 | 
			
		||||
A function literal is written down like `\params -> result`, where `params` is a comma-separated list of parameters, and `result` is the function's resulting expression.
 | 
			
		||||
 | 
			
		||||
```haku
 | 
			
		||||
square: \x -> x * x
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
A newline is permitted after the arrow `->`, which should be preferred for most functions.
 | 
			
		||||
 | 
			
		||||
```haku
 | 
			
		||||
magnitude: \v ->
 | 
			
		||||
  hypot vecX.v vecY.v
 | 
			
		||||
 | 
			
		||||
normalize: \v ->
 | 
			
		||||
  l = magnitude v
 | 
			
		||||
  v / vec l l
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Note that there must be at least one parameter.
 | 
			
		||||
In case you need a function with no parameters, you almost always want a constant value instead.
 | 
			
		||||
 | 
			
		||||
Functions can be used by _calling_ them with space-separated arguments.
 | 
			
		||||
Note that space-separated function calls have higher precedence than most arithmetic operators, which means you have to use parentheses or tighten the expression to pass more complicated expressions.
 | 
			
		||||
 | 
			
		||||
```haku
 | 
			
		||||
normalize (vec 4 4)
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Note that a call must pass in _exactly_ the amount of arguments defined by the function.
 | 
			
		||||
Calling the above-defined `normalize` with more than one argument will not work:
 | 
			
		||||
 | 
			
		||||
```haku
 | 
			
		||||
normalize (vec 4 4) (vec 5 5)
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
In places where a call with space-separated arguments is inconvenient, there are two alternative syntaxes for calling a function.
 | 
			
		||||
 | 
			
		||||
The first is by using the `.` operator, which, when used tightly, can be used to do a function call with higher operator precedence than an ordinary space-separated call would have.
 | 
			
		||||
 | 
			
		||||
```haku
 | 
			
		||||
f x == f.x
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Combined with [records](#Records) and [tags](#Tags), it mimics the record field access syntax found in C-like programming languages.
 | 
			
		||||
 | 
			
		||||
```haku
 | 
			
		||||
withDotter \d ->
 | 
			
		||||
  stroke 8 #000 (line d.From d.To)
 | 
			
		||||
                      ------ ----
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The other alternative syntax is the _pipe_ `|` operator.
 | 
			
		||||
It calls the function on the right with the argument on the left.
 | 
			
		||||
 | 
			
		||||
```haku
 | 
			
		||||
2 |sqrt
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
When a space-separated function call is found on the right, the `|` operator instead inserts the value from the left as the first argument of the function call.
 | 
			
		||||
 | 
			
		||||
```haku
 | 
			
		||||
x |mod 2 == mod x 2
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The spacing convention around `|` is a bit unusual, but the above example demonstrates why: the `|` operator effectively turns an arbitrary function into an infix operator on par with built-in arithmetic operators.
 | 
			
		||||
Therefore, the function name is glued to the pipe, like `|mod`, to appear as one word visually.
 | 
			
		||||
 | 
			
		||||
Certain functions are _built-in_, and implement core functionality that cannot be implemented in haku alone (at all, or in a performant manner).
 | 
			
		||||
The [haku system library](system.html) is what defines all the built-in functions.
 | 
			
		||||
 | 
			
		||||
Due to temporary limitations of the implementation, built-in functions cannot be referenced like regular functions.
 | 
			
		||||
They always have to appear in a call.
 | 
			
		||||
 | 
			
		||||
If you'd like to reference a built-in function to e.g. pass it to a list-transforming function, you will have to wrap it in a function of your own:
 | 
			
		||||
 | 
			
		||||
```haku
 | 
			
		||||
add: \x, y -> x + y
 | 
			
		||||
sum: [1, 2, 3] |reduce 0 sum
 | 
			
		||||
 | 
			
		||||
sin': \x -> sin x
 | 
			
		||||
sines: [0, pi*1/2, pi*2/2, pi*3/2] |map sin'
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### `if` expressions
 | 
			
		||||
 | 
			
		||||
`if` expressions allow for choosing between two different results based on a condition.
 | 
			
		||||
 | 
			
		||||
```haku
 | 
			
		||||
if (cond)
 | 
			
		||||
  a
 | 
			
		||||
else
 | 
			
		||||
  b
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
When `cond` is [_true_](#Truth), `a` will be computed and returned as the result.
 | 
			
		||||
Otherwise, `b` will be computed and returned as the result.
 | 
			
		||||
 | 
			
		||||
Note that in both cases, only one of the two expressions is computed.
 | 
			
		||||
This allows for implementing bounded recursion to achieve repetition.
 | 
			
		||||
 | 
			
		||||
```haku
 | 
			
		||||
-- Fibonacci sequence
 | 
			
		||||
fib: \x ->
 | 
			
		||||
  if (x > 1)
 | 
			
		||||
    fib n-1 + fib n-2
 | 
			
		||||
  else
 | 
			
		||||
    x
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### Let expressions
 | 
			
		||||
 | 
			
		||||
Let expressions introduce a new _variable_, or _let_, that can be referenced in the expression on the next line.
 | 
			
		||||
 | 
			
		||||
```haku
 | 
			
		||||
x = y
 | 
			
		||||
expr
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The difference between lets and [defs](#Structure-of-a-brush) is that the value of a let can change, because it can depend on non-def values, such as function arguments (therefore making it _variable_.)
 | 
			
		||||
 | 
			
		||||
This however means that lets have reduced _scope_.
 | 
			
		||||
The name introduced by a def can be used in the entire program---even before the line it's introduced on---while the name introduced by a let can only be used in the expression that immediately follows the let.
 | 
			
		||||
 | 
			
		||||
```haku
 | 
			
		||||
x: 1
 | 
			
		||||
 | 
			
		||||
f: \y ->
 | 
			
		||||
  z = x + 1
 | 
			
		||||
  x + y + z  -- ok
 | 
			
		||||
 | 
			
		||||
z  -- not ok
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
This also means that lets cannot be used to create recursive functions, because the name introduced by a let only becomes visible in its following expression.
 | 
			
		||||
 | 
			
		||||
```haku
 | 
			
		||||
-- This is okay:
 | 
			
		||||
defib: \x ->
 | 
			
		||||
  if (x > 1)
 | 
			
		||||
    defib n-1 + defib n-2
 | 
			
		||||
  else
 | 
			
		||||
    x
 | 
			
		||||
 | 
			
		||||
-- This will not work:
 | 
			
		||||
letfib = \x ->
 | 
			
		||||
  if (x > 1)
 | 
			
		||||
    -- Because letfib is not yet defined at this point.
 | 
			
		||||
    letfib n-1 + letfib n-2
 | 
			
		||||
  else
 | 
			
		||||
    x
 | 
			
		||||
 | 
			
		||||
defib 5 + letfib 5  -- It is only defined in this expression.
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Since a let can be followed up by any other expression, multiple lets can be chained together.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
x = 4
 | 
			
		||||
y = x + 3
 | 
			
		||||
x + y
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Note however that `x + y` finishes the chain of lets, which means we cannot introduce additional ones after that line.
 | 
			
		||||
That would begin another expression!
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## Types
 | 
			
		||||
 | 
			
		||||
haku distinguishes values between a few different types.
 | 
			
		||||
 | 
			
		||||
- [*nil*](#Nil)
 | 
			
		||||
- [*tag*](#Tags)
 | 
			
		||||
 | 
			
		||||
  - [*boolean*]{id="Boolean-type"} - either [`False` or `True`](#Tags). Indicates truth or falsehood, used in [`if` conditions](#if-expression).
 | 
			
		||||
 | 
			
		||||
- [*number*](#Numbers)
 | 
			
		||||
- *vec* - a 4-dimensional vector, composed of four `number`s.
 | 
			
		||||
- [*rgba*](#Colors) - an RGBA color, composed of four `number`s. This is the type of color literals.
 | 
			
		||||
- [*function*](#Functions)
 | 
			
		||||
- [*list*](#Lists)
 | 
			
		||||
- *shape* - a mathematical shape.
 | 
			
		||||
- _*effect*_ - an action that can be performed by rakugaki.
 | 
			
		||||
 | 
			
		||||
  - *scribble* - something that can be drawn on the wall.
 | 
			
		||||
  - *reticle* - an interaction the user can make with the wall.
 | 
			
		||||
 | 
			
		||||
These types are incompatible with each other.
 | 
			
		||||
If you pass in a *tag* to a value that expects a *number*, you will get an error.
 | 
			
		||||
 | 
			
		||||
You can refer to the [system library documentation](system.html) for more information on the types accepted by functions.
 | 
			
		||||
Note that it has a more precise notation for describing types, which explicitly documents the types of values that will be found in more nuanced situations, such as the `map` function.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### Truth
 | 
			
		||||
 | 
			
		||||
Conditions in `if` expressions, as well as the `!` operator, consider certain types of values _truthy_, and others _falsy_.
 | 
			
		||||
 | 
			
		||||
Falsy values include *nil* and the boolean `False`.
 | 
			
		||||
All other values are considered truthy.
 | 
			
		||||
| 
						 | 
				
			
			@ -23,6 +23,7 @@ import_roots = [
 | 
			
		|||
 | 
			
		||||
"docs/rkgk.dj" = "Introduction to rakugaki"
 | 
			
		||||
"docs/system.dj" = "System library"
 | 
			
		||||
"docs/haku.dj" = "haku language reference"
 | 
			
		||||
 | 
			
		||||
[wall_broker.default_wall_settings]
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue