What sets rakugaki apart from other drawing apps is that all drawing is done via a tiny computer program called _the brush._
Most drawing programs offer very customizable brushes, but rakugaki is unique in that the brushes are computer programs!
::: aside
The name _rakugaki_ comes from the Japanese word 落書き, which roughly translates to _scribbles_!
Japanese artists also sometimes use the abbreviation rkgk, which is where the website _rkgk.app_ comes from.
:::
The task of a brush is to take the strokes you make on the wall, and turn them into instructions on what should be drawn on the wall.
We call these instructions _scribbles._
You can edit your brush in the _brush editor_, which can be found in the top right corner of your screen.
Try fiddling with the code a bit and see what happens!
## The code
Brushes are written in rakugaki's custom programming language called _haku._
haku belongs to a family of programming languages known as _functional_ programming languages.
In these languages, instead of giving the computer direct instructions on what to do, we instead _declare_ what we'd like the computer to do by using various forms of data.
haku treats all sorts of things as data.
Numbers are data, shapes are data, colors are data, and of course, scribbles are also data.
The task of a haku program is to manipulate data to produce a _single scribble._
Theoretically, this would mean brushes are very limited.
After all, if we're only limited to drawing single scribbles, wouldn't that mean a brush can only draw a single shape?
But the magical part is that you can _compose scribbles together._
haku vectors however are a little more constrained, because they always contain _four_ numbers---this makes them _four-dimensional_.
We call these four numbers X, Y, Z, and W respectively.
Four is a useful number of dimensions to have, because it lets us do 3D math---which technically isn't built into haku, but if you want it, it's there.
For most practical purposes, we'll only be using the first _two_ of the four dimensions though---X and Y.
This is because the wall is a 2D space---it's a flat surface with no depth.
It's important to know though that vectors don't mean much _by themselves_---rakugaki just chooses them to represent points on the wall, but in a flat 2D space, all points need to be relative to some _origin_---the vector `(0, 0)`.
In brushes, this position is at the tip of the mouse cursor.
Vectors in haku are obtained with another function---`vec`---though we don't use it in the basic example, because `d To` already is a vector.
Vectors support all the usual math operators though, so if we wanted to, we could, for example, add a vector to `d To`, thus moving the position of the dot relative to the mouse cursor:
```haku
withDotter \d ->
stroke 8 #000 (d To + vec 10 0) -- moved 10 pixels rightwards
The experience of drawing with that example brush is pretty crap, because it can draw dots that don't connect with each other at all.
Let's fix that by drawing a `line` instead!
```haku
withDotter \d ->
stroke 8 #000 (line (d From) (d To))
```
We replace the singular position `d To` with a `line`. `line` expects two arguments, which are vectors defining the line's start and end points.
For the starting position we use a _different_ property of `d`, which is `From`---this is the _previous_ value of `To`, which allows us to draw a continuous line.
That's quite a lot of copy-pasting for such a simple thing!
Luckily, haku has a solution for this: we can give a _name_ to a piece of data by using a _definition_, and then refer to that piece of data using that name we chose.
That's a lot nicer, isn't it---a template for our circles is neatly defined in a single place, and all we do is reuse it, each time with a different `radius`.
Parameters are the names we give to a function's arguments---for a function call `splat 8`, we need the function to have a name for that `8` datum that gets passed to it.
Note that a function can only have _one_ result, just like a brush can only have one scribble.
::: aside
One interesting thing you may have noticed with parameters, is that some system functions can accept varying numbers of them.
Such as `vec`, which can accept from zero to four.
This is called _function overloading_ and is somewhat common among programming languages.
It is also kind of controversial, because if a function if overloaded to do vastly different things depending on the number or type of data that is given to it, it can become quite hard to predict what it'll really do!
haku limits the use of overloading to system functions for simplicity---adding overloading would require introducing extra syntax, which would make the language harder to grok fully.
:::
Since these transparent circles are so much easier to draw now, let's make a few more of them!
We have to make _a lot_ of these circles, and we're still repeating ourselves.
There's less to repeat, but my brain can quickly recall only so many increments of 8.
::: aside
Seriously, 64 is my limit.
:::
I wonder if there's any way we could automate this?
### The Ouroboros
You know the drill by now.
We're programmers, we're lazy creatures.
Anything that can be automated, we'll automate.
But there doesn't seem to be an obvious way to repeat a bunch of values like this, no?
Well, there isn't.
At least not in a continuous list like that, yet.
But remember how lists can nest?
What we _could_ do is define a function that constructs a list out of a circle, and then a call back to _itself_, which will then construct another list out of a circle and a call back to itself, so on and so forth...
Until some threshold is reached, in which case we just make a single circle.
The first part is easy to do: haku allows us to define a function that calls itself without making any fuss.
haku doesn't let our code run indefinitely, and that's precisely what would happen in this case.
Also, it used an important word in that error message: *recursion.*
This is what we call the act of a function calling itself.
Sometimes people say that a function calls itself _recursively_, which sounds redundant, but it clarifies it's to achieve _iteration_---the act of executing the same code repeatedly, over and over again.
Anyways, we need some way to make the function _stop_ calling itself after some time.
For that, there's another piece of haku magic we can use: `if`.
`if` will execute a bit of code and pass on its result if a condition is found to be true.
Otherwise, it will execute a different bit of code.
We call this act of switching execution paths _branching_.
Try this out---change the `radius`, and observe how your brush changes color once you set it beyond 16:
- We need three arguments to execute an `if`: the condition, the data to use when the condition is `True`, and the data to use when the condition is `False`.
All we have to do is specify the size, and the code does all the magic for us!
Obviously, it's not really shorter than what we started with when we were listing all the circles manually, but the beauty is that we can control all the parameters trivially, by editing single numbers---no need for copy-pasting stuff into hellishly long lists.
But the airbrush still looks super primitive.
Let's try increasing the fidelity by doing smaller steps!
Looks good as a single dot, but if you try drawing with it... it's gray??
## Limits of the wall
Unfortunately, we don't live in a perfect world... and neither is rakugaki a perfect tool.
What's happening here requires understanding the internals of rakugaki's graphics engine a bit, but bear with me---I'll try to keep it simple.
As much as haku works on 32-bit real numbers, due to on-disk storage and memory considerations, rakugaki renders things in an 8-bit color space.
Therefore, unlike haku, it can only represent color channels from 0 to 255, with no decimal point.
There's Red 1 and Red 2, but no Red 1.5.
::: aside
haku uses a standard representation of real numbers in the computer world, better known as IEEE 754 floating point.
This standard has its quirks, such as `NaN`---a value that is *N*ot *a* *N*umber, in a standard representation for real numbers.
Huh.
What's even funnier is that `NaN` is not equal to anything, even itself.
_Huh._
And what's _even_ funnier is that `NaN` infects anything it touches with itself.
One plus `NaN` is `NaN`.
It's like an error flag that propagates across your calculations, with no context as to what went wrong, and when.
I gotta make the appearance of `NaN` a hard error in haku someday.
:::
Now let's consider what blending colors does.
Most commonly, colors are blended using _linear interpolation_---which is essentially, you draw a straight line segment between two colors in the RGB space, and take a point across that segment, at the alpha value---where an alpha of 0 means the starting point, and an alpha of 1 means the ending point.
Mathematically, linear interpolation is defined using this formula:
What we're doing when blending colors, is mixing between a _source_ color (the wall), and a _destination_ color (the brush) on each channel.
Since the operations are the same across all four color channels, we'll simplify and only look at Red.
But due to this reduced precision on the wall, we have to convert from a real number between 0 and 1, to an integer between 0 and 255 at _every rendering step_, with each splat of the brush rendered to the wall.
Consider that we're drawing circles of opacity 0.01 every single time.
Now let's look what happens when we try to blend each circle on top of a single pixel...
Having basic knowledge of functions and scribbles, you may be wondering: _what does that `withDotter` function do?_
It surely looks a bit magical, conjuring that `d` parameter from nowhere; and `d` contains everything we need to draw!
Put simply, `withDotter` is what rakugaki calls a *reticle*.
Reticles are pieces of data representing _interactions with the wall_.
A reticle is usually composed of two parts: the reticle data, defining how the interaction is meant to be initiated, and a _continuation function_.
When your brush gives rakugaki a reticle, it will take the reticle data, and let the user perform an interaction.
Once the interaction is performed, it will give whatever user input it has gathered as an argument to the continuation function, which can return a scribble to draw on the wall, or another reticle.
rakugaki will continue performing interactions until the brush gives back a scribble.
`withDotter` is the simplest, most direct reticle for interacting with the wall.
It allows you to paint freely, and gives the brush information on your current mouse position, previous mouse position, and _number of steps_ performed thus far.
You've already seen the former two properties---those are `d To` and `d From`.
The number of steps is available as `d Num`.
This is an integer starting at 0, incremented by 1 with each execution of the brush, until you release your mouse cursor.
This allows you to _animate_ your brushes over time!
For example, this brush draws a rainbow.
```haku
colorCurve = \n ->
abs (cos n)
pi = 3.14159265
l = 0.1 -- wavelength
withDotter \d ->
let r = colorCurve (d Num * l)
let g = colorCurve (d Num * l + pi/3)
let b = colorCurve (d Num * l + 2*pi/3)
let color = rgba r g b 1
stroke 8 color (line (d From) (d To))
```
Currently, `withDotter` is the only reticle available in rakugaki, and it cannot be chained due to its immediate nature:
`withDotter` continues executing immediately after you move your mouse by the _tiniest_ bit, so it's unclear how to even continue after that!
In the future rakugaki might get reticles that let you select lines, rectangles, ellipses, curves... but today is not that day.
### What's that, `let`?
I mentioned before that you cannot have defs inside functions.
What you _can_ have though, is `let`s, which define _variables_.
Unlike defs, which are constant and cannot vary, variables' values can depend on function parameters---and a function can be called with a different set of parameters each time, thus making them variable!
A `let` always takes the following form.
```haku
let name = value
then
```
It's very similar to a def, with one major difference.
Because a `let` by itself only _names a value_ and does not have a result, it must be followed by another expression on the following line---and that expression determines the result.
The magic is that this continuing expression can refer to the `name` we had previously assigned in the `let` expression.
::: aside
Here's a bit of trivia: the variable defined by a `let` is exactly the same as a function parameter.
The `let` above is equivalent to applying the argument `value` to a function taking in the parameter `name`, and returning `then` as the result.
```haku
(\name -> then) value
```
This basic little trick with immediately applying a function stands the basis of a formal mathematical system called [_lambda calculus_](https://en.wikipedia.org/wiki/Lambda_calculus).
It underpins a large number of functional programming languages, including haku, and more famously [Haskell](https://www.haskell.org/)!
That's right. haku is a cute little Haskell for artists.
:::
`let`s aren't only useful for reusability---they're also helpful for breaking your brushes into smaller, more digestible pieces!
Compare the above version of the rainbow brush to this version, where all the `let`s are written inline:
```haku
colorCurve = \n ->
abs (cos n)
pi = 3.14159265
l = 0.1 -- wavelength
withDotter \d ->
stroke 8 (rgba (colorCurve (d Num * l)) (colorCurve (d Num * l + pi/3)) (colorCurve (d Num * l + 2*pi/3)) 1) (line (d From) (d To))
```
That's one hard to read beast of a `stroke`!
Generally, if a line is so long it wraps around rakugaki's narrow little text editor, it's probably a good idea to split it into variables.
You may want to check out the [system library reference](/docs/system.html) now, to know what else you can do with the language---this little introduction barely even scratched the surface of what's possible!