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

**URL:** <https://discourse.elm-lang.org/t/limitation-flaw-of-tea-is-there-a-fix/2999>\
**Category:** Request Feedback\
**Created:** [January 24, 2019, 3:56am UTC](https://discourse.elm-lang.org/t/limitation-flaw-of-tea-is-there-a-fix/2999 "2019-01-24T03:56:51Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![z5h](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/z5h/32/390_2.png) [@z5h](https://discourse.elm-lang.org/u/z5h)\
**Post date:** [January 24, 2019, 3:56am UTC](https://discourse.elm-lang.org/t/limitation-flaw-of-tea-is-there-a-fix/2999/1 "2019-01-24T03:56:51Z")

</div>

I’ll assume readers are familiar with TEA. We were shown by Evan, in elm-sortable-table, how TEA can be used to create a “component” (and by component I simply mean a smaller part of a larger app).  
Richard Feldman’s canonical SPA example uses this same TEA style within Pages.

We are led to expect that we can compose an app of Pages and components, which themselves may contain sub-pages or components, etc.

If each component has it’s init, view, update functions, and an internal model with standard type signatures, then everything should be fine if we follow Evan’s advice [here](https://github.com/evancz/elm-sortable-table/#single-source-of-truth).

I’ll quote the advice here as it’s very important, and the emphasis is Evan’s.

> 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. **This is the most important decision in this whole library.** This choice means you can change your data without any risk of the table getting out of sync. You may be adding things, changing entries, or whatever else; the table will never “get stuck” and display out of date information.

But what if “the details specific to _displaying_” are a function of “the actual data to appear”? In other words, our `model` is a function of what occurs in `view`.

Might this be a problem? Can it be avoided?

We might have:

```elm
type alias Model = {
   manySubWidgetStates : List SubWidget.Model
}

view : {Parent.Model : parentModel} -> Model -> Html Msg
view {parentModel} model = 
  parentModel |> expensiveGenerateSubWidgetData |> List.map viewWidget |> ...

```

Here `view` calls an expensive function to determine which sub-widgets will be rendered. But their cmds will be processed by `update` which we expect will be ready with `manySubWidgetStates`. How?  
This will only work if `update` runs `expensiveMapToSubWidgetData` and stores the result.

So, we need to guarantee that `update` has “fresh” data and that it perform’s the majority of `view`’s work. Is this a problem? Yes.

First, `view` is special in that we call it exactly when we need it, with up-to-date data in our hands. We can’t help but call it with the appropriate data at the appropriate time.  
`update` is a little different … if the parent gets a `Cmd` wrapped up for our component, it’ll certainly have to send it to our component’s update, or very conspicuously throw it away. But, 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`. And since our `update` is doing work on data that is later supplied to `view`, we break the **most important decision** in our app and risk data being out of sync.

Have I missed something? Is this avoidable?

---

<div class="post-metadata">

**Author:** ![pdamoc](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/pdamoc/32/36_2.png) [@pdamoc](https://discourse.elm-lang.org/u/pdamoc)\
**Post date:** [January 24, 2019, 10:04am UTC](https://discourse.elm-lang.org/t/limitation-flaw-of-tea-is-there-a-fix/2999/2 "2019-01-24T10:04:37Z")

</div>

> [@z5h](#):
>
> In other words, our `model` is a function of what occurs in `view` .

Can you clarify this? How could the `model` be a function of the `view`?

---

<div class="post-metadata">

**Author:** ![gigobyte](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/gigobyte/32/1583_2.png) [@gigobyte](https://discourse.elm-lang.org/u/gigobyte)\
**Post date:** [January 24, 2019, 1:00pm UTC](https://discourse.elm-lang.org/t/limitation-flaw-of-tea-is-there-a-fix/2999/3 "2019-01-24T13:00:32Z")

</div>

If I understood correctly, your concern is that if the parent update (the global update function) doesn’t call the widget update (the update function exported from the widget module) or if it calls it incorrectly then the view could break / not change.

If that’s the case, that is indeed a limitation of the architecture. The solution is to make your widget as easy to integrate as possible, preferably only have the caller add a single `case WidgetMsg msg -> Widget.update msg model` line to their code to make it work. If the widget depends on the parent model then the API should be again as minimal and well documented as possible, types help a lot in this case.

---

<div class="post-metadata">

**Author:** ![Herteby](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/herteby/32/1329_2.png) [@Herteby](https://discourse.elm-lang.org/u/Herteby)\
**Post date:** [January 24, 2019, 7:02pm UTC](https://discourse.elm-lang.org/t/limitation-flaw-of-tea-is-there-a-fix/2999/4 "2019-01-24T19:02:31Z")

</div>

> [@z5h](#):
>
> But what if “the details specific to _displaying_ ” are a function of “the actual data to appear”?

Hmm, the “config arguments” don’t have to come directly from the model or be static, they can be computed as a function of the model too, and `Html.lazy` can be used to avoid too many recomputations.

For example, I have a basic sortable table component, and for one of my pages I’ve wrapped it in a function that adds search with highlighting and toggleable columns. Which columns to show is stored directly on the “page model” rather than the “table model”. It’s all “clean” with no caching of derived values in the model. I did start to see a little bit of a slowdown, but `lazy` fixed that.

---

<div class="post-metadata">

**Author:** ![z5h](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/z5h/32/390_2.png) [@z5h](https://discourse.elm-lang.org/u/z5h)\
**Post date:** [January 24, 2019, 7:38pm UTC](https://discourse.elm-lang.org/t/limitation-flaw-of-tea-is-there-a-fix/2999/5 "2019-01-24T19:38:11Z")

</div>

So, in Evan’s component document, [he argues](https://github.com/evancz/elm-sortable-table/#single-source-of-truth) that there should be a single source of truth.

If, in my `view`, I decide based on data passed in that I’d like to render X, and I need to initialize a model for X (to send X’s messages to), then it’s too late! Although I can initialize X.Model in a `view`, I can’t `update` my model with my X.Model.  
So, I must pre-initialize X.Model in my `update`, so that it’s ready for my `view`.  
If I’m initializing something in `update`, that I could also initialize in `view` then I don’t have a single source of truth. Evan says “Elm is built on the idea that there should be a single source of truth”. But it seems impossible! Therefore, as I suggested, there is a problem with TEA.

---

<div class="post-metadata">

**Author:** ![Herteby](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/herteby/32/1329_2.png) [@Herteby](https://discourse.elm-lang.org/u/Herteby)\
**Post date:** [January 24, 2019, 7:56pm UTC](https://discourse.elm-lang.org/t/limitation-flaw-of-tea-is-there-a-fix/2999/6 "2019-01-24T19:56:10Z")

</div>

Hmm, rather than talking about view and update specifically, could you give a concrete “real world-ish” example of a feature that you think is impossible to implement cleanly?

---

<div class="post-metadata">

**Author:** ![z5h](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/z5h/32/390_2.png) [@z5h](https://discourse.elm-lang.org/u/z5h)\
**Post date:** [January 24, 2019, 8:41pm UTC](https://discourse.elm-lang.org/t/limitation-flaw-of-tea-is-there-a-fix/2999/7 "2019-01-24T20:41:58Z")

</div>

Suppose my main model is a relational database and a query string. The database gets updated over the wire, as well as from the user.

Now suppose we have `ResultsPage.view : String -> DB -> Html ResultsPage.Msg`. So the results page applies the query to the DB to get result.

Suppose further, that we have a `RowEditor` that lets us edit the column values, but also lets us rollback etc before we commit. Perhaps it has some toggles do display data as various formats. It’s complex enough to warrant “componentizing” into a `RowEditor Model/init/update/view`.

We can’t simply go ahead and start using these RowEditors in our view, because when we call `ResultsPage.view`, and it wants to call `RowEditor.view`, it’ll need a `RowEditor.Model` which we don’t have yet.

Ok, we’ll need to fix `ResultsPage.update` to run the query on the DB, and generate appropriate `RowEditor.Model` values so that they are ready when `RowEditor.view` is later called from `ResultsPage.update`.

So, in `ResultsPage.update` we are deriving data (query results) and storing data (RowEditor.Models) which we can also later derive (but not store) in `ResultsPage.view`.

If you are deriving and storing data which you can later derive, then you have broken the “Single Source of Truth” principle. Don’t store data that you can derive.

Evan said: “Elm is built on the idea that there should be a single source of truth.”

Ok, so what are my options for a fix?

---

<div class="post-metadata">

**Author:** ![Herteby](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/herteby/32/1329_2.png) [@Herteby](https://discourse.elm-lang.org/u/Herteby)\
**Post date:** [January 24, 2019, 9:04pm UTC](https://discourse.elm-lang.org/t/limitation-flaw-of-tea-is-there-a-fix/2999/8 "2019-01-24T21:04:47Z")

</div>

Ah I see! How about this? 🙂

```auto
results |> List.map (\row -> RowEditor.view (model.editors |> Dict.get row.id |> Maybe.withDefault RowEditor.init

```

If the state of the `RowEditor` would be the same as `RowEditor.init`, then we don’t actually need to store it in the model. Only once the user interacts with the editors do we actually need to store their state!

---

<div class="post-metadata">

**Author:** ![z5h](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/z5h/32/390_2.png) [@z5h](https://discourse.elm-lang.org/u/z5h)\
**Post date:** [January 24, 2019, 9:18pm UTC](https://discourse.elm-lang.org/t/limitation-flaw-of-tea-is-there-a-fix/2999/9 "2019-01-24T21:18:58Z")

</div>

I have considered this, and I’m already using it. And it’s the best solution i know so far.

There are 2 issues:

1. If a subcomponent’s init takes a parameter based on the model, it’s problematic.
2. We have a memory leak. We create models dynamically but don’t t dispose of them.

Another possibility is that the subcomponent’s update requires the necessary parent model data. So we cant be sure a subcomponent’s update has been called with the most recent data, but we know when update is called the sata eill be up to date.

In any case. Theee is no solution without caveats.

---

<div class="post-metadata">

**Author:** ![Herteby](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/herteby/32/1329_2.png) [@Herteby](https://discourse.elm-lang.org/u/Herteby)\
**Post date:** [January 24, 2019, 9:35pm UTC](https://discourse.elm-lang.org/t/limitation-flaw-of-tea-is-there-a-fix/2999/10 "2019-01-24T21:35:28Z")

</div>

1. How is it problematic?
2. It’s up to you to decide when you want to dispose of them. I don’t think that’s a bad thing, having state destroyed/reset because of the view isn’t necessarily good (which happens with state stored in React components for example, although Vue has a special keep-alive directive to prevent this).

Another neat thing you can do is extend the update function with a “watch” step, so that after it has handled a message, it takes a look at the model and updates it / issues commands based on some parameters.

---

<div class="post-metadata">

**Author:** ![z5h](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/z5h/32/390_2.png) [@z5h](https://discourse.elm-lang.org/u/z5h)\
**Post date:** [January 25, 2019, 2:34pm UTC](https://discourse.elm-lang.org/t/limitation-flaw-of-tea-is-there-a-fix/2999/11 "2019-01-25T14:34:24Z")

</div>

1. is a problem because we’ve decided to lazy init something requiring model data on the NEXT update cycle when the data might be different. So the model will not be initialized to the render-time data. May or may not be a problem depending on app logic.
2. We’re lazily creating models based on messages. But cleaning it up based on model data. I don’t love this idea, but I suppose it’s doable.

So it seems the _best_ (only?) strategy for an Elm app with components/Pages is:

1. lazily generate Page/component models based on messages that expect to be sent to said model
2. don’t write a model/page initializer that accepts an input to be derived from a parent model
3. be sure to clean up sub-models on all updates

---

<div class="post-metadata">

**Author:** ![Chadtech](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/chadtech/32/609_2.png) [@Chadtech](https://discourse.elm-lang.org/u/Chadtech)\
**Post date:** [January 25, 2019, 9:42pm UTC](https://discourse.elm-lang.org/t/limitation-flaw-of-tea-is-there-a-fix/2999/12 "2019-01-25T21:42:29Z")

</div>

Ive read through this thread, but I dont see a problem.

For a big application with a relational data base, that depicts a bunch of rows and columns, and can toggle some rows to be editable; I can think of two ways of going about it:

1. You treat the database as the single source of truth, and when `RowEdit.Msg` come in, they edit that one `Row` directly. Like this:

```elm
type alias Model =
    { database : Dict String Row }

type Msg
    = RowEditMsg String RowEdit.Msg

update : Msg -> Model -> Model
update msg model =
    case msg of
        RowEditMsg key subMsg ->
            case Dict.get key model.database of
                Just row ->
                    { model
                        | database =
                            Dict.insert 
                                key 
                                (RowEdit.update subMsg row) 
                                model.database
                     }

-- RowEdit.elm

type Msg
     = NameFieldChanged String

update : Msg -> Row -> Row
update msg row =
    case msg of
        --..

```

1. Maybe if the data is a representation of data stored remotely on a server somewhere else, the process of editing is kind of arduous and involves verification from the remote server. You could spin off `RowEdit` into its own `Model`, that will be initialized from a specific row, but co exist with the data it was created from, until it gets the OK from the remote server that the edit really occured.

```elm
-- Main.elm
type alias Model =
    { database : Dict String Row
    , editor : Maybe RowEdit.Model
    }

-- RowEdit.elm

type alias Model =
      { nameField : String
      -- ..
      }

init : String -> Row -> Model
init key row =
    { key = key 
    , nameField = row.name
    -- ..
    }

```

One might claim that this is a violation of “single source of truth”. I dont think it is tho. The row itself has a single source of truth (the frontends “database”), and the row edit has a single source of truth (the `RowEdit.Model`). Two distinct things in the program, with two distinct sources of truth. I know they bear the obvious relationship that one is an edit of the other, but by that very same relationship they are distinguished from each other. A row in a database and a UI for editing a row are simply different beasts.

I dont want to put words in your mouth tho. If my examples dont address the problem you are trying to show maybe you can point out how.

---

<div class="post-metadata">

**Author:** ![madasebrof](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/madasebrof/32/363_2.png) [@madasebrof](https://discourse.elm-lang.org/u/madasebrof)\
**Post date:** [January 27, 2019, 4:11pm UTC](https://discourse.elm-lang.org/t/limitation-flaw-of-tea-is-there-a-fix/2999/13 "2019-01-27T16:11:05Z")

</div>

Yeah, I think this a bit of a fundamental difference between “backend” thinking and “frontend” thinking.

The `model` in memory is the source of truth. Not the database.

Once you try to stick a layer between the model and the data and say that something external is the source of truth, it breaks the whole conceptual idea of TEA.

For example, you can’t say that an external database is the source of truth. You can only say that data returned from a DB then loaded into a model is the source of truth, because obviously other folks could be updated the DB, the query could die, the network could timeout, etc.

Until the data is actually sent over the wire, parsed, and the `model` is successfully updated, it can’t be the source of truth.

The same applies to user input. Until a user does something to indicate that they want the model updated (e.g. onClick, etc.) and the `model` is actually updated, you can’t treat that data as a source of truth.

It is up to the `update` function to reconcile how to deal with those two things, e.g. potential DB updates & potential user updates to the same data set.

The actual model-update event loop has to be single threaded, so you only have a single value change to the model per update cycle (which is why the time-travel debugger works–only one thing changes per update cycle!). PS this is why the whole concept of “components” often falls apart–you can’t have “component” data with TEA. Ultimately, all data needs to be in the `model` somehow.

One way or another, you have to have a single source of truth for all of the data a user sees & interacts with in an Elm app, and that has to be local to the Elm app & in memory, e.g. the `model`.

That is totally different from a backend, where many processes are competing to update data, etc. and it’s up to the DB to reconcile & manage those simultaneous requests.

Make sense???

I don’t see any “limitation or flaw” in TEA. I see this is a huge benefit, as by definition nothing can ever get out of sync–there can’t be two things competing to update the same thing at the same time in TEA.

To get back to your original point:

> [@z5h](#):
>
> In other words, our `model` is a function of what occurs in `view` .

That is impossible. You would never want this, as it’s recursive. You can’t have:

```elm
functionA a =
    functionB a

functionB b =
    functionA b 

```

What you CAN have is:

> Our `view` updates our `model`, which in turn changes the `view` to reflect the newly updated `model`.

`view` does only two things:

1. Reactively renders a `model`
2. Potentially passes commands to the Elm event loop to update the `model` (which could potentially cause the `view` to be re-rendered).

The flow is: `init model` → `view model` → `update model` → `view model` → `update model` etc.

You can’t have a `model` that is a function of view directly (nor would you want to!), `view` can only render a `model`, then potentially send commands to `update` a `model`, which will in turn cause the `view` to be re-rendered (as the `view` is reactive).

Rock on,

---

<div class="post-metadata">

**Author:** ![z5h](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/z5h/32/390_2.png) [@z5h](https://discourse.elm-lang.org/u/z5h)\
**Post date:** [January 29, 2019, 4:29pm UTC](https://discourse.elm-lang.org/t/limitation-flaw-of-tea-is-there-a-fix/2999/14 "2019-01-29T16:29:12Z")

</div>

@madasebrof you’ve grossly misunderstood my understanding and experience with Elm and thus you haven’t engaged fully to understand the problem, believing instead I need an Elm lesson.

When I said

> our `model` is a function of what occurs in `view`.

I meant figuratively. Our view determines what we see, but if what we see will trigger events, our model will need to be prepared to handle them. In that sense, interests of the view dictate interests of the model and if changing our view code therefore requires changing our model code then our model CODE is a function of our view CODE, or in my misunderstood shorthand, our model is a function of our view. This was further eluded to.

As a fun tangential aside, you can actually can get very close to LITERALLY having the model a function of the view.

It’s possible to create a custom element that does `connectedCallback() {this.dispatchEvent(new CustomEvent('attempted'));` and render it with an `Html.Events.on "attempted" (Decode.succeed msg)` such that the `view : Model -> Html Msg` code can trigger an immediate model update by simply rendering.

I actually do this and it’s fine. It’s to have a better behaved implementation of [Html.Attributes - html 1.0.0](https://package.elm-lang.org/packages/elm/html/latest/Html-Attributes#autofocus).

And, as you probably know, recursion (mutual or otherwise) is fine so long as it terminates. 😉

In any case, please re-read everything I’ve written before, as it was enough for [Herteby](https://discourse.elm-lang.org/u/Herteby) to see what I was getting at. Ask me clarifications if you don’t understand something. I don’t need any Elm lessons.

---

<div class="post-metadata">

**Author:** ![madasebrof](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/madasebrof/32/363_2.png) [@madasebrof](https://discourse.elm-lang.org/u/madasebrof)\
**Post date:** [January 29, 2019, 8:41pm UTC](https://discourse.elm-lang.org/t/limitation-flaw-of-tea-is-there-a-fix/2999/15 "2019-01-29T20:41:44Z")

</div>

Yeah, sorry. I re-read your post like 5 times before I replied. The I reason I replied the way I did is that the title is of your post provocative as it presupposes a fundamental problem with TEA.

I am just saying, in fairly plain terms, that there is no problem with TEA so that future readers don’t get confused, and that, unless I am missing something, that there is no problem to fix.

If there is an actual issue you are having with Elm, I apologize for not getting it!

I wrote what I did in all sincerity (not to be patronizing), as I have seen many such posts by folks who come from other architectures like Vue, React, etc. and want to try to make “components” in Elm. It took me a while to get this myself!

Back to what you wrote:

> [@z5h](#):
>
> Suppose further, that we have a `RowEditor` that lets us edit the column values, but also lets us rollback etc before we commit. Perhaps it has some toggles do display data as various formats. It’s complex enough to warrant “componentizing” into a `RowEditor Model/init/update/view` .

To me, there is nothing that complex that could warrant doing what you describe.

I’ve posted this before, but here’s my highly opinionated way of writing big Elm apps so you can see where my head is at:

> **[GitHub - madasebrof/elm-taco-donut: A model for scaling Elm apps. (re-write...](https://github.com/madasebrof/elm-taco-donut)**
>
> A model for scaling Elm apps. (re-write of elm-taco) - GitHub - madasebrof/elm-taco-donut: A model for scaling Elm apps. (re-write of elm-taco)

This is how we write production code. Hope this helps! If not, again, apologies for not getting it. I’ll let you continue the discussion w/o me!

Best,

---

<div class="post-metadata">

**Author:** ![z5h](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/z5h/32/390_2.png) [@z5h](https://discourse.elm-lang.org/u/z5h)\
**Post date:** [January 29, 2019, 9:25pm UTC](https://discourse.elm-lang.org/t/limitation-flaw-of-tea-is-there-a-fix/2999/16 "2019-01-29T21:25:43Z")

</div>

After reading elm-taco-donit it seems that you and I have different interpretations and ideas of how Elm apps should be built.

> I believe this ‘nested component’ paradigm of organization fights TEA (The Elm Architecture) and makes for code that is difficult to maintain, write and comprehend.

This ‘nested component’ paradigm follows directly from Evan’s Table code and Richard’s SPA example.  
Pages are components nested in Main, and Tables (for example) are components nested into pages.

Also, apart form the single issue I (attempt to) bring up here, my code is not difficult to maintain, write or understand. Quit the opposite. So, I have reason to believe nested components are a net good.

BUT, let’s suppose your way of building apps is best (and I’m fully admitting that it could be!), then it seems to follow we aren’t allowed to have reusable component packages. That in itself seems like a limitation/flaw with TEA.

In any case, we either run into the issue I’m trying to present, or we run into the issue that we can’t have reusable component packages.

Therefore, I remain convinced that there is a limitation or flaw with TEA.

---

<div class="post-metadata">

**Author:** ![madasebrof](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/madasebrof/32/363_2.png) [@madasebrof](https://discourse.elm-lang.org/u/madasebrof)\
**Post date:** [January 29, 2019, 10:28pm UTC](https://discourse.elm-lang.org/t/limitation-flaw-of-tea-is-there-a-fix/2999/17 "2019-01-29T22:28:19Z")

</div>

All good, but just to be clear (as we use Evan’s table thing) it is a view component just like anything else. The data is stored in the model, not within the component itself. To render it, you pass it the model. It doesn’t ‘self render’ its own internal data.

My who rant is basically just about taking Evan’s table model and applying it to big apps, e.g. single source of truth for all data in a single model, with lots of view component that can render parts of that model in many ways.

Who knows what’s best. It works for us!

Ps I did look at Richard’s Elm-spa example. God bless Richard, but I would for sure re-factor and flatten! It’s not even that much code! LOL

To each his own!

☮

![](https://canada1.discourse-cdn.com/flex035/uploads/elm_lang/original/2X/4/4c10910a6eda2331fd871d8469881bfadd209703.jpeg)

---

<div class="post-metadata">

**Author:** ![tgelu](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/tgelu/32/1008_2.png) [@tgelu](https://discourse.elm-lang.org/u/tgelu)\
**Post date:** [January 30, 2019, 1:27pm UTC](https://discourse.elm-lang.org/t/limitation-flaw-of-tea-is-there-a-fix/2999/18 "2019-01-30T13:27:39Z")

</div>

I’ve been following this thread closely.  
Can I ask a clarification question? What do you mean by the word “component”?

Background:  
In a talk from Evan he referred to components as basically the equivalent of objects in OOP. They hold both logic and data. That can obviously be true for any React component, but that is impossible to express in Elm, and the Table and the Pages in Richard’s SPA are definitely nothing more than view functions or at most a collection of functions. They are not, in this sense components.

In my view, you are right that it follows then that we are not “allowed” to have reusable component packages, simply because that cannot be expressed. We have a whole lot of functions to share, some of which are functions that happen to return Html. But that is not a flaw of anything, just like a function from mathematics cannot hold data, it can only map data, so do elm constructs. Isn’t this the root of functional programming?

---

<div class="post-metadata">

**Author:** ![rtfeldman](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/rtfeldman/32/50_2.png) [@rtfeldman](https://discourse.elm-lang.org/u/rtfeldman)\
**Post date:** [January 30, 2019, 2:58pm UTC](https://discourse.elm-lang.org/t/limitation-flaw-of-tea-is-there-a-fix/2999/19 "2019-01-30T14:58:28Z")

</div>

I read the OP and several other clarifications in the thread, several times, and I still don’t understand what the alleged problem is, let alone how I might go about proposing a solution.

At this point it seems best to start a new thread explaining the **real-world** design problem from which this concern originated. (I’m assuming there was one.) I’d begin with the sentence “I have been building an application that does \_\_\_\_\_ and I have encountered the following problem:” and go from there.

> [@z5h](#):
>
> This ‘nested component’ paradigm follows directly from Evan’s Table code and Richard’s SPA example.

Both Evan and I have spent a lot of time [explicitly saying](https://guide.elm-lang.org/webapps/structure.html#Components) “thinking in terms of components in Elm is a mistake.” I understand that you disagree with us, based on:

> [@z5h](#):
>
> I have reason to believe nested components are a net good.

Please don’t tell people that this belief “follows directly” what Evan or I have been saying on the subject.

We’ve been super clear that we disagree strongly with this.

---

<div class="post-metadata">

**Author:** ![z5h](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/z5h/32/390_2.png) [@z5h](https://discourse.elm-lang.org/u/z5h)\
**Post date:** [January 30, 2019, 4:01pm UTC](https://discourse.elm-lang.org/t/limitation-flaw-of-tea-is-there-a-fix/2999/20 "2019-01-30T16:01:35Z")

</div>

@rtfeldman

When you say “thinking in terms of components in Elm is a mistake”, you do first say

> components = local state + methods  
> local state + methods = objects

So that’s _your_ definition of component (and I’m franky not sure how you get to decide that). My definition of component, (and it’s the original one found in every dictionary) is: “a constituent part”. A logical unit. Certainly one can define component however you like and draw consequences from one’s definition.

By my definition (and the dictionary’s, AND probably many engineers) a module with ( `Model` , `init` , `update` , `view`) IS a component, and with that definition, it’s something you’ve both argued for.

So my belief does follow directly from what you and Evan have been saying (except you’ve chosen a problematic definition for component).

I expected this to be clear when I said, in my first sentence

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

and later

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

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

[Next page](https://discourse.elm-lang.org/t/limitation-flaw-of-tea-is-there-a-fix/2999.md?page=2)
