grain-lang / grain

The Grain compiler toolchain and CLI. Home of the modern web staple. 🌾
https://grain-lang.org/
GNU Lesser General Public License v3.0
3.22k stars 115 forks source link

Reimplement DOM stdlib #126

Open ospencer opened 4 years ago

ospencer commented 4 years ago

Back in the day (before we had proper modules), we had a DOM standard library. This should be rewritten so it is usable again, and with better types.

mindplay-dk commented 3 years ago

Would this communicate with DOM via JS for every query and mutation?

I think Grain, as a language, could be interesting for DOM work, if there was a JS backend - but I don't think that's on your roadmap anytime soon?

I would hope to see this moving more in the direction of Elm, Reason or Imba - more so than the direction of C# with Blazor. Imba is perhaps particularly interesting as a reference, since the language has some of the qualities of Grain, and also makes precise DOM updates without virtual DOM or diffing. Something like Sinuous or Solid might be interesting as references too, embracing reactivity and precise DOM updates with minimal complexity and overhead.

I'm not saying the language needs to come with a library or framework, necessarily (although this was probably key to Elm's relative succes) but it would be nice if it enabled the community to build those things. The DOM model is all about mutation, so there's no particular incentive to choose a language like Grain unless it somehow enables you to conceptualize of the DOM as immutable within the language.

And it needs to be able to compete with mainstream frameworks on performance, which I'm guessing isn't really feasible if it's happening from WASM via JS? I don't think there's any real advantage to having WASM drive a UI in terms of performance, probably the contrary - and there's almost definitely only drawbacks in terms of complexity and debugging. A JavaScript target is probably the only way to make a DOM library in Grain truly useful?

phated commented 3 years ago

@mindplay-dk there will never be a "js backend", just as there will never be an x86 backend. Those are not the goal of the language and you'd be better off finding a different language.

Reference types are already in the spec and the DOM stdlib will be implemented with them.

mindplay-dk commented 3 years ago

Well, never say never. Even if a JS backend isn't on your roadmap, there's no saying the community won't do it - it happens to almost any language with some traction, sooner or later. JS looks like a much easier target than WASM. 😉

wanton7 commented 3 years ago

I don't think Grain needs JavaScript target for DOM access. I remember years ago there was talk from React team that React would have option to run in web worker that doesn't have DOM access and only code that would do DOM patching would run in main JS loop. My understanding is that they didn't implement it. But Grain or any Wasm app can use similar system. Example using something like morphdom https://github.com/patrick-steele-idem/morphdom that Elixir's LiveView is using. Wasm code will just send batch of DOM updates to JS.

jrmarcum commented 2 years ago

I know you are rewriting the DOM module. I would like to make a suggestion. The site listed below is a good example of creating PWA's with Elm and Rust. I would like to suggest that Grain would be a good match for this type of use case to develop Desktop/Mobile/Web PWA's with a web assembly base as is the case shown. This could go far for those in need of multiplatform accessibility to software paradigms, without the complication of choosing a native platform framework and working within those complexities. I feel that Electron, Photon, etc. are the way to go and that the normal platform terminal will eventually end up being the web terminal anyway in the near future.

https://sindrejohansen.no/blog/willow/rust/elm/2018/11/16/willow-elm-in-rust.html

Anything simpler than this over complicated mess with .net would be great. Bolero and F# have the right concept but the programming framework is too complex for a normal maker/programmer to utilize efficiently in both the syntax reference structure and the pieces and parts that make up a solution file set. https://fsbolero.io/docs/Elmish

Having one grain file and one generated run time file for the PWA would be ideal, or maybe two including a generated html file. I know this sounds overly simplified, but it could be done. Don't know if the manifest file would or could be generated in the same process or would need to be generated by hand.

jrmarcum commented 2 years ago

Just as a follow up, here is what can be done with Rust and Yew and web assembly. I think this is the way you would want to go. https://yew.rs/getting-started/build-a-sample-app

jrmarcum commented 2 years ago

Not sure about the DOM specific progress, but I was browsing for a solution for something and came across something that I thought I would post to pass along maybe a solution that would give similar results graphically to having direct DOM access depending on the desired results of interaction with the browser. If all that is needed is interaction and GUI then this may be a good solution if converted to a grain module for compiling to wasm for js interactivity in a web page : https://github.com/flyover/imgui-js

mindplay-dk commented 2 years ago

Isn't there also talk now of a standardized WASM API providing access to the DOM/BOM?

jrmarcum commented 2 years ago

Not sure about that, but there is a github project that is trying: https://github.com/web-dom/web-dom

jrmarcum commented 2 years ago

I also saw this in the how did they do that category: https://www.remobjects.com/elements/platforms/webassembly.aspx

mindplay-dk commented 2 years ago

Not sure about that, but there is a github project that is trying: https://github.com/web-dom/web-dom

Or "was trying"? No updates in 3 years.

Looks pretty solid though - big ✅ for generating these from WebIDL, and for building a language-neutral module for all languages targeting WASM. I suppose you could build something more language-specific on top of that, if necessary - but just having the original WebIDL APIs made available should go a long way towards adoption, as these are the APIs front-end developers already know from the browser.

s0kil commented 1 year ago

Looking forward to writing UI's with Grain.

ukd1 commented 10 months ago

Is this still being worked on?

spotandjake commented 10 months ago

It's not actively being worked on I think we may be waiting for stuff.

ukd1 commented 10 months ago

@spotandjake thanks - was just looking for new things to try, and found grain, but want to do dom stuff... I'll keep watching!

LaughingBubba commented 4 weeks ago

4 years and a big nada so far. Given WASM doesn't support DOM manipulation (nor is it ever likely to) maybe you should drop DOM from your docs and stop misleading people.

jpx40 commented 2 weeks ago

Can we bind js like Rust does it?

ospencer commented 1 week ago

I put up a PR to remove the DOM doc page from the website. We obviously aren't trying to mislead anyone—this is a project we work on for fun in our spare time. As you can imagine, it's difficult to keep the docs up to date (in fact, this was the only page of the stdlib docs that isn't auto-generated and I completely forgot it was there).

Can we bind js like Rust does it?

We absolutely can. This is a great opportunity for a community package that doesn't necessarily have to be Grain specific.

All one needs to do is define a WIT DOM world and implement the JS side. Through the power of bindgen, we can have JS and Grain bindings for free. This wouldn't be terribly difficult, just a lot of work. Could have something basic working in under an hour, but doing the entire API is likely a full-time job.