Open danielnarey opened 6 years ago
@danielnarey thanks for writing out your thoughts! My initial reaction (while continuing to mull it over) is agreement with your analysis of Elm as well as of what a strategy to take for the Modular UI framework.
A smaller framework that can be used flexibly will make it easier for Elm developers to adopt (and evangelize) Modular UI, which I very much agree is a better approach to rendering frontends than the Html
library.
Some thoughts I needed to get down before proceeding (this is long):
My personal approach to web development has been evolving rapidly since I published the Semantic DOM and Modular UI packages. At that time, I thought that web development could be simplified, or at least rationalized, by having one framework to rule them all. Now I think that being able to flexibly integrate different sets of utilities that are each designed to solve a specific problem is probably a better approach in the long run, but more on that later.
The advantage I saw in Elm as a front end framework is that it provides a common functional syntax and set of language utilities for markup, event handling, and application logic. Some other great things about Elm: immutability of data/objects, no global scope, no side effects allowed. (As a side note: A lot of Elm folks are big on type specificity—I get the point in terms of catching errors at compile time, but it also results in code duplication and more cumbersome error handling, so when we have a choice about how to implement something, it's important to ask how useful type checking is in that instance).
I also saw some shortcomings with Elm as a front end framework. First, once you get beyond "Hello, World," writing markup with the Html package is no fun (for me anyway). Multiple nested square brackets don't make for very readable or maintainable code, and the pipe operator won't help because VirtualDom nodes are unmodifiable once they are constructed. Second, for all that Elm does to simplify event handling, application logic, and state management, Elm has no utilities out of the box that would help to simplify the user interface side of front end development. Hype and corporate sponsorship aside, one of the selling points for Redux/React as a development framework is that it has React, "A javascript library for building user interfaces," whereas Elm has...the Html package?
Modular UI was an attempt to get around the first shortcoming (frustrating syntax/constrained patterns) and to try out some strategies for dealing with the second (lack of a built-in component architecture). In the syntax/pattern aspect, I think that my approach in Modular UI has been mostly successful because it aligns with a functional way of breaking down chunks of code, and with functional programming patterns more generally. In terms of moving toward a component architecture, my thinking has shifted since I last worked on this package, and I'd like to explain how.
There are two ways I tried to think about component architecture in Modular UI. The first was to build event handling into constructors for basic components like buttons and input fields—e.g., pass a message type and other data to a constructor function and get a responsive component that's hooked up to your app's update function. I find it to be really useful, even for something as simple as a button, not to have to think about how to write the markup every time, but just to be able to invoke a function and get the component I need. So far, so good.
The second line of thinking regarding component architecture is how to go beyond basic things like buttons and input fields in order to build to more complex components that could be reused (with variation) in lots of different projects. This is where I got stuck for a couple of reasons. Because I was thinking in a "framework" paradigm, I turned to popular CSS frameworks to figure out what components I should include and how to pattern them. I've had some frustrations with Bootstrap in the past; in discovering Bulma CSS as a newer alternative, I liked its class-only approach to styling, so I chose to integrate Bulma class names and to pattern components using the corresponding markup in the Bulma docs. In the Modular UI package, I only included Bulma's basic element classes, but I also have unreleased code with constructor functions for more complex Bulma components (here's one for tabs from the docs page).
Tying Modular UI to a specific CSS framework is an obvious limitation to its general usefulness and adoptability. At the same time, it's useful to have reusable components that can be plugged in to any view.
So here's my agenda:
1. Separate out the two tasks of (a) stabilizing a functional syntax for UI development in Elm and (b) moving toward a general component architecture that can guide the design of specific component libraries.
The next version of Modular UI for Elm 0.19 should only address task (a). That will make it much smaller and easier to learn, and it will remove any reference to or dependency on Bulma CSS. The necessary parts of Semantic DOM should also be made into a internal/unexposed modules for Modular UI, rather than a separate package, so that it is entirely self-contained with no dependencies except Elm VirtualDom.
The idea that I have in mind for task (b) is to create utilities that make it easier to develop components as needed, rather than creating the components themselves. I got this idea from Tailwind CSS, which is a PostCSS plugin that enables you to easily assemble custom CSS components by combining selectors with low-level utility classes. I'm not sure exactly how this translates, but it makes sense to me conceptually.