Reminder Use Cases
- One-off reminders, e.g. a dentist appointment.
- Recurring tasks in Task Warrior, e.g. to prepare lunch the evening before.
- Counting down to a particular event, e.g. 36 days until launch.
- Counting time since an event, e.g. Last blog post was 7 days ago.
Remind is extensible, and has no problem handling these kinds of tasks. For example, to handle the “days since” requirement I did this:
FSET dayssince(startdate) today()-startdate REM It has been [dayssince('2016-11-05')] days since you last blogged.
First I define a function called
dayssince that accepts an argument of
startdate. I then pass the date of my last blog post into the
function on the Reminder line, and the output of the function gets displayed in
the resulting Reminder message.
Reminders for Saturday, 5th November, 2016 (today): It has been 0 days since you last blogged.
Remind is excellent at most everything, but there was something elusive to me: How to handle “Spatial” reminders.
Have you ever had an insight that was so powerful, you were afraid to forget it? This happens to me every so often. For example, I’m working on a multi-year goal to become a productive contributor to the Linux kernel. This goal is so important to me, that I want to remind myself of its importance, to avoid the temptation of abandoning it for something shorter term.
However, I don’t want to be reminded every day. Instead, I want to be reminded more frequently at the beginning of the project, and less frequently as time goes on.
The idea for Spatial Reminders came from the writings of Piotr A. Woźniak and his work with the software called Supermemo. I use Anki every day for memorization and practice of computing rudiments, and I wanted to apply something similar to Reminders.
I scoured the Remind mailing list and came across many helpful materials, but nothing that directly explained how I could accomplish this. After some trial-and-error, I came up with the following.
FSET dsince(x,y,z) today()-date(x,y,z) FSET spatial(x,y,z) coerce("INT", shell("echo '(sqrt("+dsince(x,y,z)+")+1)^2-1' | bc")) REM [date(2016,10,23)+spatial(2016,10,23)] MSG Do not abandon kernel development for shorter term goals.
This is pretty dense, so let me explain.
spatial function receives a date, calls
dsince to get the number of
transpired days, and then runs a calculation on it.
This calculation returns the next day that we will be notified. It works like this:
- Obtain the total number of days since the start date.
- Get the square root of this number, floored (rounded down).
- Add one to this number.
- Square the result.
- Subtract 1.
For example, let’s say today is November 5th, and we started our Spatial Reminder 13 days ago, on October 23rd.
- The floor of the square root of 13 is 3.
- 3+1 is 4.
- 4 squared is 16.
- 16-1 is 15.
Therefore our next notification will be on the
start date + 15, i.e. November
On November 7th, the output of our formula
(sqrt(15)+1)^2-1 is 15. Our REM is
evaluated as follows:
# Before evaluation of spatial function: REM [date(2016,10,23)+spatial(2016,10,23)] MSG Do not abandon kernel development for shorter term goals # After evaluation of spatial function: REM [date(2016,10,23)+15] MSG Do not abandon kernel development for shorter term goals
Since today is 15 days since the start date, we will be notified.
On November 8th the new formula increments to
which has a value of 24. So, our next reminder will not appear until 24 days
since the start date, on November 16th.
Here is an interesting plot of the spatial reminder function: X is “days since”, and Y is days until the next reminder. On day 15, we are reminded. On day 16, our next reminder is 8 days out. You can see that the number of days between each reminder is increasing.
For fun, here is the same graph zoomed out to a view of 10 years. After 10 years, reminders are around 125 days apart.
I’ve had fun using Remind to solve this problem. The frequency is still a little high, so I may need to come back to it later on.
Thanks for reading and reach out to me if you have advice or questions. You can reach me at the email address viewable in my GitHub profile.