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

Discussion on Interpolation #13

Open
matthew-dean opened this issue Jan 31, 2016 · 6 comments
Open

Discussion on Interpolation #13

matthew-dean opened this issue Jan 31, 2016 · 6 comments

Comments

@matthew-dean
Copy link
Member

Related to #12. Moved from that issue:

For interpolators, I could see us doing one of two things:

  1. just use variable interpolation syntax for both:
.class@{#ns[@var]} { }

.class@{#ns[prop]} { }

...but that leaves a redundant @ in the first example:
2. Use a more generic interpolation syntax, such as borrowing from mustache: {{ }} (but could be another pair of something, if the language starts to look too curly-bracy. But used here just to demo concept)

.class{{#ns[@var]}} { }
.class{{#ns[prop]}} { }
// or for local
.class{{@var}} { }
.class{{$prop}} { }

Existing interpolation syntax (1) could be deprecated but still supported throughout 3.x.

For single property accessing, syntax doesn't need to change.

color: red;
border-color: $color;

One possible benefit of adopting a new interpolation syntax is that it doesn't need to just contain identifiers but could, like mustache, contain expressions:

.icon_{{ @startNum + @i + 1 }} { }

That's just a possible benefit, not a necessity.

Response from @seven-phases-max (which I agreed with):

As for the selector interpolation stuff, I would not take it so far yet. It's a big story on its own.
After all, the @{} syntax initially was invented for strings only, then when (~"@{var}") (almost accidentally) was found to also be usable in selectors, it was decided to be reduced to just @{var}.
The biggest problem with those curly braces in selectors is that they really make things harder to read because of the same symbol used for CSS {} block itself. So while @{} found its way to selector interpolation for some historical reasons, if we are about inventing a new syntax (especially if it's targeting for an arbitrary Less statements to appear there), the {{ }} is the last thing I'd vote for (ref.).

@calvinjuarez
Copy link
Member

calvinjuarez commented Apr 21, 2016

For this discussion, it might be useful to note the following:

  • ., #, |, ,, *, :, ,>,+,~,[, and] already have specific meaning in CSS Selectors.
  • { and } are ambiguous because CSS uses them to delimit the block, as was noted above.
  • $, ^, ~, |, and * are used in attribute selectors (the first 3 exclusively so in CSS).
    • $ is gonna be used for property reference.
    • ~ is also meaningful in Less at the moment.
  • " and ' are string delimiters in Less and CSS, and are allowed in attribute selectors.
  • @ is used for CSS At Rules and Less variables.
  • % is a Less function.
  • & has specific meaning in selectors for Less.
  • ! has (or will likely have) a specific function in CSS Selectors (not to mention strong connotations).
  • ` doesn't seem to have any specific meaning in either language, afaik.
  • / is for paths and the CSS Reference Combinator, \ is for escaping.

@calvinjuarez
Copy link
Member

calvinjuarez commented Apr 21, 2016

Note: The following is meant primarily as food for thought; I'm just spitballing.

>

Honestly, if a new syntax is required, it seems fairly safe to use <, since CSS probably won't be using it. > is the child selector, but because of how a selector's subject is determined, < won't likely be the parent selector. Instead, it's likely to be something like E! > F (or something similar; see http://www.w3.org/TR/selectors4/#subject).

The preferred use of < would be as a delimiter along with >, though, I imagine. And that starts to get ugly with the child selector:

.class< @var > > li,

Proper code coloring would probably make that conflict a non-issue, but you can't really guarantee proper coloring. Although, in that case, is it really much better than {}?

Examples

.class<@var>,
.class<$prop>,
.class<#ns[@var]>,
.class<#ns[$prop]>,
.class<.ns[ident]>,
.class<@ns[ident]>, {
  // ...
}

^

^ also seems fairly safe, though since it's not a delimiter-type character, it'd require more of a no-spaces syntax.

Examples

.class^@var,
.class^$prop,
.class^#ns[@var],
.class^#ns[$prop],
.class^.ns[ident],
.class^@ns[ident], {
  // ...
}

%

I personally like the idea of deprecating the format function %() (since it's a special, very short function name for what seems an uncommon function).

Doing so would allow using % as an interpolation signifier (and since there's technically no conflict, you could still leave the function functional). Since Less uses a modulo function rather than using % as the modulo operator, there's no conflict there.

I don't know if it would be best to use it just at the beginning, or at the beginning and end, though. Or whether even <%...%> might make sense.

Examples

.class%@var,
.class%$prop,
.class%#ns[@var],
.class%#ns[$prop],
.class%.ns[ident],
.class%@ns[ident], {
  // ...
}

@seven-phases-max
Copy link
Member

seven-phases-max commented Apr 21, 2016

.class<@var> looks fine for me - but (I guess) only because my eyes use to use C++ templates (#<@a>>.<@b>? :-/). Aside of that the more I think of the feature the more I doubt if the use-case is actually to appear often enough to deserve to pollute the language with a new operator(s). After all we also do not let functions, arithmetic expressions etc. and so on to be used directly within selector interpolation.
So if this important should not we instead invent a generic construction for all of these? i.e. "start any arbitrary expression here, end it here" instead of searching for (always artificial) marker/symbol for each specific feature. I.e. (intentionally using weird pseudo-syntax):

div.:expr(replace(extract(foo bar baz, #ns[offset] - 2), a, lu)) {
    // ...
}

After all, a minimal verbosity was never a goal of Less, and unconscious hunt for it would rather lead to a thing... like hmm... Perl.
(so leaving things as they are:

@name: replace(extract(foo bar baz, #ns[offset] - 2), a, lu);
div.@{name} {
    // ...
}

also does not look like a major fault).

@matthew-dean
Copy link
Member Author

Aside of that the more I think of the feature the more I doubt if the use-case is actually to appear often enough to deserve to pollute the language with a new operator(s)

I don't disagree with that. Or, at the least, the feature seems less of a priority to me than other 3.0 features, so that may already indicate that it doesn't have enough value to be added at this time. After all, it's not a requirement for namespacing. It's just that we addressed interpolation in the previous namespacing discussion, and the newer proposed syntax doesn't really gel with interpolation syntax. So, it's a little bit of a conflict, unless we simply require the author to assign a namespaced var to a local var, and use that with interpolation. Which is really not bad as an interim solution.

Just to prioritize other features, we could possibly shelve this for now and re-consider in the context of a future release? Or should we close entirely? What do you think?

@seven-phases-max
Copy link
Member

I think it's OK to leave it open, just to demonstrate that the feature is/was considered but w/o any solid outcome yet.

@matthew-dean matthew-dean changed the title Discussion on Interpolation for 3.0 Discussion on Interpolation Feb 11, 2018
@matthew-dean
Copy link
Member Author

matthew-dean commented Oct 7, 2019

Old thread, but what about just bringing in Sass's syntax for interpolation, where it can hold an expression? Basically, any place that can old an interpolated var can hold the interpolated expression. As in:

.class-@{var} { }
// and
.class-#{@var + 1} { }

In terms of parsing and evaluation, this would have very little overhead, as a single Less variable today can itself point to an operation. I would even suggest deprecating ${prop} and @{var} for #{prop} (or #{$prop}) and #{@var}, but allowing both to co-exist for 4.0.

There's no reason to re-invent the wheel here, and I see nothing inherently wrong / incompatible / problematic with Sass's interpolation syntax.

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

No branches or pull requests

3 participants