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

Allow identifiers to start with an uppercase letter #256

Open
cipriancraciun opened this issue Nov 19, 2024 · 8 comments
Open

Allow identifiers to start with an uppercase letter #256

cipriancraciun opened this issue Nov 19, 2024 · 8 comments

Comments

@cipriancraciun
Copy link
Contributor

As was suggested while discussing #244, I'm creating a new feature request to allow identifiers to start with an uppercase letter:

{% let X = 42 %}

This fails (both on Rinja and Askama) with the same error:

error: literals are not allowed on the left-hand side of an assignment

However, it is allowed by the Python Jinja2 code:

python -c 'import jinja2 ; jinja2.Environment().from_string("{% set X = 42 %}")'

Why might one want to use an identifier starting with an upper-case?

  • for example one could define either in partials either in base templates some constants (like colors, URLs, etc.) and thus, as per Rust and other languages conventions, such constants should be all uppercase (as in XXX_YYY_ZZZ);
  • (I'm certain there are many other use-cases that I'm not aware at the moment;)

Moreover, it would be nice (unless it conflicts with the Jinja syntax) that all Rust valid identifiers (as specified in https://doc.rust-lang.org/reference/identifiers.html) to be considered valid identifiers for let, for, match and other places where identifiers are to be used.

@Kijewski
Copy link
Collaborator

We use upper case characters to variables, and unit structs / unit enum variants apart. In this regard rust is context sensitive, we need to know what a name refers to. To keep things easy / manageable, we assume anything that contains an upper case character is not a variable.

It would be nice to have the same semantics as rust, but IMHO practicability beats completeness.

@cipriancraciun
Copy link
Contributor Author

[...] we assume anything that contains an upper case character is not a variable.

But the following, although it contains an upper case letter (but doesn't start with one) is accepted by both Askama and Rinja. Thus perhaps only the first letter must be lower?

{% let xX = 42 %}

In this regard Rust is context sensitive, we need to know what a name refers to. [...]

I didn't quite understand this: in Rust code, one can have variables starting with an upper case letter, or enum variants starting with a lower case one, and everything works just fine; thus the Rust language doesn't differentiate at all between upper case and lower case letters, and it's only a convention.

Granted, the Rust compiler is much more complex, and has much more context to decide if an identifier is a enum variant (i.e. Ok (42)) or just a function or closure (i.e. Nok (42) could be a function).


In the end, as long as it's documented, I believe having the limitation of variables needing to start with a lowercase letter is acceptable. (For example in Erlang and Prolog variables must always start with an uppercase letter.)

However, after the initial first letter (or _), the rest of the identifier shouldn't be case dependent.

@GuillaumeGomez
Copy link
Contributor

Do you have an example where there would be an ambiguity @Kijewski ?

@Kijewski
Copy link
Collaborator

Yes, None.

@GuillaumeGomez
Copy link
Contributor

Same issue with all unit struct. But I mean, in which expressions would this ambiguity be an issue?

@Kijewski
Copy link
Collaborator

How would we know what the users intends ↓ to do? Should we match on Option::None or capture into the variable None?

{% match var %}
  {% when Some(x) %}
    {% let y = None %}
    {# → let y = None #}
  {% when None %}
    {% let y = None %}
    {# → let y = &None #}
{% endmatch %}

Unless I'm altogether mistaken.

@Kijewski
Copy link
Collaborator

In the end, I don't care too much. If the tests pass, then I'm happy either way.

I just fear that this change could break things down the road if we notice that we have to undo the change. But a few unit tests could probably take away my fears. :)

@GuillaumeGomez
Copy link
Contributor

It's tricky indeed. But in case we already have a variable named Const (why? No clue, I don't judge), then next time we encounter a Const, we check if it's a variable and if not, then we don't put the reference? But it's some extra complexity in rinja templates, so not sure if worth it or not...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants