What would people think of using the term ‘state’ instead of ‘model’? I find that usually when I’m explaining the Elm Architecture to someone, I end up saying “the model represents the state of your application” and I don’t seem to be alone:
Elm in Action has an entire section titled “Representing Application State with a Model”
The elm-sortable-table package uses Table.State, not Table.Model
Even the official Elm guide describes it as “Model — the state of your application”
So why not just use the word ‘state’ everywhere? To me it seems more descriptive and plain-language, without too many obvious downsides. And as far as I can tell it could be done gradually, without breaking changes to the core language or libraries. elm/browser currently uses model as the name for the applicable type variable, but that could be changed in a patch release if desired - the word ‘model’ doesn’t appear in any record fields etc. where it would be a breaking change (they’re all init instead, which is fine).
Thoughts? Are there benefits of using ‘model’ that I’m missing, or reasons that making the switch would be harder than it looks? (This seems like the sort of thing that would have come up before, but if so I can’t remember it.)
Model is used in MVC, which is an architectural pattern taught at schools. Since Elm has both a Model and a View, the architecture can be immediately familiar to learners with that background.
Technically speaking, Elm has a Model, a View, and … an Update, not a Controller. So I’m not sure that it leverages that knowledge in a non-confusing way…
I prefer the term Model, but that may because I explain it differently. I don’t say that “the model represents the state of your application”; I say that “the model is your application”. View and Update are simply there to display and transform your model. By avoiding the word “state”, I think that we also avoid people asking things like “how do you partially update the state?” and “how can I extract half of this state and store it somewhere else?” and “what if I don’t want to share this bit of state with another part of the application?” and so on. Those questions aren’t poor questions, but (in my opinion) they don’t help you to get to grips with TEA. Change the questions to say “model” and they don’t make as much sense – and I think that’s intentional. A model is a whole, cohesive thing; it makes no sense to split it down the middle, because then you’re left with a broken model.
Of course, this is just my opinion and naming issues are contentious. No offense is intended; I simply present a counterpoint here.
As far as naming types goes: I found that the type modeling the application state usually ends up being named State.
For example, a type annotation from a more recent project:
update : Event -> State -> ( State, Cmd Event )
When introducing people new to Elm, I tend to use Model as the type name instead. The reason is to be more consistent with the elm guide from guide.elm-lang.org. Beginners refer to this guide more often, so I am inclined to reuse the Model name to make it easier for them to see the analogies.
To me ‘model’ vs. ‘state’ seems similar to ‘union type’ vs ‘custom type’:
‘Union type’ is more immediately familiar to one subset of potential Elm users, and arguably more precise
‘Custom type’ is more plain language and more descriptive to those who are new to programming in general, or don’t have a background in ML family languages
I don’t think that anyone who learned about MVC at school would have much difficulty figuring out “state == model” but I think using ‘state’ would make things easier for newcomers in general.
Interesting! Hadn’t thought of this aspect. My own counterpoint is that I think using ‘state’ leads naturally into “the application may actually be in one of several states”, e.g.
type State
= LoggingIn { ... }
| LoggedIn { ... }
| LoggedOut { ... }
instead of falling into the trap of thinking that “the model” should be a single record.
Also @cynic I’m not sure how you could have been any more polite or less offensive, the whole point was to invite debate and counterpoints =)
I currently like using Model with ModelState inside. Any “global” state-independent fields are directly in Model, and state-dependent fields are inside ModelState:
type alias Model =
{ state : ModelState
, ... global fields ...
}
type ModelState
= NothingAnalyzed
| JsonParsingError String
| Fetching Int Cache.FetchingCache
| FetchingSucceeded Cache ViewCache
| FetchingFailed (List (Html Msg))
I think “State” makes more sense, because states can change.
To me, “Model” suggests some sort of static description, as in “Domain model” or “The application model”, or perhaps a type definition. So it could make some sense to call the type definition of your application state your “Model”, but not the actual state itself.
Also, “state” is what many JS frameworks like React/Redux calls it, I haven’t heard anyone in the JS world call it “model”.
I currently like using Model with ModelState inside. Any “global” state-independent fields are directly in Model , and state-dependent fields are inside ModelState
I do something similar to this - my model includes:
Several “config” fields for things that don’t change during runtime (e.g. stuff passed into Elm from JS through flags on startup)
A few “global” fields like the current window size, the current time, the keys that are currently pressed, etc,
A field called state which holds a custom type called State that contains (what I consider to be) my app’s state.
So for me, the distinction between Model and State is useful because it differentiates between “all the random bits of data I need to keep track of” and “core application state/business logic”.
I guess both names are correct: state is of type Model
The value/variable model is your State at the moment, but Type Model describes a model of your application.
So naming the variable state and the type Model would be most correct.
type alias Model =
{ length : Int
, loginState : LoginState
, connectionState: ConnectionState
}
state : Model
state =
{ length = 5 }
, loginState = LoggedOut
, connectionState: Offline
}
Its not like you name all your variables “string” because they are of type String
So why name your model “model” just because the type is Model ?
I really like that paradigm of global data fields and an application state field. Going to be refactoring some things to take advantage of that.
To the larger topic, I did not find the term “model” confusing, and in fact it helped me understand what everyone talking about “state” meant. I do think of “model” as a more object-oriented sort of term though, which is interesting in the broader Elm context.
Especially when talking to JS people, I say that the Elm “Model” is just what JS/React people have been calling “state”. But I do think theres a conceptual difference between Model and State. I usually dont offer immediately to beginners in order to not confuse them.
A state is like a particular value, and a model is a category of values. Kind of analogous to variable and value. State is a value, model is a variable. You can transition from state to state, but you dont really transition from model to model. The model describes the possibility of all states.
We get the benefit of this distinction because our language is strongly typed. In JS all states are just JS objects which could have any fields of any value.
Exactly, which is why {model | foo = 42} and initialModel = { foo = 0 } is weird.
So it would make sense to still call the type “Model”, but instances of “Model” should be called “state”, because they change on every update.
Btw I also think it would make sense to just call the type “State” as well, just to keep the number of names down - because it’s the definition of what any state can be.
I agree with Ian that “State” seems (to me) more intuitive than “Model”.
“Model” is an opaque term that doesn’t help my internal monologue when I’m trying to understand the Elm Architecture. My internal explanation is always “the model represents all the possible states of an application” or even just “the model is the state”. The definition of Model always ends up back at State, and I think the mental gymnastics can be avoided by calling it the “state” from the start.
I disagree with others who suggest that using “Model” as the type name makes it clearer that we’re referring to “the set of all states”. If we follow that logic then we deduce that “List” and “Person” are bad type names as well because they truthfully refer to “the set of all lists” and “the set of all people”.
I’m new to Elm, and every time I read the word “model”, I have to translate it to “state” before continuing. Model is simply not descriptive of what it is or does. It’s just one of those mystery words someone has to learn when they take on a new language.
If you really like state more, just name it state. The only place where you would need to go from model to state would be in the entrypoint of your main
I’ve been struggling with this recently. I’ve started using a ViewModel in my project, and the naming isn’t intuitive or very accurate.
My ViewModel essentially works out the relational data for the route I’m on. It saves me from having to do a bunch of logic in my views, and keeps this cleaner overall.
However, the most accurate name for the ViewModel would just be Model, and the name of my Model to be the data.
Here is what it currently looks like:
model
|> toViewModel
|> toView
Here is what I initially though would make more sense:
data
|> toModel
|> toView
But after reading this thread, perhaps:
model
|> toState
|> toView
Just because I store the data in that shape, it doesn’t exactly mean that is how I want the data Modeled in my view, maybe that’s what a state is for? Idk 🤷
The Elm Architecture is not Model-View-Controller (in any of the many flavours and variants it exists in). Period. Referring in the nomenclature of TEA to MVC will only confuse people because they are very different ways to structure your application.
I definitely find State to be a better name for the data-structure now known as Model in the guides; I think it makes sense if this data structure lives in a module named Model to indicate that it is part of your application’s domain model, but that is something that is very dependent on the application it is actually used in.