From 0063bf9d2b2c416a6317cf45f68847b5720aab49 Mon Sep 17 00:00:00 2001 From: Collin Williams <96917990+bluedragon1221@users.noreply.github.com> Date: Sun, 10 May 2026 14:46:07 -0500 Subject: updates and new post: 'Summer of PLT' --- forgejno.html | 51 ++++++---------------------------- index.html | 73 ++++++++---------------------------------------- prose.css | 82 +++++++++++++++++++----------------------------------- soplt.html | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ stars.js | 57 ++++++++++++++++++++++++++++++++++++++ style.css | 2 +- toc.js | 49 ++++++++++++++++++++++++++++++++ writing.html | 12 ++++++++ 8 files changed, 256 insertions(+), 159 deletions(-) create mode 100644 soplt.html create mode 100644 stars.js create mode 100644 toc.js diff --git a/forgejno.html b/forgejno.html index 71246e7..a413440 100644 --- a/forgejno.html +++ b/forgejno.html @@ -7,42 +7,9 @@ - - + - -
- -
- +

You Don't Need Forgejo

People @@ -69,7 +36,7 @@

I'll be using Caddy as the webserver for this setup, but I'll link tutorials for NGINX and Apache if prefer xml configuration files and manual https certificates ;)

To keep everything organized, I'll run cgit under a user called "git". Our git repos will be stored in this directory.

-

$ useradd -r -d /var/lib/cgit -s /usr/bin/git-shell git

+ $ useradd -r -d /var/lib/cgit -s /usr/bin/git-shell git

fcgiwrap

cgit is served as a cgi application.

@@ -88,7 +55,7 @@
  • Install cgit with a package manager. This will place the cgit files at /var/www/htdocs/cgit

  • Make sure that location is owned by "git", but is readable by all users:

    -

    $ chown -R git /var/www/htdocs/cgit && chmod -R 764 /var/www/htdocs/cgit

    + $ chown -R git /var/www/htdocs/cgit && chmod -R 764 /var/www/htdocs/cgit
  • @@ -109,24 +76,22 @@ }

    Lock down SSH access

    -

    Using git-shell - blocks normal shell access and allows only git-style SSH commands.

    +

    Using git-shell blocks normal shell access and allows only git-style SSH commands.

      -
    1. Create an SSH directory for the git - user: $ install -d -o git -g git -m 700 /var/lib/cgit/.ssh

    2. +
    3. Create an SSH directory for the git user: $ install -d -o git -g git -m 700 /var/lib/cgit/.ssh

    4. Add your public key to /var/lib/cgit/.ssh/authorized_keys with mode 600.

    Create some repos

    Create a bare repository:

    -

    $ sudo -u git git init --bare /var/lib/cgit/example

    + $ sudo -u git git init --bare /var/lib/cgit/example

    Push to it from your local machine:

    $ git remote add origin git@git.my.tld:example
     $ git push -u origin main

    cgitrc

    -

    A clean default /etc/cgitrc file might look like this:

    +

    A clean default /etc/cgitrc file might look like this:

    css=/cgit.css
     logo=
     virtual-root=/
    diff --git a/index.html b/index.html
    index 5a7ac62..f12f9fd 100644
    --- a/index.html
    +++ b/index.html
    @@ -10,85 +10,36 @@
     			body {
     				align-items: center;
     			}
    -			
    +
     			.content {
     				width: 47ch;
    +				z-index: 2;
     			}
    -			
    -			h1 {
    -				text-align: center;
    -			}
    -			
    -			#bg {
    -				position: fixed;
    -				inset: 0;
    -				pointer-events: none;
    -			}
    -			
    -			.star {
    -				position: absolute;
    -				width: 3px;
    -				height: 3px;
    -				border-radius: 50%;
    -				background: white;
    -				box-shadow: 0 0 4px white;
    -			}
    -			
    +
     			.cards {
     				display: flex;
     				flex-direction: row;
     				justify-content: space-around;
     				width: 100%;
     			}
    -			
    +
     			.card {
     				font-family: 'Roboto Mono';
    -				color: white;
    +				font-weight: 450;
    +				color: #e6e6e6;
     				text-decoration: none;
     				transition: color 0.1s ease;
    -			}
    -			
    -			.card:hover {
    -				color: #4DA3FF;
    +
    +				&:hover {
    +					color: #4DA3FF;
    +				}
     			}
     		
    +		
     	
     	
    -		
    -
    -

    Collin Williams

    +

    Collin Williams

    Bluesky Tangled diff --git a/prose.css b/prose.css index a9f6dc1..0babb5e 100644 --- a/prose.css +++ b/prose.css @@ -1,50 +1,8 @@ @import url('https://fonts.googleapis.com/css2?family=Gelasio:ital,wght@0,400..700;1,400..700&display=swap'); -html, -body { - overflow-x: hidden; - overflow-y: auto; -} - -body { - display: grid; - grid-template-columns: minmax(0, 1fr) minmax(0, 75ch) minmax(0, 1fr); - align-items: start; - column-gap: 2rem; - padding: 2rem 1.25rem 4rem; -} - -.toc { - grid-column: 1; - width: min(17rem, 22vw); - position: fixed; - top: 32px; - left: max(0.75rem, calc(50vw - 37.5ch - 20rem)); - max-height: calc(100vh - 2rem); - overflow-y: auto; - padding-right: 0.75rem; - z-index: 1; -} - -.toc ul { - margin: 0; - padding-left: 1rem; -} - -.toc li { - margin-bottom: 0.35rem; -} - .content { - grid-column: 2; width: 100%; - margin: 0 auto; - padding: 0 0 2rem; max-width: 75ch; - height: auto; - flex-grow: 0; - flex-shrink: 1; - overflow: visible; } p { @@ -57,12 +15,23 @@ p { a { color: #4DA3FF; transition: color 0.2s ease, background-color 0.2s ease; + border-radius: 3px; + + &:hover { + background-color: #4DA3FF; + color: #121212; + text-decoration: none; + } +} + +code { + font-family: 'Roboto Mono'; + font-size: 0.9rem; + color: #00ff78; } -a:hover { - background-color: #4DA3FF; - color: #121212; - text-decoration: none; +li { + font-family: 'Gelasio'; } li::marker { @@ -105,15 +74,20 @@ p.comment { padding: 1rem 1rem 3rem; } - .toc { - position: static; - width: auto; - max-height: none; - margin-bottom: 1.25rem; - padding-right: 0; - } - .content { padding: 0; } } + +summary { + font-family: 'Gelasio'; + color: #888; + + &::marker { + color: #888; + } +} + +code .path { + color: #888; +} diff --git a/soplt.html b/soplt.html new file mode 100644 index 0000000..4979e75 --- /dev/null +++ b/soplt.html @@ -0,0 +1,89 @@ + + + + + + Summer of PLT + + + + + + +
    +

    Summer of PLT

    +

    Looking for a summer coding project? Try making a programming language!

    +

    I think that every programmer, new or experienced, could benefit from understanding a little bit about how the languages they use daily actually work.

    +

    As such, this is my collection of resources that I used to teach myself a little bit of Programming Language Theory last summer, which concluded in my creation of CI lisp.

    +

    I'm planning on doing something similar this summer, so I figured I'd invite other people to try a 'Summer of PLT' too.

    +

    Disclaimer: I'm just a guy with no formal education in PLT. Like Daniel Fedorin said, I just love the field of programming languages.

    + +

    Read a Book

    +

    + If you're new to the field of programming languages, my first piece of advice is READ CRAFTING INTERPRETERS! + (or at least the first section, "A Treewalking Interpreter") + In my opinion, there is no better way to break into the field of PLT than by reading Bob Nystrom's book on the subject: Crafting Interpreters. + There's also a free HTML version on his site if you don't feel like paying money.

    + +

    After that, I would suggest looking into Lisp.

    + +

    Make a Lisp

    +

    Lisp is one of the foundational language of PLT. My advice to anyone trying to start in this field would be to make a Lisp. Its minimal syntax makes parsing and interpreting much easier.

    +

    For a nice overview (and a bit of history), check out the Wikipedia page on Lisp: Lisp (programming language).

    + +

    Before making your lisp, it would probably be good if you knew Lisp. Here's a good resource for that: lisp-lang.org.

    +

    Alternatively, you could consider going down the Emacs rabbit hole to teach yourself lisp. In the Emacs environment, you'll quickly gain proficiency with the parentheses, but you'll probably lose at least a few weeks in the process.

    + +

    Theory-wise, I would recommend reading the original John McCarthy Lisp paper (be prepared for dense academic writing though): Recursive Functions of Symbolic Expressions and Their Computation by Machine.

    +

    The C2 lisp rant is also a fun read (but by no means required): Lost Ina Seaof Parentheses.

    + + +

    If you want more of a guided, handhold-y tutorial for making a lisp clone, I can only recommend mal - Make a Lisp. I personally have not gone through it, but I've heard good things.

    +

    Alternatively, ask an LLM to help you learn how programming languages work. Just make sure that you're actually learning, not just copying whatever it says to do. Try something like "Don't give me any code, just explain to me..."

    + +

    What next?

    +

    After you make your lisp, you can use it as a playground for more ideas in the field of PLT.

    + +

    Lambda Calculus

    +

    + If you find yourself seeking more of the theory-side of PLT, consider learning Lambda Calculus and Church Encoding and implementing them in your lisp! +

    + There's tons of resources on Lambda Calculus, but you can't go wrong with a skim of Alonzo Church's original book on the subject, The Calculi of Lambda-Conversion +

    Or you don't feel up to reading 1940s academic rhetoric, the Wikipedia page on Lambda Calculus is nice: Lambda calculus +

    + +

    Monadic IO

    +

    Also on the theory-heavy side, you could learn about Haskell's system for safe IO operations which use monads.

    +

    This paper on the subject (discovered on the Haskell wiki) is a pretty dense, but has all of the foundational ideas for Monadic IO in Haskell: Monadic I/O in Haskell 1.3.

    + +

    Syntactic Sugar

    +

    + If you're looking more into the practical side of PLT, you could look into adding syntactic sugar to your lisp. + One source to look into might be David Wheeler's Sweet Expressions. +

    + +

    Bytecode VM

    +

    + If you're interested in becoming more like the "real programming languages", you could look into writing a bytecode VM for your language. + It's a big undertaking, but it's outlined very well in the second section of Crafting Interpreters, A Bytecode Virtual Machine. +

    + +

    Make a CAS (?)

    +

    + If you're a math nerd (like me), you could look into writing a CAS hosted in your lisp. + For me, this meant writing a deep pattern matching system and substitution engine. + Definitely a fun project! +

    + +

    Try something else

    +

    Maybe you're sick of lisp? That's fine! There's lots of other PLT stuff that might suit your fancy:

    +
      +
    • Make a Forth -- Sorry, I don't have very much information on this one, but stack-based languages are pretty neat!

    • +
    • Make a Python -- You can extend the ideas of lexing and parsing to a more complicated syntax, leading to more of a Python-like experience

    • +
    + +

    Contact

    +

    Did I interest you in a 'Summer of PLT'? Let me know! I'd love to see some toy lisps this summer!

    +
    + + \ No newline at end of file diff --git a/stars.js b/stars.js new file mode 100644 index 0000000..347d7c0 --- /dev/null +++ b/stars.js @@ -0,0 +1,57 @@ +function animate() { + const bg = document.querySelector("#bg"); + + for (const star of bg.children) { + star.x += star.vx; + star.y += star.vy; + + star.style.left = `${star.x}px`; + star.style.top = `${star.y}px`; + } + + requestAnimationFrame(animate); +} + +document.addEventListener("DOMContentLoaded", () => { + const bg = document.createElement("div"); + bg.setAttribute("id", "bg"); + + const numStars = Math.floor((window.innerWidth * window.innerHeight)/10_000); + for (let i = 0; i < numStars; i++) { + const star = document.createElement("div"); + star.classList.add("star"); + + star.x = Math.random() * window.innerWidth; + star.y = Math.random() * window.innerHeight; + + star.vx = (Math.random() - 0.5) * 0.2; + star.vy = (Math.random() - 0.5) * 0.2; + + star.style.left = `${star.x}px`; + star.style.top = `${star.y}px`; + + bg.appendChild(star); + } + document.body.prepend(bg); + + var styleBlock = document.createElement("style"); + styleBlock.textContent = ` + #bg { + position: fixed; + inset: 0; + pointer-events: none; + } + + .star { + position: absolute; + width: 3px; + height: 3px; + border-radius: 50%; + background: #e6e6e6; + box-shadow: 0 0 4px white; + } + `; + document.head.append(styleBlock); + + requestAnimationFrame(animate); +}) \ No newline at end of file diff --git a/style.css b/style.css index 43a6973..13d21ff 100644 --- a/style.css +++ b/style.css @@ -9,13 +9,13 @@ html, body { margin: 0; padding: 0; min-height: 100vh; - overflow: hidden; } body { display: flex; justify-content: center; align-items: flex-start; + padding-top: 2rem; } h1 { diff --git a/toc.js b/toc.js new file mode 100644 index 0000000..633088a --- /dev/null +++ b/toc.js @@ -0,0 +1,49 @@ +document.addEventListener("DOMContentLoaded", () => { + var tocDiv = document.createElement("div"); + tocDiv.classList += "toc"; + var toc = document.createElement("ul"); + + document.body.querySelectorAll('h1, h2, h3, h4, h5, h6').forEach(heading => { + var link = document.createElement('a'); + link.setAttribute('href', '#'+heading.id.toLowerCase()); + link.textContent = heading.textContent; + + var li = document.createElement('li'); + li.appendChild(link); + + toc.appendChild(li); + }); + + tocDiv.append(toc); + document.body.prepend(tocDiv); + + var styleBlock = document.createElement("style"); + styleBlock.textContent = ` + .toc { + position: fixed; + width: 17rem; + top: 32px; + left: calc(50vw - 37.5ch - 20rem); + padding-right: 0.75rem; + z-index: 1; + + ul { + margin: 0; + padding-left: 1rem; + line-height: 1.4; + } + + li { + margin-bottom: 0.35rem; + font-size: 1.1rem; + } + } + + @media (max-width: 1000px) { + .toc { + display: none; + } + } + `; + document.head.append(styleBlock); +}) \ No newline at end of file diff --git a/writing.html b/writing.html index d95ba16..bceef66 100644 --- a/writing.html +++ b/writing.html @@ -7,10 +7,22 @@ + + -- cgit v1.3.1