20.1.1 The + method using informal exceptions

First, we redefine the method for adding <time-offset> and <time-of-day> (this method was last defined in Section 14.3.2, page 228). The method now returns an error string in the event that the computed sum is beyond the permitted 24-hour range:

define method \+ (offset :: <time-offset>, time-of-day :: <time-of-day>)
 => (sum :: type-union(<time-of-day>, <string>))
  let sum 
    = make(<time-of-day>, 
           total-seconds: offset.total-seconds + time-of-day.total-seconds);
  if (sum >= $midnight & sum < $tomorrow) 
    sum;
  else
   "time boundary violated";
  end if;
end method \+;

We have altered the + method in two important ways. First, we have modified the original values declaration, (sum :: <time-of-day>), to allow the return of either a <time-of-day> instance or a string describing a problem. Second, we have added code that checks the computed time of day, and returns an error string if the sum is out of bounds.

To illustrate further how the informal exceptions work, we define a method that calls the + method defined in this section. We define a method, correct-arrival-time, that adds predicted weather and traffic delays to an arrival time; and we define say-corrected-time, which calls correct-arrival-time and displays the results:

define method correct-arrival-time 
    (arrival-time :: <time-of-day>, weather-delay :: <time-offset>,
     traffic-delay :: <time-offset>)
 => (sum :: type-union(<time-of-day>, <string>))
  let sum1 = weather-delay + arrival-time;
  // Check whether the result of + was a string representing an error
  if (instance?(sum1, <string>))
    sum1;
  else
    // Otherwise, if there is no error, compute the second part of the sum
    traffic-delay + sum1;
  end if;
end method correct-arrival-time;
define constant $no-time = make(<time-offset>, total-seconds: 0);
define method say-corrected-time
    (arrival-time :: <time-of-day>, 
     #key weather-delay :: <time-offset> = $no-time,
     traffic-delay :: <time-offset> = $no-time)
 => ()
  let result = correct-arrival-time(arrival-time, weather-delay, 
                                    traffic-delay);
  // Check whether the result of + was a string representing an error
  if (instance?(result, <string>))
    format-out("Error during time correction: %s", result);
  else
    // Otherwise, if there is no error, display the result
    say(result);
  end if;
end method say-corrected-time;