Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nested Invocations in Angle Bracket Syntax #457

Merged
merged 8 commits into from
Mar 15, 2019

Conversation

wycats
Copy link
Member

@wycats wycats commented Mar 5, 2019

@rwjblue
Copy link
Member

rwjblue commented Mar 6, 2019

Thanks for working on this @wycats! The inability to invoke components in subdirectories has been a significant blocker to adoption of angle bracket invocation for many people. Its great to finally see work to make a migration possible that doesn't require fundamentally restructuring your app.

While I can absolutely see how folks coming from languages that use :: essentially as a folder separator already may find it quite obvious, I do not find it intuitive at all. Given the fact that we already allow / in component invocations (inside curlies) I think that it is a better starting position than :: and I'd also suggest that most developers would just "assume" that it works.

In addition, the ember-holy-futuristic-template-namespacing-batman addon (which allows using :: as the originally intended purpose from #143) has proven very helpful in a number of applications as a way to disambiguate exactly the type of "resolver magic" that is being proposed here. Introducing this alternate meaning of :: will cause a bit of grief for those users (though they certainly new the risks when adopting the addon) and we should consider what migration path they would have here.

tldr; I disagree with your assesment of /, and think it is a much better choice than ::.

@samselikoff
Copy link
Contributor

I'll second that we also see lots of folks not adopting angle brackets due to lack of subdirectory support, so I'm glad this is being prioritized!

IMO the timeline for template imports has a big impact on the need for an intermediate solution like this. Adding another "Emberism" like :: seems to go against the spirit of the 2018 Roadmap and Octane RFCs, which are partially about re-joining the wider JS community.

ES6 imports have been used for quite some time both inside and outside the Ember community, and I have yet to hear a JavaScript developer complain about a need to abstract filesystem paths. The syntax used for absolute and relative paths is a familiar, battle-tested way to reference and look up modules on disk. The problem space for resolving component invocations in templates seems to sufficiently overlap with other environments that the benefits for a new syntax would need to be high to justify their cost.

Template imports seem to solve the general problem, so unless there's been an assessment of high risk in shipping those, I think I'd rather community effort allocated towards that RFC.

@rwjblue
Copy link
Member

rwjblue commented Mar 6, 2019

@samselikoff - Yes, you are absolutely correct that both this RFC and the general "template imports" problem are related. I think we are generally all aligned on that future, but given that we are only just now talking about exposing primitives that can be used outside of core to build these template imports (checkout #454 if you haven't already) it seems very unlikely that a concrete "template imports" implementation will be ready in the time frame of the octane edition. This RFC (once corrected to use / instead of :: 😽) aims to solve the relatively short to medium time frame. Specifically, supporting nested invocation unlocks the ability for us to generally teach that nearly all component invocation in Ember Octane Edition is done via angle bracket invocation. IMHO, that simplicity is absolutely worth a small amount of work in this RFC...

@samselikoff
Copy link
Contributor

samselikoff commented Mar 6, 2019

@rwjblue Ah - I see. Thanks for clarifying! 😀

In this case, I guess another direction we could consider would be to take the "do nothing" alternative that was mentioned in the RFC a bit further, and simply punt on promoting Angle Bracket invocation altogether until it has support for nested components via template imports. After all, if template imports is the goal, why introduce a new short-lived syntax? Why not just stick with curlies for now, if we know what we really want is being worked on & near the top of the roadmap?

The introduction of :: (or /) seems like a third syntax for invoking components, and one that won't vanish once template imports land in their final form. Maybe I would be less concerned if there was a more concrete plan around transitioning from/deprecating them once template imports work (if that is the goal).

The reality is that nested-lookup-angle-brackets and template-import-angle-brackets are two different things for folks to learn, so I'm not sure this actually makes the teaching story easier.

@pzuraq
Copy link
Contributor

pzuraq commented Mar 6, 2019

The reality is that nested-lookup-angle-brackets and template-import-angle-brackets are two different things for folks to learn, so I'm not sure this actually makes the teaching story easier.

To be fair, nested lookup is something that is already used with curly bracket components, so it's well understood by the community. That should reduce the teaching cost a fair amount.

I think that this would allow us to bundle a lot of the "frontend" concepts together all at once, teaching the new Glimmer component API, tracked properties, angle bracket syntax, named args, etc. These are all highly interrelated, and so they really rely on each other for coherence in the learning story. This way we can focus on teaching these while we work on template imports, and get things started for them instead of continuing to wait for all the things to be complete

@samselikoff
Copy link
Contributor

To be fair, nested lookup is something that is already used with curly bracket components, so it's well understood by the community.

I do think the concept of nested lookup is already used and understood, however the syntax for the three forms is quite different and will all need to be explained.

Form 1:

{{#budget/category/table-row}}
  ...
{{/budget/category/table-row}}

Form 2:

<Budget::Category::TableRow>
  ...
</Budget::Category::TableRow>

<!-- Or this: -->
<Budget/Category/TableRow>
  ...
</Budget/Category/TableRow>

Form 3:

import CategoryTableRow from './table-row';

// Or this:
// import CategoryTableRow from 'money-manager/ui/budget/category/table-row';
---

<CategoryTableRow>
  ...
</CategoryTableRow>

Forms 2 and 3 both need to be taught. I agree they can all be learned by Ember developers; my concern is just that when the day comes when we all move from Form 2 to Form 3, there'll be some mental churn as well as code changes that will need to happen to accommodate. There will be a period of time where there are many ways to invoke components, which feels a little unnecessary and confusing to me.

Related question: Do y'all have any insight on what lead to #454 being about primitives instead of the new final format? Was there just a lack of consensus during the exploratory phase?

IOW, can the core team just grab some 🍻 and make a call on the final template import syntax? 😜 I feel like if there was less uncertainty about what that final syntax would be, we probably wouldn't even be discussing a temporary interim syntax.

@mydea
Copy link
Contributor

mydea commented Mar 6, 2019

So for us, a lack of a way to easily use nested component paths is the main reason we cannot really move to Angle Bracket Invocation. This kind of leaves us in a weird space, where we have to kind of use both syntaxes to achieve certain things. Honestly, I'd definitely prefer it if we could (internally) just settle on "use angle bracket invocation for all new code", but that's just not possible (since we have a lot of existing components in nested folders, which we quite like), so we end up in a weird place where you always need to think about which variant to use.

For me, the / separated form feels quite natural, especially since I've been using it in the curly bracket form the same way for a long time, and it also matches my mental model of a folder.

@sohara
Copy link

sohara commented Mar 6, 2019

@samselikoff I believe the motivation for RFC'ing primitives instead of a final import syntax was the idea that the former would allow for exploration with various syntaxes in addon space and presumably a more complete feedback cycle for the core team prior to making a final decision about new semantics and syntaxes. I don't think that's a bad idea but of course it's subjective.

Octane is already available for (experimental) preview using the blueprint and I'm guessing a more formally published preview is on track for Ember Conf. I personally think it would be unwise to rush a new core feature with both syntactical and semantic changes in those kinds of timelines.

Also very subjective, but when I first heard about angle bracket invocation about a year ago I just assumed that nested lookup would have been supported with the syntax being advocated for by @rwjblue and others (slashes), i.e. I believe it would be a very intuitive and therefore low cost adoption for all Ember developers because there's no change to the existing mental model.

@samselikoff
Copy link
Contributor

@sohara I agree rushing such a core feature by EmberConf would be a mistake. I was under the impression Octane is not going to be finalized as of the EmberConf deadline, but rather when there is cohesion around all the new moving parts. If a core piece of one of those new moving parts isn't fleshed out, I don't see the need to rush the others. (Of course, deadlines can and should be used to force scoping down, without a loss of cohesion.)

I also am in agreement that angle-brackets-with-slash-syntax is intuitive and relatively low-cost on its own. The problem I'm having is introducing it as a temporary solution, since nothing about it suggests as much.

@rwjblue
Copy link
Member

rwjblue commented Mar 6, 2019

Another possible alternative design to the one proposed here (either :: or /) would be to introduce a new keyword that would allow us to bring components into local scope. The concept has already been proven out by the wonderful ember-template-component-import addon, though I'd suggest we specifically not use any syntax that could be confused with ES module import syntax.

Concretely, I'd propose adding a resolve-component keyword:

{{resolve-component 'app-icons/warning' as=AppIconWarning}}

<AppIconWarning @color="yellow" />

This has a few benefits:

  1. Combines nicely with the template import work, this would be a stepping stone to making a template fully import based. The presence of {{resolve-component in a template becomes a "TODO" there.
  2. It avoids adding temporary syntax just to address the nesting problem (it also adds a nice migration path for imports).
  3. It can easily be implemented in addon space without changes to the resolution rules.
  4. Is not as subjectively "ugly" as some seem to believe <Foo/Bar></Foo/Bar> is.
  5. Does not have syntax highlighting issues (both the :: and / syntaxes have highlighting issues depending on the editor/plugin in use)

h/t @mixonic for originally mentioning this idea in the Octane Meeting yesterday...

@samselikoff
Copy link
Contributor

@rwjblue (and @mixonic) I love this solution. It addresses all the concerns I have with this RFC - in particular it has a clear migration path once the final syntax for template imports lands.

@mixonic
Copy link
Member

mixonic commented Mar 6, 2019

I really, really do not want to turn the comments here off the rails entirely. Please, if you want to experiment with syntax specifics join us on Discord and do it there ❤️ #dev-ember-js or #st-octane are appropriate.

I would however like to clarify that I don't prefer as=SomeSymbol to in @rwjblue's example because it is hard to rationalize why the right side of = is setting a symbol for the scope of the template.

I would suggest:

{{lookup Warning in 'app-icons/warning'}}

<Warning @color="yellow" />
  • lookup matches the API already on the owner object, which is exactly the semantics we want people to learn
  • in or at avoid re-using from and creating confusion around import semantics

Again please help us keep the conversation focused for this design and discuss tweaks and exploratory ideas on Discord ❤️ Thank you.

@ro0gr
Copy link

ro0gr commented Mar 6, 2019

Do {{resolve-component and {{lookup variants differ somehow from let + component?

{{#let (component "app-icons/warning")
  as |Warning|
}}
  <Warning />
{{/let}}

@rwjblue
Copy link
Member

rwjblue commented Mar 6, 2019

@ro0gr - no, the idea is that they would transform into that syntax

@rtablada
Copy link
Contributor

rtablada commented Mar 6, 2019

Some initial impressions I have:

  1. Based on the tone and some of the stuff in Alternatives it feels like this is very much a stopgap with some potential future drawbacks
  2. The Alternatives should mention that the let component wrapper is a valid way to use AngleBracket syntax today with any nested component.

Reactions to comments so far, I think if we are going to do something to allow better semantics than having to write lots of let blocks then a lookup or resolve-component helper would be a really nice alternative.
It can easily be implemented now with an AST transform to the let (component) syntax and later could use the template import build functions as listed in #454

@csantero
Copy link

csantero commented Mar 6, 2019

As someone with an app full of nested components I'd rank my preferences as:

  1. Slash-separated syntax <AppIcons/Warning>
  2. Double-colon-separated syntax <AppIcons::Warning>
  3. Just wait until template imports are ready.

I don't find {{resolve-component 'app-icons/warning' as=AppIconWarning}} or {{lookup Warning in 'app-icons/warning'}} or {{#let (component "app-icons/warning") as |Warning|}} compelling. Converting curly invocations that already use slashes to angle-bracket invocations that also use slashes seems like the simplest and most obvious stopgap until template imports.

@scudco
Copy link

scudco commented Mar 6, 2019

My team recently converted a couple apps with plenty of nested and dynamic components to use Angle Bracket syntax. We opted to use let blocks as that gave us a better migration path toward imports (or whatever shakes out). If the / or :: syntax had been there it would've made angle bracket adoption much easier but left us with more theoretical rework when imports shipped. I can say that the in-progress state of imports would've had us adopting the lower-cost / or ::.

I think what most people need right now isn't a learning story or migration path to future features. They need a way to provide consistency to their code. They need an answer to Angle Bracket invocation for nested components that doesn't require a blog post. If template imports aren't actually coming in Octane, then the / or :: choice seems fairly obvious. It requires the least amount of cognitive load to actually switch to Angle Brackets.

Personally, I would gladly take resolve-component or lookup. That makes the most sense to me, and I think I get most of the reasoning behind it. However, I suspect what most devs expect when switching to Angle Bracket invocation is for <AppIcon/Warning> to just work. They'll learn about imports when they are shipped.

I'd rank my personal preferences as

  1. resolve-component or lookup
  2. This RFC's proposal of / or ::

If I attempt to empathize with devs not reading RFCs, but just googling and reading docs when running into issues, I'd rank my theoretical preferences as

  1. / syntax

@wycats
Copy link
Member Author

wycats commented Mar 6, 2019

I want to try to clarify something.

The :: (or /) syntax aren't a new mechanism for importing components. The :: syntax would be an extension to the normalization rules in RFC #311, and the / syntax would be an extension to the tokenization rules in RFC #311.

We could have designed a syntax for nested lookups in that RFC, but intentionally chose not to because we felt, at the time, that Module Unification would replace the need for that syntax:

In today's semantics, {{foo/bar}} does not try to lookup this.foo.bar and invoke it as a component. Instead, it is used as a filesystem scoping syntax. Since this feature will be rendered unnecessary with Module Unification, we recommend apps using "slash components" to migrate to alternatives provided by Module Unification (or, alternatively, keep using curly invocations for this purpose).

In the interim, we have come to believe that template imports, rather than local lookup in Module Unification, is the correct solution for bringing nested components into the scope of a component. However, the template imports feature is not yet RFCed, while angle bracket components have already shipped.

In light of that, this RFC suggests revisiting the decision made in RFC #311 to punt on designing a syntax for nested lookups. It is narrowly scoped to introducing a syntax for that purpose, in order to allow users attempting to use already landed angle bracket syntax today to migrate to them uniformly from the curly syntax. We intend to continue working on template imports, but I personally believe that we need a fully general way to use angle bracket syntax while we design, implement and ship template imports.

@wycats
Copy link
Member Author

wycats commented Mar 6, 2019

Another thing I want to note: the resolve-component family of solutions has a more difficult "how we should teach this" story (I was thinking about how I would write that RFC).

In particular, it would require us to introduce the concept of bringing external components into scope, but it would only be necessary in nested scenarios. This introduces some questions: should people use the same syntax for bringing in non-nested components? Should we recommend that? Will community members want it to be recommended?

While folks this thread might feel pretty good about introducing an import-like API to Glimmer templates, it really does introduce a big new thing to teach: the concept of bringing external templates into scope. I don't think it will make sense to teach it as a desugaring to (component) and #let, because those concepts are more advanced (and appear later) than the need to group components into directories.

In contrast, this RFC maintains the current mental model around using name resolution to get components out of the file system, but adds a way to refer to nested directories. I just think that's a smaller scoped thing to add and teach.

@mydea
Copy link
Contributor

mydea commented Mar 7, 2019

For me, the argument that <My/Component> would be a stopgap solution to eventual template imports is not necessarily that important - The alternatives we have right now are imho much worse stopgaps. Basically, you could either:

a) Refactor your whole codebase to not use nested components
b) Continue using curly braces everywhere
c) Use a mixture of curly braces & angle bracket invocation, based on if you are using a root or a nested component
d) Use let everywhere - which really clutters the codebase and makes everything harder to read, with "unnecessary" indentation etc.

For me, all of these options are definitely worse then <My/Component>. Sure, I'll have to change it "again" in the future to use eventual imports, but I'd also have to do that with all other alternatives I currently have (except for a), which is just not feasible for us).

Also, it has been said before, but I really think that it is not unreasonable for a regular developer to just expect that, if {{my/component}} works, <My/Component> will also work. You really have to start reading about this to figure out why the one works and the other doesn't - it does not feel natural at all, in my opinion.

Basically, I'd say that it is harder to teach that <My/Component> does not work, than to teach how it works - nobody on my team ever really had any trouble understanding the nested curly brace syntax.

(I'd prefer / over ::, but would definitely still prefer :: over no nesting at all)

@MonsieurDart
Copy link

For me, Octane is great because it will bring clarity, readability and coherence. This is why I really like angle bracket invocations. So, I don’t like a path where we go back to curly invocation. And I don’t like a mixed solution: angle bracket should be used everywhere for direct component invocation (do we have a plan to deprecate curly yet?).

We stared to migrate to angle bracket invocation and we love it! But we need a solution for our numerous nested component.

The lookup solution seems more aligned with the import future tool, but is really not simple to discover and adds indirection when reading the template.

Meanwhile, I don’t see the :: syntax as a new way to invoque components, rather the angle bracket way for nested components. And it will be learnt at the same time as the angle bracket syntax.

Additionally, the :: operand is quite familiar to people using namespaces in other languages.

Finally, I foresee a lot of problems with the / operand. A lot of editors (offline, but also online) will have troubles with it. We move to the angle brackets, allowing us to be closer to the HTML syntax, but we then use this / character which will bring back confusion...

I’m in favour of the new funky :: syntax! 😉

@ppcano
Copy link

ppcano commented Mar 7, 2019

(I'd prefer / over ::, but would definitely still prefer :: over no nesting at all)

Me too and I guess most of the folks prefer / than :: but the reason of using :: is detailed on the Drawbacks and Alternative RFC section:

it has poor syntax highlighting in virtually all existing highlighters

The syntax highlighter and autocompletion look to be the blocker for adopting /. I don't know the status of the different IDEs and syntax highlighters; a quick test showed me that :: is better supported.

Anyway, I think if syntax highlighters and IDE autocompletion start widely supporting /, I don't see an impediment to migrate from :: to / in the future.

I am not sure about the resolve-component/lookup solutions, I will have to include a lot of imports that it won't be needed when using a convention. My main issue could be solved with something like the prelude.hbs option.

Have : be considered instead of ::? Apologies for suggesting another alternative.

<AppIcons:Warning></AppIcons:Warning>

Probably, the : syntax can conflict with the <:blockName> proposal at the Yieldable named blocks RFC or future ones.

Anyway, I am excited to see progress on both initiatives!

@tschoartschi
Copy link

Since module unification still is not completely finished we decided to use nested components to structure our code better. So the described problem also hits us. Another problem with the / solution could be the adoption of the syntax which is prepared for the future (not sure if module unification and/or template imports will affect and change something).

If we need to change the / to something different it could become tricky to spot all the components which have to be changed. For example, a "find in path" on / could result in many search results which have nothing to do with the thing we want to change. The :: seems to be better for this. I assume there would be less "false positives" when searching for ::.

But I'm not sure what's the migration idea when module unification and/or template imports are released. When we need to adjust the syntax of component invocation by hand the / solution could be tricky. If there is a good code-mod my argument against / will be not too important.

Also, I agree with the syntax highlighting problem described in the RFC for /.

But for me, it's most important to have a solution which can be easily changed to the future syntax.

@wycats
Copy link
Member Author

wycats commented Mar 7, 2019

My perspective on / vs. :: is that, perhaps unexpectedly, / is significantly more work to implement than ::.

First, it would require us to update simple-html-tokenizer. This is definitely possible, but does represent another (significant) divergence from the standard tokenization rules. On its own, I think this would be acceptable, and not too bad (although I do suspect that there are some unknown risks that come from introducing another divergence).

Second, it would require updates to all of the syntax highlighters in common use in Ember. This is harder than it looks, because Ember highlighters typically use Handlebars syntax, which typically delegates to HTML syntax highlighters.

In order to update Ember's syntax highlighting, we'd have to do one of these per highlighter:

  • get the change added to html formats
  • fork the html format into hbs, make the change, and get the change accepted by the maintainer of the hbs format
  • fork the hbs format into Ember (and in some cases create a new Ember/Glimmer format), then fork the html format into Ember and do the update ourselves

All of these represent a significant amount of effort.

Finally, we'd need to get editors to avoid treating <Foo/> as the beginning of a self-closing tag for the purpose of auto-complete. This has the same kind of problems as updating syntax highlighters, but it makes them more acute because auto-complete is a much more bespoke situation.

For these reasons, and especially because we're talking about a temporary stopgap, I really prefer that we go with ::, which is already a valid character in Handlebars identifiers, is already tokenized properly by simple-html-tokenizer, and is already handled correctly in most cases by syntax highlighters and autocomplete systems.

@chancancode
Copy link
Member

Meanwhile, I don’t see the :: syntax as a new way to invoque components, rather the angle bracket way for nested components. And it will be learnt at the same time as the angle bracket syntax.

Additionally, the :: operand is quite familiar to people using namespaces in other languages.

I agree with both of these points. Since you already have to learn the CapCase rule for angle bracket components, in the grand scheme of things, "another transformation" is barely a side note here in my opinion. Especially that so many fewer developers would come across this feature at all (I would argue that we shouldn't feel the need to teach this upfront).

Also, I agree that :: generally means "namespace-y" things in other languages (Ruby, Rust, C#, C++, Java..), and that's in the same ballpark as what we are using it for here.

At the end of the day, just like the CapCase rule in angle bracket invocation itself, it's a mild inconvenience, and in an ideal world maybe we wouldn't need both of those things. But at the end of the day, from the experience of using angle bracket invocations, it's something you learn once and it just quickly becomes second nature, you are not even thinking about it anymore every time you type it. And having something is so much better than not having anything, that the tradeoff was easily worth it. I think the same is true here as well.

@wycats wycats changed the title Nested lookups Nested Invocations in Angle Bracket Syntax Mar 7, 2019
@wycats wycats added the Octane label Mar 7, 2019
@wycats wycats self-assigned this Mar 7, 2019
@davewasmer
Copy link
Contributor

@tomdale

we want to make sure this pressing pain point gets addressed in the short term.

Completely agree. We need to have some solution in the short term.

Under this proposal, the :: syntax is a first-class thing that will be supported for a long time to come, and people should feel confident adopting it.

Also agree 😄

My concern with this proposal then is not so much focused around the particular sigils (/ vs. ::), but rather, should we be adopting a core solution for this at all? If we know that this will be superseded by template imports, and userland solutions exist to solve the immediate pain, do we want to add more long term cognitive load (including all the eventually outdated docs, SO questions, blog posts, etc referencing this syntax) for something that we know will not be the long term recommended path?

I suppose in some sense this is really a question of how far out template imports are.

If it's a month or two (not suggesting it is, but just to demonstrate the point), then clearly the long term cost of this RFC is not worth the benefits for a couple months.

If it's a couple years, then having a "blessed" interim solution feels appropriate.

If it's somewhere in the middle - it gets a bit fuzzier? 🤷‍♂️ I realize accurately predicting this is a fools errand, but I want to call attention to the tradeoff at least, in case anyone more informed than I could weigh in.

@tomdale
Copy link
Member

tomdale commented Mar 9, 2019

@davewasmer Totally agreed with you on the tradeoff.

Speaking personally, if the answer is not "in less than a month," I think we have to plan as though it's far out, as past history suggests we often get these kinds of guesses wrong. I think our motivation is also to not plan based on having a better new design "soon," which creates pressure to ship something fast even when if we discover flaws.

I think in this case, even if we do end up shipping template imports in a couple months (which I'd love to see but honestly think is a stretch), this proposal is a relatively small extension on top of the existing system that will need to be migrated from anyway. So in the grand scheme of things, I think any additional "churn" cost this introduces will be a drop in the bucket compared to the overall migration from runtime lookup to template imports, which we'll need to heavily automate anyway due to the scope of the change.

@tomdale
Copy link
Member

tomdale commented Mar 9, 2019

Thank you to everyone who has provided feedback so far! We discussed this RFC at the core team meeting today and reached consensus that my claims about relative difficulty of / vs :: were overstated, but concerns about syntax highlighting and autocompletions in text editors still gave :: the edge.

Given core team consensus, we are moving this RFC to Final Comment Period to ensure people have an opportunity to raise any additional concerns or provide additional feedback before we merge.


Finally, the goal of this RFC is to make it possible to recommend that users always use angle-bracket invocation for components other than control flow (`if`, `each`).

This means that we should update the syntax conversion guide to no longer say that `{{` syntax is sometimes required, and avoid recommending it.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
This means that we should update the syntax conversion guide to no longer say that `{{` syntax is sometimes required, and avoid recommending it.
This means that we should update the [syntax conversion guide](https://guides.emberjs.com/release/reference/syntax-conversion-guide/#toc_when-to-use-classic-invocation-syntax) to no longer say that `{{` syntax is sometimes required, and avoid recommending it.


![rental-listing in the docs](../images/457-dasherization.jpg)

After this RFC, the documentation should add a "Zoey says" sidebar that describes the rule in more detail, and mentions that you can refer to components nested in a directory with the `::` separator.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
After this RFC, the documentation should add a "Zoey says" sidebar that describes the rule in more detail, and mentions that you can refer to components nested in a directory with the `::` separator.
As part of shipping the feature in Ember.js, updates should be made to the API documentation for [components](https://emberjs.com/api/ember/release/classes/Component). Then, the Guides section on components should add a "Zoey says" callout that describes Angle Bracket normalization rules. The callout can mention that components are nested in a directory with the `::` separator, and it will have a link to more details in the API docs.

@jrowlingson
Copy link

jrowlingson commented Mar 10, 2019

...inability to invoke components in subdirectories has been a significant blocker to adoption of angle bracket invocation for many people.

I want to pump the breaks a bit here and this is going to be unpopular, but I am in favor of the proposed alternative to recommend the usage of #let as an interim solution. I'm not convinced that this is a significant blocker toward the adoption of angle bracket syntax either. In our apps we've been using this effectively as a top level import placeholder. We will likely pass on adopting this interim syntax as it will be difficult to justify the churn.

If we know that this will be superseded by template imports, and userland solutions exist to solve the immediate pain, do we want to add more long term cognitive load (including all the eventually outdated docs, SO questions, blog posts, etc referencing this syntax) for something that we know will not be the long term recommended path?

Introducing new syntax seems like a fairly strong signal to send for something that will, from my read, eventually become a candidate for a deprecation cycle.

The two forms have a 1-1 translation between each other, which is pretty easy to learn. If there was not a 1-1 translation, it would introduce more overhead, and be less desirable.

Agree and for my part, if we must introduce a new syntax I do prefer :: to /. I never quite liked that meaning of / changes depending on its position e.g. closing the tag or referring to a directory {{/x-foo/x-bar}}.

@billdami
Copy link

billdami commented Mar 10, 2019

@jrowlingson as was mentioned later down in the thread, it appears the core team members don’t see this as a “stop gap” or “interim” feature that already has a planned deprecation/end of life before it even ships. Looks like this is intended to be a first class pattern that’s supported for a long time to come, even after when/if template imports do land.

Imo, trying to teach something like the ‘{{let}}’ pattern as a “for now, wait and see” solution is a much stronger signal to send (and is quite an ugly/awkward workaround I think), especially considering it’s only needed in certain situations, and since this is something that was already supported via the old curly syntax.

As we’ve seen with Controllers/routable components etc in the past, designing current patterns around a possible/eventual future pattern is generally not a good idea. :-D

@jrowlingson
Copy link

@billdami That is fair - I may be underestimating the teaching cost of the let / component pattern. The let pattern is also indeed rather ugly. Using fully qualified names is also a bit ugly from a readability bias so the choice between the two becomes a bit muddied.

@wycats
Copy link
Member Author

wycats commented Mar 12, 2019

@billdami That is fair - I may be underestimating the teaching cost of the let / component pattern. The let pattern is also indeed rather ugly. Using fully qualified names is also a bit ugly from a readability bias so the choice between the two becomes a bit muddied.

I agree with @billdami that the high-order-bit here is the understanding cost. People encounter the need for component grouping earlier in their Ember experience than the point where they understand #let, component and the interaction between the two.

@Panman82
Copy link

Since MU is on hold, I'll be sticking with pods going forward. Will this work with the pods structure?

@rwjblue
Copy link
Member

rwjblue commented Mar 14, 2019

Since MU is on hold, I'll be sticking with pods going forward. Will this work with the pods structure?

The invocation proposed in this RFC will work the same in "pods" and "classic" resolver setups.

@ro0gr
Copy link

ro0gr commented Mar 14, 2019

Does it make sense to restrict depth of nesting?

  <Namespace::ComponentName::IamLikely::APrivateComponent>
    <Content />
  </Namespace::ComponentName::IamLikely::APrivateComponent>

I don't like an idea to write a closing tag for deeply nested components. For deep components, it's more natural to use let and component. I think the main issue with let is a block-only form.

Assuming we have an inline form(inspired by ember-let) of let:

{{let Short=(component "nested/path")}}

<Short>
    <Content />
</Short>

@rtablada
Copy link
Contributor

@ro0gr for reference this RFC doesn't stop you from using let with the component helper. This is just a syntax to give AngleBracket parity with curly bracket components when it comes to invocations for nested components.

I think restricting nesting depth could be a linting preference since it would likely vary from team to team.

@pzuraq
Copy link
Contributor

pzuraq commented Mar 15, 2019

We decided to accept this RFC at the framework core team meeting today. Thanks @wycats for working on this and everyone else for the discussion 🎉

@pzuraq pzuraq merged commit 33007e8 into emberjs:master Mar 15, 2019
rwjblue added a commit to rtablada/ember-angle-bracket-invocation-polyfill that referenced this pull request Apr 4, 2019
rwjblue added a commit to rwjblue/ember-holy-futuristic-template-namespacing-batman that referenced this pull request Aug 15, 2019
Since Ember has decided to repurpose the `::` sigil to mean "nested
folder invocation" (see emberjs/rfcs#457), this introduces `$` as a
replacement sigil. Ultimately, usage of `::` will be deprecated by this
addon (though that will be in a future commit).
rwjblue added a commit to rwjblue/ember-holy-futuristic-template-namespacing-batman that referenced this pull request Aug 15, 2019
Since Ember has decided to repurpose the `::` sigil to mean "nested
folder invocation" (see emberjs/rfcs#457), this introduces `$` as a
replacement sigil. Ultimately, usage of `::` will be deprecated by this
addon (though that will be in a future commit).
rwjblue added a commit to rwjblue/ember-holy-futuristic-template-namespacing-batman that referenced this pull request Aug 15, 2019
Since Ember has decided to repurpose the `::` sigil to mean "nested
folder invocation" (see emberjs/rfcs#457), this introduces `$` as a
replacement sigil. Ultimately, usage of `::` will be deprecated by this
addon (though that will be in a future commit).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.