saved-value.rkt
#lang racket/base

(require racket/contract racket/file)

(define top (build-path (find-system-path 'home-dir) ".config/values"))

(when (not (directory-exists? top)) (make-directory* top))

(define (make name init #:reader (read read) #:writer (write write))
   (let* ((name (build-path top (symbol->string name)))
          (thing
           (if (file-exists? name) (with-input-from-file name read) init)))
     (values
      (λ () thing)
      (λ (new)
        (set! thing new)
        (with-output-to-file #:exists 'replace name (λ () (write thing)))))))

(provide/contract
  (make (->* (symbol? any/c) (#:reader (-> any) #:writer (-> any/c any)) any)))