JohnEarnest/Decker

JS vs C - Two Implementations

relector-tuxnix opened this issue · 3 comments

Is there any reason you have a C implementation and a JS implementation ? Won't this double the cost of long term maintenance and increase the burden of implementing new features?

You could in theory scrap the C version and use Node for desktop (Electron app etc). Or you could take the C SDL version and get it working with WebAssembly? There are lots of options out there to eliminate having two code bases.

Having a whole development environment within a single .html is absolutely amazing and so really the C version has less advantage long term. Everyone has a browser installed and so you already have a runtime environment for the .html vs C version which requires the Decker binary.

Just some thoughts.

Decker is the closest I have seen to HyperCard and would love to see it well supported and used going into the future.

I considered this very carefully during Decker's development. The twin-codebase approach does increase the maintenance cost of the project, but I think it's ultimately very important. Given the present ubiquity of web browsers, Web-decker is absolutely essential for sharing projects with other people (and has some side-benefits for letting people author decks from public machines without installing anything), while native-decker offers a superior editing experience (direct filesystem access, more reliable copy+paste, etc) and makes Decker accessible to people with limited internet access or older, slower hardware.

C and JS are, respectively, the linguae francae of native and web applications, so I view each as the maximally "hackable" option for technically-inclined users: it's fairly easy to bodge in your own wrappers for native functions, experiment with changes, or customize a build for your personal preferences. There are lots of inherently "non-portable" features I don't intend to add to mainline Decker which a given user might want for a project, and letting them easily add things themselves is what open source is all about.

Electron might make shipping cross-platform binaries a bit easier, but it's very heavyweight and resource-demanding; Decker would be unusable on a wide range of older machines it currently works fine on. The C version of Lilt doesn't even depend on SDL, so it can run on positively ancient personal machines, limited web servers, etc.

WASM has some promise, but I consider it an immature technology; there's still a lot of churn in functionality and tooling that I'm not interested in dealing with. If the application was shipped as a blob of WASM it would not be possible for end-users to easily tweak, customize, and debug problems with standalone builds. As an example, take a look at the kinds of things the Bitsy Community do by direct tweaking of that tool's output.

The web ecosystem is presently quite vital and universal, but I'm not sure that will always be the case. We're rapidly approaching a web in which there is a single browser engine- Chrome- controlled by an advertising company. It's great to take advantage of what browsers can do today, but in the long view, I would like Decker and the things people make with it to be able to outlive the web ecosystem as we know it. Avoiding hard-dependencies on web technology and having a plurality of freestanding implementations helps.

Finally, it may not be obvious at first glance, but there are many small differences in functionality and design between the js and c versions of decker: some are spelled out here. The web version has to deal with lots of constraints that do not exist for C applications, and it also gets to take advantage of some browser features that are not as accessible from a C application. Even if I did cross-compilation of some kind there would be a mess of ifdefs and platform-specific code needed to handle the differences.

The Decker document format and the Lil programming APIs expose a simple, lowest-common-denominator of functionality, so from a user's perspective, a deck works the same in both clients. They get the best of both worlds, and I pay some upkeep to make it happen. In my opinion, well worth it.

WASM has some promise, but I consider it an immature technology; there's still a lot of churn in functionality and tooling that I'm not interested in dealing with. If the application was shipped as a blob of WASM it would not be possible for end-users to easily tweak, customize, and debug problems with standalone builds.

I think as Decker is open source, you would allow a person to add plugins/extensions to the C version then rebuild. If you had a single C -> WASM port it would also mean the .html (including the wasm blob) would also contain all the custom code.

The web ecosystem is presently quite vital and universal, but I'm not sure that will always be the case. We're rapidly approaching a web in which there is a single browser engine- Chrome- controlled by an advertising company.

I appreciate your concerns. But there is sufficient competition in the web engine space: https://en.wikipedia.org/wiki/Comparison_of_browser_engines . I also think the trends indicate that Web Browsers are here to stay too the point that the underlying OS is less of a consideration over a good browser. So an investment on Decker JS would likely yield better returns than a native desktop application.

As the Decker C implementation is essentially C and SDL its not a far stretch to use Emscripten (https://www.jamesfmackenzie.com/2019/12/01/webassembly-graphics-with-sdl/) to build the core for Web. I'm not 100% on loading from disc and other potential issues. But the rendering of the canvas and most of the logic is definitely achievable. However, you may have already explored this avenue and discovered its limitations.

Again. Great work.

1jss commented

@JohnEarnest Your answer here is so clear and well written (as is all the Decker and Lil documentation I've encountered). I'm happy I went to look at the list of closed issues! This peek into the thinking behind the stack is great reading and would deserve a blog post!