I'm thinking about eliminating groups in favor of reusable mixins. The syntax might look something like this:
$weekdays = days(mon-fri)
$noon = hours(12)
$weekdaysAtNoon = { $weekdays $noon }
$weekdaysAtMidnight = { $weekdays hours(0) }
Tokens beginning with $ would be treated as mixins. Attempting to reassign a mixin should throw a syntax error (they can be overridden, however - described later). Since they can't be reassigned, it means we can make them order-independent, so you could use a mixin before it is defined and it will still have the correct value.
As with the rest of the language, whitespace would be insignificant. Mixin identifiers would be case-insensitive. Comma separators would be optional inside the {} since they feel natural, but the syntax is unambiguous without them. The braces would be optional when the mixin only consists of one expression.
The compiler would simply expand the mixins (recursively, as necessary) in order to flatten out the structure. The impact on the existing compiler code should be minimal.
The question becomes, how does this play with the definition of the actual schedule you want sch to use? I see a few possibilities, but here's what I'm leaning towards:
sch should look for a schedule in the following order:
- Any free floating schedule (i.e.
min(0%2)). This is how sch already works, and it seems like it will remain the most common use case - no reason to break that. There can only be one free-floating schedule (m(0) $midnight = { hours(0) } sec(0) should be invalid syntax).
- Look for a "use" statement. There can be either a free floating schedule or a use statement. If both are present, a syntax error should be thrown. Examples:
use min(0)
use $mixinName
use { min(0) $mixinName }
- If none of the above conditions are met, a syntax error is thrown.
The use statement is technically redundant, but I think it improves the readability of a schedule which may be cluttered with mixin definitions. We could consider enforcing the use of "use" if a schedule string contains mixin definitions, but that seems unnecessary.
I would like sch to have a .mixin property where global mixins could be defined. Sch could actually ship with a default value for that property with some helpful mixins, but it would still allow users to override, or add to it, with their own mixins.
The sch function itself could accept a second optional argument sch( schedule, [mixins] ). This would allow users a high degree of flexibility in defining their mixins without screwing up the global defaults for everything else.
Mixins cannot be reassigned (they're not variables), but they can be overridden based on order of precedence.
- Any mixins defined in the schedule string.
mixins argument.
sch.mixins global property.
For example, if sch.mixins defines $a=h(12) and the mixins argument redefines it as $a=h(14) then any reference to $a in the schedule string will expand to h(14), but any reference to $a in sch.mixins will still expand to the original h(12). This is to prevent unintended consequences in composite mixins. You could think of it as inheriting parent scopes - you can redefine a variable in an inner scope without it affecting the outer scope.
If anyone has any thoughts (@rossipedia in particular), let's discuss them here.
I'm thinking about eliminating groups in favor of reusable mixins. The syntax might look something like this:
Tokens beginning with
$would be treated as mixins. Attempting to reassign a mixin should throw a syntax error (they can be overridden, however - described later). Since they can't be reassigned, it means we can make them order-independent, so you could use a mixin before it is defined and it will still have the correct value.As with the rest of the language, whitespace would be insignificant. Mixin identifiers would be case-insensitive. Comma separators would be optional inside the
{}since they feel natural, but the syntax is unambiguous without them. The braces would be optional when the mixin only consists of one expression.The compiler would simply expand the mixins (recursively, as necessary) in order to flatten out the structure. The impact on the existing compiler code should be minimal.
The question becomes, how does this play with the definition of the actual schedule you want sch to use? I see a few possibilities, but here's what I'm leaning towards:
sch should look for a schedule in the following order:
min(0%2)). This is how sch already works, and it seems like it will remain the most common use case - no reason to break that. There can only be one free-floating schedule (m(0) $midnight = { hours(0) } sec(0)should be invalid syntax).use min(0)use $mixinNameuse { min(0) $mixinName }The
usestatement is technically redundant, but I think it improves the readability of a schedule which may be cluttered with mixin definitions. We could consider enforcing the use of "use" if a schedule string contains mixin definitions, but that seems unnecessary.I would like sch to have a
.mixinproperty where global mixins could be defined. Sch could actually ship with a default value for that property with some helpful mixins, but it would still allow users to override, or add to it, with their own mixins.The sch function itself could accept a second optional argument
sch( schedule, [mixins] ). This would allow users a high degree of flexibility in defining their mixins without screwing up the global defaults for everything else.Mixins cannot be reassigned (they're not variables), but they can be overridden based on order of precedence.
mixinsargument.sch.mixinsglobal property.For example, if
sch.mixinsdefines$a=h(12)and the mixins argument redefines it as$a=h(14)then any reference to$ain the schedule string will expand toh(14), but any reference to$ainsch.mixinswill still expand to the originalh(12). This is to prevent unintended consequences in composite mixins. You could think of it as inheriting parent scopes - you can redefine a variable in an inner scope without it affecting the outer scope.If anyone has any thoughts (@rossipedia in particular), let's discuss them here.