Tags: rc<< previousnext >>
Started with some presentations about the philosophy of the Recurse Center and how to get the most out of the experience. There's lots to learn about how RC works, from Zulip (their messaging system) to Virtual RC (a "virtual space" where you can move around your avatar and interact with other RCers). We also did some Chat Roulette-style meet-and-greets. Met maybe 15 people from my batch, but there are many others! Keeping a list of people with shared interests and who I think would be interesting to pair with.
Between Zoom calls, I watched the first video in Andrew Ng's machine learning course on 2x speed. I'm not sure yet if I want to work through that course while at RC, but it seemed like a fun way to spend an hour. Considering whether to do the homework exercises in J, but not very confident in my J skillz.
Feeling tempted by people talking about their programming language projects, makes me want to dive into the Crafting Interpreters book, or maybe Engineering a Compiler.
I'm going to fill in this blog post as I go along, seems easier than trying to remember everything at the end of the week.
Next up, I wanted to get my feet wet and actually start a programming project. What better for that than a small generative art piece! I got the gist of how to visualise the Lorenz attractor from a Coding Train video, which I then went ahead and did.
The only stumbling block was figuring out whether I could draw it in 2d, given that sketch, the Common Lisp drawing framework I use, does not support 3d and that The Coding Train's version is in 3d. I realised I could just ignore the z dimension when drawing, and I could use the z value to determine the colour of the line.
I made it so that pressing the space key resets the drawing and randomises the parameters. It was kinda awkward to record this video, though -- I had to rush to press the 'record' button after starting the animation. So tomorrow I think I'll work on adding to sketch the ability to save a video of an animation, probably by piping video output to ffmpeg.
I ended the day by starting to read about the BitTorrent protocol, since I want to implement it in order to learn more about computer networking.
Tried to catch up with all the messages on Zulip -- there are a lot! At some point I'll have to filter everything down to make it more manageable. For now, I'm rolling with the chaos.
Started my BitTorrent client project. Found that someone else has already implemented such a client in Common Lisp. I don't intend to use their code, but it will be useful to have a reference and to see what packages they used.
After skimming the specification, I jumped into writing a parser for the bencoding text format. It has integers like "i123e" and strings like "4:spam", as well as lists and dictionaries. I've been meaning to try out esrap for parsing in Common Lisp, and this seemed like the perfect opportunity! It uses the idea of parser generators, which I think are like composable building blocks for parsing.
I ran into some early trouble with esrap due to an annoying technical issue. Basically, I was trying to use the '?' symbol from the esrap package without having access to it. This was frustrating because it felt like I was squandering my day on a trivial issue.
There are edge cases in even the simplest of tasks, like parsing bencoded integers: "i0e" is valid, "i01e" is invalid, and "i-0e" is invalid. On that note, esrap has nice error messages!
BENCODE> (parse 'benteger "i01e")
^ (Line 1, Column 2, Position 2)
In context INTEGER:
While parsing INTEGER. Expected:
the character e (LATIN_SMALL_LETTER_E)
[Condition of type ESRAP-PARSE-ERROR]
Here's a taste of what the DSL looks like for defining grammar rules! Courtesy of macros. Maybe I should give a presentation on macros, even though I'm still learning about them.
(and (? #\-)
Parsing bencoded strings is a little tricky, because the length of the string is determined by the integer prefix. I had to go outside the constraints of the
defrule syntax and write a custom
parse-bencoded-string function, which, thankfully, integrates well with esrap parsing. I was then able to define the rest of the parser in 4 lines of code:
(defrule str (function parse-bencoded-string))
(defrule ben (or str benteger list dict))
(defrule list (and "l" (* ben) "e") (:function second))
(defrule dict (and "d" (* (and str ben)) "e") (:function second))
BENCODE> (parse 'list "l4:spam4:eggse")
BENCODE> (parse 'dict "d3:cow3:moo4:spam4:eggse")
(("cow" "moo") ("spam" "eggs"))
Pretty neat! Here's the code so far. Next week I'll come back to this and write unit tests to make sure I've covered all the edge cases. I haven't done unit testing in Common Lisp before, so it'll require some effort to set up. Seems like a good candidate for pair programming!
I'm trying to reach out to people with similar interests, but it's hard to keep track of everyone. I'll start attending the daily check-ins next week, and also some of the meetings like "Creative Coding" and "Emulators + VMs", which will hopefully lead to new connections.
To finish the week, I made a 2-line pull request to sketch (don't draw a border around images by default!) and described my proposal to the other developers about how to fix a tricky bug where the first render call gets lost due to the window getting resized.
Posting this now because I want my weeks to start on a Monday and end on a Friday. Hopefully I'm not being too verbose!
I'd be happy to hear from you at firstname.lastname@example.org.