User Tools

Site Tools


newsletters:2025-12

This is an old revision of the document!


December 2025 newsletter

What we've been up to

Nonprofit 501(c)3

Daniel: We are now officially a 501c3 nonprofit. This means we can accept tax-deductible donations and are eligible to apply for grants.

Folk is a long-term project. Many people want to work on it and even more people want to support its growth and development. When thinking of the possible organizational structures that could sustain this development, we decided that a nonprofit was the best fit. It allows us to continue providing something valuable without needing to rope off parts of that value behind a paywall. We want as many people as possible to be able to participate in this exciting new computing paradigm.

Funding is a big challenge for a nonprofit. It will take some time to grow. Because we have no plan to charge for Folk, we can't sell portions of ownership to venture capital or other investors. This is good long-term. We can avoid the pitfalls that come from developing a technology in service of shareholder value. But it means we can't rapidly grow into a 10-50 person team the way a traditional startup would.

The first major milestone will be hiring Omar full-time and Andrés part-time. They will continue development of Folk and the gadget. We also want to cover studio rent and hardware costs. In the future, we could expand this to include things like growing the core team, covering conference attendance, more gadget development, or anything else that advances our vision of tangible computing for everyone.

If you would like to support us, please join the 30+ people already donating on GitHub Sponsors. A special thank you to all of you who are already sponsoring the project.

folk2 merge

Omar: We've merged the new version of folk into the main branch.

It's a nice feeling that the work we've been doing is finally going to be visible on the main repo and get used by people out of the box.

Along with the nonprofit news, I think we want to use this as a trigger to enter a new, more public phase where we do more applications and demos (and work more on fundraising).

folk2 isn't quite caught up to folk1 feature-wise (a lot of features are still not implemented, and documentation isn't great), but we weren't really supporting folk1 anyway (we wouldn't want anyone to submit a patch for it, for instance).

And folk2 is so much faster (and more expressive for complicated integrations) that I think we want it to be the default experience for people. Still lots to do to communicate the new stuff you can do in it.

Minor improvements

from the lead-up to merge & party:

/setup page

Omar: The /setup page which now lets you set up camera and projector and initiate calibration looks pretty good now. (it replaces the old setup.folk file)

You can see the /setup interface on the left here, and some of its source code on the right (which uses the new HtmlWhen construct):

img_7052.jpeg

Live display and camera selection doesn't work perfectly yet (switching displays crashes), but it feels really cool and shows the dynamism of the system and the display/camera modules. The live preview of camera when you choose a resolution is really nice.

JPEG frames

TODO: Decompress and do AprilTag detect, making the normal Folk pipeline work again.

Rob Fielding suggested moving toward claiming decompressed color frames in the system as well. Currently, the system only exposes the decompressed grayscale channel (which is all you need for AprilTag detection). By using the raw JPEG data from webcams, we can potentially allow color use cases to coexist with grayscale detection without redundant decompression/compression cycles.

HtmlWhen improvements

I implemented the HtmlWhen construct that I discussed last month, made web/programs use it, and made web/setup use it.

Made some improvements after initial implementation:

Idiomorph

Last month, we mentioned wanting to use a morphing library to preserve HTML elements (including their internal state: focus, selection, details-open, input value) when the HtmlWhen updates. I added support for idiomorph, a library from the HTMX people, which pretty much just works for this!

This is as long as you put HTML ids on all your elements so they can be reconciled across the update. You might also need to add custom JS handlers to filter out attributes that you don't want to be destroyed by the update.

Here's the templated Folk-HTML that implements the /programs endpoint now, including the -beforeAttributeUpdated filter to preserve the <details> tag open state across updates:

<html>
<head>
    <title>Running programs</title>
    <link rel="stylesheet" href="/style.css">
    <style>
        body {
            font-family: math;
        }
        summary {
            font-family: monospace;
            font-size: 2em;
        }
    </style>
    <script src="/lib/folk.js"></script>
    <script src="/vendor/idiomorph.js"></script>
    <script>
      const folk = new FolkWS();
    </script>
</head>
<body>
[HtmlWhen the collected results for [list /programName/ has program code /programCode/] \
          are /programs/ {
    emitHtmlForPrograms $programs

} -beforeAttributeUpdated {(attributeName, node, mutationType) => {
    if (attributeName === "open") { return false; }
}}]
</body>
</html>

Statement reuse bug fix (fixes editor freeze)

Omar: We noticed before and during the folk2 launch party that the editor would often freeze after a minute or so of usage. You'd be typing stuff and suddenly your keystrokes wouldn't do anything, and you'd have to un-cover and re-cover the editor or even reboot the system to get the editor to work again.

I dug into the problem for a few days. I started by finding that for some reason the last statement in this block sometimes wasn't going through:

Whenever I got the editor freeze bug, I'd see that the block was executing, and some of the statements from the block were in the database, but one was missing & would never show up as a result to any queries (so we were lacking a max cursor x or view dimensions or cursor position statement, which broke the editor).

This made me feel that there was some really bad race in the evaluator (it violates what I would think of as core Folk invariants), so I did more digging.

I found that the missing statement (s4409:77 here) was actually present in the database and was alive, but was not queryable (didn't exist in the trie):

(whereas the other two child statements of the block, s4408:77 and s4419:77, were properly indexed and queryable)

I added some print statements and found this problem with editor locking.

After this point, the statement is in the weird state we saw earlier (alive but not in trie):

(Also, extremely alarming and a clear invariant violation to have two different statements w/ identical clause.)

It turned out the problem was in statement reuse (which makes sense, since these were reoccurring statements about editor state) – we were assuming that the new statement was added, but we were actually not changing the old trie, just swapping it with itself, so the new statement was not in the trie. The fix was to rerun the loop if the new trie is same as old trie.

This one-line fix fixed the editor freeze bug, and it also seemingly fixed the Added tag pileup that has been bothering me for months, and it also probably fixes other mysterious bugs. I feel a lot happier with the evaluator now.

Editor refactor

Mason did a big editor refactor that removes traces of the old “code view” terminology, cleans up the state, and makes the line numbers render more cleanly. Scroll also works better (retains more context)

This mostly came out of us trying to fix a bug where the scroll viewport was weirdly small on editor reboot (due to some race in the old way we were doing state).

Folk for DnD

Paul and Naveen discussed building a “DnDKit” for Folk. The idea is to have a DM laptop interface that projects a symbolic map onto the table, allowing the DM to selectively hide or expose rooms (fog of war) while players move physical miniatures around.

with /...options/ options

Omar: I've been experimenting with trying to break out When with /...options/ into When with x /x/ y /y/ while still supporting any option order and letting unused options pass through. This is nice because it makes the When declaration better reflect the actual options needed by the body.

Richer captures

Omar and Mason brainstormed some more ways to make Folk's When captures more expressive, instead of having ad hoc code in the body of the When to destructure arguments and check argument validity.

  • Optional and default values: We're exploring syntax like /layer?/ for optional captures or /layer or 0/ for default values.
  • Type constraints and filters: There is interest in “contracts” for captures, such as /x where [string is double $x]/ or even range checks.
  • The “with” keyword: We are looking at making with a bare keyword in statements to better denote special flags or contexts without complicating the dictionary matching.

The main challenge here is tokenization—balancing the ergonomics of the forward-slash /capture/ syntax with the need to parse more complex expressions inside them.

/quads experiment

Omar: I've felt for a while that we're not doing enough with the full 3D geometry that we have of all quads (program areas) and of the camera and projector. I wanted to do a little 3D visualization of the 3D space that you can pan and zoom. Slapped this together just using CDNed three.js. It shows Folk's perception of the 3D space in front of the camera:

I want to clean it up and do some more stuff (maybe texture the quads with the camera slices of each quad). It'd be cool for this to be a livestream UI with these 'computational objects' in the stream for all viewers to interact with.

Experimental tcl interpreter update

Mason: slowly but surely, the custom interpreter is coming together! The core object APIs are now in place, and the interpreter works, so now it's mainly working on the standard library.

Expression parsing ended up being a lot easier to figure out than I expected—precedence climbing is surprisingly intuitive! There were some infinite recursion and infinite loop bugs that took some time to hunt down, but it's working pretty well now.

I ran into a really nasty reference counting bug the other day, because I've been swapping objects in place whenever they need to be replaced. This created some really scary situations where I accidentally freed an object that was still in use by the caller, so I've opted against swapping in place except for the outermost API. I'm mostly done refactoring it out, but there's still more stuff to clean up.

Overall, I'm feeling really good about the design. Having a custom allocator lets me do some really cool stuff, like splitting an existing allocation into individual parts in-place, which lets me do some efficient list shimmering (I store objects directly in the list, so if one of the objects became shared when freeing the list, I need some way to keep the objects in place. I can split the list's allocation into individual objects, and free all the non-shared objects).

I still haven't been able to do much performance testing though, since the pieces kind of all interlock, so I have a nagging feeling that may be my interpreter will be slower than Jim. But, I've built in a lot of room for modifying when structures are copied/referenced, so I have room to tune. So stay tuned for when I can get enough standard functions in place, so I can start benchmarking Folk!

Outreach

Our friend Max Krieger visited:

img_6965.jpeg

folk2 launch party

We had a launch party for folk2 on Friday, Dec 12. It was very fun. Brian Lee helped out, and Daniel came in from Utah to help out as well. Was a good way to bring people in who hadn't seen Folk in a while, announce nonprofit and folk2 updates, and force ourselves to make progress on public-facing niceties in the Folk system. (We probably made a couple months' worth of progress on little nits in the week before the party.)

Omar made some programs to do the merge live on stage:

img_7671.jpeg img_7669.jpeg

We had multiple systems — the main system (folk-hex), two portable systems set up on the first floor of Hex House, and three gadgets (one of which was Daniel's home-made gadget) being passed around. People had a lot of fun trying out folk2 by making buttons, playing with the editors, and using points-at programs to have programs effect each other:

crowd_3.jpeg crowd_1.jpeg

editor_with_cat.jpeg

Brian made this poster board with various demo programs people could try out on one of the systems downstairs and was a convenient surface to point gadgets at to demonstrate that they can run all the same programs a bigger system can:

board.jpeg

Omar and Andrés gave a short talk about their work on folk2 and the hopes they have for the future of the project. Afterward Daniel talked about the non-profit and funding this work:

daniel_speech.jpeg

Folk gadgets at SVA

Andrés presented to a class they were teaching on UX/UI Fundamentals at the SVA Interaction Design masters program about the future of interfaces. It culminated in a live demo of the Folk gadget, which students had a lot of interesting ideas for building prototypes with:

img_2720-medium.jpeg img_2719-medium.jpeg

img_2716-medium.jpeg img_2714-medium.jpeg

What we'll be up to in January

  • Omar will mostly be in China and mostly working on the gadget (calibration, setup process, new hardware iterations/capabilities) and maybe RFID
  • Omar wants to do some more model/perception experiments as well
  • Andrés will be working on getting dot detection demos working again and exploring dot interaction demos

Omar

Andrés

newsletters/2025-12.1768641591.txt.gz · Last modified: by osnr

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki