-
Notifications
You must be signed in to change notification settings - Fork 1
CCS 2.0
-
No more "descendant" selector (
a > b
).This one I've rarely used, it complicates the implementation somewhat, it makes rule specificity more ambiguous and less intuitive, and I'm no longer convinced it's a very good idea anyway. Unless there are objections, it's dead.
-
No more complex multi-valued constraints. This shows up in the 1.0 API as more complex invocations of
context.constrain()
andcontext.builder()...
, and in the language as selectors likefoo.bar.baz/quux.frob
. (If this doesn't look familiar, that just shows how rarely it's used.)This one is almost never used, the syntax is a little complex, and the meaning is a little obscure. In the absence of a compelling use case, I think it's better to simplify.
-
Constraint keys will be single-valued.
There will now be an expectation that a given context contains only one constraint with a given key. So if at some point you add the fact
env.prod
, you can't also later sayenv.dev
or whatever. (This will be checked at runtime.) We do sometimes do this now, but it's virtually always a case of "punning" where the same key (say,env
) is actually being used to mean two different things. This will be a breaking change, but I think it's worth it, because it allows to more aggressively prune the applicable rules (since, for example, once we knowenv.prod
, we can be certain that we'll never match any rules that require any other value forenv
). Also, it opens the door for the next change: -
Negative matches will be allowed.
This is a valuable addition, and I think it's worth sacrificing some other stuff to get it. I haven't settled on a definitive syntax yet, but as you can write a rule like
env.production
now, you'll be able to write something likeenv.!production
which will match in any context containing anenv
value other thanproduction
. Note that rule matching is still monotonic, so a negative selector won't match in a context that's missing the given key, only in a context where the key is known to have a different value. (For that reason, I don't like the syntax!env.production
, which suggests the reading "not (env is production)" rather than "env is not production".)This depends on the "single-valued keys" change above. Syntax suggestions are welcome!
-
Specificity will be more intuitive.
No major conceptual change here, and I have extensive thoughts on this subject, but I think I have some minor improvements here, based on a whole bunch of examples and questions that I'm happy to share.
The goal is to find an intuitive approach, without leading to too many cases where we report a conflict even though a reasonable user would say her intentions were clear, but also without resolving conflicts in ways that seem arbitrary. And of course we want something that can be implemented efficiently and without too much complication.
-
@override
will be improved.The current single blanket that
@override
provides is heavy-handed and annoying to use. I still think too much reliance on overrides is a smell, but something more subtle than this is probably needed. I'm thinking of just generalizing it to a multi-leveled@override/@default
or@foreground/@background
scheme, but I'm very open to ideas here. I have examples of where we've been frustrated by the way it works currently. -
constrain()
will change, probably toaugment()
.I believe this was just a poor choice of name. If anything, the selectors in the CCS language could probably be called "constraints", while the facts known about the context really aren't constraints in any meaningful sense, they're simply facts. The name
assert()
would be ok, but it now has a very different standard meaning to most programmers, so I'm leaning towardaugment()
. The@constrain
directive will probably be renamed to@define
, which is sensible since keys will be single-valued.If I make this change, the existing
constrain()
functions will remain as deprecated synonyms. -
@unset
will be added.In some situations, it's desirable to have a value for a property by default or in a more general scenario, but to have that property be missing in a more specific situation. There will be an
@unset
directive for this purpose.
With the above changes, here are some things I'm hoping to gain:
-
Diffing in context: The ability to specify a context and then enumerate all rules still satisfiable
in that context, in a normal form suitable for diffing. This would be really valuable to me, so that I
could, for instance, say: given this pile of rules, and restricted to the case that
env
will beprod
, what differences might there be? - More introspection: ability to enumerate visible properties cheaply, as well as some ability to enumerate "useful" additional constraints, or not-yet-matched but still satisfiable rules.
- More powerful and flexible interpolation. It would be nice to interpolate not only environment variables, but also other property values as well as constraint values. Single-valued constraints are a pre-requisite in order for the latter to be unambiguous. It would nice for interpolation sources to be pluggable, and to have the option to error on a failed interpolation.