3 ms·
Thanks for your comment, very interesting! That being said, when you say that no-parenthesis are the least important feature of templated strings, they seem to
by globuous 8y ago
Thanks for your comment, very interesting!
That being said, when you say that no-parenthesis are the least important feature of templated strings, they seem to be mandatory for "deconstructing" them via function arguments:
const bar = "bar"
f = (s, ...v) => console.log(s, v);
f(`foo ${bar} baz`); // => foo bar baz ; []
f`foo ${bar} baz`; // => ["foo ", " baz"] ; ["bar"]
So it's not so much that "you can call functions without parents in some cases" or "they're not that nuts of a feature", rather than "if you want to deconstruct templated strings, you must call your function without parenthesis"
Which means that sometimes, there's just no other way around.
Cheers !
- ehsankia 8y agoI think you're confusing what's happening here? The first example is doing a normal string interpolation, and then passing the result to a function. The latter is doing template literals, which is a whole other feature. You're not really "running a function without parenthesis".
- globuous 8y agoSo you're not running a function when I write "f`some ${foo} lols`" ? What's f then ? This is HN and I'm a self taught noob, so probabilistically I'm wrong and you're right. But I'm having such a hard time believing it. To me, it's still running the sequence of instructions defined by f in both cases. Just that the arguments passed to f are different whether it's called with parenthesis or not. And as far as I understand, that's the feature that comes with string literals. But you're still calling f, and f is still a function. It's defined as a function and executed as a function. "If there is an expression preceding the template literal (tag here), this is called a "tagged template". In that case, the tag expression (usually a function) gets called with the processed template literal, which you can then manipulate before outputting." - [1] Now when i open my console (FF) and I type: a = 12 a`hello` I get "TypeError: a is not a function". But if I do b = () => "yo" b`hello` I get, as expected, "yo" and no TypeError. Furthermore, I didn't know this feature, the article called it "functions without using parenthesis" so i called it like that. N.B. I'd like to know what the interpreter / JIT is doing now ;p [1] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#Tagged_templates https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
- ehsankia 8y agoEventually, f is called as a function, but in the syntax tree, it's not a direct "function call". The obvious way to see that is, as you can see in your example, "hello" isn't passed as an argument. Instead, there's an intermediate form internally that does some magic, and calls the function with some other parameters. Maybe I was being a little pedantic, but yeah, f`test` and f(`test`) are two very different operations under the hood.
- Twisol 8y agoThat's correct. But the article is making a subtly different comparison, which the parent is responding to. Specifically, with one string-literal argument, f`hi` and f(`hi`) are nearly identical from the perspective of the caller, as long as you deconstruct the extra array in the function body. This is cute, but since you're limited to literal strings, you can't push this very far before using a regular parenthesized function is better again.