Help with FOOP
Posted: Sun Aug 24, 2008 5:07 pm
I've finally got round to trying to understand the FOOP features of newLISP, and any guidance would be appreciated! (Where is FOOPerman?:)
I decided to try to do something where I understood the problem domain reasonably well but was useful enough to be able to see whether there are any practical benefits to using FOOP. So although it's probably overkill, I thought I'd try to learn FOOP using date/times.
Here are my first ideas:
It looks reasonably OK for such a simple problem domain. But I want to write some functions called 'adjust-hours' or something which increases a time by a given number of, say, days. I can't see how to pass a time instance to a function and modify the instance, other than by doing this. The pass by reference idea seems to work only with contexts... ?
Is this the general idea of FOOP? It has promise and I can see how it might be good but I'd like to know where the problems are too.
I decided to try to do something where I understood the problem domain reasonably well but was useful enough to be able to see whether there are any practical benefits to using FOOP. So although it's probably overkill, I thought I'd try to learn FOOP using date/times.
Here are my first ideas:
Code: Select all
; class for time instant/instances
(define (Time:Time (t (date-value)) (zone 0))
(list Time t zone))
(define (Time:show t)
(println (date (t 1) (t 2))))
(define (Time:days-between t1 t2)
; return difference in days between two times
(div (abs (- (t1 1) (t2 1))) (* 24 60 60)))
(define (Time:get-hours t)
; return hour
(int (date (t 1) (t 2) {%H})))
(define (Time:get-day t)
; return day of week
(date (t 1) (t 2) {%A}))
(define (Time:leap-year? t)
(let ((year (int (date (t 1) (t 2) {%Y}))))
(and (= 0 (% year 4))
(or (!= 0 (% year 100)) (= 0 (% year 400))))))
; class for Durations
(define (Duration:Duration (d 0))
(list Duration d))
(define (Duration:period-to-string d)
; convert period in days to day hour min sec string
(letn
((s (mul 24 60 60 (d 1)))
(secs (mod s 60))
(mins (mod (div s 60) 60))
(hours (mod (div s 3600) 24))
(days (mod (div s 86400) 86400)))
(format "%02dd %02dh %02dm %02ds" days hours mins secs)))
(context MAIN)
(set 'my-birthday (Time (date-value 2008 5 26)))
(set 'christmas-day (Time (date-value 2008 12 26)))
(set 'time-now (Time))
(:show my-birthday)
;-> Mon May 26 01:00:00 2008
(:show christmas-day)
;-> Fri Dec 26 00:00:00 2008
(println "hours " (:get-hours time-now))
;-> hours 17
(println "day " (:get-day time-now))
;-> day Sunday
(println "shopping days " (:days-between time-now christmas-day))
;-> shopping days 123.314919
(println "leap year " (:leap-year? my-birthday))
;-> leap year true
(println (set 'shopping-day-string (: period-to-string (Duration (:days-between time-now christmas-day)))))
;-> 123d 06h 57m 12s
Code: Select all
(define (Time:adjust-days t n)
(list Time (+ (* 24 60 60 n) (t 1)) (t 2)))
(println (set 'christmas-day (:adjust-days christmas-day 3))) ; ?
(println (:show christmas-day))