clerk

flowthing 2025-09-10T07:38:16.970049Z

I want to demonstrate that a form throws an exception. However, if the notebook has such a form, Clerk itself throws the error. Is the correct approach just to wrap the form in a try/catch, or is there some sort of viewer I can use, or...?

borkdude 2025-09-10T07:42:07.965519Z

I think normally clerk should render the error?

flowthing 2025-09-10T07:42:22.558489Z

Hmm, all right. Maybe I'm holding it wrong, then.

borkdude 2025-09-10T07:42:38.158999Z

maybe I'm misremembering. let me look at the book

borkdude 2025-09-10T07:48:00.083109Z

neh probably you're right, you should catch

borkdude 2025-09-10T07:48:51.383079Z

borkdude 2025-09-10T07:49:19.007549Z

I guess it makes sense since when in a notebook successive values depend on each other, and in the middle there is an exception, it's not defined what to do after it?

flowthing 2025-09-10T07:50:56.373779Z

Yeah, it definitely makes sense. 👍 I guess I was wondering if there`s a {:nextjournal.clerk/something ...} thingy that I can use to alter the behavior.

flowthing 2025-09-10T07:51:14.958939Z

But all right, I'll just catch, thanks! 👍

borkdude 2025-09-10T07:52:43.010189Z

I'm not aware of such a thing, but perhaps @mkvlr or @andrea712 is. You could use a macro but note that macros inside a notebook don't work well with caching at the moment, so such utilities should be placed in another namespace currently.

👍 1
mkvlr 2025-09-10T12:57:24.444679Z

if you want to show the exception as a value, you need to catch it, yes

flowthing 2025-09-10T12:57:44.535749Z

All right, thanks!

rutledgepaulv 2025-09-10T16:05:07.603569Z

Has there been any thought put into an "async viewer" for clerk that runs a form in a background thread while showing a spinner or something until the result returns? I realize the primitives exist to create something but might be nice as a built-in.

rutledgepaulv 2025-09-15T14:07:29.220759Z

Yeah that sounds like the experience I'd want too. I can't think of a reason derefing from another thread would be problematic to start with

👍 1
mkvlr 2025-09-15T17:27:38.990189Z

feel free to make an issue if you don’t mind

👍 1
rutledgepaulv 2025-09-15T17:54:01.168449Z

https://github.com/nextjournal/clerk/issues/769

🙏 2
2025-09-11T19:59:28.475799Z

Give us a couple of use cases so we can better understand what you’re after

rutledgepaulv 2025-09-11T20:10:09.545909Z

A notebook full of db queries and graphs of the results that might run quickly or take a long time. It's an improved user experience if the entire notebook opens and queries that are fast render quickly without being delayed by earlier slower ones. You could imagine a macro like (clerk/async-viewer (do-something-expensive)) where the macro runs the body in a background thread, shows a viewer + spinner immediately, and when (do-something-expensive) completes it would render the value in whatever the appropriate viewer is for the return value (or if the return value is itself a viewer, it would just use that)

rutledgepaulv 2025-09-11T20:11:39.377449Z

could just be a function too I suppose that accepts a IDeref, that's probably better than a macro layer that couples it with the creation of the future

mkvlr 2025-09-14T16:40:29.558479Z

I’ve been wanting this as well. One solution I thought about was showing the document early right after parsing and then filling in the results as they’re evaluated. I guess to work well, we’d only want to do this if something takes longer (more than ~100ms?) to execute.

mkvlr 2025-09-14T16:44:35.919239Z

as for the async part, clerk’s IDeref viewer could show the loading state while it’s waiting on the value.

mkvlr 2025-09-14T17:18:32.045269Z

would it be reasonable to assume that if something implements IDeref that i would be safe to deref it on another thread?

borkdude 2025-09-12T18:38:33.310259Z

there's also a promise viewer, if that makes sense

borkdude 2025-09-12T18:39:01.851059Z

but I guess that's only about the "front-end" code

borkdude 2025-09-12T18:39:40.161599Z

there's also a sync-atom which could be interesting to use here you could use that to asynchronously populate the atom and view the change on that