Oh hello, remember this website? Probably? Is anyone reading? Oh well. I'm back, and it's time for some fun updates.

First off, Slayer

I talked about how I was going to leave Oldschool RuneScape for a spell. Well, I did that for a few weeks before inevitably going back. Job hunts weren't very successful, and my brain wasn't very active for finding new coding projects to come up with. I could make a game, but games are really chores more than interesting programming tasks. I play my guitar to improve a little bit each time, and I am trying to be more active in arts and crafts more than anything. I am sadly not much of a major coder.

I went back to RuneScape for a bit to knock out one of my longest grinds in the game, 99 Slayer, and I finally accomplished just that a few weeks ago.

This felt pretty good

This felt pretty good

Slayer was a great avenue for really learning how to be better at RuneScape, and it was certainly a challenge of being not mentally defeated. There were a lot of optimizations to make but it was a great adventure to have.

A Better Understanding of Macros

I like Lisp and I like Racket. They're different, then they're kind of not, but Lisp I had found was more profound and more 'pure' in a way that Scheme was only really ever talked about in MIT's 6.001 course. Lisp is infamous for being the environment that had so many grass-roots solutions that could only be done because Lisp allowed it.

With Lisp comes Lisp Macros, where it changed the game fundamentally in so many ways that I truly never respected before. I finally got around to reading Paul Graham's On Lisp and Doug Hoyte's Let Over Lambda and I found them both extremely interesting reads on what you can do with Lisp (and probably shouldn't for the sanity of code-sharing).

Reading bits and pieces of both, I felt a little inspired to try my hand at Rust macros, only to reveal some uncomfortable truths about Rust itself: Rust doesn't allow forward-referencing, and Rust only allows you to place Boolean values inside if-statements.

Now, why do any of those matter? One common macro that you can use in Lisp/Scheme is something called an anaphoric if, where a computation is saved after it is computed so that you can refer to the computation in the if-block. Python recently decided to add this as part of their language standard (you know, after like, twenty something years) because it seemed like a neat idea to avoid double-evaluation. This anaphoric if is defined as:

(defmacro aif (test then &optional else)
  `(let ((it ,test))
     (if it ,then ,else)))

What this boils down to is a new macro that expands into a let-statement that carries an if-statement underneath, referencing a variable 'it'. You pass the aif macro code that you would like to execute if your code evaluates to true (lots of datatypes can be used as Booleans).

Let's say I wanted to implement half of this by implementing the when keyword which executes a block only if the condition is eval'd to true. If I wanted to do an anaphoric when in Rust, to avoid double-evaluation, my macro might look like this:

macro_rules! awhen {
    ($ x : expr, $ t : block) => { { let v = $ x ; if v { $ t } } }
}

Seems plausible, and Rust has no complaints. However, because only Boolean values can be used as expressions in Rust, the final result isn't exactly very telling of what we computed, we can only have a true/false value. Secondly, Rust seems to parse blocks of codes before being passed into a macro. Meaning if we tried to refer to our new anaphoric value v in that code, we would get a compiler error because v does not exist... Except we're trying our damndest to make sure it does!

// This will not compile because v doesn't exist... yet?
fn main() {
    awhen!( 3 == 3,
    {
        println!("Our value is: {}", v); // errors out, v does not exist
    });
}

When the macro expands, v will exist. But the Rust compiler sees that v does not exist in the block we just tried passing, meaning it parses for a valid Rust block, and if it sees an issue, it halts compilation. Or so I would think. If I expand the macro code, some of it is valid by Rust's standards, so I'm unsure where the real issue lays in Rust's compilation of macros. I don't think the Rust devs anticipated Lispers using macros in a similar vein.

To say the least, I'm interested in macros now more than I was before, and I am looking for ways to change how I code this website entirely. I would like to approach the idea of writing a much better tool for editing posts and pages, but I just haven't even gotten there yet. I only picked up editing this website after such a long time only today.

That'll be it for now. I have some other changes I need to work on but hopefully I will get back on a productive train soon.