The Story of business_days(...)
I've been really busy with work recently. However, while going over my requirements for the nth time, something caught my eye: business days. In particular, finding the date 7 business days from a another date.
Far from being a hard task, it fell more into the annoying category. Or maybe it would make for a good interview question. In the end, how complicated or simple can someone make such a function?
A little background first. I had to use JavaScript, a language I'm only superficially familiar with. Also, after discussion with the customer, the definition of business days was Monday to Friday. No holidays are included... In fact, which holidays? And from what region/country?
Having flirted with Haskell recently and being "influenced" by the SICP lectures, a few ideas came to mind.
"business days" is a subset of "days", and both are infinitely lists. If I have a list of all the days and I filter it through the is_business_day(date) function, and I access the element at position 7, I get the answer. I was getting pretty angry with my inability to accomplish my task in such a straightforward way. I started to understand what people mean when they talk about the expressiveness of a programming language.
I then turned to Ruby for ideas. The succ function came to mind, I made that my starting point.
A few comments:
Far from being a hard task, it fell more into the annoying category. Or maybe it would make for a good interview question. In the end, how complicated or simple can someone make such a function?
A little background first. I had to use JavaScript, a language I'm only superficially familiar with. Also, after discussion with the customer, the definition of business days was Monday to Friday. No holidays are included... In fact, which holidays? And from what region/country?
Having flirted with Haskell recently and being "influenced" by the SICP lectures, a few ideas came to mind.
"business days" is a subset of "days", and both are infinitely lists. If I have a list of all the days and I filter it through the is_business_day(date) function, and I access the element at position 7, I get the answer. I was getting pretty angry with my inability to accomplish my task in such a straightforward way. I started to understand what people mean when they talk about the expressiveness of a programming language.
I then turned to Ruby for ideas. The succ function came to mind, I made that my starting point.
function include(value, list) {
for (var i=0; i < list.length; i++) {
if(list[i] == value) return true;
};
return false;
}
function succ(date) {
return new Date(date.getTime() + 1000 * 60 * 60 * 24);
}
function is_business_day(date) {
return include(date.getDay(), [1,2,3,4,5]); // mon-fri
}
function business_succ(date) {
var result = succ(date);
return is_business_day(result) ? result : business_succ(result);
}
function repeat(f, x, n) {
if(n == 1)
return f(x);
return f(repeat(f, x, n-1));
}
function days(date, n) {
return repeat(succ, date, n);
}
function business_days(date, n) {
return repeat(business_succ, date, n);
}
Personally, the moment of enlightenment came when I realized that iterating for days or business days was the same code and that it could be made even more generic by the repeat function.A few comments:
- the include function would usually be borrowed from prototype.js
- recursion has become part of my day-to-day programming techniques
- all functional
- definitely not the shortest code I've written, but all pieces are both trivial and reusable
- a definite LISP-like flavor
- proof that SICP and friends have been damaging my brain :)