disastrs :: present! :: notes

Welcome to my #2024DecentureAdvember log

This december I'm deciding to focus on term re-writing.

A secondary objective will be re-writing the site. It's important!

Days

  1. Day 1 :: Intro to modal :: In which I am confused by single-token re-writes
  2. Day 2 :: Cursors and registers in modal :: In which I am enticed by a NAS
  3. Day 3 :: A cursor with personality :: In which I attempt a challenge
  4. Day 4 :: Rewriting Addled :: In which I solve the challenge
  5. Day 5 :: Tic Tac Toe :: In which I gain confidence, and a head-cold
  6. Day 6 :: Tri-angler :: In which I am awed
  7. Day 7 :: Brush Bubble :: Om Swasti
  8. Day 8 :: Fun can work :: In which I refine the sketchpad
  9. Day 9 :: Percolation :: In which I modify the site
  10. Day 10 :: Game of Life pt. 1 :: In which I begin another challenge
  11. Day 11 :: Brief Diversion :: In which I implement applicative-order evaluation
  12. Day 12 :: Static, Life :: In which I iterate
  13. Day 13 :: Try to Optimize :: In which I am lead down a false path
  14. Day 14 :: Fun Can Work II :: In which I revisit a friend
  15. Day 15 :: Pain :: In which I crack a rib
  16. Day 16 :: Style :: In which I add a little padding
  17. Day 17 :: A Day Off :: In which I suffer from bad noodles
  18. Day 18 :: Poly Gonner :: In which I am still recovering
  19. Day 19 :: Recovery :: In which I reflect
  20. Day 20 :: Game of Life pt. 3 :: In which I am in over my head
  21. Day 21 :: Style 2 :: In which I make the edges crisp
  22. Day 22 :: Wrapping Up :: In which I write
  23. Day 23, 24, 25 :: Epilogue

Rules

  1. have some fun
  2. simplify (!)
  3. stay hydrated

Day 23, 24, 25 ::

The 25th of December formally concludes the 2024 December Adventure.

Here are some other things I've done in the last few days:

: : : :

Here's the draft I worked on:

Here's "just the bones"

: : : :

See you next year :)

Day 22

I am beginning to thing that I should wrap up this year's DecemberAdventure.

This month I have:

I also received my jiu jitsu blue belt, and drank a lot of water. (Hydration?)

: : : :

When I asked on Merveilles how other multi-disciplinary artists "keep it together", I got one response, from Devine:

"journaling"

I'm honestly pretty new to this, trying to write constructively about what I'm doing, as I'm doing it.

I've journalled before, extensively, and when I went back to re-read them this year I found the contents utterly useless.

This was because I was often only writing about my hard feelings. (Somehow, writing about them didn't make them any softer.)

I am also pretty new to trying to approach art more systematically than "Just do what I feel like".

This seems important to figure out, though. I am spread somewhat thin, in terms of interests. Finding through-lines is essential.

: : : :

I think if you're aware of what you're doing, as you're doing it, you'll automatically refine your approach.

It could be the dishes, cooking mussels, routing baseboards, chopping breaks, etc.

There's work to do, too, you can't just retreat into what's rote -- that would seem to be a strategy to avoid being present.

In a way, a more refined approach is more empty -- maybe you're doing less, maybe as you "get better" you're paring away more and more unnecessary movement

In a way, a more refined approach is more full -- maybe what you're doing fits closer and closer to the subject matter and substance of the medium.

: : : :

What now?

I haven't touched upon Fractran, or Vera, or any other re-writing language.

My site is still half one thing, half another. I will continue to write for it, and let my writing workflow co-evolve with the structure for it. I really like this format.

Day 21

I was gathering wood with my father, when I turned to him and said:

"I probably spend an abnormal amount of time thinking about how to lapel-choke people"

: : : :

Images on the site now default to crisp edges!

    img {
    image-rendering: crisp-edges;
    }
  

Day 20

I decide to tackle my implementation of Conway's Game of Life

I learned something very useful, which is that the color codes used in Thuesday (#72dec1) are parsed as integers. So, we can do normal math on them.

I also had the idea of using the first row of pixels on my screen as ram for my implementation.

When evaluating one tick in the Game of Life, you have to buffer (at minimum) the most-recently evaluated cell, as well as the previous row of cells, otherwise you lose access to that history when you draw your new cells in the grid

How's the implementation going, you ask?

Bad.

: : : :

Because I cannot leave well enough alone, and because I will have no time tomorrow, I decided to finish my implementation today.

What the hell, I did all the chores already, and it's the start of vacation."

The Pulsar oscillator, from Conway's Game of Life. Conway's game of life, starting from a random seed.

My implementation is here

There are still bugs, I'm sure, because things behave oddly at the boundaries.

I would probably fix this by adding more granular re-write rules for the edge-cases.

There are also optimizations one could do --

For example, instead doing two row-copies every row, you could copy to row 0 and row 1 alternately, and use alternating rules to get neighbors from it.

But this is done. I'm going to say it's done now.

Day 19

I have finished working at my day job for the year!

Yesterday I stretched a bit to finish Poly-Gonner

Today I realize I'm not so sure what to with Modal

Then I also thought, "What's the point of making these cool tools if you don't use them?"

: : : :

I think these partially-occluded lines you can get from drawing black lines on top of colored lines are very interesting. They reveal something about the line-drawing algorithm, that I don't "get" by reading the source code.

I sometimes thing \

Reading the source code is also important. Reading the source code would have helped me earlier when I attempted an ill-fated optimization.

Maybe I should do that next?

Day 18

I finish work on my polygon drawing tool

Actually, it's more of a circle - line - triangle - quadrangle - fill-circle draw tool

Poly Gonner

Day 17

I was rather comically sick all night last night, and every part of my body (seemingly even my hair) aches.

There will be no work on modal or the website tonight.

Stay Hydrated!

Day 16

Thankfully, my rib injury isn't as bad as I feared it might be.

: : : :

I decide on a short break from modal, and work on styling for disast.rs

The left side is a little cramped against the side of the screen, and the very long paragraphs are a little annoying.

Let's do something about it!

    pre {
    background: #efefef;
    margin: 0 -111em;
    padding: .5em 112em;
    overflow-x: scroll;
    }
    main { max-width: 768px; padding: 0 24px; }
    .sep { margin-left: 1em; }
    hr { margin: .5em -10em; }
    header { margin-left: 24px; }
    footer { margin-left: 24px; }
  

Day 15

I implemented an integer square-root approximator, which lets me calculate distances. Now, I can draw circles in a rather controlled manner.

Wonderful!

Intersecting circles, placed in a manner the author finds visually pleasing.
    ?(?-) (Implement floor(sqrt(n)), for any non-negative n)
    <> ((?0) (?1) `?:) ?:
      ?(?-) (I am sure there is a more efficient way)
      <> (sqrt-intermed (?i) (?n) (1) (?x)) ((?i) (2) `-)
        <> (sqrt-intermed (?i) (?n) (0) (1)) ((?i) (1) `-)
          <> (sqrt-intermed (?i) (?n) (0) (0)) (sqrt-intermed ((?i) (1) `+) (?n)
            ((?n) ((?i) (?i) `*) `<) ((?n) ((?i) (?i) `*) `=)) <> (sqrt (1)) 0
              <> (sqrt (?n)) (sqrt-intermed (1) (?n) (0) (0))
                <> (square (?x)) ((?x) (?x) `*)
                  <> (distance (?a ?b) (?c ?d)) (sqrt ((square ((?c) (?a) `-)) (square ((?d) (?b) `-)) `+))
                    ?(?-) (Evaluates to 111. Real result is `111.75866856759`)
                    (distance (1 1) (112 14))

Cracked a rib (or something) at open mat.

Ouch!

Day 14

Unrelated to creative coding, but otherwise related to my work as an artist, I decided it was finally time to patch my jeans.

I got it in my head to do Sashiko-style stitching for the patch.

However, I do not have the weight of thread necessary for it.

I found myself unable to move forward, because I wanted to get the project started.

So I used a little bit of PVA to glue the bottom end of the patch in place.

Now I can move on!

you are met by four brothers on the road

I thought: "What if I could draw quadrangles too?"

We can track one more set of coordingates in the draw rule

Now the triangler to make is a quadrangler instead:

    <>> (state ((?a ?b) ((?c ?d) ((?e ?f) ((?g ?h) ?s)))) listening)
    (draw line (number ?a) (number ?b) (number ?c) (number ?d) (color #ff0000)
    draw line (number ?c) (number ?d) (number ?e) (number ?f) (color #cc0000)
    draw line (number ?e) (number ?f) (number ?g) (number ?h) (color #aa0000)
    draw line (number ?g) (number ?h) (number ?a) (number ?b) (color #880000)
    state ?s listening)
  

This makes me wonder how I would draw a polygon of any number of sides

We would need a running iteration step that also kept track of the first point, for the last line.

What If I wanted to draw circles, too?

Then I would need to be able to calculate square roots, for the distance between two points.

: : : :

Day 13

Today I decided I would try chunking my iteration step into rows

This way, for a grid of 256x256 pixels, I could cut some math rewrites out of the inner iteration loop

I was successful at creating a rule which would draw an entire row of random pixels

For example, for a grid size of `4`, I would generate a rule like this:

<> ((?r) do-row) ((flip-flatten ((1 ?r (0 2 `rand) cell) ((2 ?r (0 2 `rand) cell) ((3 ?r (0 2 `rand) cell) (($screen-size ?r (0 2 `rand) cell) ()))))) (?r 1 `-) do-row)

In an ideal world, I would generate a rule like this (notice that the `cell` calls are on the same level of nesting):

<> ((?r) do-row) ((1 ?r (0 2 `rand) cell) (2 ?r (0 2 `rand) cell) (3 ?r (0 2 `rand) cell) (4 ?r (0 2 `rand) cell) (?r 1 `-) do-row)

(Looking at this now, I noticed another bug with my row-rule, but it's much too late to fix it.)

However, I needed some way to deal with the remains of evaluation of the row-rule, which was producing vast nested empty tuples.

I tried to flatten my cons-cells out using `flip-flatten`, but this resulted in modal applying the `flip-flatten` rule inside the row-iteration step

This resulted in a noticeably slower implementation than yesterdays.

Have I learned a lesson?

(It turns out there is an explanation for this. Thanks CapitalEx!)
      CapitalEx — Today at 2:17 PM
      When I was trying to make modal program fast, the number one thing I tried to do was make my program size stay
      extremely small
      rosin — Today at 2:17 PM
      I was curious to see if it would be faster to do a single large expansion of size n, rather than n small
      expansions
      in fact, as far as I can tell the do-row version of the program has 1 fewer re-write per cell, but it's still
      slower
      so what I am learning here is that indeed it is better to keep things small
      CapitalEx — Today at 2:19 PM
      Devines implementation flips your program between two buffers. It writes your changes first, then copies the rest
      of the old buffer. So the long that copy has to be the slower things run.
      rosin — Today at 2:19 PM
      aha
      Thank you for the explanation
      CapitalEx — Today at 2:19 PM
      No problem
      rosin — Today at 2:19 PM
      it was worth the attempt >:)
      (wryl) — Today at 2:19 PM
      The original Python implementation uses a single buffer, a queue, which means we don't need to spend time copying.
      But it's not fast because.. Python.
      CapitalEx — Today at 2:20 PM
      I've been meaning to write a compile to Lua for my implementation cause the C impl is still leagues faster lol
      (Well, outside of some cases where the rolling queue is a major win and the program is small)
    
A slower version of yesterday's result
    ?(?-) (
    A tv-snow simulator running smoothly at 30fps, 256 x 256.
    A resounding failure.
    )
    <> $screen-size 16
    ?(?-) (Utils)
    <> (?0 ?1 `?:) ?:
    <> ((draw ?: ?0 ?1 ?2)) ?:
    <> (draw ?: ?0 ?1 ?2) ?:
    ?(?-) (Initialize the game board)
    <> ((?x ?y (0) cell)) (draw pixel ?x ?y #000000)
    <> ((?x ?y (1) cell)) (draw pixel ?x ?y #FFFFFF)
    <> (handle-event (Tic ?x)) (($screen-size) do-row)
    <> (handle-event ?x) (?(?: ?:) (print (Unknown event: ?x \n)))
    <> (on-event ?~) (handle-event ?~ on-event Any)
    <> ((0) do-row) ()
    <> (flip-flatten ()) ()
    <> (flip-flatten (?x ?y)) (flip-flatten ?y ?x)
    <> (?s <put-it>) (<> ((?r) do-row) (?s (?r 1 `-) do-row))
    <> ((0) unroll ?s) ((flip-flatten ?s) <put-it>)
    <> ((?x) unroll ?s) ((?x 1 `-) unroll ((?x ?r (0 2 `rand) cell) ?s))
    ($screen-size) unroll ()
    on-event Any
  

I spent an hour or so banging away at this. Then decided it was ok to admit defeat.

Into every life a little rain must fall!

Day 12

I decide today's the day to learn to iterate

The code became rather long again, so I will link to it: Conway Part 2

I can now draw a 48x48 64x64 box of tv snow. Any larger and it is noticeably slow.

It takes me 6 5 re-writes to draw one pixel with this implementation. I wonder if I could get it lower?

(As I wrote this entry, I came up with another little optimization to save one more rewrite.)

a 48x48 box of flickering black and white TV snow

: : : :

When I started today's work, I made an implementation of a random-pixel-painter using my function-application tool.

These were nice for readability, but they added additional re-write steps.

I also had a conditional expression, until I realized it was better to leverage the rewriter to handle conditional evaluation for me.

To optimize in Modal, it's best to take out as many intermediate re-write steps as possible.

It seems that there is no way to reduce IO rewrites. Or, is there?

I also wonder if it's possible to perform loop-unrolling.

I might run out of memory. Or, will I?

Day 11

I haven't been able to use variables in rule definitions. It's been bugging me a little bit.

I decide to take a brief diversion from Life to figure this out.

Variables are necessary for code readability.

More than variables, it also allows applying all rewrites to the right-hand-side of a rule before creating it. If we're going to do much iteration, it would be helpful to move as much of the re-writing needed for an evaluation outside of the iteration step as possible. It's an optimization.

Shift things left, basically.

Is this applicative-order evaluation? I think so. In this case, we are fully-evaluating all rules before we register the new rule.

    ?(?-) (Implement a syntax for evaluating variables in rule definition right-hand side)
    ?(?-) (
    The trick here is to use a lambda to delay evaluation of (?x ?y <=>) until after ?y is evaluated.
    This may be used as an alternative "fully evaluating" rule definition
    In order to match the syntax of "non-evaluating" rule definition, we need to match two cases:
    - right-hand-side is a tuple of 1 element (semantic unpack)
    - otherwise, unpack right-hand-side using ?. register
    )
    <> ((?x) (?y) <=!=>) (<> ?x ?y)
    <> ((?x) ?. <=!=>) (<> ?x (?.))
    <> (?x ?y <=!=>) (<> ?x ?y)
    <> (<!> ?x ?y) ((?x) (?y) ?(?x ?x) <=!=>)
    <!> $bam (of an englishmun)
    <!> $bar (I smell the blood)
    <!> ($fum) ($bar $bam)
    <!> (fee fie foe) ($fum)
    ?(?-) (this evaluates to:
    <> $giant-says (I smell the blood of an englishmun)
    )
    <!> $giant-says (fee fie foe)
    $giant-says
    ?(?-) (And do something similar, for lambdas. Have to use a different symbol than ?...)
    <> ((?l ?r) ?. <=!@=>) (?(?l ?r) ?.)
    <> (<!@> (?l ?r) ?x) ((?l ?r) ?x ?(?z ?z) <=!@=>)
    <> $x 10
    <> $y 20
    ?(?-) (Because we rely on intermediate non-prefix syntax, the right-hand-side must always be a tuple)
    <!@> ((?0 ?: ?1) ?:) ($x + $y)
  

It feels good to work on something like this, before starting the dayjob-workday

I'm still recovering from a cold and a rather severe poison-ivy reaction, both of which totally disrupted my sleep schedule

But I'm pleased to say I got up before sunrise today, and did this all before opening the browser window.

Just how I like it!

Day 10 ::

I realize I am getting stuck in my head about doing more modal, so I decide to just do something:

    ?(?-) (An implementation of conway's game of life, with a grid-size of 256.
    Incomplete.)
    ?((?0 ?1 ?:) ?:) 256 256 size
    <> (?x -> ?y) (<> ?x ?y)
    $screen-size -> (number 256)
    $live-color -> (color #ffffff)
    $dead-color -> (color #000000)
    ?(?-) (Utils)
    <> (?0 ?1 `?:) ?:
    <> (-1 ?x) (?x 1 `-)
    <> (+1 ?x) (?x 1 `+)
    <> (read ?: (point ?0 ?1) (color ?2)) ?:
    <> (draw ?: (point ?0 ?1) (color ?2)) ?:
    ?(?-) (Operations)
    <> (neighbors (point ?x ?y)) (
    (point -1 ?x -1 ?y)
    (point -1 ?x ?y)
    (point -1 ?x +1 ?y)
    (point ?x -1 ?y)
    (point ?x ?y)
    (point ?x +1 ?y)
    (point +1 ?x -1 ?y)
    (point +1 ?x ?y)
    (point +1 ?x +1 ?y)
    )
    draw pixel (point 128 128) (color #ffffff)
    read @pixel (point 128 128) (color #000000)
    (neighbors (point 128 128))
  

It took a little effort figuring out how to read a pixel. It turns out the documentation for Thuesday is not quite correct; you must supply a color to use as a default, in case you try to access out-of-bounds.

Stay tuned.

Day 9

Work was a little heavy today, so I let my study of modal breathe a bit

Instead, I made rice stir-fry, cleaned the kitchen, did my laundry, and read more Hidden In Plain Sight (Amdur)

: : : :

I particularly liked this advice from Josh Avanier's site, regarding website redesigns:

Strip everything down to just plain markup tags. No classes, no styling. Focus on how the information you’re presenting flows vertically. Format things semantically—use the correct headings, use articles and sections, etc. (see HTML § guidelines).

This adventure log is where I'm testing styles out. I'm trying to only add what's needed.

Here is my stylesheet so far:

    pre {
    background: #eee;
    margin: 0 -1em;
    padding: .5em 2em;
    overflow-x: scroll;
    }

Other than that, I refined the notes page, my about page, and deleted a lot of unlinked loose-leaf.

You cannot see it, but this page is now subdivided with <section> tags :]

Day 8

I have a little less time today, because I spent so long in the city

No problem though. It was a good use of time.

: : : :

I start off thinking about how I could make a buffered canvas -- like you would have for a drawing program

You'd need something like that if you wanted to 1) draw a cursor without 2) drawing it permanently on your nice picture

One idea that presents itself to me is buffering to a sprite. But there's an issue there, I don't understand how sprites work in modal

I spend a little time reading thuesday's source, then I cut up Devine's sprite demo. Then, I start to get it.

More on this later.

: : : :

I had this idea to add more brushes to my sketchpad, and make it behave slightly more like a real sketchpad (i.e. only draw when you're touching the page)

The source code for it ended up a little bit large, so here's a link to it instead: sketchbook.modal

smudge

After a few attempts, I even draw a passable Hung(ཧཱུྃ).

HUNG

I also retooled my triangle sketcher a bit, and made the lines 3-wide on the diagonal. I think it looks pleasant.

curtain faceted

Then I have some cold sake, and write up this entry. What a day!

Day 7

I've been reflecting on what my teacher said to me the other day, talking about the way we converse with tools

"If you can do anything you dream of, you'll find out your dreams are boring."

: : : :

In order to understand evaluation order, I thought it would be good to do a project that required some math

My original idea was to draw a vector at the mouse indicating speed/direction.

I found this very visually boring, so I made it draw a circle with a radius scaling off velocity instead. Oh my.

bubbles scrawls
    ?(?-) (Draw a vector indicating the current direction and velocity of the mouse cursor)
    ?(?-) (Variables and procedures)
    <> ($screen-size) ((number 512))
    <> ($screen-color) ((color #FFFFFF))
    <> ($brush-color) ((color #000000))
    <> (!clear-screen) ((number 0) (number 0) $screen-size $screen-size $screen-color draw fill-rect)
    ?((?0 ?1 ?:) ?:) 512 512 size
    ?(?-) (
    Keybinds:
    c - clear screen
    q - quit
    )
    <> (?s handle-event (Key (?x c))) (
    !clear-screen
    ?s
    )
    <> ((state ?s ?f) handle-event (Key (?x q)))
    (cmd quit)
    <> (cmd ?:) ?:
    <> (read-event ?~) (handle-event ?~ read-event Any)
    <> ((state (?a ?b ?c ?d) polling) handle-event (Move (?x ?y ?z))) ((state (?c ?d ?x ?y) drawing))
    <> (handle-event ?x) ()
    ?(?-) (I will use a type system to enforce evaluation order, because I am not that clever)
    <> ((number ?0) (number ?1) `?:) ((number ?:))
    <> ((number ?0) (number ?1) (number ?2) (number ?3) (color ?4) draw ?:) ?:
    <> ((draw ?: (number ?0) (number ?1) (number ?2) (color ?3))) ?:
    <> (state (?a ?b ?c ?d) drawing) (
    (draw circ
    (number ?c)
    (number ?d)
    (number ?d) (number ?b) `-
    (number ?a) (number ?c) `- `+
    $brush-color)
    state (?a ?b ?c ?d) polling)
    !clear-screen
    (state (0 0 1 1) polling) read-event Any
  

This is the sort of thing I'll idly draw on napkins, or in the margins of paper.

Day 6

I am simply in awe of Modal

    ?(?-) (Draw a triangle with points indicated by three mouse clicks)
    ?((?0 ?1 ?:) ?:) 1024 1024 size
    ?(?-) (First we may begin by getting the mouse position)
    <> (read-event ?~) (handle-event ?~ read-event Any)
    <> ((state ((?a ?b) ?s) debouncing) handle-event (Touch (?x ?y ?z)))
    ((state ((?x ?y) ?s) listening))
    <> ((state ?s listening) handle-event (Touch (?x ?y 1)))
    ((state ((?x ?y) ?s) debouncing))
    ?(?-) (c - Clear)
    <> ((state ?s ?f) handle-event (Key (?x c)))
    ((draw fill-rect 0 0 1024 1024 #000000 state () listening))
    ?(?-) (q - Quit)
    <> ((state ?s ?f) handle-event (Key (?x q)))
    (cmd quit)
    <> (handle-event ?x) ()
    ?(?-) (State Handlers)
    <> (state ((?a ?b) ((?c ?d) ((?e ?g) ?s))) listening)
    (draw line ?a ?b ?c ?d #ffffff
    draw line ?c ?d ?e ?g #ffffff
    draw line ?e ?g ?a ?b #ffffff
    state ?s listening)
    ?(?-) (Action handlers)
    <> (draw ?: ?0 ?1 ?2 ?3 ?4) ?:
    <> (cmd ?:) ?:
    draw fill-rect 0 0 1024 1024 #000000
    (state () listening) read-event Any
  

Astonishing. Marvellous.

triangles in black space

Day 5

I asked around on Merveilles what I should do next with modal, and Devine suggested I make a game

I woke up and decided to try implementing Tic Tac Toe. I did not know if I could do it. Then, I did it.

    <> (console ?:) ?:
    <> (print-state (?x ?y) { ?a | ?b | ?c ?d | ?e | ?f ?g | ?h | ?i }) (console (current turn: ?x \n) console (?a
    |
    ?b | ?c \n) console (?d | ?e | ?f \n) console (?g | ?h | ?i \n))
    ?(?-) (x wins by diagonal)
    <> (?m ?n ?o { x | ?b | ?c ?d | x | ?f ?g | ?h | x }) (console (x wins))
    <> (?m ?n ?o { ?a | ?b | x ?d | x | ?f x | ?h | ?i }) (console (x wins))
    ?(?-) (x wins by row)
    <> (?m ?n ?o { x | x | x ?d | ?e | ?f ?g | ?h | ?i }) (console (x wins))
    <> (?m ?n ?o { ?a | ?b | ?c x | x | x ?g | ?h | ?i }) (console (x wins))
    <> (?m ?n ?o { ?a | ?b | ?c ?d | ?e | ?f x | x | x }) (console (x wins))
    ?(?-) (x wins by column)
    <> (?m ?n ?o { x | ?b | ?c x | ?e | ?f x | ?h | ?i }) (console (x wins))
    <> (?m ?n ?o { ?a | x | ?c ?d | x | ?f ?g | x | ?i }) (console (x wins))
    <> (?m ?n ?o { ?a | ?b | x ?d | ?e | x ?g | ?h | x }) (console (x wins))
    ?(?-) (o wins by diagonal)
    <> (?m ?n ?o { o | ?b | ?c ?d | o | ?f ?g | ?h | o }) (console (o wins))
    <> (?m ?n ?o { ?a | ?b | o ?d | o | ?f o | ?h | ?i }) (console (o wins))
    ?(?-) (o wins by row)
    <> (?m ?n ?o { o | o | o ?d | ?e | ?f ?g | ?h | ?i }) (console (o wins))
    <> (?m ?n ?o { ?a | ?b | ?c o | o | o ?g | ?h | ?i }) (console (o wins))
    <> (?m ?n ?o { ?a | ?b | ?c ?d | ?e | ?f o | o | o }) (console (o wins))
    ?(?-) (o wins by column)
    <> (?m ?n ?o { o | ?b | ?c o | ?e | ?f o | ?h | ?i }) (console (o wins))
    <> (?m ?n ?o { ?a | o | ?c ?d | o | ?f ?g | o | ?i }) (console (o wins))
    <> (?m ?n ?o { ?a | ?b | o ?d | ?e | o ?g | ?h | o }) (console (o wins))
    <> ( (?x ?y) (read) (turn ?x ?~) { ?a | ?b | ?c ?d | ?e | ?f ?g | ?h | ?i }) ( (?x ?y) (go) (turn ?x ?~) { ?a
    |
    ?b | ?c ?d | ?e | ?f ?g | ?h | ?i })
    <> ( (?x ?y) (go) (turn ?x 1) { _ | ?b | ?c ?d | ?e | ?f ?g | ?h | ?i }) (dbg (?y ?x) (read) (turn ?y (?~)) {
    ?x
    | ?b | ?c ?d | ?e | ?f ?g | ?h | ?i })
    <> ( (?x ?y) (go) (turn ?x 2) { ?a | _ | ?c ?d | ?e | ?f ?g | ?h | ?i }) (dbg (?y ?x) (read) (turn ?y (?~)) {
    ?a
    | ?x | ?c ?d | ?e | ?f ?g | ?h | ?i })
    <> ( (?x ?y) (go) (turn ?x 3) { ?a | ?b | _ ?d | ?e | ?f ?g | ?h | ?i }) (dbg (?y ?x) (read) (turn ?y (?~)) {
    ?a
    | ?b | ?x ?d | ?e | ?f ?g | ?h | ?i })
    <> ( (?x ?y) (go) (turn ?x 4) { ?a | ?b | ?c _ | ?e | ?f ?g | ?h | ?i }) (dbg (?y ?x) (read) (turn ?y (?~)) {
    ?a
    | ?b | ?c ?x | ?e | ?f ?g | ?h | ?i })
    <> ( (?x ?y) (go) (turn ?x 5) { ?a | ?b | ?c ?d | _ | ?f ?g | ?h | ?i }) (dbg (?y ?x) (read) (turn ?y (?~)) {
    ?a
    | ?b | ?c ?d | ?x | ?f ?g | ?h | ?i })
    <> ( (?x ?y) (go) (turn ?x 6) { ?a | ?b | ?c ?d | ?e | _ ?g | ?h | ?i }) (dbg (?y ?x) (read) (turn ?y (?~)) {
    ?a
    | ?b | ?c ?d | ?e | ?x ?g | ?h | ?i })
    <> ( (?x ?y) (go) (turn ?x 7) { ?a | ?b | ?c ?d | ?e | ?f _ | ?h | ?i }) (dbg (?y ?x) (read) (turn ?y (?~)) {
    ?a
    | ?b | ?c ?d | ?e | ?f ?x | ?h | ?i })
    <> ( (?x ?y) (go) (turn ?x 8) { ?a | ?b | ?c ?d | ?e | ?f ?g | _ | ?i }) (dbg (?y ?x) (read) (turn ?y (?~)) {
    ?a
    | ?b | ?c ?d | ?e | ?f ?g | ?x | ?i })
    <> ( (?x ?y) (go) (turn ?x 9) { ?a | ?b | ?c ?d | ?e | ?f ?g | ?h | _ }) (dbg (?y ?x) (read) (turn ?y (?~)) {
    ?a
    | ?b | ?c ?d | ?e | ?f ?g | ?h | ?x })
    ?(?-) (Helpfully output game state to player)
    <> (dbg ?x ?y ?z { ?a | ?b | ?c ?d | ?e | ?f ?g | ?h | ?i }) (print-state ?x { ?a | ?b | ?c ?d | ?e | ?f ?g |
    ?h
    | ?i } ?x ?y ?z { ?a | ?b | ?c ?d | ?e | ?f ?g | ?h | ?i })
    ?(?-) (Helpfully notify player when an illegal move is attempted)
    <> ((?x ?y) (go) (turn ?x ?z) { ?a | ?b | ?c ?d | ?e | ?f ?g | ?h | ?i }) ((console (?x attempted to mark ?z
    illegally\n)) (?x ?y) (read) (turn ?x (?~)) { ?a | ?b | ?c ?d | ?e | ?f ?g | ?h | ?i })
    ?(?-) (Play the game, start on turn x)
    console (enter a number between 1 and 9 to indicate the space you wish to mark \n)
    dbg
    (x o)
    (read)
    (turn x ?~)
    {
    _ | _ | _
    _ | _ | _
    _ | _ | _
    }
  

: : : :

It seems I've come down with a cold

Day 4

I went to bed last night wondering how I would reverse a tuple without exploding it

Then it struck me that I could unpack it into the land of square-braks

    ?(?-) (Use our cursor from before, as well as a NEW friend)
    <> (<-_-> ()) ()
    <> (<-_-> (?x ?y)) (?x <-_-> ?y)
    <> (() <-_->) ()
    <> ((?x ?y) <-_->) (?x <-_-> ?y)
    .. (<-_-> (1 (2 (3 ()))))
    .. ((((() a) b) c) <-_->)
    <> ([ ] ^v^]> ?x) (?x)
    <> (?i ] ^v^]> ?x) (] ^v^]> (?x ?i))
    <> (revAgain ?.) ([ ?. ] ^v^]> () <-_->)
    (revAgain (mary had a little lamb))
    ?(?-) (Evaluates to (lamb little a had mary))
    (revAgain (foo bar baa ma (nested list) (another nested list) (an even (more (deeply) nested) list)))
    ?(?-) (Evaluates to ((an even (more (deeply) nested) list) (another nested list) (nested list) ma baa bar foo))
  

We can now reverse a tuple, without disturbing tuples it may contain. Success!

: : : :

To brush up on the state of the art, I attempt reading Devine's page on rewriting languages, until my eyes cross

Day 3

I spoke with my brother a bit before today's DecAdvemCture work

While he was describing to me his goal of doing 20,000 (!) pull-ups this year, a thought occurred to me:

"Some goals require pushing towards, and some goals pull you along. The pulling goals are over there. Pushing goals are right here. Pulling goals are bounded. Pushing goals are boundless."

That is to say, a goal that can be accomplished is a pulling-goal. It pulls you toward it. Some effort is required, but it, the situation, naturally directs your efforts.

: : : :

Today I gave myself a challenge with modal: reverse a tuple

    ?(?-) (Given a tuple of any number of elements, re-write the tuple in reverse order)
    ?(?-) (here is a cursor, her name is "zyp", and she flattens cons-cells into tuples)
    ?(?-) (she is very talented, and can work from either direction.)
    <> (<-_-> ()) ()
    <> (<-_-> (?x ?y)) (?x <-_-> ?y)
    <> (() <-_->) ()
    <> ((?x ?y) <-_->) (?x <-_-> ?y)
    .. (<-_-> (1 (2 (3 ()))))
    .. ((((() a) b) c) <-_->)
    ?(?-) (Now, given zyp's example, can we reverse an exploded tuple?)
    <> (flipcons ()) ()
    <> (flipcons (?x ?y)) (flipcons ?y ?x)
    <> (rev ?*) (flipcons (?*))
    (rev (1 2 3 4))
    ?(?-) (Unfortunately, it doesn't behave like we expect -- instead it explodes nested lists too)
    (rev (foo bar baa ma (nested list) (another nested list) (an even (more (deeply) nested) list)))
  

A little disappointing, but it's ok. I enjoyed starting with a file that contained only a prompt, then trying to fulfill that prompt

That was setting myself a "pulling-goal", rather than a "pushing goal" of "I'm going to figure out modal."

Day 2

Today I:

Day 1

    Let's enumerate a couple ideas for December Adventure:
    - re-build disast.rs (using term rewriting??)
    - learn modal, and the ecosystem around it, and use it
    "But how we get from A to B, it can't be up to me"
    
  
: : : :
    Without further ado, modal:
    ::
    I thought it would be nice to build logic circuits out of nand:
    <> (nand #t #t) #f
    <> (nand #t #f) #t
    <> (nand #f #t) #t
    <> (nand #f #f) #t
    ?(?-) (It seems we have to explicitly unpack if we want to build things with nand)
    ?(?-) (I suspect this is because I am inadvertantly matching non-boolean expressions)
    ?(?-) (more on this later?)
    <> (nand (?x) (?y)) (nand ?x ?y)
    ?(?-) (The rest of the circuitry)
    <> (not ?x) (nand ?x ?x)
    <> (and ?x ?y) (not (nand ?x ?y))
    <> (or ?x ?y) (nand (not ?x) (not ?y))
    <> (xor ?x ?y) (and (or ?x ?y) (nand ?x ?y))
    ?(?-) (Now can we build up some kind of if-else expression?)
    ?(?-) (We will have to unpack here as well?)
    <> (if #t ?x ?y) ?x
    <> (if #f ?x ?y) ?y
    <> (eq ?x ?x) #t
    <> (eq ?x ?y) #f
    ?(?-) (Somehow our ternary operator does not behave as expected.)
    ?(?-) (Eval: `(if (#f) True! False!)`)
    .. if (eq #t #f) True! False!
    ?(?-) (Evaluates to `False!`, which is more like what we would expect)
    .. if eq #t #f True! False!
    ?(?-) (So, why is it that we seem to rewrite to a token sometimes and a one-element tuple other times?)
  

::::

    ?(?-) (I decide to go and cover some basics)
    ?(?-) (A rule has the following syntax)
    ?(?-) (<> left right)
    <> hello goodbye
    .. hello ?(?-) (evaluates to `goodbye`)
    .. hellogoodbye ?(?-) (no match; no rule is applied)
    ?(?-) (What if we want to evaluate to something a little bigger than a token?)
    ?(?-) (tuples are "unpacked", I think this is a vocabulary word I am possibly misusing.)
    <> good (even better)
    .. good bye ?(?-) (evaluates to "even better bye")
    ?(?-) (Use registers)
    <> (swap ?x ?y) (?y ?x)
    <> (spin ?x ?y ?z) (?y ?z ?x)
    .. swap it out ?(?-) (evaluates to `out it`)
    .. spin me right round ?(?-) (evaluates to `right round me`)
    .. spin swap a b c d e ?(?-) (evaluates to `a b d c e`)
    .. spin (swap a b) c d e ?(?-) (evaluates to `c d (b a) e`)
    ?(?-) (I get as far as the I/O section before realizing that rule evaluation is tricky)
    ?(?-) (Consider I/O, maybe we want to check if a user enters the same thing twice?)
    ?(?-) (use the ?~ register to read input)
    ?(?-) (Oh, actually I don't know how to use stdin as an arg twice)
    <> (read ?~) ?~
    <> (eq ?x ?x) (these terms are equivalent)
    <> (eq ?x ?y) (these terms are different)
    ?(?-) (Oops, we match the eq rule here, and always get the true result.)
    eq (read stdin) (read stdin)
    ?(?-) (How would we achieve application of `eq` to the results of two sequential reads?)
  

:: I decide to try zooming in on what was confusing me above ::

    ?(?-) (I will try to dig a little more into tuple/token rewriting now)
    <> (does-this-wrap ?x) (?x)
    .. does-this-wrap abc ?(?-) (evaluates to `abc`)
    .. does-this-wrap (abc) ?(?-) (evaluates to `(abc)`)
    .. (does-this-wrap abc) ?(?-) (evaluates to `(abc)`)
    .. (does-this-wrap (abc)) ?(?-) (evaluates to `((abc))`)
    <> (what-about-this ?x) ?x
    .. what-about-this efg ?(?-) (evaluates to `efg`)
    .. what-about-this (efg) ?(?-) (evaluates to `(efg)`)
    .. (what-about-this efg) ?(?-) (evaluates to `(efg)`)
    .. (what-about-this (efg)) ?(?-) (evaluates to `((efg))`)
    <> (and-this ?x) ((?x))
    .. and-this hij ?(?-) (evaluates to `(hij)`)
    .. and-this (hij) ?(?-) (evaluates to `((hij))`)
    .. (and-this hij) ?(?-) (evaluates to `((hij))`)
    .. (and-this (hij)) ?(?-) (evaluates to `(((hij)))`)
  
: : : :

Then I go and have some dinner and prepare this log entry