Implementation of the FSRS algorithm in Common Lisp and auto-transpiled to Emacs Lisp.
CL-USER> (ql:quickload :lisp-fsrs) ; Ensure you have cloned this repository into the `local-projects' directory under your Quicklisp installation root.
To load "lisp-fsrs":
Load 1 ASDF system:
lisp-fsrs
; Loading "lisp-fsrs"
(:LISP-FSRS)
CL-USER> (defparameter *parameters* (coerce '(0.2172 1.1771 3.2602 16.1507 7.0114 0.57 2.0966 0.0069 1.5261 0.112 1.0178 1.849 0.1133 0.3127 2.2934 0.2191 3.0004 0.7536 0.3332 0.1437 0.2) 'fsrs:parameters))
*PARAMETERS*
CL-USER> (defparameter *scheduler* (fsrs:make-scheduler :parameters *parameters*))
*SCHEDULER*
CL-USER> (defparameter *card* (fsrs:make-card))
*CARD*
CL-USER> *card*
#S(LISP-FSRS:CARD
:CARD-ID 0
:STATE :LEARNING
:STEP 0
:STABILITY NIL
:DIFFICULTY NIL
:DUE @2025-06-08T13:39:42.230941+08:00
:LAST-REVIEW NIL)
CL-USER> (setf *card* (fsrs:scheduler-review-card *scheduler* *card* :good))
#S(LISP-FSRS:CARD
:CARD-ID 0
:STATE :LEARNING
:STEP 1
:STABILITY 3.2602
:DIFFICULTY 4.884632
:DUE @2025-06-08T13:49:49.476969+08:00
:LAST-REVIEW @2025-06-08T13:39:49.476969+08:00)
CL-USER> (setf *card* (fsrs:scheduler-review-card *scheduler* *card* :good))
#S(LISP-FSRS:CARD
:CARD-ID 0
:STATE :REVIEW
:STEP NIL
:STABILITY 3.5362437
:DIFFICULTY 4.8680573
:DUE @2025-06-12T13:39:50.242969+08:00
:LAST-REVIEW @2025-06-08T13:39:50.242969+08:00)To generate the fsrs package for Emacs after changing the code, ensure
you are running the current Lisp session using sly in Emacs, then:
CL-USER> (ql:quickload :lisp-fsrs/emacs)
To load "lisp-fsrs/emacs":
Load 1 ASDF system:
lisp-fsrs/emacs
; Loading "lisp-fsrs/emacs"
[package lisp-fsrs.emacs]..
(:LISP-FSRS/EMACS)
CL-USER> (fsrs.emacs:translate-system)
NILELISP> (package-vc-install "https://github.com/open-spaced-repetition/lisp-fsrs.git")
t
ELISP> (setq fsrs-parameters [0.2172 1.1771 3.2602 16.1507 7.0114 0.57 2.0966 0.0069 1.5261 0.112 1.0178 1.849 0.1133 0.3127 2.2934 0.2191 3.0004 0.7536 0.3332 0.1437 0.2])
[0.2172 1.1771 3.2602 16.1507 7.0114 0.57 2.0966 0.0069 1.5261 0.112
1.0178 1.849 0.1133 0.3127 2.2934 0.2191 3.0004 0.7536 0.3332
0.1437 0.2]
ELISP> (setq fsrs-scheduler (fsrs-make-scheduler))
#s(fsrs-scheduler :parameters
[0.2172 1.1771 3.2602 16.1507 7.0114 0.57 2.0966
0.0069 1.5261 0.112 1.0178 1.849 0.1133
0.3127 2.2934 0.2191 3.0004 0.7536 0.3332
0.1437 0.2]
:desired-retention 0.9 :learning-steps
((1 :minute) (10 :minute)) :relearning-steps
((10 :minute)) :maximum-interval (36500 :day)
:enable-fuzzing-p t)
ELISP> (setq fsrs-card (fsrs-make-card))
#s(fsrs-card :card-id 0 :state :learning :step 0 :stability nil
:difficulty nil :due "2025-06-08T05:38:50Z" :last-review
nil)
ELISP> (setq fsrs-card (cl-nth-value 0 (fsrs-scheduler-review-card fsrs-scheduler fsrs-card :good)))
#s(fsrs-card :card-id 0 :state :learning :step 1 :stability 3.2602
:difficulty 4.884631634813845 :due "2025-06-08T05:48:52Z"
:last-review "2025-06-08T05:38:52Z")
ELISP> (setq fsrs-card (cl-nth-value 0 (fsrs-scheduler-review-card fsrs-scheduler fsrs-card :good)))
#s(fsrs-card :card-id 0 :state :review :step nil :stability
3.536243655619573 :difficulty 4.868056502338024 :due
"2025-06-10T05:38:53Z" :last-review
"2025-06-08T05:38:53Z")