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

composes is the wrong word #24

Closed
lofye opened this issue Aug 19, 2015 · 27 comments
Closed

composes is the wrong word #24

lofye opened this issue Aug 19, 2015 · 27 comments

Comments

@lofye
Copy link

lofye commented Aug 19, 2015

"The composes keyword says that .normal includes all the styles from .common"
Great, except you have the meaning of the word reversed.
In the context above it actually means ".normal is part of .common", which is clearly not the intent.
If you wanted it to mean that ".normal includes all the styles from .common" then perhaps .normal should be "composedOf: common" or "comprises: common"

follow-up at: https://news.ycombinator.com/item?id=10084954

@bobwaycott
Copy link

I, too, scratched my head at the word choice here. A composes: keyword would more naturally be expected in the rule that is included in other rules. As it is, I read composes: and think the .normal class is composing or being included in the .common class.

This should be the behavior expected by the word choice, and would be easily understood at-a-glance:

.common {
  composes: normal, special, variant;
  /* common rules */
}
.normal {
  /* .normal-specific rules; .common rules included */
}
.special {
  /* .special-specific rules; .common rules included */
}
.variant {
  /* .variant-specific rules; .common rules included */
}

In addition to the sense of composedOf: as a better option, here are some additional keywords, in no particular order, that seem to better convey the meaning and intent, so one could easily grok the purpose & intent at-a-glance:

  • include:
  • includes:
  • including:
  • inherit:
  • inherits:
  • inheriting:
  • parent:
  • require:
  • requires:
  • requiring:
  • use:
  • uses:
  • using:
  • with:
  • contains:
  • childOf:
  • consistsOf:
  • buildsOn:

Fwiw, 'comprises' is quite a specific word with a stricter meaning than 'includes'--'comprises' means "these things are included and nothing else"; 'includes' is much looser, meaning "these things are included, but other things probably are, too".

In the context of CSS rules that can include multiple rules from multiple modules, I think 'comprise' would be too strict of a keyword, and would look pretty weird. Using your example from the blog post:

/* submit-button.css */
.common { /* font-sizes, padding, border-radius */ }
.normal {
  comprises: common;
  comprises: primary from "../shared/colors.css";
}

That just looks like too many comprises to me for a keyword that means "I'm the included thing and there's nothing else." Unless you could comma-separate the items after a single keyword use.

@nsisodiya
Copy link

composes is good choice . other choice can be mix

@nkbt
Copy link

nkbt commented Aug 19, 2015 via email

@andrantis
Copy link

+1 to "extends"

@sokra
Copy link
Member

sokra commented Aug 19, 2015

We initially named it extends, but now trying to avoid this, because it could be confused with the extend from other compile-to-css languages (i. e. less, stylus, etc.). (It works fundamental different)

Here is the discussion: https://gitter.im/css-modules/css-modules?at=5571479b463d0c7c066e23e3

@nkbt
Copy link

nkbt commented Aug 19, 2015 via email

@paulcsmith
Copy link

includes makes sense too. I think comprises is wordy and easy to mistype

@nkbt
Copy link

nkbt commented Aug 19, 2015

Not really

"It's a bit like @extends in SASS, except instead of altering the CSS to
add new selectors, it passes extra classes to your element"

@braco
Copy link

braco commented Aug 19, 2015

inherits, comprises, ...

I agree that compose is wrong.

@geelen
Copy link
Member

geelen commented Aug 20, 2015

It fits the implementation better than the way I've been describing it, actually. It's not that .normal includes the styles from .common, but that referencing normal gives you a new object with multiple classes, of which one is normal and one is common. So in a sense, the rules in normal and common compose this bigger entity.

At the level where you require it, you have a series of styles that is composed of the styles in normal, common and whatever else.

It's a little backwards, yeah, but I'm not super keen on the alternatives. Sass took the good names with @extends and @includes! And the way specificity follows source order not order-of-inclusion means it definitely doesn't work like Sass's @includes.

@lofye
Copy link
Author

lofye commented Aug 26, 2015

you just said it yourself ^ "is composed of the styles in normal, common and whatever else".
composedOf (is made up of X, Y, Z) has the opposite meaning of composes (is a part of W).
composedOf is a bigger thing.
composes is a smaller thing.

@NekR
Copy link

NekR commented Aug 26, 2015

For me, use or variants of it seems more comfortable, but maybe it's just me. Although I am perfectly okay with current name since it's just name, but use also could make sense like "use other classes with this class" or "this class uses other classes".
Also interesting thing is that using "common" name might not be a good idea since we cannot know what will be later added in CSS spec, so it makes sense to use name with a little prefix (-composes: foo from 'bar', just example), but yeah, it looks a bit weird.

@geelen
Copy link
Member

geelen commented Aug 29, 2015

So I've been thinking about this a bit, and the best I can come up with is a wiktionary link that includes:

  1. (transitive, nonstandard) To comprise.

I think there's something weird going on with this word in english right now. I think comprise is falling out of use and compose is going to end up being its own inverse. So we're pretty forward-thinking!

I also like this one:

  1. To arrange in proper form; to reduce to order; to put in proper state or condition.

I also don't mind inherit these days, but everyone knows composition is better than inheritance 😜

@nkbt
Copy link

nkbt commented Aug 29, 2015

@geelen as @NekR suggested, adding dash-prefix would solve compatibility issue, so then you could use either word: -css-modules-import: test from "./test.css" or -import: test from "./test.css" or whatever word looks nice. Even composes itself. Using vendor prefix would eliminate potential compat issues in future.

@olegstepura
Copy link

is import: really reserved is CSS? I know @import is.

I really like this: import: test from "./test.css".

@bobwaycott
Copy link

@geelen I think you're grasping at straws here to defend a poor choice.

There is nothing weird going on with the word "composes" in English right now. This is not forward-thinking at all. Your wiktionary offering states that fact explicitly. And when that's the best you can come up with, that should be screaming alarm bells that the choice is demonstrably poor. In attempting to defend the keyword choice, you seem to be missing what the definitions of the word, even as offered by wiktionary, actually mean.

transitive, nonstandard

That using "compose" to mean "to comprise" is nonstandard means it is not conforming to the language as accepted by the majority of its speakers.

composes is the third-person singular simple present indicative form of compose. The indicative is for telling what is happening, what happened, and what will happen. It gives facts.

Your use of composes in the inheriting object is saying this child puts its parent in the proper condition. But that's not at all what is happening. Instead, the parent is putting the child in order, by ensuring that the child is composed of the parents attributes. Except even that isn't what's technically happening, as you've stated in other comments in this issue and the one you linked. What you've said is happening (in the other issue) is that the classes declared in the composes property are included directly on the element in advance of the current selector so the current selector can cleanly override, not that the rules are being inherited and included into the given selector's ruleset. (Of course, you haven't done a very good job of explaining and resolving the confusion, so I could be misunderstanding still; that's what it sounds like given your explanations so far. If composes is really indicating a set of classes that the object class is overriding, overrides: would probably be the clearest term that immediately tells users what they're doing.)

Let's take it out of the context of this keyword that you have such a strong attachment to, and use it in a few humorous, yet homologous examples:

Jack sings a song.
Aliens will be unable to breathe our air.
The dog is eating steak.

This is the indicative. It properly conveys its meaning. What you're doing with the usage of composes on the object of composition is saying this, instead:

A song sings Jack.
Our air will be unable to breathe aliens.
Steak is eating the dog.

Language-wise, this issue has become amusingly absurd. composes is simply a poor choice, probably a result of a simple misunderstanding when the choice was made. That you're digging in your heels and offering continued defense with even worse arguments, instead of recognizing a simple language mistake and conceding that it was a poor choice--even if it is difficult or not easy to correct at this point--seriously puts me off trusting that CSS Modules doesn't have other serious code smells based in incorrectly choosing terminology that is going to lead to significant confusion in the future.

If the heart of the issue is that you chose the term and are married to it, confusion be damned, why not just say so?

If the real problem is that changing this keyword would be a significant and non-trivial, backward-incompatible, breaking change to CSS Modules, even that would be easy to understand.

However, continuing to reach for increasingly weaker defenses of a poor word choice that has users confused about what it means when they use it in their projects is very poor form.

You misunderstood (or continue to misunderstand) what composes means. Not a big deal. Several people have offered quite thoughtful and valid explanation for why this is a mistake. Why not allow your position to be changed by thorough evidence proving the alternate position correct?

@geelen
Copy link
Member

geelen commented Sep 5, 2015

Holy wall-of-text batman!

First up, the word nonstandard in the definition means this usage has been observed by native speakers but isn't accepted by native speakers as a whole. That's exactly what we're talking about here. The current usage makes perfect sense to me, but reads totally backwards to other native speakers. It isn't about misunderstanding the term, it's about language adapting to fill holes when low-frequency words (in this case "comprises") fall out of usage. Given that only a small proportion of people have raised the issue, and none of us thought it incorrect at the time of coining, that's what I do think is happening here.

But linguistic curiosities aside, there's clearly a problem with communication. Not the use of the word per se, but the whole concept. The number of "why doesn't composes work in situation X" issues, as well as the people adding their thoughts here, we're clearly not explaining the mechanism well enough. Because as @NekR said "it's just a name", once the mechanism becomes clear, it becomes simply a token by which you invoke the mechanism.

Personally, I'd prefer include, since that's a better description of the mechanism, but for anyone who understands @include in Sass (which is going to be a lot of our audience), that's immediately misleading. Semantically, composes is more similar to @extends in Sass, but works totally differently, hence why we changed it.

So it's not a matter of not wanting to "correct" it, it's trivial to change. It's just a word. We changed it once already. I resent the accusation that we're somehow digging in our heels because we didn't understand the language. We're looking for the highest signal-to-noise term, and right now using a term that lets us speak to composition of styling (over extension, inheritance, overriding or duplication) is the best we have, even if, for some English speakers, trying to read .foo { composes: bar; } as a sentence sounds backwards.

So that's what I'm looking for. I appreciate all the suggestions in this thread but I really don't feel like any of them better capture the mechanism, without having existing meaning in the CSS/Sass world.

@bobwaycott
Copy link

Sometimes adequately explaining oneself and helping move a conversation forward requires more than a couple sentences. Here's a bigger wall of text. Read at your peril. We might accomplish understanding. Or something. I'll even include headers so you can skip things you don't care about.

Nonstandard usage

First off, here is nonstandard, word-for-word, directly from wiktionary. I only included the wording because you offered the wiktionary record as a defense of composes as used, not to create yet another wording disagreement. That the usage is observed is rather like saying this word exists. Of course the usage is observed--we could not otherwise document that such usage does not conform to accepted usage standards. Anyway, appealing to dictionaries is often fruitless. Dictionaries are recorders, not arbiters, of language. But look, this is pointless. We aren't going to get anywhere by arguing over the terms used to describe usage in a dictionary.

A sincere apology

I apologize (sincerely) that my comment about digging in your heels came across as an overly negative accusation. Digging in one's heels in defense of a choice is not an automatic negative. However, I never suggested any reasons for why you appear to be digging in your heels; you've misunderstood. I was relaying how it appears, given your comments to date, that you're defending the word choice as a good choice (with increasingly weaker and unconvincing arguments). Continuing to defend the word as appropriately conveying what you want it to convey has really left few conclusions to be made other than an initial misunderstanding of the meaning of the indicative form chosen as a property name (which is correctable, and seemed like what we needed to accomplish first), or there being deliberate reasons for remaining with the word that had yet to be clearly explained (hence my questions as to whether it was personal taste, technical difficulty of change, or something else). Now, at least you've offered an explanation that you felt it was the best choice possible given the mechanism you are needing to signify and convey. Awesome.

Verbs are problematic

I've tried to speak directly to the issue of signifying the underlying mechanism properly when discussing the word choice in both of my comments so far. Given this conversation, as well as other related issues that include references to this keyword and its confusing nature, it seemed to me from the start that was what really needed to be resolved. A great deal of the trouble is having chosen a verb, which are almost non-existent in CSS. Nearly all CSS properties are nouns.

So, what we hopefully all agree on is composes is confusing, rather than helping, users. So, CSS Modules and its users would be jointly helped by finding a better term that satisfies

  • appropriately conveying the underlying mechanism of composition
  • does not immediately leave users confused

Suggestions

If I'm understanding the underlying mechanism correctly, why not simply go for a hyphenated verbal phrase like compose-with:? It would look plenty standard to all who use CSS, as there are plenty of hyphenated CSS rules that are standard, and immediate convey accurate meaning--things like margin-bottom, text-transform, border-width.

.base {
  /* base rules */
}
.extras {
  /* extra rules */
}
.modified {
  compose-with: base, extra;
  /* custom stuff */
}

Since you guys want to target the composition of styling, this hyphenated keyword would actually speak directly to the mechanism of composition, while avoiding the inherent confusion that comes from using the third-person indicative verb form. That's really the problem. Hell, the form chosen is so much the problem, that if you utterly detest hyphenated properties, and you really want to make sure people are aware they are specifying composition, there's an even simpler solution:

.base {
  /* base rules */
}
.extras {
  /* extra rules */
}
.modified {
  composition: base, extra;
  /* custom stuff */
}

Of course, include would probably work just fine. I'm rather doubtful that most users are going to mentally care to differentiate the composition of styling from the idea I need to include .base and .extras into .modified, but with a slight tweak. That's why I included it in my first list of many suggestions that would, to developers using the product, signify what they were actually trying to do, regardless of underlying implementation details.

Exeunt

Anyway, that will be my last "wall of text". I'm one random guy on the internet who happens to care simultaneously about good programming tools and clarity of language. I also tend to forget that people want a tl;dr for everything. Meh. ¯_(ツ)_/¯

@geelen
Copy link
Member

geelen commented Sep 7, 2015

Actually hyphenation might be the ticket. And I think you're spot on that a big confusion is shoehorning a verb into a noun's place. This "property" is actually an instruction to the CSS Modules compiler to export something, so it somehow felt like it needed to be a verb. That and you can have multiple of them and they're all meaningful, unlike CSS declarations.

I'm quite partial to compose-with, but then I never had a problem with composes, so I'm not the best judge of whether it helps. So for those who did find it confusing, what do you think? Suggestions for other hyphenated options (given that the aim is to best describe the mechanism underlying here).

@webappzero
Copy link

CSS Modules is an awesome idea. Thank you for sharing it!

I think a change is justified to prevent the need for newcomers to ever have to read this issue, which I did because the use of the term "composes" confused me.

I think both "comprises" and "composes" are cumbersome words in general and this issue offers a good opportunity to simplify early on. CSS Modules has the potential to make CSS much more readable and semantically friendly than any tool I've seen. Which is why I think this issue is really important.

Given that "Composition" is a central idea for this project, I like the idea of compose-with or composed-of because these honor this core aspect of the project. My best.

@chanon
Copy link

chanon commented Nov 22, 2015

I'd like to vote for includes, include is fine also.

@ianstormtaylor
Copy link

Hey all,

I just implemented CSS modules for the first time today (or yesterday, it's been a blur) in getting up to speed on everything frontend for the past two years. In other words, total newcomer to this syntax, but not a newcomer to Javascript or CSS at all. So maybe I can add...

This is a bit of a departure from this conversation's suggestions, so don't hate me, but give it a chance!

I think the real reason most all of these words are (and will be) confusing for people is not necessarily the exact wording (although that's important), but because of where the syntax is placed. Right now, we're using CSS properties to define an augmentation of the CSS selectors.

If I understand correctly, then:

.button {
  cursor: pointer;
  color: red;
}

.active {
  composes: button;
  color: black;
}

Really means:

.button { /* export: "button" */
  cursor: pointer;
  color: red;
}

.active { /* export: "active button" */
  color: black;
}

But the reason that's super hard to grok is that the composes property is impacting the "active button" exported class name selectors. Intuitively, whenever we read properties we're going to jump to thinking about them in terms of mixing in properties from the target.

I actually formally understood how CSS Modules composition worked, and then went back to CSSing for a few hours and I kept defaulting back to the incorrect behavior in my mental model.

Instead, I think it would be best to find a syntax that revolves around the selector itself. Something like:

.button {
  cursor: pointer;
  color: red;
}

.active %button {
  color: black;
}

Which more intuitively translates into:

.button { /* export: "button" */
  cursor: pointer;
  color: red;
}

.active { /* export: "active button" */
  color: black;
}

We could even get even more intuitive (but at the cost of getting the syntax mixed up with that of the next-sibling selector):

.button {
  cursor: pointer;
  color: red;
}

.active +button {
  color: black;
}

Or:

.button {
  cursor: pointer;
  color: red;
}

.active &button {
  color: black;
}

What do you guys think?

I'd lean towards the % since it doesn't appear to be used anywhere in CSS, but the + could also work. (Edit: Actually, & could work too, since I don't think it's used in CSS last I checked.) We'd need a different syntax for composition from other files, but that seems like it wouldn't be that hard to figure out with something like @value or similar.

@ianstormtaylor
Copy link

Using the selector-based syntax, it also becomes a bit more clear why things like :hover and + can't be extended, because it would be more awkward to write and understand:

.active:hover %button {
  ...
}

.active + .active %button {
  ...
}

@tivac
Copy link

tivac commented Jan 7, 2016

@ianstormtaylor No real opinion about selector vs property, but a quick correction

.active {
    composes: button;
}

will become button active, not active button.

I think it makes your selector proposal look backwards.

@markdalgleish
Copy link
Member

I disagree that it has an effect on the selector. In fact, syntax like .active:hover %button gives the impression that the button class is nested inside the active class. With class composition, you're affecting the output of that class, not the selector itself.

@ianstormtaylor
Copy link

@tivac thanks for the clarification there! Good point.

@markdalgleish Also a good point. I agree that having the syntax be .active %button means that it overlaps mentally with selector nesting, which is not good.

It might be better then to think of it similarly to decorators in Javascript, which makes their effects more clear, and also makes the ordering more clear too:

@button
.active {
   ...
}

Or using a potentially less-overloaded symbol:

%button
.active {
   ...
}

+button
.active {
   ...
}

&button
.active {
   ...
}

Such that a more complex example might look like:

@button @blue @solid
.active {
  ...
}

Or:

@button
@blue
@solid
.active {
  ...
}

@sokra
Copy link
Member

sokra commented Jan 7, 2016

Interessing fact: The first syntax had the composition in the selector.


I agree with @markdalgleish the selector is the wrong location. The selector specifies what is affected and the properties specify what happens with the selector.

That composition exports multiple classes instead of one is only a implementation detail. Technically the properties could also be copied into the class with the same effect.

Transformations that are valid for selectors and rules are also valid for composition as property.
i. e. .a { composes: base; } .b { composes: base; color: red; }
<=> .a, .b { composes: base; } .b { color: red; }

So composition behave much more like a property than a selector or an at-rule.


will become button active, not active button.

Sadly the order of classes in the class attribute has no influence for CSS...

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