Grant Forrest 2023-07-10 01:17:40 I've had this idea rattling in my head to make a frontend framework that's only signals, and after almost a year of maturation I finally put down some code today. Genuinely surprised this works.
I'm curious where it starts to break down. It's not like modern frameworks are unaware of signals, most feature them heavily, so there's probably some reason they haven't gone all-in on them too, right?
I'm using tldraw's lovely signia
for signals implementation, hence the first param of atoms being a 'name' and not meaningful for execution. This also gave me an excuse to read signia
's source and discover their clever trick for tracking atom inheritance which is pretty neat.
Andrew F 2023-07-10 03:40:16 It looks a little like a logic programming approach to web UI. Not sure how much that's coincidental...
Lu Wilson 2023-07-10 06:18:21 Awesome! I'll pass this on to David and the rest of the team. It's been really great to hear David's thoughts on signals, and how signia came to be, and the unique approach that it takes! I still think that the signia docs gives one of the best explanations of what signals are.
tldraw has to deal with a huge amount of state changes at high speed, which is why we needed signia (alongside React). We tried other libraries, but they all started to break down with tldraw's unusual use-case. (eg: memory leaks, eg: triggering too many recalculations, eg: too slow)
Chris Granger 2023-07-10 12:29:46 Solidjs is fairly popular and is built entirely around signals. solidjs.com
📝 SolidJS
Solid is a purely reactive library. It was designed from the ground up with a reactive core. It's influenced by reactive principles developed by previous libraries.
Grant Forrest 2023-07-10 12:35:30 Lu Wilson yeah David's work is great, I toyed with making my own signals first but couldn't crack the dependency problem. When I read capture.ts
my jaw hit the floor! Such an elegant way to do it. I was afraid I'd find Proxy usage but not at all!
I visited Steve in the office when we were in London last year and he was talking about what I now know is signia, seemed really excited about it, but I couldn't grasp the concept at the time. Glad I got to revisit and appreciate it, it's fun to use.
Chris Granger I checked out Solid a while back but bounced off for some reason, I can't remember why. I'll read their docs again. Part of what I'm curious about is why the need for a compile step, why JSX syntax, etc. I'm curious to see if the needs which drove those features emerge in my own little experiment.
Grant Forrest 2023-07-10 12:43:51 From a scan of their tutorials it was probably the magic that bothered me about Solid, like how computed signals are plain functions. Perhaps in practice it feels natural, but I have a strong preference for more native-feeling code.
Marcelle Rusu (they/them) 2023-07-11 13:48:56 I've started to work on a structural editor for my language coil coil-editor.netlify.app
It's still early & buggy, but the idea is to directly turn the AST into html with contenteditable for leaf attribute nodes.
So an expression like:
document.body
which is the coil AST:
{type: :property_lookup, lhs: {type: :id_lookup, name: "document"}, property: "body"}
Turns into:
<div data-kind="property_lookup">
<div data-attr="lhs">
<div data-kind="id_lookup">
<div data-attr="name" contenteditable>document</div>
</div>
</div>
<div data-attr="property" contenteditable>body</div>
</div>
And now we can easily query this expression with css selectors. So all the syntax highlighting AND formatting is done in css. It also means that static analysis can be done using querySelector.
Marcelle Rusu (they/them) 2023-07-11 14:14:56 Where I see this going is establishing a highly extendable editor system.
I want it to be attainable for an average library author to ship with a linter, and editor plugins.
To start I need a dead simple editor system. So with embedding AST information in the html, it gives web developers a clear path how to inspect the AST & come up with custom rules, or swap out parts of the ast with something more visually interesting (imagine putting in a colour picker in usages of a color function).
I haven't realized its full potential yet, there might need to be more metadata in the DOM, but I'm starting small & seeing how far I can get.
David Alan Hjelle 2023-07-11 21:32:15 I'd wondered about such things myself. You are lot further along than I am, though! The "ground truth" representation is still the AST, right? Do you have to do a lot of work to keep the DOM and AST in sync with each other? Are you using something like ProseMirror or…hmm…looks like your are writing your own! Cool!
Marcelle Rusu (they/them) 2023-07-11 21:51:43 The code to do the mapping from html to ast, and vice versa is here github.com/coil-language/coil-lang/blob/main/editor/src/ast.coil
The file is 67 lines of coil so its totally manageable, and I suspect it shouldn't have to grow much larger.
In terms of keeping them in sync, the data is stored in the dom, so when you edit a node, it will parse it as coil code & turn it back into dom. So I guess ground truth is html. We only turn it back into coil AST when we evaluate it.
Keeping the state in the dom lets us use query selectors for all sorts of things. Here's an example of checking for using undefined variables:
And here's the linter in coil
fn lint-unused-variables {
let ids = document.querySelectorAll("
[data-kind=let] >
[data-attr=assign_expr]
[data-text]")
::map(:textContent)
::into(Set[])
document.querySelectorAll("[data-kind=id_lookup] [data-text]")
::reject(:textContent ids)
::each($.setAttribute["data-warn", "Use of undefined variable"])
}
Peter Saxton 2023-07-12 14:47:52 I think very cool, but I must admit I can't work out how to try it out. Would you be able to do a video where you explain the keypresses you do to make edits
Marcelle Rusu (they/them) 2023-07-12 14:55:20 Admittedly it might be too early for #share-your-work but here's an attempt to show.
One thing is, its rough on mobile, you can eval it but editing is hard.
There's also a handful of crucial features missing notably
- ability to tack on an operator after a node -> going from
a.b
to a.b.c
- delete the upcoming node - going from
a[0]
to a::first()
is hard/impossible right now
Also there's some awkwardness of dealing with the editor as ast nodes, you can only edit within a leaf node, to move on to the next part you must tab into.
Here's a video, hope it helps.
Marcelle Rusu (they/them) 2023-07-12 14:56:28 I believe those problems are solvable, but right now I'm just showcasing the simplicity of the model, and the benefits of storing AST as html.
Marcelle Rusu (they/them) 2023-07-12 14:58:50 When you insert a new line, its temporarily a plain text editor for that line until you focus away & it parses it
Tyler Adams 2023-07-13 01:32:01 Paul Tarvydas 2023-07-13 02:20:28 could
env | grep OPENAI_API | cut -d '=' -f 2 | ....
have been written as
echo $OPENAI_API | ....
?
greg kavanagh 2023-07-14 19:44:51 Added some filters and shadows to QuickPoint. "We are mere shadows and filters Horatio"