schyntax / js-schyntax Goto Github PK
View Code? Open in Web Editor NEWA simple Node.js utility for parsing schedule strings, and finding the next scheduled event time.
License: MIT License
A simple Node.js utility for parsing schedule strings, and finding the next scheduled event time.
License: MIT License
Proposed keywords: s
, sec
, seconds
, secondofminute
, secondsofminute
(for consistency).
This would allow describing a repeating task at sub-second resolution, rather than the default smallest unit being minutes, which could be useful if you wanted a repeating task say on the minute and at :30 seconds (twice a minute).
Also, milliseconds could possibly be useful, although when you need sub-1s resolution, I'm not sure that aligning the events to a specific millisecond is really useful.
What do you think?
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:
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 $mixinName
use { min(0) $mixinName }
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.
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.
The current range operator is the minus (-) sign. I chose this because that's generally how we write ranges. "I'll have that done in 6-8 weeks." Cron also uses -
as its range operator, but I really couldn't care less what cron uses.
The down side of this operator choice is that it means the -
is overloaded because dayofmonth
supports negative numbers (for counting backwards from the last day of the month). If you want to specify a range using negative numbers, the syntax can look a little ugly.
dom(-5--1)
or you could write it a little nicer as dom(-5 - -1)
, but I concede that it's still not great.
It was pointed out to me by someone who likes Ruby that if the range operator was ..
, it wouldn't require any overloading and might look nicer. dom(-5..-1)
. I had an initially negative visceral reaction for two reasons. 1. I hate Ruby, and 2. that's not how I write ranges in any context.
The first reason isn't a good one, but the second is. So here's my stance: I am not going to entertain the idea of eliminating the minus sign as a range operator. Yes, it will remain overloaded in this spec. What I am willing to entertain is adding ..
as an alias for the range operator, and _only_ the two-dot version... three-dot non-inclusive nonsense would serve no purpose except to confuse people.
My philosophy with the language is that you shouldn't have to remember a lot of syntax because the first time you see it, it should already feel familiar. The way we write ranges 3-5
, the way we write dates 4/16
, the way we use %
as a modulus operator in other languages, etc. It's also the reason there are several aliases for most of the expressions (you don't have to remember whether it's minute
or minutes
because both work). I don't want you to have to consult the documentation every time you write a schedule. The limit to that flexibility is that it still has to be terse, unambiguous and not misleading.
I think adding an alias for the range fits in with that philosophy, so I don't have any good reasons to object to it.
The current tokenizer assumes that all operators are one character, but that's not a huge change.
The ..
wouldn't be an alias for the literal -
since the minus sign has two meanings, and ..
would only be an alias for one meaning. Therefore, we have to implement the operator at the compile step. This should be as simple as altering ScheduleBuilder.js line 182 to read:
if (t.value === '-' || t.value === '..')
There's no reason js-schyntax and js-schtick couldn't be packaged for use in the browser.
I'm starting to think there needs to be a weeks
expression to help express things like:
The two above examples could be expressed as:
days(friday) weeks(1,3)
and (monday) weeks(-1)
Just like days of month, the week number could be expressed either as the number of weeks from the start of the month, or a negative number representing the number of weeks from the end of the month (1 and -1-indexed respectively).
Technically this is just syntactic sugar since both of the above examples could already be expressed as:
days(friday) dom(1..7, 15..21)
and days(monday) dom(-7..-1)
but the weeks
expression is far more readable and less error prone. It should also be rather trivial to implement.
Weeks should have the aliases: w
, week
, weeks
, weekofmonth
, and weeksofmonth
. Anticipating this expression was actually the reason for commit 1606847 a couple months ago.
What would be more than simply syntax sugar would be to add a fullWeeks
expression. Say you want something to run everyday for the first full week of a month, not simply the first seven days
fullweeks(1)
That would run everyday at midnight for seven days starting on the first Sunday of each month.
I can't think of any way to express this with the existing syntax so I think it would be a good addition to the language and still relatively trivial to implement.
Negative numbers would also be supported:
fullweeks(-1)
would run for seven days ending on the last Saturday of the month.
Zero and negative zero would also be supported:
fullweeks(0)
would run any day of the month which is before the first Sunday, and fullweeks(-0)
would run any days of the month after the final Saturday.
Aliases: fw
, fullweek
, fullweeks
, fullweekofmonth
, and fullweeksofmonth
.
I've been doing a lot of thinking lately about what else the language needs in order to be powerful enough to express most schedule requirements people have. The language is already fairly powerful. The best thing it has going for it is its terse, but still readable, syntax which feels familiar the first time you see it. This needs to continue to be the guiding philosophy for additions to the language.
The language does have some flaws and missing features I would like corrected before I start trying to bring attention to it. Items will be crossed out once they're accomplished.
y/m/d
.js-schyntax
. Other officially sanctioned implementations will follow a similar naming scheme (i.e. go-schyntax
, cpp-schyntax
, etc).schyntax
on bower and npm, not js-schyntax
.schyntax
to improve discoverability with the language itself.I'd like to make decisions on all of these issues before anyone starts working on a second implementation.
Right now, the easiest way to run once an hour is to say hours()
, but this has readability issues, whereas hours(*)
would probably make more sense to someone glancing at it. Do let's do that and deprecate the empty expression format. This should also make things like hours(*, !6)
easy to write.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.