23

I Built This Website Using Racket. Here's What I Can Do Now

 4 years ago
source link: https://sagegerard.com/racket-powered.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
cd ~

I Built This Website Using Racket. Here's What I Can Do Now.

It looks like there’s not much to see here. Isn’t it great? Barring exceptional cases, every page on this website takes up fewer than 20 kibibytes on disk and runs no JavaScript. Throttle your connection and hit refresh a few times. It loads in milliseconds . No one does that anymore.

It’s funny. I spent years learning the ins and outs of front-end web development, only to feel happy making a tiny, 90s-looking page that loads in a blink of an eye with nothing to do but make a point. Is that ironic? I haven’t decided yet.

But I did not just write vanilla HTML and give up my shiny toys. I use Racket to shape content using any language I want. What better tool for starting with a blank slate?

A Website With Superpowers

Racket is a programming language programming language. Racket allows you to write your own languages in terms of itself, and it is a joy to use. I released unlike-assets —an open source build tool that functions as an alternative to Webpack for my purposes—to say thank you and to show off what it can do.

I built a specific configuration for unlike-assets called polyglot that lets me write web content with arbitrary DSLs.

This snippet computes a Sierpinsky Triangle when building this page. A cool part about that is that I expressed the code only once. My system knows to display the code for you to read, and then run it.

#lang racket
(require "tri.rkt" polyglot)
(provide replace-page)
(define (replace-page page-tx)
  (tx-replace-me
    page-tx
    (λ _ `((div ((style ,(string-join 
                       '("margin: 0 auto")
                       ";")))
             ,(sierpinsky-triangle 4 "#800" "tri"))))))

Here I use rash —a shell dialect by William Hatch—to compute the download size of Bootstrap. Honestly, I did it just because I can. I’d have to configure Webpack for countless hours to get this kind of flexibility.

#lang rash
(require polyglot)
(provide replace-page)
(define size-box (box "Unknown"))

curl -so /dev/null -w '"%{size_download}" \
  https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css \
  |>> set-box! size-box

(define (replace-page page-tx)
 (tx-replace-me page-tx
   (λ _ `((span ((style "color: rebeccapurple"))
        "The total download size of Bootstrap v4.3.1 is "
        ,(unbox size-box) " bytes")))))
The total download size of Bootstrap v4.3.1 is 155758 bytes

This page starts as a Markdown file. Since Markdown supports use of HTML tags, I use <script> elements to express Racket modules that are available only within a page.

text/racket
application/racket

I parse the Markdown, process the Racket code in a sensible order, and then scan for dependencies in href and src attributes (such as other pages) to automagically build the rest of the website until all dependencies are fulfilled.

Things get fun when I can “drop down” from prose at any time to prepare a deeply integrated application that sits snug in any surrounding context. So if you are interested in using this kind of engine for your code, give polyglot a try. If you want to start from a lower level, then use unlike-assets .


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK