12 ms·
This is a debate that has been going on since I started in the late 90ies. You need some sort of logic in your views, no matter what system you use, i. e. loop
by matt4077 11y ago
This is a debate that has been going on since I started in the late 90ies.
You need some sort of logic in your views, no matter what system you use, i. e. loops or formatting dates.
Because people are raised on the "don't mix logic & layout" maxim, they feel dirty when they write sich logic in their usual language.
.. so they invent template languages...
... that then expand to be turing-complete and basically offer everything their primary language offered in the beginning.
So you end up with a new language to learn, which is usually clunky and ugly just for the bragging rights of "not mixing logic & views". Which is completely stupid. Views can (and almost always need) to contain some logic and the best language for that is the one you're using everywhere else.
- aikah 11y ago> ... that then expand to be turing-complete and basically offer everything their primary language offered in the beginning. then they wrote template languages on top of the template language to separate layout and logic again ( PHP vs Twig/Smarty ) so maybe we need to step back a little and figure out how to write a language that wouldn't need a different syntax for logic and layout. This family of languages exists already, but since current developers grew up with C like languages, it is not that popular. IMHO the best compromise is direct support for XML syntax inside languages (which Javascript had at some point with E4X) because I don't think anyone will be able to make developers use LISP like languages on a wide scale. JSX, with some modifications and standardisation could also be a solution.
- escherize 11y agoI'm a huge fan of Clojure's Hiccup library. It allows the user to make html like the following. Here's a function that always returns true - but it could do any kind of data access. It is just plain Clojure. (defn selected? [] true) Here is a datastructure that represents html: [:h2 {:class (when (selected?) "selected")} "Hello"] Calling the function hiccup.core/html on that datastructure yeilds an html string like this: "<h2 class='selected'>Hello</h2>" So that's great for _strings_ right? But there is an awesome library for ClojureScript called Reagent. And it uses those simple datastructures to generate react components!! I put some more examples at: http://hiccup.space http://hiccup.space
- teej 11y agoI don't know man. Every time I've worked with that style of approaching the problem, it feels like I'm just writing HTML with different syntax.
- mst 11y agoIf (if) you already like lisp, it more feels like writing HTML with cleaner, more composable syntax. Were I working on an all-lisp team, I'd be totally happy to use it. Since I'm generally not, JSX function components seem to be the next best (or at least next-least-worst) thing.
- chimeracoder 11y ago> I'm a huge fan of Clojure's Hiccup library. It allows the user to make html like the following. It helps that Clojure's syntax is based on s-expressions, and s-expressions are already isomorphic to HTML/XML. So in a way, you're still mixing your templates and your code, but you happen to be using the same syntax for both. Which is arguably an improvement.
- deleted 11y ago[deleted]
- munro 11y agoI love Clojure, but I'm tired of embedded DSLs, they're a dime a dozen. You can argue the benefits of Hiccup's syntax & s-expr all day, but it's still a different, and unpopular syntax for describing HTML. The ability to copy snippets of HTML from web, or old code when refactoring, or from Clojure/Hiccup to another language & framework, or changes from developer tool, or familiarity for new engineers, or not having to care about what flavor of HTML is hip today is a huge productivity boost for me. I would love to see push for template strings [1] in Clojure, it should be trivial with macros. It would only take some time for IDEs to catch up. They're good. So good they've even influenced Python 3 to add them. (defui my-component [x] "<h2 class=(when (selected? x) ["selected"])>Hello</h2>") [1] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/template_strings https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
- pekk 11y agoIf you are trying to make a language that doesn't need a different syntax for logic and layout, do you not end up with a templating language similar to PHP? Is this the right goal?
- matt4077 11y agoYes – look for example at the .erb templates that rails uses. It's still possible to do evil stuff in those, but I actually haven't seen it in practice. The whole framework is organized in such a way that people get where their logic belongs. The worst I've seen is a bit of confusion between models and controllers. But views are usually as clean as the Gods of MVC commanded.
- paulddraper 11y agoScala has inline XML support. Not a good thing, IMO, since it makes the syntax way more complicated, but there you have it.
- dminor 11y agoIt's not true though that you need logic in your templates - see https://github.com/cgrand/enlive https://github.com/cgrand/enlive for a counterexample.
- toolz 11y agoPakyow also uses logicless templates. It achieves this by having processors in ruby that you can bind to scopes/attributes. <div data-scope="users"><div data-attr="name"></div></div> Now I have everything I need to process this html with my logic to turn it into <div id="users"> <div id="user_1"> Frank </div> <div id="user_2"> Bob </div> </div> https://pakyow.org/ https://pakyow.org/ edit: I wish downvotes required commenting on why you're downvoting.
- mst 11y agoI suspect it's because people regard the implied foreach loop of data-scope to not count as logicless. Personally I can see the arguments both ways, and have concluded that simply ensuring I'm using the same definition of logicless as the people I'm talking to is the best answer.
- toolz 11y agoAhh, well I never claimed it was logicless. I claimed the templates were logicless, and they are. The logic is kept separate inside the processors that you bind to the template.
- mst 11y agoExcept the -scope part means that the foreach-ness is indicated by the template, so people consider that to be not-logicless. I understood your claim fine. I'm trying to explain why it might be considered false (and I did already say I consider the arguments each way basically hair splitting).
- toolz 11y agoInteresting, I've never imagined an identifier could be labeled as logic. There is no need for a scope, if you mean that the outer identifier is logic. Anything could be the identifier and inside the processor you could define anything to be the outer layer. You could flip data-attr and data-scope just as easily, so I'm not sure where there could ever be an argument that those things represent logic rather than markup. Either way, I _think_ I have a better understand of potential conflicting views. Thanks for taking the time to explain.
- pekk 11y agoIt is the people who LIKE putting logic in templates who want Turing-complete template languages with all the features of the host language. If you don't do much or any logic in templates, you have no reason to want that. It sounds to me like you are arguing that because people will put logic in templates, and this leads to ugly template languages, we should just program in ugly template languages rather than doing any separation of logic from templates.
- TranquilMarmot 11y agoDefinitely agree with "the best language for that is the one you're using everywhere else" Where I work right now, we use the newer versions of ASP.NET that come bundled with the Razor templating engine, which uses .cshtml files. You can write C# inside the files much the same way you can write JavaScript in a JSX file, it makes creating forms and such a breeze. Big bonus is that moving from writing server-side logic to client-side logic doesn't require much of a context switch, and you can use the same objects to represent your data on both sides. If I spend all day moving between half a dozen different languages that get compiled by a dozen different tools, it can get a little exhausting.
- samizdatum 11y agoRazor is really quite different from React. Razor seems to have been born out of a frustration someone had with writing return "<div>" + model.name + "</div>"; Razor is basically a DSL for C# string concatenation, where everything not escaped with an @ is a string literal to be concatenated. This means it's fairly unopinionated about structuring code. React, on the other hand, forces you to define components- ideally, pure functions from properties to JSX (which is just sugar for JS). This means composition is the default solution to everything. Razor doesn't place nearly as much emphasis on composable components, and the mechanisms it has for doing so, like helpers or calls to RenderPartial, are clunky and worlds away from the first-class component support of React. While it's technically possible to write Razor code with a React-style focus on composition, the syntax and architecture of viewmodels/templates actively pushes you away from doing so. In my experience, most Razor ends up like a C# translation of PHP, and I think that's really the paradigm Razor inherited. Razor has been around since 2011, which significantly predates the Cambrian explosion of clientside js frameworks, so it makes sense.
- TranquilMarmot 11y agoGood point that it's hard to write nice and modular views with Razor; helpers and RenderPartial are pretty clunky and overall just hard to manage. I suppose it is pretty PHP-like...
- lopatin 11y agoExactly. I'm only able to write such powerful React components by having a full programming language (JS) in my view (the React render method). The logic-less template approach would have been crippling for me.
- lmm 11y ago> You need some sort of logic in your views, no matter what system you use, i. e. loops or formatting dates. No you don't. Look at Wicket for how to do this right: everything is a component, the only thing[1] your templates contain is a) markup (which is 100% valid, using a namespace for the only wicket-specific part) and b) ids that indicate that a given tag will be replaced with a component. Everything else is handled by the component hierarchy in code, using proper OO polymorphism (it's also a great example of proper use of OO, with classes left with only the correct extension points, and classes or methods declared "final" if the developers don't intend to support custom ones going forwards). You end up making truly reusable components that can be very small - even something like an address input is a component defined in terms of smaller components. I wish there were Wicket equivalents in other languages. [1] There are a few other conveniences, but they really are minimal
- munro 11y agoWhen the parent says view, they're not talking about "a) markup", they're talking about the thing the user is looking at. > b) ids that indicate that a given tag will be replaced with a component With that in mind, your disagreement is contradicted by this statement because logic has just been described to update the view. Logic is necessary to generate a view of the data for the user. With JSX, keeping all of this code closer together that is intrinsically tied together increases cohesion, by definition. Subjectively, this makes it easier to manage UI because one only have too check one place for all the pieces. For further exploration of this idea, check out the intro of this video on separation of concerns vs technology. [1] On a separate point, it sounds like one must imperatively update the UI with Wicket, which is objectively more complex than what React affords, which is stateless UI. Time is removed from the equation, which also makes things easier to reason about. [1] https://www.youtube.com/watch?time_continue=275&v=x7cQ3mrcKaY https://www.youtube.com/watch?time_continue=275&v=x7cQ3mrcKa...
- lmm 11y ago> With that in mind, your disagreement is contradicted by this statement because logic has just been described to update the view. Logic is necessary to generate a view of the data for the user. There is no logic in the "template". No looping, no branching. Only inert ids. There is logic in determining which component replaces each id, but that logic lies in the code, not the template. > it sounds like one must imperatively update the UI with Wicket, which is objectively more complex than what React affords, which is stateless UI. Not so. Wicket clearly separates its state into models, you write UI that depends on a model as a function of that model. It leads to a very declarative/functional style, where the only "magic" is encapsulated and explicitly managed. (You do have to declare which changes update which UI (for performance reasons), but you can make that "always re-render the whole page" if that suits your use case).
- unclebucknasty 11y agoGood points. So, some people say, "hey, let's use a declarative language like XML." Problem is that you still need to decide what, when and how to display your model. So, we end up with tags or otherwise that are merely attempts to hide logic. <foreach>. Yeah, right. You can go the other way...just put the logic in the controller to format data and otherwise build the model in a way that is cognizant of the view. But, then you've just "polluted" the controller with the view. One approach at solving this is frameworks like Wicket, which (in spite of shortcomings) encourages the use of view components in a way that allows them to render a more organic model. Yes, you may write some Java to render specialized components, but you're at least using the same language and being specific about writing rendering code that is also reusable.