mustache / spec

The Mustache spec.
MIT License
361 stars 71 forks source link

Adding dynamic partials, discussed in #54 #134

Closed ghost closed 1 year ago

ghost commented 2 years ago

The idea is to allow to dynamically load partials.

Brief example: Data:

{
  content: "mainpage",
  world: "there"
}

Templates:

{{!template.mustache}}
{{*content}}

{{!mainpage.mustache}}
Hello {{world}}!

Result:

Hello there!
jgonggrijp commented 2 years ago

Update after my previous comment: I just implemented the feature, so that won't be a bottleneck in the remainder of the review process.

ghost commented 2 years ago
  • The spec should be made optional. That's just a matter of prepending a tilde ~ to the name of the spec, i.e., ~dynamic.yml. Actually, make that ~dynamic-partials.yml

Yes, that's a good point.

  • As currently proposed, the spec covers only half of the behavior of the {{*}} tag, i.e., the partial-like behavior. I think the other half should be specified as well, i.e., the part where it resolves a name in the context in the same way that an interpolation tag would.

Okay so I just need to describe the name resolution in the context.
I'm working on it!

gasche commented 2 years ago

Is there a strong reason for using {{*foo}} instead of the alternative proposal: {{>*foo}}? I find the latter clearer (it's easier to guess what it does, or at least to get some idea), it could be extended to other forms if there was a clear case for it (possibly {{<*foo}} for example?), and it has the advantage of preserving the "syntactic space" of the main symbol for other usages if we wanted to.

ghost commented 2 years ago

Is there a strong reason for using {{*foo}} instead of the alternative proposal: {{>*foo}}?

The main reason was to keep the language simple and not introducing a general deference operator.
Take also look at this comment https://github.com/mustache/spec/issues/54#issuecomment-986413726
@jgonggrijp I think that active maintainers (like you, bobthecow and the others with more experience with mustache) should discuss or take poll in order to make a decision before we continue working on this PR.

Here I wrote a brief list of both options' pros and cons.
By one side I am intrigued by general dereference, it would make the language complete.
By the other side though I feel like it's unnecessary and too complex.

New general dereference operator

Pros:

Cons:

Dynamic partials

Pros:

Cons:

What do you think?

gasche commented 2 years ago

Note: I am not suggesting that this specification should add support for {{#*foo}}, {{<*foo}}, etc. I understand that the proposal is limited to dynamic partials. But even if we restrict it to dynamic partials, the syntax could use {{>*foo}} instead of {{*foo}}, and I am asking why we would want to prefer {{*foo}}.

jgonggrijp commented 2 years ago

@gasche

My reasons for not wanting to have a general purpose dereference operator can be found here and here. Whether you find them strong is up to you. :-)

I think there doesn't need to be a dynamic parent because dynamic partials and parents are mostly alternatives; the former enable polymorphism through a tagged union like construct while the latter enable polymorphism through an inheritance like construct. As for preserving the * sigil for possible other future purposes, that's a point I'll concede, although I think it fits this particular feature well.

(This post crossed the previous two.)

jgonggrijp commented 2 years ago

@anomal00us

Dynamic partials

(...)

Cons:

  • It's syntactically less consistent.

I don't think it's less consistent, just consistent in a different (and more limiting) way. It's perfectly consistent with the current practice of having a tag consisting of an opening delimiter, a single-character sigil, a content without much internal structure and finally a closing delimiter.

gasche commented 2 years ago

I think there doesn't need to be a dynamic parent because dynamic partials and parents are mostly alternatives; the former enable polymorphism through a tagged union like construct while the latter enable polymorphism through an inheritance like construct.

On the other hand, if you think of "parent templates" as "partials with parameters" (instead of an inheritance-like construct), then having those selected at runtime based on the data makes just as much sense as for partials.

Again: I'm not proposing this (or any other extension of the feature) for inclusion in the currently-proposed specification. But I see value in making a syntactic choice that leaves our options open in the future, if we found out that there are in fact valid use-cases (at acceptable complexity costs) for other forms of dynamic resolution.

jgonggrijp commented 2 years ago

@gasche I see your point, but I feel that {{>*dynamic.partial}} is a syntax we should avoid unless we also allow {{$*dynamic.block}} and {{#*dynamic.section}}. Allowing only the former would make a really inconsistent situation. It would also require overhauling an implementation to the point where you may just as well implement the general purpose dereference right away (at least, that is true of my own implementation).

As far as I'm concerned, there are only three flavors possible:

  1. no dynamic partials in any form;
  2. a dedicated sigil (such as *) that is yet another flavor of partial (note that < and $ are special flavors of partials, too);
  3. a general purpose dereference operator that is allowed in all tags.

Number 3. would be a severely breaking change requiring a major version upgrade. Also, I would not want to use or implement such a Mustache 2.0 myself.

In my opinion, number 2. is not a very strange thing to do. Partials are a powerful and versatile language feature, so it makes sense to dedicate a relatively large share of the sigils to them. Consider also https://github.com/mustache/spec/issues/63#issuecomment-985048166 and my immediate follow-up comment, which would introduce : as a dedicated sigil for yet another flavor of partial.

Number 1. would be a bit disappointing in my opinion, but not as disappointing as number 3.

ghost commented 2 years ago

But I see value in making a syntactic choice that leaves our options open in the future

I think that we have to decide this now, once for all.
The problem with >* syntax in this proposal is that >* has to be treated as a single token and many mustache implementations will have to rewrite parts of the tokenizer (like this https://github.com/bobthecow/mustache.php/blob/db2bc776c4d01665eb9b7e0e3259b0b9a2d20e84/src/Mustache/Tokenizer.php#L136 @bobthecow ) in order to support the only 2 characters long token prefix.
On the other side, if we go for a single character syntax then if in the future general dereferencing will be implemented we will have a redundancy (being the composition of > and the dereferencing tag)

jgonggrijp commented 2 years ago

@gasche As for parents as "partials with parameters": I subscribe to that way of thinking, but even when you think of it that way, dynamic partials are also an alternative way of passing parameters. You can replace parents and blocks entirely by dynamically resolved non-parametric partials, if you are happy with the inversion of control. Which you must be in order to want to use dynamic partials in the first place.

@anomal00us I think you make a valid point that if we do a dedicated * sigil in an optional extension to Mustache 1.x, this wouldn't stop us from introducing a general purpose * dereference operator in Mustache 2.x. A major version upgrade is going to be a breaking change anyway. Although, again, I wouldn't like to go there myself.

ghost commented 2 years ago

[ ] I'd like to see at least one other implementation that passes the proposed spec (at least mostly, with a motivation for any omissions). If I'm right, you already implemented this feature yourself, so this point might be easy to address.

At the moment my implementation isn't really compliant to mustache standards, regarding whitespaces and names (dotted names and objects) resolution, but for the rest it isn't that bad.
Here if you want to take a look for the dynamic partials: https://pastebin.com/ugk3BsEp

gasche commented 2 years ago

@jgonggrijp

dynamic partials are also an alternative way of passing parameters. You can replace parents and blocks entirely by dynamically resolved non-parametric partials, if you are happy with the inversion of control.

I'm not sure I see what you have in mind, can you show a sketch of the translation?

Allowing only the former would make a really inconsistent situation.

Personally I think that the situation would not be any worse than with the {{*foo}} syntax: the fact of the matter is that, with this specification, only >-style partials can be dynamically resolved. So we have ad-hoc support for dynamic resolution of one form only. Whether the syntax is ad-hoc or more regular does not change this. Personally I am fine with the ad-hoc-ness of it ("we only had clear use-cases for this one"), but I would prefer having a regular syntax, because I think it reads better -- it is easier for users to make a guess at what it does.

ghost commented 2 years ago

A major version upgrade is going to be a breaking change anyway.

Isn't it better if we plan things well now in order to have less breaking changes? Anyway is there a timeline/planning or something for version 2?

bobthecow commented 2 years ago

Number 3. would be a severely breaking change requiring a major version upgrade.

IMO, neither {{>*foo}} nor {{*foo}} requires a major version upgrade if (1) they're implemented as optional, like lambdas, and (2) they're toggled via pragmas or library flags.

I believe the main concern is whether *foo collides with valid tag names in the rendering context. It collides just as much with a variable (in the {{*foo}} case) as a partial tag (in the {{>*foo}} case) so if one requires a major version, both do.

The problem with >* syntax in this proposal is that >* has to be treated as a single token and many mustache implementations will have to rewrite parts of the tokenizer

I haven't tried it yet, but I imagine it wouldn't be a two-character sigil; I'd implement it as a general purpose dereference operator, restricted to only work inside partial tags. It'd require another couple of transitions in the tokenizer state machine, but no more weird than, e.g., supporting the triple-mustache alt for &.

bobthecow commented 2 years ago

To limit the slipperiness of this slope, I'd be perfectly happy limiting it to a single dereference, which applies to the (resolved) dotted tag name in its entirety. So:

  1. {{*foo.bar.baz}} resolves as {{ dereference(foo.bar.baz) }},
  2. {{*foo | *bar}}, resolves as {{ dereference(bar)(dereference(foo)) }}, and
  3. {{**foo}} and {{*foo.*bar}} are syntax errors.
ghost commented 2 years ago

I haven't tried it yet, but I imagine it wouldn't be a two-character sigil; I'd implement it as a general purpose dereference operator, restricted to only work inside partial tags.

Makes more sense yeah.
So if >* is just a combination of the partial operator > and the dereference operator * , should we update/close this PR and write a spec for the dereference operator?

bobthecow commented 2 years ago

This is my opinion but I think we're far from consensus still 😛

jgonggrijp commented 2 years ago

@anomal00us

At the moment my implementation isn't really compliant to mustache standards, regarding whitespaces and names (dotted names and objects) resolution, but for the rest it isn't that bad. Here if you want to take a look for the dynamic partials: https://pastebin.com/ugk3BsEp

Thanks. To guide my reading, could you mention the line numbers that specifically address dynamic partials?

jgonggrijp commented 2 years ago

@gasche

dynamic partials are also an alternative way of passing parameters. You can replace parents and blocks entirely by dynamically resolved non-parametric partials, if you are happy with the inversion of control.

I'm not sure I see what you have in mind, can you show a sketch of the translation?

Inheritance:

{{!parent.mustache}}
Hello, {{$block}}colleague{{/block}}.

{{!child.mustache}}
{{<parent}}{{$block}}friend{{/block}}{{/parent}}

Dynamic partials, same result:

{
    "relation": "job",
    "greet": "parent",
    "informal": {
        "relation": "social"
    }
}
{{!parent.mustache}}
Hello, {{*relation}}.

{{!child.mustache}}
{{#informal}}{{*greeting}}{{/informal}}

{{!job.mustache}}
colleague

{{!social.mustache}}
friend
ghost commented 2 years ago

Thanks. To guide my reading, could you mention the line numbers that specifically address dynamic partials?

Sure!
Lines 443-471 are the lines which "compile" partials and dynamic partials into code.
Dynamic partials differ by normal partials only by this line (457): $value = $args[$value];, which resolves the reference in the data.
Then, once the script has the partial name in $value it proceeds to load it, compile it and link it to the current template.

So it's pretty simple since it doesn't really handle complex objects.

For being even more clear here's a more detailed example: Let's say a template is like this: {{*dynamic}}

// These are the arguments we render the partial with.
$args = array("dynamic" => "mainpage");

// This is the abstract syntax tree generated by the parser.
// I don't resolve constants for being more clear
$AST = array(
  0 => array(
    self::AST_TYPE = > self::TOKEN_TYPE_DYNAMIC_PARTIAL,
    self::AST_VALUE => "dynamic"
));

// When the compiler translates the AST into code, 
// we enter a the for loop on line 371 and at some point we will have
// $value = $AST[$i][self::AST_VALUE]; // = "dynamic"

// Now it should be more clear how this line resolves the reference
$value = $args[$value]; // = $args["dynamic"] = "mainpage"
jgonggrijp commented 2 years ago

@bobthecow

Number 3. would be a severely breaking change requiring a major version upgrade.

IMO, neither {{>*foo}} nor {{*foo}} requires a major version upgrade if (1) they're implemented as optional, like lambdas, and (2) they're toggled via pragmas or library flags.

I believe the main concern is whether *foo collides with valid tag names in the rendering context. It collides just as much with a variable (in the {{*foo}} case) as a partial tag (in the {{>*foo}} case) so if one requires a major version, both do.

Good point, agreed.

To limit the slipperiness of this slope, I'd be perfectly happy limiting it to a single dereference, which applies to the (resolved) dotted tag name in its entirety. So:

  1. {{*foo.bar.baz}} resolves as {{ dereference(foo.bar.baz) }},
  2. {{*foo | *bar}}, resolves as {{ dereference(bar)(dereference(foo)) }}, and
  3. {{**foo}} and {{*foo.*bar}} are syntax errors.

It's ironic how you suggest restricting the dereference operator to a single level in order to limit the slipperiness of the slope, and immediately follow up by illustrating exactly what I'm worried about, i.e., more complexity inside the tag content in the form of a pipe operator. It reminds me of filters in Jinja and several other templating languages. I presume your implementation already supports that notation.

Even if we're only adding a single-level dereference operator now, it will set a precedent for people to want to add other notational refinements to the tag content. Your pipe operator might be a likely candidate. I could also think of direct arguments like in Handlebars helpers, or perhaps case modifiers. I'm not opposed to people adding such extensions to their own implementations, but if we start adding them to the spec, I feel that Mustache is giving up its logic-less soul. I feel that the extremely minimal syntax is what distinguishes Mustache from other template languages in the first place.

That doesn't mean that I want to limit the functionality of the language; I just want to uphold the clean, logic-less syntax. Filters, case modifiers, and even dereference operations could all also be achieved by making lambdas just slightly more powerful. All it requires is to pass a second argument to lambdas that accept it, containing the full context stack. This is an extension I've actually been meaning to suggest for a while; I'd call it "power lambdas". We don't need to discuss that now, though; I'm just pointing out that complicating tag contents is not the only way to make the language (even) more powerful.

Long story short: I don't mind if people add support for expression inside tag contents to their own implementations, but please let's keep them out of the spec. If that means that we don't specifiy any way to do dynamic partials, so be it.

bobthecow commented 2 years ago

It's ironic how you suggest restricting the dereference operator to a single level in order to limit the slipperiness of the slope, and immediately follow up by illustrating exactly what I'm worried about, i.e., more complexity inside the tag content in the form of a pipe operator. It reminds me of filters in Jinja and several other templating languages. I presume your implementation already supports that notation.

Right, sorry, I wasn't suggesting that this proposal include that feature, I was illustrating how that same principle would work in a feature (filters / pipe operators) which is an extension already present in some mustache implementations. Happy to remove that example if it makes things clearer 😛

ghost commented 2 years ago

Dereferencing would be a really nice thing to have.

I rewrote part of my script to see how it would look with a general dereference "operator".
On line 382 you can see how references are resolved (with only one dereferencing level) for all tokens: https://pastebin.com/SXiqNwB0 In this way we can have, as discussed earlier:

{{>*dynamic}}
{{*var}}

I thought it would have been worse. What do you think?

jgonggrijp commented 2 years ago

@bobthecow

Right, sorry, I wasn't suggesting that this proposal include that feature, I was illustrating how that same principle would work in a feature (filters / pipe operators) which is an extension already present in some mustache implementations. Happy to remove that example if it makes things clearer 😛

Please don't. :-) I understand that you didn't mean to suggest filter syntax, so you don't need to change your post. In fact, it perfectly illustrates how one operator can bring other in-tag expression syntax to mind. I'm just talking about associations here, and what they might do to future spec developments - if it crosses your mind now, it will cross other people's minds later as well.

jgonggrijp commented 2 years ago

@anomal00us

Dereferencing would be a really nice thing to have.

Agreed.

I rewrote part of my script to see how it would look with a general dereference "operator". On line 382 you can see how references are resolved (with only one dereferencing level) for all tokens: https://pastebin.com/SXiqNwB0 In this way we can have, as discussed earlier:

{{>*dynamic}}
{{*var}}

I thought it would have been worse. What do you think?

I understand. To be honest, I already realized that this particular operator wouldn't be so hard to implement, especially if restricted to a single level, since it relies on the name resolution algorithm that we need for interpolation and sections anyway. It's not a big difference whether you apply it in one special-purpose dynamic partial tag, or add support for it to all tags. @gasche and @bobthecow also made valid points that it's basically the same from a specification compatibility point of view.

I just don't want to set a precedent for adding expression syntax to tag contents. But I'm afraid I'm the only one holding this opinion. Am I?

bobthecow commented 2 years ago

I just don't want to set a precedent for adding expression syntax to tag contents. But I'm afraid I'm the only one holding this opinion. Am I?

I don't think of this as adding expression syntax to tag contents, per se. It feels kind of like the & tag to me. It's a variant on an existing tag.

I'm generally against string literals, brackets, parentheses, nested mustaches, etc, as a matter of principle, but this one thing seems like an elegant way of solving some common user needs without introducing "logic". There's no way to extend this beyond the basic set of combinations:

We could do all of this by doubling the number of single-character tag sigils we use, and have a bunch of "like X but dynamic" tags, but that seems both more confusing to users and wasteful of the few typeable ASCII characters we have at our disposal 😛

ghost commented 2 years ago

I just don't want to set a precedent for adding expression syntax to tag contents. But I'm afraid I'm the only one holding this opinion. Am I?

In my opinion this isn't going to be a precedent for adding expression syntax to tag contents because as far as we go (like, even if we allow multiple dereferences **var ****var) this proposal isn't really changing the "core" logic of the tags: it's just dereferencing data for then using it like it would have done without the dereference operator.
Instead the thing that seems to be adding the expression syntax to the tokens is rather the pipe/filter | operator, isn't it?

Also, the dereferencing operator in some use cases may replace the behaviour of the lambdas ( for example for dynamic partials loading ) and I think that this takes out even more logic from the template, which is nice for a logic-less engine.

Maybe we should define what we intend with logic and expressions.

ghost commented 2 years ago

and have a bunch of "like X but dynamic"

What if we keep the * operator in the token name/value and resolve it at compile time?

bobthecow commented 2 years ago

What if we keep the * operator in the token name/value and resolve it at compile time?

I don't think the spec should require one way or the other. I plan to implement it at parse/compile time (similar to what I do with dot notation), but it should be just as viable to deal with it during context lookup at runtime. Also some mustaches only have a runtime implementation ¯\_(ツ)_/¯

jgonggrijp commented 2 years ago

@bobthecow

I don't think of this as adding expression syntax to tag contents, per se. It feels kind of like the & tag to me. It's a variant on an existing tag.

I'm generally against string literals, brackets, parentheses, nested mustaches, etc, as a matter of principle, but this one thing seems like an elegant way of solving some common user needs without introducing "logic". There's no way to extend this beyond the basic set of combinations:

  • {{ a }} → {{ *a }} (and {{{ b }}} → {{{ *b }}}, and {{& c }} → {{& *c }})
  • {{# d }} → {{# *d }}
  • {{^ e }} → {{^ *e }}
  • {{> f }} → {{> *f }}
  • {{< g }} → {{< *g }}
  • {{$ h }} → {{$ *h }}

We could do all of this by doubling the number of single-character tag sigils we use, and have a bunch of "like X but dynamic" tags, but that seems both more confusing to users and wasteful of the few typeable ASCII characters we have at our disposal 😛

I see what you mean. I don't think a dereferenced name makes sense for every tag type (consider dynamic blocks - I doubt there is a sensible use case for that), but I'll readily concede that it could make sense for parents and possibly some future tags as well. So that would still support using {{>*}} instead of {{*}} for economy, as you're describing.

To further counter my own argument so far, it could also be argued that dotted names are already a form of expression syntax that is supported inside tag contents. They only have a special meaning inside interpolation, section and inverted section tags, similar to how the dereference operator might only carry special meaning inside a subset of tags.

Alright, I'm nearly convinced. I take your word that you (and @anomal00us and probably @gasche) don't want to set a precedent for introducing tag-internal expressions, but I still worry a bit about other people in the future. Perhaps a solution is to indeed restrict the tags in which the dereference is possible, so that it is clear that it should be considered a special form. How about only allowing it in partials and parents?

{
    "key": "name",
    "name": "John"
}
{{*key}} could simply be {{name}}
{{!parent.mustache}}
I'm {{$title}}Darth{{/title}} {{$name}}Vader{{/name}}.

{{!child.mustache}}
{{!hmm... which block will we override today?}}
{{<parent}}{{$*override}}Professor{{/*override}}{{/parent}}

{{!or even this:}}

{{!parent.mustache}}
{{!hmm... what name will child templates have to pass in order to override the next block?}}
Hello {{$*parameter}}there{{/*parameter}}.
{{!template.mustache}}
{{<*animal}}{{$sound}}grunt{{/sound}}{{/*animal}}

{{!cow.mustache}}
Cow goes {{$sound}}moo{{/sound}}.

{{!chicken.mustache}}
Chicken goes {{$sound}}bok{{/sound}}.

@anomal00us

Maybe we should define what we intend with logic and expressions.

Perhaps, but at this point, in order to reassure me, it might already be sufficient to just agree on what we're going to say when people start asking for pipes/filters or other tag content expression syntax in the future. If we can agree to restrict the dereference notation to only partials and parents, maybe even that isn't necessary.

Ironically, @gasche already suggested restricting the {{>*}} notation to partials at the start of the discussion. Sorry for not seeing your point back then, @gasche. I needed more time to adjust my viewpoint.

bobthecow commented 2 years ago

I think as long as it's spec'd as "partials tags support dereferencing", similar to the way it's "sections and interpolation support dots" it's not a problem to limit it to just partials. I'd want to explicitly include both {{>*foo}} and {{<*foo}}, because it'd feel inconsistent if they both didn't support it, but I don't think we need to extend it to any other tags for the purposes of this spec. I just don't want to preclude ourselves from doing that in the future with the way we frame what's happening in a dynamic partials tag, if that makes sense.

bobthecow commented 2 years ago

All that said, I've definitely seen people asking for dereferencing with interpolation as well. Two examples I found with a quick search:

That's not to say we should make this PR depend on resolving those as well, just that in the past people have asked for it.

gasche commented 2 years ago

Perhaps a solution is to indeed restrict the tags in which the dereference is possible, so that it is clear that it should be considered a special form. How about only allowing it in partials and parents?

This aligns very well with what I had in mind when I proposed the {{>*foo}} syntax. (Having it just for partials would also work for me personally, but I certainly agree that parent are a natural cousin to also support.)

I think that the same criteria that are being used right now (is there a clear use-case that cannot be conveniently done in another way? is it hard to implement? does it make reasoning or implementation more difficult?) could be used to evaluate the idea of dynamic lookup for other forms, if the question arises in the future.

ghost commented 2 years ago

Perhaps, but at this point, in order to reassure me, it might already be sufficient to just agree on what we're going to say when people start asking for pipes/filters or other tag content expression syntax in the future.

For me the point we should stop is to introduce features that allow string/data manipulation within the tags.

I just don't want to preclude ourselves from doing that in the future with the way we frame what's happening in a dynamic partials tag, if that makes sense. I think that the same criteria that are being used right now (...) could be used to evaluate the idea of dynamic lookup for other forms, if the question arises in the future.

These are some good points.
So, since the discussion moved towards the general dereference operator, when we meet an agreement I think that we could close this PR and start working on a spec for the dereference operator.

gasche commented 2 years ago

when we meet an agreement I think that we could close this PR and start working on a spec for the dereference operator.

... or you could just keep the current spec proposal, make the syntax {{>*foo} instead of {{*foo}}, and explain that while this can be interpreted as a general dereference operation, this document only specifies its use for partials.

(Either would be fine, but that is less work, and it avoids the decision fatigue of how to frame the General Thing.)

jgonggrijp commented 2 years ago

@bobthecow

I think as long as it's spec'd as "partials tags support dereferencing", similar to the way it's "sections and interpolation support dots" it's not a problem to limit it to just partials.

I like this suggestion.

@gasche

Perhaps a solution is to indeed restrict the tags in which the dereference is possible, so that it is clear that it should be considered a special form. How about only allowing it in partials and parents?

This aligns very well with what I had in mind when I proposed the {{>*foo}} syntax. (Having it just for partials would also work for me personally, but I certainly agree that parent are a natural cousin to also support.)

Yes, I remembered that when I wrote the quoted line. I also acknowledged it in the same post, but that was all the way at the bottom.

I think that the same criteria that are being used right now (is there a clear use-case that cannot be conveniently done in another way? is it hard to implement? does it make reasoning or implementation more difficult?) could be used to evaluate the idea of dynamic lookup for other forms, if the question arises in the future.

Straightforward and sensible. As always!

@anomal00us

For me the point we should stop is to introduce features that allow string/data manipulation within the tags.

Certainly also something I agree with.

(...) So, since the discussion moved towards the general dereference operator, when we meet an agreement I think that we could close this PR and start working on a spec for the dereference operator.

Please keep it within the same PR. It's just a syntax change, and you might add a few specs for parents, but otherwise it's still largely the same proposal (with the same ongoing review). Don't worry about features you haven't implemented yourself; @bobthecow, @gasche and I all have implementations that we can probably test with.

@gasche

(...) and explain that while this can be interpreted as a general dereference operation, this document only specifies its use for partials.

I'd prefer not including such a remark. Better to frame it the way @bobthecow did, as I quoted at the top of this comment.

ghost commented 2 years ago

and explain that while this can be interpreted as a general dereference operation, this document only specifies its use for partials.

This could work. My main doubt it's whether we should do instead a spec for the general dereference op. and stating in that its limited use-case, rather than a specific spec announcing a general dereference operator with limited use-case.
The latter seems to be more clear in my opinion.

Please keep it within the same PR. It's just a syntax change, and you might add a few specs for parents, but otherwise it's still largely the same proposal (with the same ongoing review).

Oh, okay, soon I'll update the pull request with the new syntax.

ghost commented 2 years ago

Oh, okay, soon I'll update the pull request with the new syntax.

I'm not sure how should I do it.
Maybe I should change partials.yml and add some examples and statements about the support of the dereference operator.
Having ~dynamic-partials.yml just feels wrong. What do you think?

bobthecow commented 2 years ago

because it's an optional portion of the spec it needs to be in a ~ file. ~dynamic-partials.yml feels like it's the best answer?

jgonggrijp commented 2 years ago

@anomal00us To answer your other question, you can just copy a few tests from ~inheritance.yml and adjust them to use {{<* instead of {{<. Parents are very similar to partials.

Alternatively, don't even include tests for parents. Just mention that the dereference operator may also be supported for parents in implementation that support the inheritance spec.

bobthecow commented 2 years ago

i think testing the permutations of optional specs is going to be a problem. ~dynamic-inheritance.yml? if/when we add dereferencing for variables, how does it interact with lambdas? ~dynamic-lambdas.yml? though i guess we don't have the intersection of "lambdas" and "inheritance" currently?

ghost commented 2 years ago

can just copy a few tests from ~inheritance.yml and adjust them to use {{<* instead of {{<.

And put it into ~dynamic-partials.yml? Wouldn't this be too out of scope?

i think testing the permutations of optional specs is going to be a problem. ~dynamic-inheritance.yml?

Yeah, that's why I was suggesting to work on a more general ~dereference.yml rather than ~dynamic-inheritance.yml.

jgonggrijp commented 2 years ago

Yes, permutations are a problem. The good news is that implementations can choose to support optional specs only partially.

A good approach may be to group optional specs by a common dimension. That would support a ~dereference.yml as @anomal00us is suggesting. Alternatively, you could name it ~dynamic.yml, which ironically is what you started out with (but optional). I like that name more.

bobthecow commented 2 years ago

~splat.yml

bobthecow commented 2 years ago

Maybe ~dynamic-tags.yml, or ~dynamic-names.yml? Describe the lookup, rather than what it's used for?

jgonggrijp commented 2 years ago

~dynamic-names.yml works for me, too. Analogous to "dotted names".

ghost commented 2 years ago

( I didn't forgot about this, I'm just really really busy at the moment: as soon as I'll finish my exams I'll update everything! )

jgonggrijp commented 2 years ago

@anomal00us Did you finish your exams?

ghost commented 2 years ago

Yeah, I did finish now... it was a pretty though period :/ I'm really sorry for being so late.
Anyway I rewrote the specification for dynamic names, I need a review.
I was wondering whether we should write more examples for all the other tags combinations, what do you think?

Also thank you to @nminet for pointing out that string problem, I have solved it in my latest commit.