The entire notion of “persistence” that observable has is a huge half baked PITA without any real benefits.
- Slugs are non reusable.
- Unpublish is limited to 24h.
- It’s hard and annoying to change notebook urls.
I’d be all in for this kind of “immutable reference” stuff if it was exactly that: immutable.
But notebooks are not immutable, they change a lot, and they can get edited and deleted willy nilly.
This does not solve the problem of code reuse and breakage, it only makes it more annoying to deal with, because it imposes restrictions which in no way alleviate the existing problems, and only create new ones.
Notebooks almost exclusively link to other notebooks latest versions, which is bad and breaks stuff. But it’s the way encouraged by the system, because versioned notebooks are not a first class citizen but an after-thought.
Visit any “@user/notebook@version” url and it will convert into the “d/whateverweirdstuff@version” slug.
The reason why this is so broken is because it complects “user convenient url” with “notebook reuse references”. Those should not be the same thing.
So here’s how it could be:
- You can choose the notebook url freely, this is just for advertising it to other people (the @user/notebook stuff). Let’s call this the “public URL”.
- Notebooks also have a “content URL”, which is based on the content of the notebook, just like a git hash. Notebooks are always accessible under that address, unless they are explicitly deleted.
- When visiting a “public url” a redirect happens to the most recently published “content URL”, making the “content URL” the “real URL” of the notebook.
- You can unpublish at any time, which will simply remove the “public URL”, but leave the “content URL” intact.
- You can also delete the notebook, but you will get a modal reminding you that this might break other peoples code, and a list of other options you have that don’t break linkage, like unpublishing.
- Whenever you import another notebook via a “content URL” the system just leaves it as is.
- Whenever you import another notebook via a “public URL” the system automatically substitutes the cell with one containing the “content URL”.
- You can add as much ceremony and tooling around the previous point as you want. “Hey we’ve noticed that your dependencies have updated! Do you want them to point to the latest version?”
- Profit: No more breaking notebooks, no more annoying slug burning, no more “ah shit I don’t want this on my profile but I don’t want to break other code”, no more “I wish I hadn’t deleted that notebook I’d like to use that slug again”, no more “I really wanna cleanup all this fork mess but the slug is burned”.
Side note: In theory one could push this content addressability into referencing individual cells, but those “code as a graph” approaches, while totally awesome, and a super cool match for observables “code as a reactive graph” philosophy, somehow always fail. Maybe because they are too fine grained for the human mind, with whole “file” and “notebook” versioning being easier to reason about .