I have been doing some thinking about how to scale the view as applications get larger and more complicated, and I think that using a Type to define the view has a lot of benefits. I’ve gone in to some more details in the article below.
You talk about the idea of ‘Reusable Views’ which is something that chimes with me. I also like the idea of using types to guide the implementation of a program at a larger scale. We use types all the time for small stuff, like making sure we put the right kind of thing into a list, but it can be very powerful to use types in a more zoomed out fashion to give shape to a whole application.
The principal way in which functional programming allows for code re-use is through higher-order functions. In your article you have explored a different approach, which is to use a custom type to describe a set of permitted options (TextBanner, ViewerBanner, ArticleBanner, …) and to restrict construction of the view using that type so that the various pieces of the view can only be plugged together in the right way.
I have previously explored the other option, which is to make use of higher-order functions; to allow customizable behaviour to be plugged into some defined piece of view logic in order to make it work in different settings. This is a more open-ended way of re-using code.
Perhaps you will find this interesting, when considering the use of ‘large types’ in overall program structure.
That last one uses higher order functions to describe templates and layouts with links and an editor - its for a content editor. In client mode, the editor is active and allows content to be edited in the browser. In server mode, a dummy editor is supplied that just renders the content. That one is still on Elm 0.18.
That editor looks interesting, and a lot of my stuff is still in 0.18 to be honest.
I’m having trouble understanding what’s going on, but it looks like the view code defines the html, and then the layout code transforms it, adding styling and wrapping the html (within a header / footer and other layout things), is that right?
Yes, that is why layout is a function Template -> Template. A template builds some HTML for a page body, and a layout wraps that in header footer etc. The result of applying a layout is just another template, but one that builds a page body with all the other stuff.
I see what you mean, it’s a bit like express middleware.
I’ve had a think, and I believe that the following is the main difference between our approaches (they’re kind of opposites of each other it seems).
In mine, child views must know about the master view type, but the master view render function doesn’t need to know anything about the child views.
In yours, the child views don’t need to know about the Layout transformation, but the Layout transformation must know about the child views (for example to detect the presence of an editor, and render either the real editor or a dummy editor)
Kind of. The template only needs to know about the editor through its type:
type alias Editor msg =
Zipper Content -> Html msg
So long as an editor is supplied with this type, the template can use it, but without knowing in advance which one it will get and how it will be implemented. It is basically an interface describing what an editor does - takes a tree of content and renders it to html.
So I think in both our cases the ‘master’ or top-level view does not need to know about the child view, its just that you enumerated the child views as a custom type, and I described them as function types.
I don’t think your approach or my approach is better; they are different ways of using types to describe pieces of software that can be flexibly combined together. That is what interests me about this topic, seeing different ways that types can be used to describe how an application is structured and learning about the merits of different approaches.
I am sure there are plenty other ways that types can be used at the application design level and to hear what other ideas may exist for this purpose.
Hi Rupert, I’m not trying to work out who’s is best, so apologies if its coming across that way. Like you say, its an interesting topic, and I think relatively unexplored. I have a good feel for how master view types work, having used them once in a real app and another two times when writing / thinking about the blog post. I haven’t used guide types, so I don’t have the same level of understanding. I’m not as sure what the pros and cons are, and what situations it is best suited to and things like that. Maybe I need to take the plunge and give them a try
Not at all - was really just trying to say that I don’t think my approach is better either and to encourage others to put forward ideas and be experimental in this space.
I really like this approach! One other cool advantage I can think of is that the render-to-HTML step can look at the entire structure of the view to determine how best to render it. The rendering engine might choose to merge borders between adjacent elements depending on exactly what they are, or might choose to render a List Option as either a set of radio buttons or as an auto-completing dropdown depending on how many options there are in the list.
Now that is an interesting idea Ian! I can see that being combined with an Elm only view library like elm-ui to create a lot of interesting possibilities for restricting and also managing View
Hi Will. The concept is agnostic to the view library. The example code from the blog post uses the standard elm Html functions with bootstrap, but I’ve also used it with style-elements (the predecessor to elm-ui - I need to get round to upgrading)
You can look at the rendering code for this if you are interested. It is probably a bit less clear at demonstrating the point, as its part of a real application, but probably better than nothing.
Oh for sure! Sorry, wasn’t trying to say you idea needed a specific view library. I was just thinking it could be leveraged with a elm view library to be able to use Types to explore some of the thing Ian mentioned with types to help along the way.
Okay cool sounds like we are on the same one about me not trying to say that you not trying to say that I was trying to say that it needs a specific view library.