I put together a helper package called
kinda-ferpy for Racket that models dependency relationships like this:
(require kinda-ferpy) (define x (stateful-cell 1)) (define y (stateful-cell 1)) (define sum (stateful-cell (+ (x) (y)))) (displayln (sum)) ; 2 (y 8) (displayln (sum)) ; 9
stateful-cell encapsulates a Racket value such that it will always be up to date according to its dependencies. It’s a super boiled-down form of functional reactive programming, except signals, events, and dependency relationships are implicitly defined by how you write code. It’s not a full functional-reactive programming interface, just an expressive kind of one with some reasonable trade-offs. I borrowed the approach from MaiaVictor’s PureState library, which had a refreshing rant for those deep in thought about how to manage state.
For a less trivial example, here’s a progression from a Markdown file to an HTML document, plus a few ways to use it.
% is an alias of
stateful-cell, so I’ll shorten it here.
(require kinda-ferpy markdown) (define md-path (% (build-path "index.md"))) (define html-path (% (path-replace-extension (md-path) #".html"))) (define content-xexpr (% (parse-markdown (md-path)))) (define page-xexpr (% `(html (head (title "My Page")) (body ,(content-xexpr))))) (define html-string (% (string-append "<!DOCTYPE html>" (xexpr->html (page-xexpr))))) (define html-link (% (string-append "/" (path->string ,(html-path)))))
This hooks up a file system path to a Markdown file and expresses different output formats regarding an HTML document.
(html-string) evaluates to the content as a string, and
(html-link) evaluates to a string that you can use as an
href attribute. If I write
(md-path (build-path "other.md")), then all of the values update to reflect
usinghave used this package to upgrade
unlike-assets, creating a better build system for Racket. If you are interested in this kind of work and want to have both support and a say over future development, please consider purchasing a subscription.