5 ms·
The DOM syntax makes perfect sense, but you have to realise it's not a 'transformation' in the sense of taking a stream of text and converting it into a stream
by Fr0styMatt88 10y ago
The DOM syntax makes perfect sense, but you have to realise it's not a 'transformation' in the sense of taking a stream of text and converting it into a stream of HTML for the browser. It's just Elm code that returns DOM nodes.
The HTML functions in Elm tend to take two parameters: a list of attribute values and a list of child DOM nodes. Again, this is all code. The list values you specify are again just functions that get evaluated.
It's a little less obvious because of the syntax style of Elm, but it does let you write the function calls out in such a way that they express that tree structure.
It bears repeating: your Elm div example, at the top level, is a single function call with the first parameter '[]' being an empty list (because you aren't assigning the node any attributes like a DOM id or CSS class) and the second parameter being a list that'll be made up of the DOM nodes that result from each of the function calls within it.
This was one of the biggest mental roadblocks I had to get past when learning Elm. Just forget the idea of HTML and think instead of DOM tree-of-nodes and a lot falls into place. The 'view' function you write will return a DOM tree data structure which is then taken and applied to the browser document. You pass in your model as a parameter to that function and then other functions you call within this DOM-generating code you've written will use that data to return different DOM contents depending on it.
- allover 10y agoYes I do understand all that, as I'm a React dev, in which render() methods and 'pure function components' work in exactly the same way (take props and state as input and return dom-creation-calls). That is why I used JSX as a counterexample. Basically I'm questioning Elm's choice to stick with the raw dom-creation-function-style vs adopting a JSX equivalent.
- dustinfarris 10y agoWhy introduce additional syntax when the native language works fine? Elm is a functional language, and you build the desired DOM structure with functions. Why should it be any other way? JSx looks sort of like HTML, but HTML isn't even the target here, just DOM nodes.
- allover 10y agoI'm suggesting it doesn't 'work fine', because syntax matters. Lisp-style 'S-expression' syntax for describing documents never took off. We have to take something from that - it seems the vast majority of developers don't enjoy that syntax, irrelevant of how 'simple' its just-functions nature makes it. JSX also 'targets DOM nodes', but I don't see what that has to do with anything. The closer correspondence between how JSX looks, what you see in your browser DevTools, and how it seems that most developers prefer to mentally model documents ... is where the win comes from IMO. The reality is the vast majority of React code I see uses JSX, even though it's optional. It's been hugely successful in React world and I don't think that should be ignored by Elm.
- michaelscott 10y agoIt's an interesting balancing act. I think when most devs look at JSX for the first time they instantly recoil at the rebellion against years and years of "separation of concerns", yet as you say it's a syntax that devs have embraced regardless. I love Elm and think it or something very close to it should become way more mainstream, but I do find its bracket-heavy DOM syntax off-putting in comparison. EDIT: That said, I do agree with the leading commas in laying out models as opposed to the trailing. Scanning the models of an Elm file is far faster than, say, a JS file, subjectively at least.
- xixixao 10y agoI'd say the problem isn't "this is not JSX", but that the syntax just looks awful: div [] [ div [] [ button [ onClick Increment ] [ text "+" ] ] , div [] [ text <| toString model.counter ] , div [] [ button [ onClick Decrement ] [ text "-" ] ] ] JSX isn't the only syntax that took off, there are for example indentation based syntaxes for HTML, theoretically: div div button onClick: Increment text "+" div text <| toString model.counter div button onClick: Decrement text "-" already much nicer (and if it was all wrapped in parens it wouldn't make much of a difference). Given that Elm is "just" for making HTML apps, this does seem like something the language should focus on.