-
Notifications
You must be signed in to change notification settings - Fork 3.4k
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
Collector variable structure if only one or zero arguments are collected #1943
Comments
It definitely looks wrong now. Expected output looks ok to me - more workable and would only effect js eval right? Do it in 2.0? |
I looked at this. The issue is that both expression and value make no difference between list with one member and a single non-list value. No matter what context, expression treats one member list as a single value. So, if we would fix this, it would influence more then just javascript evaluation. For example this:
now evaluates into:
but would evaluate into:
I would fix this by making difference between one member list and single value in expression and value (if no one objects). |
The only problem I see is that how this will work then with a code like this:
If I understand it right, with these changes the above example will require an Related to #1576. |
I do not think about this as being js friendly/unfriendly, that is just the context where I found that. To your example, Imagine that you would want modify your mixin to work with lists instead of numbers and generate box-shadow:
This compiles into:
After would compile into:
If you have a mixin that takes list of lists [[a b][c d]], the mixin works only if outer list has at least two members. If the outer list contains only one list inside [[a b]], then it becomes indistinguishable from list of values [a b]. |
Btw, the above is made up example, not something I would need. My only goal is to close this issue one way (wont fix) or the other (fix it). I have time for bug fixing now, so I want to fix as many bugs as possible (while I remember how less.js works). |
Yes, but the length of
Yes, this is an issue too. Curiously I face it quite often myself recently. The trick I use for such cases: .mixin(@args) {
box-shadow+: @args black;
}
.mixin(@args...) when (default()) {
.-(length(@args));
.-(@i) when (@i > 0) {
.-((@i - 1));
.mixin(extract(@args, @i));
}
}
a {
.mixin(10px 10px);
}
b {
.mixin(10px 10px, -20px -20px);
} which is not so quite evident on its own of course (So, yep, there's complication price for not distinguishing Thinking of it more, I guess I'll support the proposed changes (I'm afraid they seem to be unavoidable anyway as we'll have all this "working with arrays/lists code" growing). So the only thing to keep in mind that these are breaking changes for certain "pure Less code" snippets too (I'm afraid I've already propagated a couple of such snippets at the SO already :( |
I think it makes sense to make the change.. but I'm scared it requires a major version update since it is a breaking change.. |
Stuff like this worries me:
... because such complication always seems to me to be an indication of a syntax hole. Just like mixin libraries using JavaScript. It seems like what's missing in this example (but correct me if I'm wrong) is not necessarily a way to distinguish list types and iterate through like a function, but a way to bind a list to a mixin, declaratively. Something like:
And, for @seven-phases-max:
That requires no complex I'm not sure if the mixin name seems more intuitive as the first value or the last value or which order would be more CSS-like. But something like this should work. Does it omit any common use case? |
Oh, and obviously, that means you could pass a variable into a mixin without knowing if the variable is a list or not.
|
Well, just FYI in my real code this stuff looks like this:
so you can have syntactic sugar if you want. |
It makes sense to me to have a native |
Moved my comment about loops to the gist to not clutter this issue with unrelated stuff. |
Well, as far as method of implementation, that doesn't seem so important to me, so much as getting rid of the more complex Less code or JavaScript shims required for some functionality. Do you think |
Yep. For instance it does not help you to write the loop body directly w/o a dedicated mixin which makes it even more verbose for basic loops (example in my gist above). Besides it really just encodes only one pattern (even if it's the most used one) - so if I will need to loop through an array in reverse will I have to propose |
Why would you need to loop through an array in reverse? I mean, in terms of CSS properties? I can see modification of items on the list for output, but I can't think of a scenario where someone would be inputting a list in the reverse from what the CSS value required. And in general, I feel the same about any looping using Less: if it is the only way to solve a common use case, to me it indicates a syntax hole. The fact that you can use a loop in Less to solve a problem doesn't indicate to me that a problem has been (elegantly) solved, just that there's a possible workaround. A loop is trivial for programmers, but it's a way more complex concept for a designer who knows CSS but has never coded, especially the way they're typically implemented in Less. A Less loop is probably the most complex Less code that someone new to Less would encounter. So, I've long been on the lookout for something simpler in concept. If there are multiple simpler somethings to replace a loop structure, that seems fine, if it makes the language and concepts more accessible. The avoidance of complex programming structures is one of the advantages Less has over Sass. It's a lot more accessible for people of different backgrounds. |
And that's why we have
But as soon as you have to introduce some
? (and this is already currently available syntax, so this looks more like a matter of "standard library"/documentation stuff). |
@matthew-dean Don't you mind if I'll move our whole discussion to #2270? It would be really unfortunate to link to #1943 when the changes proposed here are implemented. |
That's fine. |
Correcting myself, actually it's not that dramatic as I thought above... .mixin(@args_...) {
@args: extract(args_, 1); // <- here's the trick
.-(length(@args));
.-(@i) when (@i > 0) {
.-((@i - 1));
padding+_: (extract(@args, @i) * 20);
}
}
a {
.mixin(1);
}
b {
.mixin(1 2 3 4);
} So no |
@seven-phases-max Does your last comment mean this can be closed? |
No, it's just I revoked my initial objections to the fix proposed by @SomMeri (toning it down from "very breaking" to just "subtly breaking"). But since the problem is pretty subtle itself (3 years of inactivity here) I guess it can be safely closed untill someone rises something like this again. |
By collector variables I mean either @arguments variable or any mixin parameter declared with
...
.If collector collected multiple values, then it contains a list. However, if it collected only on variable, then it does not contains a list. It contains that one variable. That makes it impossible to differentiate between these two things:
.mixin(1, 2, 3)
// three parameters.mixin(1, 2, 3;)
// one parameterFull test case:
current output:
Expected output:
Background: I was trying to find out how LessHat could work if we would fix #1939 (pull request #1941). Spaces/commas/argument separator difference is lost in less->js conversion. Which might be ok if would could partially deduce them from structure which is impossible.
LessHat current prints
@arguments
into string and then uses javascript to parse that string.The text was updated successfully, but these errors were encountered: