The nice thing about React, vs others like Vue and Angular, is that we've learned not to write code in strings. You'd think this would be a fundamental law of software engineering, but we keep seeing things like
Writing code, not strings, means you can do everything to it that you can do to code. You can type check code. You can lint it. You can optimize it, compile it, validate it, syntax highlight it, format it with tools like Prettier, tree shake it...
That's why I like JSX, it's Javascript all the way down. Everything is code. It's a very well designed and thought out DSL.
> Writing code, not strings, means you can do everything to it that you can do to code.
These are tagged templates, not strings. They work as code at runtime, and it already has support to optimize it, compile it, etc. This is JS all the way down. And spankalee mentioned below they're adding typescript support to type check the very similar lit-html, so that's coming too.
> That's why I like JSX, it's Javascript all the way down. Everything is code. It's a very well designed and thought out DSL.
It's also kind of a weird to highlight all this for a DSL that actually has to be parsed from a string to get it to be Javascript. Everything else you're talking about is tooling that had to be built special for it, not the language itself.
Why not just say "I like the style of jsx embedding and existing tools better" :)
The difference is even more pronounced once you start typing your code.
TS/TSX = 100% typed
arbitrary template DSL = 0% typed
and now these string template based on interpolation = 5% typed:
Only the dynamic values inside ${} expressions are "typed", but there are no coherence checks. DOM attribute names and values remain untyped
In the absence of any real advantage for string templates, why even bother?
Sure, stringly typed programming is sometimes a quick and dirty solution - and that's fine, even permanently, if you just don't want to invest much in whatever you're doing - which too, is fine.
But it's not a good thing. It's cheap and easy, which is sometimes something you need to settle for.
to give a clear answer here, tagged templates don't actually perform string concat. the function being used as the tag receives an array of the string literals, and the rest of the arguments as the values passed in templates, and can perform any processing it wishes at that point. I've seen some js sql libraries actually using this to prevent people from having the exact problem you're complaining about.
Thanks, I was coming here to say how a bad idea is this thing. Totally agree with you, I can't understand why people still like write magic. I like your comparison strings Vs code. I'll steal that!
JSX is not Javascript, you need to transpile, and not everybody wants to mess with webpack+babel or create-react-app, or anything other what involves downloading 1000+ packages from npm just to do some quick PoC. Sometimes you want to stay light (and fast), and incrementally build your stack, just you like can do with vue.
So I actaully like this project, thanks for this :-)
If I find myself doing something like that in Vue, I immediately make it a computed property. Granted, v-bind:id="something" is still markup that has little chance of being well understood by the IDE, but at least there isn't much to get wrong, and I don't have to remember if I need ', ", \', or \".
When you write JavaScript, you can only optimize it..as JavaScript. It still needs to be parsed, compiled, and optimized as JavaScript.
When you write templates, you get more room for optimization. Glimmer engine compiles templates to binary bytecodes to bypass JavaScript parsing. Vue3 inlines component fragments as part of the compilation step.
Writing code, not strings, means you can do everything to it that you can do to code. You can type check code. You can lint it. You can optimize it, compile it, validate it, syntax highlight it, format it with tools like Prettier, tree shake it...
Both intellij and emacs do all of these things for Vue code. That seems to cover >90% of developers' tooling needs.
I wrote React for a couple years and was pretty dogmatic against the whole "stringy code" thing. Obviously and generally, we'd rather write code not in strings. But guess what? Moving to Vue from React was a major productivity boost for us - "stringy code" and all.
I’ve written tooling to support lit-html and styled-components in editors. Template strings are sort of nice to write but complete pain to support in editors. They are just like a macro language, so you end up with stuff like: `<${tag}>...<${tag}${slash}>` which is not possible in jsx. Even just detecting syntax errors is a pain
Obviously if deciding between making life easy for editor implementers or making life easier for coders, the coders win, but if something is unnecessarily difficult to build good tooling for, that’s a sign of poor design in my book. And coders will ultimately suffer too because their tooling will suck and because their code will make use of all the crazy flexibility the library allows.
I think though that the concern here is a little misplaced given the constraints that HTM and lit-html work under - which is that the template strings themselves, without the values, have to be well-formed because they're passed to the HTML parser without values.
In HTM, `<${tag}>...<${tag}${slash}>` is not possible to interpret as a possibly self-closing tag because self-closing tags are expanded before values are written into VDOM.
In lit-html `<${tag}>` is not allowed at all. So we know what the tag name will be, and what attributes and properties are bound. The same amount of type-checking is possible as with JSX.
We have our own lit-html-inspired html tagged template literals that render directly to DOM, but it’s nice to see HTM’s improved support for function attributes (e.g., onclick), spread attributes, etc.
Eventually we'll get some great parts of this approach standardized, starting with Template Instantiation, and we'll finally have a great way to create and update lots of DOM from data right in the platform.
A future d3 based on that would be very awesome too :)
I remember when everyone suggested their own way of s-expressions (basically) to avoid having to write superfluous end-tags and other XML/HTML tchotchkes, now we're getting multiple ways to get all the markup boilerplate into our programming language.
Sometimes it's weird how tastes change. Same thing happened with the nigh universal hacker-ish dislike of "bondage and discipline" languages, now it's enforced formatting wherever you look.
There's so much money in web apps now that your average team is flooded with mediocre devs. These joints need "bondage and discipline" languages and frameworks to be productive. It's better business value to have your 50 work-a-day devs productive than your 2 rockstars.
Maybe it's just me being an old man at this point but I still dislike doing templating in JavaScript. It's not natural. I want Jinja2 and server side rendering. If you absolutely must do JavaScript you should keep it separate of your HTML and other stuff... again maybe I'm just getting old.
Honestly I don't find neither JSX, or this new alternative particularly readable.
With the exception of html comments, these are invariably antifeatures. Optional quotes/closing tags save zero to negligible typing time in exchange for added complexity for tooling and reduced readibility in many circumstances.
I can understand why these features were added to HTML5 (backward compatibility is of more benefit than prescriptivism) but I would never have thought anyone would argue that having these features in HTML1 was a good idea in retrospect!?
Adding them to a new syntax that isn't burdened with backward compat requirements seems daft.
HTM is React-compatible, and has all the React semantics: e.g. you can interpolate attributes (with ...${foo} instead of React's ...foo) and tag names (with <${foo}> instead of React's capitalization-dependent <Foo>).
In other words, HTM is a drop-in replacement for JSX that avoids the need for a compiler by using the corresponding language features. (At the cost of a few extra ${}s.)
lit-html and its ilk render directly to the DOM. They give similar developer ergonomics to React/JSX, but don't integrate with that ecosystem. They aren't a drop-in replacement for a JSX compiler within your React app; they're more of a competitor to the entire React paradigm.
Also of note is that, as a drop-in replacement, HTM is properties-first, like React/JSX. lit-html has you use different syntax for properties and for attributes.
This is a neat syntax, but it doesn’t seem at all typesafe (typesafety was the main benefit of JSX over the various string templates that came before it).
JSX is only type-checked because someone wrote a type-checker for it.
It's completely possible to write a type-checker for HTML templates like lit-html. In TypeScript we even have access to third-party extensible interfaces for all the elements with the HTMLElementTagNameMap, so we can check buildings to properties.
We'll be working on a lit-html type-checker for TypeScript early next year.
So,I guess mixing presentation and logic is OK now? 'Cos as a PHP programmer I used to get shat on all the time for that and I'd like a chance to, you know, unload on someone else for a change.
Tracking whether a button is disabled or not is presentation logic.
Projecting a snapshot of business state onto a presentation is also presentation logic.
"Old school PHP application" style seldom made a distinction.
Also, you must add indirection (bad) to split things apart, and indirection doesn't necessarily pay its own rent. An example would be putting an ajax api request (a client's business concern) into a component where the <button> exists that triggers it. Collating that logic with the UI is nice until you want to reuse the logic, and it's usually cheap to extract it from a component, so you can often add indirection on an as-needed basis as you scale.
[+] [-] stevebmark|7 years ago|reply
Writing code, not strings, means you can do everything to it that you can do to code. You can type check code. You can lint it. You can optimize it, compile it, validate it, syntax highlight it, format it with tools like Prettier, tree shake it...
That's why I like JSX, it's Javascript all the way down. Everything is code. It's a very well designed and thought out DSL.
[+] [-] magicalist|7 years ago|reply
These are tagged templates, not strings. They work as code at runtime, and it already has support to optimize it, compile it, etc. This is JS all the way down. And spankalee mentioned below they're adding typescript support to type check the very similar lit-html, so that's coming too.
> That's why I like JSX, it's Javascript all the way down. Everything is code. It's a very well designed and thought out DSL.
It's also kind of a weird to highlight all this for a DSL that actually has to be parsed from a string to get it to be Javascript. Everything else you're talking about is tooling that had to be built special for it, not the language itself.
Why not just say "I like the style of jsx embedding and existing tools better" :)
[+] [-] boubiyeah|7 years ago|reply
The difference is even more pronounced once you start typing your code.
TS/TSX = 100% typed
arbitrary template DSL = 0% typed
and now these string template based on interpolation = 5% typed: Only the dynamic values inside ${} expressions are "typed", but there are no coherence checks. DOM attribute names and values remain untyped
In the absence of any real advantage for string templates, why even bother?
[+] [-] emn13|7 years ago|reply
Sure, stringly typed programming is sometimes a quick and dirty solution - and that's fine, even permanently, if you just don't want to invest much in whatever you're doing - which too, is fine.
But it's not a good thing. It's cheap and easy, which is sometimes something you need to settle for.
[+] [-] snek|7 years ago|reply
[+] [-] ttty|7 years ago|reply
[+] [-] cztomsik|7 years ago|reply
So I actaully like this project, thanks for this :-)
BTW: it's similar to lit-html, t7 and hyperx
[+] [-] forrest92|7 years ago|reply
Write a method to get the list id.
And FWIW I honestly think JSX is misstep.
[+] [-] kgwxd|7 years ago|reply
[+] [-] lightblade|7 years ago|reply
When you write templates, you get more room for optimization. Glimmer engine compiles templates to binary bytecodes to bypass JavaScript parsing. Vue3 inlines component fragments as part of the compilation step.
[+] [-] m1sta_|7 years ago|reply
[+] [-] shawn|7 years ago|reply
Both intellij and emacs do all of these things for Vue code. That seems to cover >90% of developers' tooling needs.
Also, code itself is a string. Code is data.
[+] [-] Bizarro|7 years ago|reply
[+] [-] mattbierner|7 years ago|reply
Obviously if deciding between making life easy for editor implementers or making life easier for coders, the coders win, but if something is unnecessarily difficult to build good tooling for, that’s a sign of poor design in my book. And coders will ultimately suffer too because their tooling will suck and because their code will make use of all the crazy flexibility the library allows.
[+] [-] spankalee|7 years ago|reply
I think though that the concern here is a little misplaced given the constraints that HTM and lit-html work under - which is that the template strings themselves, without the values, have to be well-formed because they're passed to the HTML parser without values.
In HTM, `<${tag}>...<${tag}${slash}>` is not possible to interpret as a possibly self-closing tag because self-closing tags are expanded before values are written into VDOM.
In lit-html `<${tag}>` is not allowed at all. So we know what the tag name will be, and what attributes and properties are bound. The same amount of type-checking is possible as with JSX.
[+] [-] mbostock|7 years ago|reply
https://beta.observablehq.com/@mbostock/hello-htm
We have our own lit-html-inspired html tagged template literals that render directly to DOM, but it’s nice to see HTM’s improved support for function attributes (e.g., onclick), spread attributes, etc.
[+] [-] spankalee|7 years ago|reply
Eventually we'll get some great parts of this approach standardized, starting with Template Instantiation, and we'll finally have a great way to create and update lots of DOM from data right in the platform.
A future d3 based on that would be very awesome too :)
[+] [-] mhd|7 years ago|reply
Sometimes it's weird how tastes change. Same thing happened with the nigh universal hacker-ish dislike of "bondage and discipline" languages, now it's enforced formatting wherever you look.
[+] [-] BigJono|7 years ago|reply
[+] [-] leowoo91|7 years ago|reply
[+] [-] mrweasel|7 years ago|reply
Honestly I don't find neither JSX, or this new alternative particularly readable.
[+] [-] eksemplar|7 years ago|reply
[+] [-] coder543|7 years ago|reply
[+] [-] lucideer|7 years ago|reply
With the exception of html comments, these are invariably antifeatures. Optional quotes/closing tags save zero to negligible typing time in exchange for added complexity for tooling and reduced readibility in many circumstances.
I can understand why these features were added to HTML5 (backward compatibility is of more benefit than prescriptivism) but I would never have thought anyone would argue that having these features in HTML1 was a good idea in retrospect!?
Adding them to a new syntax that isn't burdened with backward compat requirements seems daft.
[+] [-] sddfd|7 years ago|reply
https://github.com/Polymer/lit-html
[+] [-] domenicd|7 years ago|reply
In other words, HTM is a drop-in replacement for JSX that avoids the need for a compiler by using the corresponding language features. (At the cost of a few extra ${}s.)
lit-html and its ilk render directly to the DOM. They give similar developer ergonomics to React/JSX, but don't integrate with that ecosystem. They aren't a drop-in replacement for a JSX compiler within your React app; they're more of a competitor to the entire React paradigm.
Also of note is that, as a drop-in replacement, HTM is properties-first, like React/JSX. lit-html has you use different syntax for properties and for attributes.
Both are cool!
[+] [-] Scarbutt|7 years ago|reply
[+] [-] unknown|7 years ago|reply
[deleted]
[+] [-] dixie_land|7 years ago|reply
I'm not a JavaScript developer so this is news to me, very neat feature!
[+] [-] simlevesque|7 years ago|reply
https://github.com/declandewet/common-tags
[+] [-] qwerty456127|7 years ago|reply
[+] [-] ricardobeat|7 years ago|reply
[+] [-] bcherny|7 years ago|reply
[+] [-] spankalee|7 years ago|reply
It's completely possible to write a type-checker for HTML templates like lit-html. In TypeScript we even have access to third-party extensible interfaces for all the elements with the HTMLElementTagNameMap, so we can check buildings to properties.
We'll be working on a lit-html type-checker for TypeScript early next year.
[+] [-] ricardobeat|7 years ago|reply
Do you have a source for that?
[+] [-] unknown|7 years ago|reply
[deleted]
[+] [-] thedonkeycometh|7 years ago|reply
[deleted]
[+] [-] drivingmenuts|7 years ago|reply
NM, I'll just go back to my cave now.
[+] [-] stevebmark|7 years ago|reply
[+] [-] wild_preference|7 years ago|reply
Tracking whether a button is disabled or not is presentation logic.
Projecting a snapshot of business state onto a presentation is also presentation logic.
"Old school PHP application" style seldom made a distinction.
Also, you must add indirection (bad) to split things apart, and indirection doesn't necessarily pay its own rent. An example would be putting an ajax api request (a client's business concern) into a component where the <button> exists that triggers it. Collating that logic with the UI is nice until you want to reuse the logic, and it's usually cheap to extract it from a component, so you can often add indirection on an as-needed basis as you scale.