On to the next Exercism problem in Rust. This one is also quite simple, and a situation programmers have typically learned about: leap years. Plus, you’ll see how Rust closures help clear up my (admittedly) simple code.

Leap years aren’t like daylight savings time; they’re actually necessary. I learned that Mother Goose poem as a kid – mainly the first two lines and, to this day, it’s how I remember which months have 30/31 days.

TL;DR: if the year is divisible by 4, unless divisible by 100, unless divisible by 400, it is a leap year. So, right out of the gate you could brute-force the answer:

sub is_leap_year { $year = shift; return 0 unless year && year !~ /\D/; return 1 if year % 400 == 0; return 0 if year % 100 == 0; return year % 4 ? 1 : 0; }

Sorry, I slipped into perl… I love coding in perl 5. Instead, here comes some cringe-worthy Rust code:

pub fn is_leap_year(year: u64) -> bool { if year == 0 { return false; } if year % 400 == 0 { return true; } if year % 100 == 0 { return false; } if year % 4 == 0 { return true; } false }

## Rust Closures

Easy enough, we accept a u64 (why use a u8 when a u64 will do?) Actually, I’m not sure why this is u64, but that is how Exercism delivered the problem. And, of course, is_leap_year should return a boolean. So, lets Rust this one up, let’s change this to use a closure. This is a good example for a closure, look how clean this is (though I had to wrap things short to fit on mobile screens):

pub fn is_leap_year(year: u64) -> bool { let is_divisible = |n| { year % n == 0 }; is_divisible(4) && (!is_divisible(100) || is_divisible(400) ) }

We define the closure is_divisible – which takes parameter n and performs a modulo against year with it and returns the remainder – and then our function is, once again, a single expression returning the true or false it evaluates to.

BTW, I am pretty sure that “and performs a modulo against year” is grammatically incorrect: programming made modulo a verb, but the dictionary still only identifies it as an adverb.

Leap year: if year divisible by 4 AND either (*isn’t* divisible by 100 OR *is* divisible by 400).