6 ms·
What Mustache can learn from Clojure
- stevelosh 15y agoHowever, there appears to be a set of common denominators that can be used to represent all possible data-structures: Maps or dictionaries, lists, strings, numbers, boolean and null. I'd add sets to this list. You can kind of simulate them using a map where the keys are the members and the values are anything, but they just work more smoothly when you have real support for them (like in Python and Clojure, but not Javascript/JSON).
- chrisvest 15y agoI was wondering whether to add sets to the list or not. In the end I decided not to because they look just like lists for the purpose of destructuring and I liked how this list of things matched what JSON provides, plus as you say, they can be simulated. It also left me with one less thing to explain, except now that it didn't.
- bascule 15y agoAs a user of Clojure and an onlooker of things like mustache (and handlebars) who has used neither of the latter, this post left me incredibly confused. I like the points about destructuring and having something like a let binding. Those seem like useful addition. However, about half the post discusses how "looping and conditional branching are conflated", and the end focuses on adding a separate branching construct to what's supposed to be a logic-free templating language. So I guess what he's trying to say is he wants to add logic to a logic-free templating language. It seems like he missed the point of Mustache: Looping and branching are conflated by design to eliminate logic from the template. About the only way I see the connection between Clojure and Mustache at all is through the potential value destructuring could bring, and destructuring isn't exactly a feature which is unique to Clojure (CoffeeScript, Scala, and Erlang come to mind). Otherwise this post is apples and oranges: Clojure macros are about as far as you can get from a logic-free templating language. I'm wondering if the additions he proposes are sufficient to turn what's supposed to be a logic-free templating language into a Turing-complete one (see this example of why XSLT is Turing-complete: http://www.unidex.com/turing/utm.htm http://www.unidex.com/turing/utm.htm)
- stevelosh 15y agoLooping and branching are conflated by design to eliminate logic from the template. That doesn't eliminate logic, it just makes it annoying and obtuse. You can still branch in mustache templates, and you can still loop. No particular kind of logic has been eliminated. But now you need to know what a particular item happens to be in order to know what the magic branch/loop operator is going to do. About the only thing it prevents is saying "show this if X is truthy", but only prevents it when X is a list! Removing the ability to do something for some arbitrary objects doesn't make the language clean and logic-free, it makes it annoying and complicated.
- bascule 15y agoExcept there's no logic in the language itself, from the perspective of Mustache what you're doing is purely declarative. Adding an explicit "if" operator does introduce logic into the language, and may very well make the language sufficiently expressive to be Turing complete.
- true_religion 15y agoIt wouldn't make it turning complete because while the template could read the hypothetical infinite tape, and write infinitely to another tape---it can't write what its written so its prohibited from being turing complete. It's basically a finite state machine. Now you can do a whole lot with a FSM---and lo, some people will claim that our current brand of machines are only realistically as powerful as FSMs because of the lack of infinite memory.
- bascule 15y agoThe proposed changes, particularly tail recursion, an if operator, and a zip operator in effect give you a functional language with immutable state. While you can't "write" to the Turing tape as a side effect as the language is immutable, you can create a new "tape" from previous states which is a modified version of the old tape.
- 15y ago
- tomdale 15y agoHandlebars (handlebarsjs.com) solves several of these issues: Items in lists don't have to be objects with fields; you can display primitives like strings and numbers by using {{this}}: {{#each tags}} <li><a href="tags.html#{{this}}">{{this}}</a></li> {{/each}} Shadowing properties from parent context objects isn't a problem. Handlebars allows you to reach parent contexts with a '../' notation: {{#each comments}} <h2><a href="/posts/{{../permalink}}#{{id}}">{{title}}</a></h2> <div>{{body}}</div> {{/each}} Regarding looping and conditional branching, Handlebars has an {{#if}} helper that does not evaluate to true for empty arrays: {{#if authors}} {{#each authors}} {{firstName}} {{lastName}} {{/each}} {{else}} No authors to display. {{/if}} I don't fully understand the complaint about recursive data structures. I usually just register a helper that can invoke itself recursively.
- wycats 15y agoIt's worth noting that #if, #each etc. are not built-in structures. They are simply helpers that you can register in the host language. Block helpers receive the block as a function that can be invoked as though it was a top-level template. Consider the simple #with helper: Handlebars.registerHelper('with', function(object, options) { // invoke the sub-template passed as a block to the with helper with the object parameter return options.fn(object); }); And its usage: {{#with person}} Name: {{name}} {{/with}} This means that you can build arbitrary control structures and iterators in the host language and expose them to Handlebars.
- grayrest 15y ago> Items in lists must be objects with fields because it is always decomposed, and there is no way to get a handle on the list item itself. {{%IMPLICIT-ITERATOR}} {{#foo}} {{.}} {{/foo}} But...Handlebars.
- benatkin 15y agoYes, Handlebars. I much prefer {{this}} to {{.}}, which at first glance looks a bit like a Perl 6 or Haskell operator rather than a dot surrounded by tags.
- chrisvest 15y agoI did not know about the {{.}} construct when I wrote that article, but have since been told about it a couple of times. It is indeed a useful thing that would have resolved one of the issues I wrote about. However, it is not in the Mustache spec, nor is it implemented in the particular Mustache implementation, Pystache, that I happen to be using. It could be that Pystache is just behind the curve. I don't know. I have also since found out about Handlebars.js. It looks nice. If Mustache is the 80% solution then Handlebars.js is probably the 99% solution or something like that. Except I would need an implementation in Python, and I haven't come across one.
- LeafStorm 15y agoTo be honest, I have never seen the appeal of logic-less templates to begin with. I can understand wanting a sandboxable template engine independent of language, but that doesn't necessarily translate to "lack of logic." And yeah, it's easier to shoot yourself in the foot with templates that have logic, but on the other hand with logic-less templates you may need to do something that the template language won't let you do, and then you have to go and write some more code in your domain logic. Which means that you're doing something even worse than pushing your business logic into your display logic - you're pushing your display logic into your business logic!
- rhdoenges 15y agoI think mustache is at its core a reaction to ERB, which allows for pretty baroque logic in templates. Mustache goes all the way in the other direction (which is really not any better).
- spooneybarger 15y agoYou don't push display logic into business logic, you have an adapter for domain objects to become display objects.
- leeoniya 15y agoi've also had a few quibbles about the way Mustache is specced - i felt like it was 80% there, but forced too-verbose templates. i re-implemented and modified it a bit to alleviate some of the ambiguity. never had a chance to do full docs, but the js code/readme is up on github if anyone wants to check it out: https://github.com/leeoniya/handlebar.js https://github.com/leeoniya/handlebar.js
- xnxn 15y agoHmm, you might want to consider a different name for the project, since there is already a well-known handlebars.js: http://www.handlebarsjs.com/ http://www.handlebarsjs.com/
- leeoniya 15y agoto be fair, my project (and actually another project before mine - https://github.com/getify/HandlebarJS https://github.com/getify/HandlebarJS) existed before wycats's. i'll prolly change it if i ever decide it needs publicity.