Commits: 2

Outline tree growing and a basic implementation of a tree program

index b4c52b5..b6f46a0 100644
--- a/index.md
+++ b/index.md
@@ -384,9 +384,9 @@ Day 3
=
=        There are a number of functions that operate on lists, for example `List.length` and `List.map`.
=
-        Examples of a map: a shopping list, after you find each item and place it in your basket, you are 'mapping' from a list of needed items to a list of items in your basket. Now you have two lists, and they are related. One is your original shopping list, the other the list of items in the basket. 
+        Examples of a map: a shopping list, after you find each item and place it in your basket, you are 'mapping' from a list of needed items to a list of items in your basket. Now you have two lists, and they are related. One is your original shopping list, the other the list of items in the basket.
=
-        Demonstrate: 
+        Demonstrate:
=
=        ```elm
=        > things = ["Programming", "Swimming", "Dancing", "Saddle brown"]    
@@ -406,12 +406,12 @@ Day 3
=            : List String
=        ```
=
-        Notice our original `things` list is unchanged. This is different from our rubber duck machine. The rubber duck turns the plastic and paint into rubber ducks. A function on the other hand 'creates' the value it gives you. You don't loose the original value given to it. 
+        Notice our original `things` list is unchanged. This is different from our rubber duck machine. The rubber duck turns the plastic and paint into rubber ducks. A function on the other hand 'creates' the value it gives you. You don't loose the original value given to it.
=
=      - Make a `palette : List color`
=
=        ```elm
-        palette = 
+        palette =
=          [ "darkred"
=          , "fuchsia"
=          , "saddlebrown"
@@ -436,14 +436,14 @@ Day 3
=        List.indexedMap dot palette
=        ```
=
-        We can introduce a `let` block to make our code more readable and avoid repetition. 
+        We can introduce a `let` block to make our code more readable and avoid repetition.
=
=        ```elm
=        dot index color =
=            let
-                angle = 
+                angle =
=                    (360 / count) * index
-    
+
=                count =
=                    List.length palette
=            in
@@ -491,8 +491,8 @@ Introduce SVG groups
=        ]
=    ```
=
-    We see a problem here. The gradient always goes from saddlebrown to pink from top left to bottom right. If we want to use the same gradient to connect different points, we'll need to be creative. 
-    
+    We see a problem here. The gradient always goes from saddlebrown to pink from top left to bottom right. If we want to use the same gradient to connect different points, we'll need to be creative.
+
=    ```
=    main =
=        svg [ width "600", height "600", viewBox "-300 -300 600 600" ]
@@ -513,7 +513,7 @@ Introduce SVG groups
=
=    We need to fix the viewbox!
=
-    Here's the trick: we have the lines initially match the gradient. We're using the same x and y values for all the lines and the gradient. Then we transform the lines to position them where we'd like them. We're actually using our old friend polar coordinates here. 
+    Here's the trick: we have the lines initially match the gradient. We're using the same x and y values for all the lines and the gradient. Then we transform the lines to position them where we'd like them. We're actually using our old friend polar coordinates here.
=
=    If you're interested in what `gradientUnits "userSpaceOnUse"` does, come see me after the lesson.
=
@@ -524,23 +524,23 @@ Introduce SVG groups
=            [ Svg.stop [ Svg.Attributes.offset "0", Svg.Attributes.stopColor "saddlebrown" ] []
=            , Svg.stop [ Svg.Attributes.offset "1", Svg.Attributes.stopColor color ] []
=            ]
-    
-    
+
+
=    line : Int -> String -> Svg msg
=    line index color =
=        let
=            angle =
=                (360 / toFloat (List.length pallete)) * toFloat index
-    
+
=            transformation =
=                "rotate(" ++ String.fromFloat angle ++ "),scale(" ++ String.fromInt radius ++ ",1)"
-    
+
=            url =
=                "url(#Gradient-" ++ String.fromInt index ++ ")"
=        in
=        Svg.line [ x1 "0", y1 "0", x2 "1", y2 "0", transform transformation, stroke url ] []
-    
-    
+
+
=    main =
=        svg [ width "600", height "600", viewBox "-300 -300 600 600" ]
=            [ Svg.g [] (List.indexedMap dot pallete)
@@ -549,23 +549,23 @@ Introduce SVG groups
=            ]
=    ```
=
-    This may look like a lot, but our `gradient` and `line` functions are very similar to our `dot` function from earlier. In fact we see an essential principle of good programming design here. We spent a lot of time banging our heads over gradients. Now that we've done that work, we can hide the implementation in our gradient and line functions. Now, if we want to draw a new dot, line, and gradient going from the center to the dot, we only need to add a new item to our palette. Our functions do the rest for us. Our functions conceal our complexity. We can forget about the implementation, so long as we know how to operate them. They're like black boxes, we know what goes in and what comes out, but we don't have to know how they work on the inside. 
+    This may look like a lot, but our `gradient` and `line` functions are very similar to our `dot` function from earlier. In fact we see an essential principle of good programming design here. We spent a lot of time banging our heads over gradients. Now that we've done that work, we can hide the implementation in our gradient and line functions. Now, if we want to draw a new dot, line, and gradient going from the center to the dot, we only need to add a new item to our palette. Our functions do the rest for us. Our functions conceal our complexity. We can forget about the implementation, so long as we know how to operate them. They're like black boxes, we know what goes in and what comes out, but we don't have to know how they work on the inside.
=
=
=Day 5
=
-    Our project is looking pretty good at this point. We've created some interesting graphical elements, and learned some interesting ways to place them programatically. However, it doesn't take user input like many of the programs we use. We'll be doing some pretty interesting things with user input later in this workshop, but for now we'll start with a deceptively simple step: setting the background color. 
+Our project is looking pretty good at this point. We've created some interesting graphical elements, and learned some interesting ways to place them programatically. However, it doesn't take user input like many of the programs we use. We'll be doing some pretty interesting things with user input later in this workshop, but for now we'll start with a deceptively simple step: setting the background color.
=
-I say this step is deceptively simple, because we'll need to make some big changes to our program and introduce a number of new concepts. 
+I say this step is deceptively simple, because we'll need to make some big changes to our program and introduce a number of new concepts.
=
-Show complete code. 
+Show complete code.
=
-There's a lot going on here, and it's not obvious how it all works. 
+There's a lot going on here, and it's not obvious how it all works.
=
-Our `main` function has changed. 
+Our `main` value has changed.
=
=```
-main : Program () Color Msg
+main : Program () State Msg
=main =
=    Browser.sandbox
=        { init = init
@@ -574,7 +574,8 @@ main =
=        }
=```
=
-Previously, our `main` function contained an SVG element. Now it contains a call to `Browser.sandbox`. A sandbox is a basic interactive program. For a program to be interactive, it need more than just a SVG element. It also needs a `state`. The state of an application is basically the information used to determine how the application should be rendered. Think about the Atom program we are all running at the moment. We know we are all running the same program, however we are not all looking at exactly the same thing. The text in our neighbours editor might be slightly different than the text in our own. If they opened another file, a letter to a friend for example, the text would be very different. The text input is part of the state of the Atom application. Maybe your neighbour has scrolled to another point in the screen. The scroll point is also part of the state of the Atom application. The cursor might be on another line in their viewport. The cursor position is also part of the state of the Atom application. Atom uses all of this state information to render exactly what you are seeing on your computer screen. Anything that can change will be represented in a state variable. If you input or delete text, move the cursor, scroll up or down, or change any of the application settings, you are updating the state of the Atom application.
+Previously, the value of `main` was an SVG element. Now it contains a call to `Browser.sandbox`. A sandbox is a basic interactive program. For a program to be interactive, it need more than just a SVG element. It also needs a `state`. The state of an application is basically the information used to determine how the application should be rendered. Think about the Atom program we are all running at the moment. We know we are all running the same program, however we are not all looking at exactly the same thing. The text in our neighbors editor might be slightly different than the text in our own. If they opened another file, a letter to a friend for example, the text would be very different. The text input is part of the state of the Atom application. Maybe your neighbor has scrolled to another point in the screen. The scroll point is also part of the state of the Atom application. The cursor might be on another line in their viewport. The cursor position is also part of the state of the Atom application. Atom uses all of this state information to render exactly what you are seeing on your computer screen. Anything that can change will be represented in a state variable. If you input or delete text, move the cursor, scroll up or down, or change any of the application settings, you are updating
+the state of the Atom application.
=
=```
=type alias State =
@@ -585,9 +586,11 @@ type alias Color =
=    String
=```
=
-Here we create something called a type alias. We've already discussed types. A type alias is basically a way to give an alternative name for a type. We give the alias `Color` to string and the alias `State` to `Color`. All of these types are strings, and Elm will treat them all as strings. But it will make our code more readable to use these aliases. We are writing an application that allows the user to change the background color. That should explain why our `State` is a `Color`. 
+Here we create something called a type alias. We've already discussed types. A type alias is basically a way to give an alternative name for a type. We give the alias `Color` to `String` and the alias `State` to `Color`. So in the end all three names point to the same type!
+
+Why are we doing this? All of these types are strings, and Elm will treat them all as strings. But it will make our code more readable to use these aliases. We are writing an application that allows the user to change the background color. That should explain why our `State` is a `Color`.
=
-Our `Browser.sandbox` takes something with the name `init`. This is our initial state. Let's take a look at the value of `init`. 
+Our `Browser.sandbox` takes something with the name `init`. This is our initial state. Let's take a look at the value of `init`.
=
=```
=init : State
@@ -595,9 +598,9 @@ init =
=    "white"
=```
=
-We see that the initial state is `"white"`. We'll see how our application uses this value in a moment. 
+We see that the initial state is `"white"`. We'll see how our application uses this value in a moment.
=
-Looking back at our `sandbox`, we see it also takes a `view`. Let's take a look at our view function: 
+Looking back at our `sandbox`, we see it also takes a `view`. Let's take a look at our view function:
=
=```
=view : State -> Html Msg
@@ -616,14 +619,13 @@ view color =
=
=You'll notice that this `view` function looks very similar to the `main` variable from earlier. Before, our application was only a view. Now the view is only one piece of our interactive application.
=
-One important way our `view` function differs from the `main` variable from ealier is that `view` is a function. We see it takes a variable of type `State` (a string), which we have named `color`. In an Elm sandbox project the `view` always takes a variable with the same type as the `init` variable. This is the current state of the application. `view` can use the state to render the application properly, just as Atom uses its state to render text for its user. 
-
-We see that we've added a line to the svg attributes, `Svg.Attributes.style ("background: " ++ color)`. Here we use the state of the application to set the background color of the svg element. 
+One important way our `view` function differs from the `main` variable from ealier is that `view` is a function. We see it takes a variable of type `State` (a string), which we have named `color`. In an Elm sandbox project the `view` always takes a variable with the same type as the `init` variable. This is the current state of the application. `view` can use the state to render the application properly, just as Atom uses its state to render text for its user.
=
+We see that we've added a line to the svg attributes, `Svg.Attributes.style ("background: " ++ color)`. Here we use the state of the application to set the background color of the svg element.
=
=All we need now is some way to update the state (the background color) of the application.
=
-Taking a look at our `main` function, we see that it take a third and final function, `update`. Let's look at our update function: 
+Taking a look at our `main` function, we see that it take a third and final function, `update`. Let's look at our update function:
=
=```
=type Msg
@@ -638,13 +640,58 @@ update msg state =
=
=```
=
-We see our `update` function takes two variables, of type `Msg` and `State`. If we think of update as a machine which takes an old state and spits out a new state, this state variable corresponds to the old state. 
+We see our `update` function takes two variables, of type `Msg` and `State`. If we think of update as a machine which takes an old state and spits out a new state, this state variable corresponds to the old state.
+
+The `msg` variable is something new. Looking above, we see that we have defined a `Msg` variable type. This is similar to our `State` and `Color` union types, in that we have defined a new type that Elm understands. However, unlike the `type alias` constructor, the `type` constructor does not simply give a new name for an existing type. Instead, here we define a completely unique type. We see values with type Msg must have the form `SetBackground Color`. `SetBackground "white"`, `SetBackground "blue"`, `SetBackground "saddlebrown"` are all valid values of the type `Msg`.
+
+What is important to understand is that our `msg` variable is used by `update` to determine how it should update the state. We see that update first checks that `msg` has the form `SetBackground color`, and then returns the value of `color`. This will become our new state. Every time update is called, the sandbox will re-render our view with the new state.
+
+So now we see how our application changes the background color of the svg element. However, we haven't seen when it will update the background color. Well, we want to change the background color by clicking a dot. So let's take a look at our `dot` function to see if we can find a hint there.
+
+- `Model`:
+
+  the structure of the state of the program
+
+  TODO: Consistently use `Model` and `model` instead of less standard `State` to make it easier to our participants.
+
+- `Msg`
=
-The `msg` variable is something new. Looking above, we see that we have defined a `Msg` variable type. This is similar to our `State` and `Color` union types, in that we have defined a new type that Elm understands. However, unlike the `type alias` constructor, the `type` constructor does not simly give a new name for an existing type. Instead, here we define a completely unique type. We see values with type Msg must have the form `SetBackground Color`. `SetBackground "white"`, `SetBackground "blue"`, `SetBackground "saddlebrown"` are all valid values of the type `Msg`. This is a bit complex, but will become familiar once we've seen some examples in use. 
+  What events can there be in the program. Currently have only one possible event - setting the background to a given color.
=
-What is important to understand is that our `msg` variable is used by `update` to determine how it should update the state. We see that update first checks that `msg` has the form `SetBackground color`, and then returns the value of `color`. This will become our new state. Every time update is called, the sandbox will rerender our view with the new state. 
+- `update`
+
+  the instructions of how to change the state when a particular message comes in.
+
+- `view`
+
+  the instruction of what to display on the screen. It also contains instructions of what messages to send when certain events (like clicks on elements) happen. Every time the state changes the instructions will be applied.
+
+- `init`
+
+  What is the initial state right after the program is started.
+
+- `main`
+
+  glues it all together.
+
+Next steps:
+
+- How do we model the tree
+
+  - introduces the model for later interactive program
+
+  - naturally introduces union types
+
+
+- Make a tree grow
+
+  - Make a function that given the age of the tree and rules returns a tree
+
+  - Use time subscription to make the tree grow
+
+<!-- slide -->
=
-So now we see how our application changes the background color of the svg element. However, we haven't seen when it will update the background color. Well, we want to change the background color by clicking a dot. So let's take a look at our `dot` function to see if we can find a hint there. 
+``
=
=```
=dot : Int -> String -> Svg Msg
@@ -663,15 +710,15 @@ dot index color =
=        []
=```
=
-We see there is a new line here: 
+We see there is a new line here:
=
=```
=Svg.Events.onClick (SetBackground color)
=```
=
-`onClick` is an event. It basically tells our svg element to listen for someone to click on it. It will then handle the event by emitting the Msg `SetBackground color`. We know `color` is the color of the dot. We see then that when someone clicks on the dot, the Msg will be emitted, `update` will be called with this Msg and will update our state. Our sandbox will rerender the view with this new state. The user will see the svg element with a new background color. 
+`onClick` is an event. It basically tells our svg element to listen for someone to click on it. It will then handle the event by emitting the Msg `SetBackground color`. We know `color` is the color of the dot. We see then that when someone clicks on the dot, the Msg will be emitted, `update` will be called with this Msg and will update our state. Our sandbox will rerender the view with this new state. The user will see the svg element with a new background color.
=
-Notice that our `view` function, as well as all the functions that call functions responsible for rendering svg elements, including `gradient`, `line`, and `dot` have return values with type `Svg Msg` or `Html Msg`. This is because svg element can emit Msgs which will be handled by `update`. 
+Notice that our `view` function, as well as all the functions that call functions responsible for rendering svg elements, including `gradient`, `line`, and `dot` have return values with type `Svg Msg` or `Html Msg`. This is because svg element can emit Msgs which will be handled by `update`.
=
=
=<!-- slide -->

Basic implementation of a tree growing program

Accidentally not included in previous commit.

new file mode 100644
index 0000000..1939a19
--- /dev/null
+++ b/src/Tree.elm
@@ -0,0 +1,179 @@
+module Tree exposing (main)
+
+import Browser
+import Browser.Events
+import Dict exposing (Dict)
+import Html exposing (Html)
+import Svg exposing (..)
+import Svg.Attributes exposing (..)
+
+
+main =
+    Browser.element
+        { init = init
+        , view = view
+        , update = update
+        , subscriptions = subscriptions
+        }
+
+
+type alias Flags =
+    ()
+
+
+type alias Model =
+    { time : Float
+    , rules : Rules
+    }
+
+
+type Msg
+    = Progress Float
+
+
+type Tree
+    = Tip Segment
+    | Node Segment (List Tree)
+
+
+type alias Color =
+    String
+
+
+type alias Segment =
+    { color : Color
+    , angle : Float
+    , length : Float
+    }
+
+
+type alias Rules =
+    Dict Color (List Segment)
+
+
+init : Flags -> ( Model, Cmd Msg )
+init () =
+    ( { time = 1
+      , rules =
+            Dict.fromList
+                [ ( "red"
+                  , [ Segment "yellow" (degrees 15) 10
+                    , Segment "yellow" (degrees 175) 10
+                    ]
+                  )
+                , ( "yellow", [ Segment "blue" (degrees 15) 10 ] )
+                , ( "blue", [ Segment "red" (degrees 15) 10 ] )
+                ]
+
+      -- [ ( "red"
+      --   , [ Segment "blue" (degrees 90) 10
+      --     , Segment "yellow" (degrees -45) 4
+      --     ]
+      --   )
+      -- , ( "yellow", [ Segment "red" (degrees 90) 6 ] )
+      -- ]
+      }
+    , Cmd.none
+    )
+
+
+view : Model -> Html Msg
+view model =
+    Html.div []
+        [ Html.h1 [] [ Html.text <| String.fromFloat model.time ]
+        , Segment "red" 0 0
+            |> Tip
+            |> grow model.rules (model.time / 1000)
+            |> svgTree
+            |> List.singleton
+            |> svg [ viewBox "-1000 -1000 2000 2000", height "800px", width "800px" ]
+        ]
+
+
+update : Msg -> Model -> ( Model, Cmd Msg )
+update msg model =
+    case msg of
+        Progress delta ->
+            ( { model | time = model.time + delta }
+            , Cmd.none
+            )
+
+
+subscriptions : Model -> Sub Msg
+subscriptions model =
+    Browser.Events.onAnimationFrameDelta Progress
+
+
+
+-- Sub.none
+
+
+htmlTree : Tree -> Html Msg
+htmlTree tree =
+    case tree of
+        Tip segment ->
+            Html.li [] [ Html.text <| "Tip: " ++ Debug.toString segment ]
+
+        Node segment trees ->
+            Html.li []
+                [ Html.text <| "Tip: " ++ Debug.toString segment
+                , Html.ul [] <| List.map htmlTree trees
+                ]
+
+
+svgTree : Tree -> Html Msg
+svgTree tree =
+    case tree of
+        Tip segment ->
+            circle [ cx "0", cy "0", fill segment.color, r "10" ] []
+
+        Node segment trees ->
+            let
+                x =
+                    segment.length * cos segment.angle
+
+                y =
+                    segment.length * sin segment.angle
+
+                transformation =
+                    "translate("
+                        ++ String.fromFloat x
+                        ++ ", "
+                        ++ String.fromFloat y
+                        ++ ")"
+            in
+            g [ transform transformation ] <|
+                circle [ cx "0", cy "0", fill segment.color, r "10" ] []
+                    :: List.map svgTree trees
+
+
+grow : Rules -> Float -> Tree -> Tree
+grow rules age branch =
+    if age > 0 then
+        case branch of
+            Tip segment ->
+                let
+                    tips =
+                        rules
+                            |> Dict.get segment.color
+                            |> Maybe.withDefault []
+                            |> List.map
+                                (\rule ->
+                                    { rule
+                                        | angle = rule.angle + segment.angle
+                                        , length = rule.length * age
+                                    }
+                                )
+                            |> List.map Tip
+                in
+                tips
+                    |> Node segment
+                    |> grow rules (age - 1)
+
+            Node segment trees ->
+                trees
+                    |> List.map (grow rules age)
+                    |> Node segment
+
+    else
+        branch