Limitation/Flaw of TEA ... is there a fix?

In my first sentence I said

and by component I simply mean a smaller part of a larger app

That’s it. Later I said:

each component has it’s init, view, update functions, and an internal model

So, I would consider a Page a component. Or the elm-sortable-table a component. I also understand and agree with Evan saying:

The data displayed in the table is given as an argument to view . To put that another way, the Table.State value only tracks the details specific to displaying a sorted table, not the actual data to appear in the table.

Edit: catch me on slack, @z5h if you think it’s better to discuss there, and post our final ideas here.

By definition, every Elm application has a model, a view, and an update.

I consider it a serious architectural mistake to aim to subdivide that into smaller model/view/update pieces.

A majority of my Elm conference talks have been about either how and when to apply this technique, or about techniques that are a better fit for various scenarios. I really don’t want to spend more time talking about it.

Mainly I wanted to suggest a different approach for the thread (start with a concrete scenario) and ask that you not suggest I’m on board with the notion that “Elm programs are made up of components” - for any definition of the word “component.” Plenty of people will read it and assume the OO definition, so I’d prefer if you left me out of it and let your beliefs stand on their own.

1 Like

I consider it a serious architectural mistake to aim to subdivide that into smaller model/view/update pieces.

So when I look at

for example, and see an app subdivided into smaller model/view/update compo… uh things, written by you, I considered that an endorsement. I don’t think that’s unreasonable. If one followed your example, and had used Evan’s sortable tables in those pages, they would end up with what you call a " serious architectural mistake".

Can I be confused at this point?

@z5h, we are both here confirming that we think something different than you think personally.

Please take Richard’s advice about starting a new thread about a concrete issue. If you have a problem in your code, it seems plausible to illustrate that with code. People are happy to help, and having concrete examples to start from are a great way to illustrate an argument about how code looks given different organizational strategies.

2 Likes

These are not the same:

  • “It is a mistake to aim to subdivide that into smaller model/view/update pieces”
  • “It is a mistake to ever subdivide into smaller model/view/update pieces”

This is one of many techniques for organizing code. I consider it a serious mistake to apply it eagerly to a broad range of scenarios - that is, to aim to subdivide your program this way, as opposed to reaching for it only on the occasions where it’s the right fit.

SPA pages are one occasion where it is usually seems to be the right fit.

4 Likes

I would like to add that this took me quite a while to understand. For a long time, I was convinced that anything that steered me towards this subdivision was misguiding.

6 Likes

Right, so when it’s the right fit, then we should aim to subdivide into smaller model/view/update pieces!

And Richard agrees that with SPA’s this usually seems the right fit. And in his Elm Europe 2017 talk, Richard seems to indicate “reusable signup forms” might be the right fit. And Evan (seems to) agree that with sortable tables, it’s the right fit.

Yet, somehow when I define a “component” to be in-line with one of these “smaller part of a larger app”, with “init, view, update”, and following from the above, and further claim that we are led to believe (by Richard and Evan) that we can use their suggestions and code, I’m simply told:

and yet

Huh?

What a gaslighting way of shutting down someone earnestly trying to make sense of thing. I’m trembling out of frustration here.

@evancz If you (or people) are happy to help, can you clearly state what I think, what you think, and how they differ? That would help me. That’s the help I need.

1 Like

I’ll try to put together an example and blog post about my fundamental concern.

5 Likes

I believe is comment 29 in this thread, so it seems like people are trying to help. For some posters, like myself, it is hard to engage in online discussions for a variety of reasons, and it can have negative personal consequences for those people outside of any specific online discussion.

Framing questions like this to be as specific as possible can help folks in that sort of situation understand your problem, participate, suggest answers, etc. Maybe they can, maybe they cannot though! There are many demands on their attention. Furthermore, I have noticed that a more specific framing also helps more active participants help you get a satisfying answer as well.

Point is, thank you for working on an example! Without promising any future behavior in online forums, I think that will be helpful.

5 Likes

Like the others, I’m not sure I fully understand what your issue is, but the above makes me think that it is in two parts.

The first part is indicated by:

it’ll need a RowEditor.Model which we don’t have yet.

This is a problem. Your top-level model should contain everything required to fully represent the state of the application, including whether or not a row editor is applicable to the current state, and if it is, whatever data is required to display and interact with that row editor. Your view code should be able to take this information and decide whether or not to display the row editor, and if it does, populate it appropriately. In other words, you should always have a row editor model, even if the value of that model is Nothing. If you find yourself in a situation where the view needs to display a row editor, and the data for that row editor is not already available, you have an error in your state transition logic.

The second part is that you seem to be folding the backend database into your model. This isn’t going to work (very well), because it takes away the ability to model the database for what it is, some external state that you don’t have complete control over. Instead, you’re better off dealing with the backend in a transactional fashion, analogous to how the Http module works in Elm, fetching query results by sending the query off as a command, and retrieving and storing the results upon receipt of the corresponding message. When you do it that way, your model is always in a self-consistent state, and the above problem of needing the view before the data is available should never occur.

There is possibly a third part to your issue, related to the problem of caching/memoizing expensive computations. This is not TEA-related, and is instead a “feature” of the pure functional approach.
The solution involves including some variation of the State monad in your model (Haskell includes some packages for this; I haven’t seen anything comparable for Elm). I’d need to see more details regarding what you’re trying to do before I can comment further.

2 Likes

This is the problem! When I said:

if we write/modify an update and just hope that it will be called every time our parent’s model changes in some way, it could be very easy for the parent to accidentally not call our update

I meant:
Reasonable adherence to TEA as preached can lead to situations where we can’t easily defend against state transition log errors.

This thread has spun a bit out of control, and I believe I need to come up with a much better example along with code. I’m a bit wary at this time of making incremental clarifications to a line of logic that appears woefully insufficient in illustrating my point.
Thanks for the efforts of taking a look at this.

The database was a very unfortunate example. It was more of a “let’s pretend we have stuff in memory” where “stuff” could have been anything but I just said “DB”.

I think the problem in @z5h’s example isn’t actually due to “model/view/update components” at all. I think you would face the same issue in a super-flat structure as @madasebrof proposes.

The core issue from what I understood it is when you have necessarily stateful UI elements that are tied to a List or Dict of data, and how you can initialize and destroy their states in a clean way.

@z5h perhaps in your future post you should go for a “componentless” example, to avoid accidentally muddying the waters.

1 Like

Right. The problem is largely exacerbated with model/view/update “things”.

I could be wrong, but this sounds like part of the subject of https://www.youtube.com/watch?v=28OdemxhfbU - namely the “when do I put duplicate data somewhere in my model?” question.

Maybe it’s helpful?

2 Likes

Hmmm. I find that difficult to visualize. Yes, it’s easy to have errors in your state transition logic, but I can’t see how that’s tied to TEA. I will have to take your word for it for the time being. :wink:

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.