From: gavino
Subject: I Gavino have hacked my first clisp program, believe it or not.
Date: 
Message-ID: <b6864071-06f5-4a21-b633-828a92b6922f@s37g2000prg.googlegroups.com>
#!/usr/bin/clisp

(defun generate-hms(seconds)
    (let ((days (floor (/ seconds (* 3600 24)))))
        (let ((hours (floor (/ (- seconds (* days 3600 24)) 3600))))
            (let ((minutes (floor (/ (- seconds (* days 3600 24) (*
hours 3600)) 60))))
                (let ((secs (- seconds (* days 3600 24 ) (* hours
3600) (* minutes 60))))
                    (values days hours minutes secs))))))

(defun show-hms-time(seconds)
    (multiple-value-bind (d h m s) (generate-hms seconds)
        (format t "Uptime: ~a days, ~a hours, ~a minutes, ~a seconds"
d h m s)))

(defun parse-proc-uptime(line)
    (let ((text-first-number (subseq line 0 (search " " line))))
        (subseq text-first-number 0 (search "." text-first-number))))

(with-open-file (s "/proc/uptime" :direction :input)
    (let ((line (read-line s)))
        (show-hms-time (parse-integer (parse-proc-uptime line)))))

From: Vagif Verdi
Subject: Re: I Gavino have hacked my first clisp program, believe it or not.
Date: 
Message-ID: <d5a0a20f-0392-4bbe-b956-97d929ee0c3b@i7g2000prf.googlegroups.com>
You do not need to nest lets

(defun generate-hms(seconds)
     (let* ((days    (floor (/ seconds (* 3600 24))))
            (hours   (floor (/ (- seconds (* days 3600 24)) 3600)))
            (minutes (floor (/ (- seconds (* days 3600 24) (* hours
3600)) 60)))
            (secs    (- seconds (* days 3600 24 ) (* hours 3600) (*
minutes 60))))
        (values days hours minutes secs))
From: gavino
Subject: Re: I Gavino have hacked my first clisp program, believe it or not.
Date: 
Message-ID: <e1d6739d-26a9-4e23-97c4-23c9cc9679c7@e6g2000prf.googlegroups.com>
On Mar 31, 6:36 pm, Vagif Verdi <···········@gmail.com> wrote:
> You do not need to nest lets
>
> (defun generate-hms(seconds)
>      (let* ((days    (floor (/ seconds (* 3600 24))))
>             (hours   (floor (/ (- seconds (* days 3600 24)) 3600)))
>             (minutes (floor (/ (- seconds (* days 3600 24) (* hours
> 3600)) 60)))
>             (secs    (- seconds (* days 3600 24 ) (* hours 3600) (*
> minutes 60))))
>         (values days hours minutes secs))

can't get this to work
keeps complaining about hours being undefined function
hmm
From: gavino
Subject: Re: I Gavino have hacked my first clisp program, believe it or not.
Date: 
Message-ID: <df996754-a404-45d4-84e0-f06ec65d3c00@d21g2000prf.googlegroups.com>
On Apr 1, 2:53 pm, gavino <·········@gmail.com> wrote:
> On Mar 31, 6:36 pm, Vagif Verdi <···········@gmail.com> wrote:
>
> > You do not need to nest lets
>
> > (defun generate-hms(seconds)
> >      (let* ((days    (floor (/ seconds (* 3600 24))))
> >             (hours   (floor (/ (- seconds (* days 3600 24)) 3600)))
> >             (minutes (floor (/ (- seconds (* days 3600 24) (* hours
> > 3600)) 60)))
> >             (secs    (- seconds (* days 3600 24 ) (* hours 3600) (*
> > minutes 60))))
> >         (values days hours minutes secs))
>
> can't get this to work
> keeps complaining about hours being undefined function
> hmm

GOT IT

#!/usr/bin/clisp

(defun generate-dhms(seconds)
    (let* ((days        (floor (/ seconds (* 3600 24))))
           (hours       (floor (/ (- seconds (* days 3600 24)) 3600)))
           (minutes     (floor (/ (- seconds (* days 3600 24) (* hours
3600)) 60)))
           (secs        (- seconds (* days 3600 24) (* hours 3600) (*
minutes 60))))
           (values days hours minutes secs)))

(defun show-dhms-time(seconds)
    (multiple-value-bind (d h m s) (generate-dhms seconds)
        (format t "Uptime: ~ad ~ah ~am ~as" d h m s)))

(defun parse-proc-uptime(line)
    (let ((text-first-number (subseq line 0 (search " " line))))
        (subseq text-first-number 0 (search "." text-first-number))))

(with-open-file (s "/proc/uptime" :direction :input)
    (let ((line (read-line s)))
        (show-dhms-time (parse-integer (parse-proc-uptime line)))))
From: Jason
Subject: Re: I Gavino have hacked my first clisp program, believe it or not.
Date: 
Message-ID: <d698716a-3a2b-493a-95e0-3fc77c6bda8f@i36g2000prf.googlegroups.com>
On Apr 1, 3:01 pm, gavino <·········@gmail.com> wrote:
> On Apr 1, 2:53 pm, gavino <·········@gmail.com> wrote:
>
>
>
> > On Mar 31, 6:36 pm, Vagif Verdi <···········@gmail.com> wrote:
>
> > > You do not need to nest lets
>
> > > (defun generate-hms(seconds)
> > >      (let* ((days    (floor (/ seconds (* 3600 24))))
> > >             (hours   (floor (/ (- seconds (* days 3600 24)) 3600)))
> > >             (minutes (floor (/ (- seconds (* days 3600 24) (* hours
> > > 3600)) 60)))
> > >             (secs    (- seconds (* days 3600 24 ) (* hours 3600) (*
> > > minutes 60))))
> > >         (values days hours minutes secs))
>
> > can't get this to work
> > keeps complaining about hours being undefined function
> > hmm
>
> GOT IT
>
> #!/usr/bin/clisp
>
> (defun generate-dhms(seconds)
>     (let* ((days        (floor (/ seconds (* 3600 24))))
>            (hours       (floor (/ (- seconds (* days 3600 24)) 3600)))
>            (minutes     (floor (/ (- seconds (* days 3600 24) (* hours
> 3600)) 60)))
>            (secs        (- seconds (* days 3600 24) (* hours 3600) (*
> minutes 60))))
>            (values days hours minutes secs)))
>
> (defun show-dhms-time(seconds)
>     (multiple-value-bind (d h m s) (generate-dhms seconds)
>         (format t "Uptime: ~ad ~ah ~am ~as" d h m s)))
>
> (defun parse-proc-uptime(line)
>     (let ((text-first-number (subseq line 0 (search " " line))))
>         (subseq text-first-number 0 (search "." text-first-number))))
>
> (with-open-file (s "/proc/uptime" :direction :input)
>     (let ((line (read-line s)))
>         (show-dhms-time (parse-integer (parse-proc-uptime line)))))

Congrats Gavino! This is pretty cool! :)

Now that you have written this sweet program, try `man uptime`. :(

-Jason
From: Lars Rune Nøstdal
Subject: Re: I Gavino have hacked my first clisp program, believe it or not.
Date: 
Message-ID: <47f307fa$0$28891$c83e3ef6@nn1-read.tele2.net>
On Tue, 01 Apr 2008 17:57:14 -0700, Jason wrote:

> On Apr 1, 3:01 pm, gavino <·········@gmail.com> wrote:
>> On Apr 1, 2:53 pm, gavino <·········@gmail.com> wrote:
>>
>>
>>
>> > On Mar 31, 6:36 pm, Vagif Verdi <···········@gmail.com> wrote:
>>
>> > > You do not need to nest lets
>>
>> > > (defun generate-hms(seconds)
>> > >      (let* ((days    (floor (/ seconds (* 3600 24))))
>> > >             (hours   (floor (/ (- seconds (* days 3600 24))
>> > >             3600))) (minutes (floor (/ (- seconds (* days
>> > >             3600 24) (* hours
>> > > 3600)) 60)))
>> > >             (secs    (- seconds (* days 3600 24 ) (* hours
>> > >             3600) (*
>> > > minutes 60))))
>> > >         (values days hours minutes secs))
>>
>> > can't get this to work
>> > keeps complaining about hours being undefined function hmm
>>
>> GOT IT
>>
>> #!/usr/bin/clisp
>>
>> (defun generate-dhms(seconds)
>>     (let* ((days        (floor (/ seconds (* 3600 24))))
>>            (hours       (floor (/ (- seconds (* days 3600 24))
>>            3600))) (minutes     (floor (/ (- seconds (* days 3600
>>            24) (* hours
>> 3600)) 60)))
>>            (secs        (- seconds (* days 3600 24) (* hours
>>            3600) (*
>> minutes 60))))
>>            (values days hours minutes secs)))
>>
>> (defun show-dhms-time(seconds)
>>     (multiple-value-bind (d h m s) (generate-dhms seconds)
>>         (format t "Uptime: ~ad ~ah ~am ~as" d h m s)))
>>
>> (defun parse-proc-uptime(line)
>>     (let ((text-first-number (subseq line 0 (search " " line))))
>>         (subseq text-first-number 0 (search "."
>>         text-first-number))))
>>
>> (with-open-file (s "/proc/uptime" :direction :input)
>>     (let ((line (read-line s)))
>>         (show-dhms-time (parse-integer (parse-proc-uptime line)))))
> 
> Congrats Gavino! This is pretty cool! :)
> 
> Now that you have written this sweet program, try `man uptime`. :(

Yes! Embrace, extend, extinguish!

http://en.wikipedia.org/wiki/Embrace,_extend_and_extinguish
http://common-lisp.net/project/movitz/

-- 
Lars Rune Nøstdal
http://nostdal.org/
From: Jason
Subject: Re: I Gavino have hacked my first clisp program, believe it or not.
Date: 
Message-ID: <m2myodc7qs.fsf@gmail.com>
gavino <·········@gmail.com> writes:

> (defun generate-dhms(seconds)
>     (let* ((days        (floor (/ seconds (* 3600 24))))
>            (hours       (floor (/ (- seconds (* days 3600 24)) 3600)))
>            (minutes     (floor (/ (- seconds (* days 3600 24) (* hours
> 3600)) 60)))
>            (secs        (- seconds (* days 3600 24) (* hours 3600) (*
> minutes 60))))
>            (values days hours minutes secs)))

I'm looking at this and all I see are magic numbers and increasingly complex
subtractions and divisions. Yeah, it works, but it's kinda freaky. :P

Personally, I prefer code to look a little more tidy. Check this out:

CL-USER> (defun generate-dhms (seconds)
  (let ((time seconds)
	(seconds 0)
	(minutes 0)
	(hours 0)
	(days 0))
    ;; first: mod seconds from time, and subtract seconds from time
    (setf seconds (mod time 60))
    (setf time (/ (- time seconds) 60))

    ;; second: mod minutes from time, and subtract minutes from time
    (setf minutes (mod time 60))
    (setf time (/ (- time minutes) 60))

    ;; third: mod hours from time, and subtract hours from time
    (setf hours (mod time 24))
    (setf time (/ (- time hours) 24))

    ;; fourth: set days equal to time, and return values as a plist
    (setf days time)
    (list :days days :hours hours :minutes minutes :seconds seconds)))

GENERATE-DHMS
CL-USER> (generate-dhms 882865)
(:DAYS 10 :HOURS 5 :MINUTES 14 :SECONDS 25)

I went ahead and modified the return to be a plist instead of a regular list.
I think that might give you a bit more flexibility in the long run.

-- 
-Jason
From: Leslie P. Polzer
Subject: Re: I Gavino have hacked my first clisp program, believe it or not.
Date: 
Message-ID: <b6dcdaa0-cdf1-4d1f-bf5a-27e2c8758ad2@8g2000hsu.googlegroups.com>
On Apr 2, 4:26 am, Jason <·······@gmail.com> wrote:

> Personally, I prefer code to look a little more tidy. Check this out:
>
> CL-USER> (defun generate-dhms (seconds)
>   (let ((time seconds)
>         (seconds 0)
>         (minutes 0)
>         (hours 0)
>         (days 0))
>     ;; first: mod seconds from time, and subtract seconds from time
>     (setf ...)
>     (setf ...)
>
>     ;; second: mod minutes from time, and subtract minutes from time
>     (setf ...)
>     (setf ...)
>
>     ;; third: mod hours from time, and subtract hours from time
>     (setf ...)
>     (setf ...)

Personally, I think you hate functional programming and should put on
the Haskell straitjacket. Could that be?

Or is that... no wait, you wrote that post on April 2nd.

  Leslie
From: Alex Mizrahi
Subject: Re: I Gavino have hacked my first clisp program, believe it or not.
Date: 
Message-ID: <47f36407$0$90266$14726298@news.sunsite.dk>
 LPP> Personally, I think you hate functional programming and should put on
 LPP> the Haskell straitjacket. Could that be?

um, for those who love functional programming:

(defun crack-seconds (seconds)
  (labels ((c (periods time acc)
                  (if periods
                      (destructuring-bind ((name dur) . rest-periods)
                                  periods
                        (multiple-value-bind (q r)
                            (floor time dur)
                          (c rest-periods q (cons (cons name r) acc))))
                      acc)))
    (c '((:seconds 60)
          (:minutes 60)
          (:hours 24)
          (:days #.most-positive-fixnum))
        seconds
       ())))

and compile-time code generation via macros, also 100% pure functional:

(defun crack-seconds (seconds)
  (macrolet ((c (name dur rest)
        `(multiple-value-bind (res time)
              ,rest
           (multiple-value-bind (q r)
              (floor time ,dur)
            (values (cons (cons ,name r) res) q)))))
    (c :days most-positive-fixnum
      (c :hours 24
       (c :minutes 60
        (c :seconds 60
            (values () seconds))))))) 
From: John Thingstad
Subject: Re: I Gavino have hacked my first clisp program, believe it or not.
Date: 
Message-ID: <op.t8zc72bbut4oq5@pandora.alfanett.no>
P� Wed, 02 Apr 2008 12:46:25 +0200, skrev Alex Mizrahi  
<········@users.sourceforge.net>:

>  LPP> Personally, I think you hate functional programming and should put  
> on
>  LPP> the Haskell straitjacket. Could that be?
>
> um, for those who love functional programming:
>
> (defun crack-seconds (seconds)
>   (labels ((c (periods time acc)
>                   (if periods
>                       (destructuring-bind ((name dur) . rest-periods)
>                                   periods
>                         (multiple-value-bind (q r)
>                             (floor time dur)
>                           (c rest-periods q (cons (cons name r) acc))))
>                       acc)))
>     (c '((:seconds 60)
>           (:minutes 60)
>           (:hours 24)
>           (:days #.most-positive-fixnum))
>         seconds
>        ())))
>
> and compile-time code generation via macros, also 100% pure functional:
>
> (defun crack-seconds (seconds)
>   (macrolet ((c (name dur rest)
>         `(multiple-value-bind (res time)
>               ,rest
>            (multiple-value-bind (q r)
>               (floor time ,dur)
>             (values (cons (cons ,name r) res) q)))))
>     (c :days most-positive-fixnum
>       (c :hours 24
>        (c :minutes 60
>         (c :seconds 60
>             (values () seconds)))))))
>
>

You want BIND..

(bind ((a 2)
        ((b &rest args &key (c 2) &allow-other-keys) '(:a :c 5 :d 10 :e 54))
        ((:values d e) (truncate 4.5)))
   (list a b c d e args))
==> (2 :A 5 4 0.5 (:C 5 :D 10 :E 54))

http://common-lisp.net/project/metabang-bind/

--------------
John Thingstad
From: Alex Mizrahi
Subject: Re: I Gavino have hacked my first clisp program, believe it or not.
Date: 
Message-ID: <47f3bc5f$0$90272$14726298@news.sunsite.dk>
 JT> (bind ((a 2)
 JT>         ((b &rest args &key (c 2) &allow-other-keys) '(:a :c 5 :d 10 :e
 JT> 54))
 JT>         ((:values d e) (truncate 4.5)))
 JT>    (list a b c d e args))
 JT> ==> (2 :A 5 4 0.5 (:C 5 :D 10 :E 54))

 JT> http://common-lisp.net/project/metabang-bind/

impressive! 
From: Paul Donnelly
Subject: Re: I Gavino have hacked my first clisp program, believe it or not.
Date: 
Message-ID: <87bq4srfaa.fsf@plap.localdomain>
Jason <·······@gmail.com> writes:

> gavino <·········@gmail.com> writes:
>
>> (defun generate-dhms(seconds)
>>     (let* ((days        (floor (/ seconds (* 3600 24))))
>>            (hours       (floor (/ (- seconds (* days 3600 24)) 3600)))
>>            (minutes     (floor (/ (- seconds (* days 3600 24) (* hours
>> 3600)) 60)))
>>            (secs        (- seconds (* days 3600 24) (* hours 3600) (*
>> minutes 60))))
>>            (values days hours minutes secs)))
>
> I'm looking at this and all I see are magic numbers and increasingly complex
> subtractions and divisions. Yeah, it works, but it's kinda freaky. :P
>
> Personally, I prefer code to look a little more tidy. Check this out:
>
> CL-USER> (defun generate-dhms (seconds)
>   (let ((time seconds)
> 	(seconds 0)
> 	(minutes 0)
> 	(hours 0)
> 	(days 0))
>     ;; first: mod seconds from time, and subtract seconds from time
>     (setf seconds (mod time 60))
>     (setf time (/ (- time seconds) 60))
>
>     ;; second: mod minutes from time, and subtract minutes from time
>     (setf minutes (mod time 60))
>     (setf time (/ (- time minutes) 60))
>
>     ;; third: mod hours from time, and subtract hours from time
>     (setf hours (mod time 24))
>     (setf time (/ (- time hours) 24))
>
>     ;; fourth: set days equal to time, and return values as a plist
>     (setf days time)
>     (list :days days :hours hours :minutes minutes :seconds seconds)))
>
> GENERATE-DHMS
> CL-USER> (generate-dhms 882865)
> (:DAYS 10 :HOURS 5 :MINUTES 14 :SECONDS 25)

That's what he did, except you made it harder to follow and added
meaningless comments. Good call on returning a list rather than using
VALUES though. You can store that list, create accessor functions for
that list, and declare it as a data type. Can't do that with multiple
values.
From: Raymond Wiker
Subject: Re: I Gavino have hacked my first clisp program, believe it or not.
Date: 
Message-ID: <m263v0pawn.fsf@Macintosh-2.local>
Paul Donnelly <·············@sbcglobal.net> writes:

> Jason <·······@gmail.com> writes:
>
>> gavino <·········@gmail.com> writes:
>>
>>> (defun generate-dhms(seconds)
>>>     (let* ((days        (floor (/ seconds (* 3600 24))))
>>>            (hours       (floor (/ (- seconds (* days 3600 24)) 3600)))
>>>            (minutes     (floor (/ (- seconds (* days 3600 24) (* hours
>>> 3600)) 60)))
>>>            (secs        (- seconds (* days 3600 24) (* hours 3600) (*
>>> minutes 60))))
>>>            (values days hours minutes secs)))
>>
>> I'm looking at this and all I see are magic numbers and increasingly complex
>> subtractions and divisions. Yeah, it works, but it's kinda freaky. :P
>>
>> Personally, I prefer code to look a little more tidy. Check this out:
>>
>> CL-USER> (defun generate-dhms (seconds)
>>   (let ((time seconds)
>> 	(seconds 0)
>> 	(minutes 0)
>> 	(hours 0)
>> 	(days 0))
>>     ;; first: mod seconds from time, and subtract seconds from time
>>     (setf seconds (mod time 60))
>>     (setf time (/ (- time seconds) 60))
>>
>>     ;; second: mod minutes from time, and subtract minutes from time
>>     (setf minutes (mod time 60))
>>     (setf time (/ (- time minutes) 60))
>>
>>     ;; third: mod hours from time, and subtract hours from time
>>     (setf hours (mod time 24))
>>     (setf time (/ (- time hours) 24))
>>
>>     ;; fourth: set days equal to time, and return values as a plist
>>     (setf days time)
>>     (list :days days :hours hours :minutes minutes :seconds seconds)))
>>
>> GENERATE-DHMS
>> CL-USER> (generate-dhms 882865)
>> (:DAYS 10 :HOURS 5 :MINUTES 14 :SECONDS 25)
>
> That's what he did, except you made it harder to follow and added
> meaningless comments. Good call on returning a list rather than using
> VALUES though. You can store that list, create accessor functions for
> that list, and declare it as a data type. Can't do that with multiple
> values.

	No? What do you think multiple-value-list is for?

(defun seconds-to-dhms (secs)
	   (multiple-value-bind (t1 seconds) (truncate secs 60)
	     (multiple-value-bind (t2 minutes) (truncate t1 60)
	       (multiple-value-bind (days hours) (truncate t2 24)
		 (values days hours minutes seconds)))))
From: Paul Donnelly
Subject: Re: I Gavino have hacked my first clisp program, believe it or not.
Date: 
Message-ID: <877ifgqdue.fsf@plap.localdomain>
Raymond Wiker <···@RawMBP.local> writes:

> Paul Donnelly <·············@sbcglobal.net> writes:
>
>> Jason <·······@gmail.com> writes:
>>
>>> gavino <·········@gmail.com> writes:
>>>
>>>> (defun generate-dhms(seconds)
>>>>     (let* ((days        (floor (/ seconds (* 3600 24))))
>>>>            (hours       (floor (/ (- seconds (* days 3600 24)) 3600)))
>>>>            (minutes     (floor (/ (- seconds (* days 3600 24) (* hours
>>>> 3600)) 60)))
>>>>            (secs        (- seconds (* days 3600 24) (* hours 3600) (*
>>>> minutes 60))))
>>>>            (values days hours minutes secs)))
>>>
>>> I'm looking at this and all I see are magic numbers and increasingly
>>> complex subtractions and divisions. Yeah, it works, but it's kinda
>>> freaky. :P
>>>
>>> Personally, I prefer code to look a little more tidy. Check this out:
>>>
>>> CL-USER> (defun generate-dhms (seconds)
>>>   (let ((time seconds)
>>> 	(seconds 0)
>>> 	(minutes 0)
>>> 	(hours 0)
>>> 	(days 0))
>>>     ;; first: mod seconds from time, and subtract seconds from time
>>>     (setf seconds (mod time 60))
>>>     (setf time (/ (- time seconds) 60))
>>>
>>>     ;; second: mod minutes from time, and subtract minutes from time
>>>     (setf minutes (mod time 60))
>>>     (setf time (/ (- time minutes) 60))
>>>
>>>     ;; third: mod hours from time, and subtract hours from time
>>>     (setf hours (mod time 24))
>>>     (setf time (/ (- time hours) 24))
>>>
>>>     ;; fourth: set days equal to time, and return values as a plist
>>>     (setf days time)
>>>     (list :days days :hours hours :minutes minutes :seconds seconds)))
>>>
>>> GENERATE-DHMS
>>> CL-USER> (generate-dhms 882865)
>>> (:DAYS 10 :HOURS 5 :MINUTES 14 :SECONDS 25)
>>
>> That's what he did, except you made it harder to follow and added
>> meaningless comments. Good call on returning a list rather than using
>> VALUES though. You can store that list, create accessor functions for
>> that list, and declare it as a data type. Can't do that with multiple
>> values.
>
> 	No? What do you think multiple-value-list is for?
>
> (defun seconds-to-dhms (secs)
> 	   (multiple-value-bind (t1 seconds) (truncate secs 60)
> 	     (multiple-value-bind (t2 minutes) (truncate t1 60)
> 	       (multiple-value-bind (days hours) (truncate t2 24)
> 		 (values days hours minutes seconds)))))

For situations where someone returned multiple values instead of a list
like they should have?
From: Alex Mizrahi
Subject: Re: I Gavino have hacked my first clisp program, believe it or not.
Date: 
Message-ID: <47f35b91$0$90269$14726298@news.sunsite.dk>
 J> Personally, I prefer code to look a little more tidy.

 J> CL-USER> (defun generate-dhms (seconds)
 J>   (let ((time seconds)
 J>  (seconds 0)
 J>  (minutes 0)
 J>  (hours 0)
 J>  (days 0))
 J>     ;; first: mod seconds from time, and subtract seconds from time
 J>     (setf seconds (mod time 60))
 J>     (setf time (/ (- time seconds) 60))

i'd call this "shitty" rather than "tidy". (meaningless comments that just 
say what code do "in other words", doing division twice, repeating pieces of 
code..)

i see repeating pieces here, hence it is possible to do this in loop:

(defun crack-seconds (s)
  (loop for (name duration) in
            '#.(reverse (loop for (name rel-duration)
                                         in '((:seconds 1)
                                               (:minutes 60)
                                               (:hours 60)
                                               (:days 24))
                                         for abs-duration = 1 then (* 
abs-duration rel-duration)
                                         collect (list name abs-duration)))
              for (whole rest) = (multiple-value-list (floor s duration))
              collect name collect whole
              do (setf s rest)))

this might be an overkill, but this allows to easily add more intervals, 
like monthes and years (albeit that's more tricky, since they are varying).
we can do this without loop, capturing repeating pieces into a local 
function:

(defun crack-seconds (time)
  (flet ((crack (name duration)
    (multiple-value-bind (q r)
        (floor time duration)
      (setf time q)
      (cons name r))))
    (list (crack :seconds 60)
           (crack :minutes 60)
           (crack :hours 24)
           (list  :days time))))

that's just like your code, except it does not suck. 
From: Jason
Subject: Re: I Gavino have hacked my first clisp program, believe it or not.
Date: 
Message-ID: <6c8f04bd-1140-4e90-aaeb-6c5801f2a39e@d21g2000prf.googlegroups.com>
On Apr 2, 3:10 am, "Alex Mizrahi" <········@users.sourceforge.net>
wrote:
>  J> Personally, I prefer code to look a little more tidy.
>
>  J> CL-USER> (defun generate-dhms (seconds)
>  J>   (let ((time seconds)
>  J>  (seconds 0)
>  J>  (minutes 0)
>  J>  (hours 0)
>  J>  (days 0))
>  J>     ;; first: mod seconds from time, and subtract seconds from time
>  J>     (setf seconds (mod time 60))
>  J>     (setf time (/ (- time seconds) 60))
>
> i'd call this "shitty" rather than "tidy". (meaningless comments that just
> say what code do "in other words", doing division twice, repeating pieces of
> code..)
>
> i see repeating pieces here, hence it is possible to do this in loop:
>
> (defun crack-seconds (s)
>   (loop for (name duration) in
>             '#.(reverse (loop for (name rel-duration)
>                                          in '((:seconds 1)
>                                                (:minutes 60)
>                                                (:hours 60)
>                                                (:days 24))
>                                          for abs-duration = 1 then (*
> abs-duration rel-duration)
>                                          collect (list name abs-duration)))
>               for (whole rest) = (multiple-value-list (floor s duration))
>               collect name collect whole
>               do (setf s rest)))
>
> this might be an overkill, but this allows to easily add more intervals,
> like monthes and years (albeit that's more tricky, since they are varying).
> we can do this without loop, capturing repeating pieces into a local
> function:
>
> (defun crack-seconds (time)
>   (flet ((crack (name duration)
>     (multiple-value-bind (q r)
>         (floor time duration)
>       (setf time q)
>       (cons name r))))
>     (list (crack :seconds 60)
>            (crack :minutes 60)
>            (crack :hours 24)
>            (list  :days time))))
>
> that's just like your code, except it does not suck.

Criticism received.

-Jason
From: Giorgos Keramidas
Subject: Re: I Gavino have hacked my first clisp program, believe it or not.
Date: 
Message-ID: <874pajriff.fsf@kobe.laptop>
On Wed, 2 Apr 2008 13:10:20 +0300, "Alex Mizrahi" <········@users.sourceforge.net> wrote:
>  J> Personally, I prefer code to look a little more tidy.
>
>  J> CL-USER> (defun generate-dhms (seconds)
>  J>   (let ((time seconds)
>  J>  (seconds 0)
>  J>  (minutes 0)
>  J>  (hours 0)
>  J>  (days 0))
>  J>     ;; first: mod seconds from time, and subtract seconds from time
>  J>     (setf seconds (mod time 60))
>  J>     (setf time (/ (- time seconds) 60))
>
> i see repeating pieces here, hence it is possible to do this in loop:
>
> (defun crack-seconds (s)
>   (loop for (name duration) in
>      '#.(reverse (loop for (name rel-duration)
>                        in '((:seconds 1)
>                             (:minutes 60)
>                             (:hours 60)
>                             (:days 24))
>                        for abs-duration = 1 then (* abs-duration rel-duration)
>                        collect (list name abs-duration)))
>      for (whole rest) = (multiple-value-list (floor s duration))
>      collect name collect whole
>      do (setf s rest)))
>
> this might be an overkill, but this allows to easily add more
> intervals, like monthes and years (albeit that's more tricky, since
> they are varying).

Days can be tricky too; especially when leap seconds are involved.

There's also something implicitly hidden in the (name rel-duration) list
above that I am a bit uncomfortable with.  The rel-duration part of each
list refers to the number of smaller scale units, but it does so without
any sort of reference to the units themselves.

I'd probably go for an alist of the smaller scale units, and keep
converting to the next unit until no more conversions are possible:

CL-USER> (let ((time-units '((:seconds ((:seconds 1)))
                             (:minutes ((:seconds 60)))
                             (:hours ((:minutes 60) (:seconds 3600))))))
           (labels ((find-next-unit (unit-alist)
                      (car (rassoc (list (apply #'min (mapcar #'cadr unit-alist)))
                                   unit-alist
                                   :test #'equal))))
             (loop :for (name units)
                :in time-units
                :collect (list :name name
                               :next-unit (find-next-unit units)))))
=> ((:NAME :SECONDS :NEXT-UNIT :SECONDS)
    (:NAME :MINUTES :NEXT-UNIT :SECONDS)
    (:NAME :HOURS :NEXT-UNIT :MINUTES))

CLOS seems like a better match at arbitrary conversions between units,
though.  With a few custom classes like `time-interval-seconds', or
`time-interval-minutes', `time-interval-hours', etc. it seems like it
would be possible to have a more natural mapping between any-to-any
class of time intervals.

BTW: Congrats on the Lisp program, gavino :)
From: Ken Tilton
Subject: Re: I Gavino have hacked my first clisp program, believe it or not.
Date: 
Message-ID: <47f38f06$0$15167$607ed4bc@cv.net>
Good lord, isn't /anyone/ going to point out that floor takes a divisor???

Vagif Verdi wrote:
> You do not need to nest lets
> 
> (defun generate-hms(seconds)
>      (let* ((days    (floor (/ seconds (* 3600 24))))

   (floor seconds (* 3600 24))

>             (hours   (floor (/ (- seconds (* days 3600 24)) 3600)))
>             (minutes (floor (/ (- seconds (* days 3600 24) (* hours
> 3600)) 60)))
>             (secs    (- seconds (* days 3600 24 ) (* hours 3600) (*
> minutes 60))))
>         (values days hours minutes secs))

Once so taciturn now so prolix. Why?

(macrolet ((mvb (bs f &body bod) `(multiple-value-bind ,bs ,f ,@bod)))
   (let ((seconds (floor (get-internal-real-time) 
internal-time-units-per-second)))
     (mvb (tot-min sec) (floor seconds 60)
       (mvb (tot-hr min) (floor tot-min 60)
         (mvb (day hr) (floor tot-hr 24)
           (values day hr min sec))))))

kenny

-- 
http://smuglispweeny.blogspot.com/
http://www.theoryyalgebra.com/

"In the morning, hear the Way;
  in the evening, die content!"
                     -- Confucius
From: Alan Crowe
Subject: Re: I Gavino have hacked my first clisp program, believe it or not.
Date: 
Message-ID: <86ej9ojoqe.fsf@cawtech.freeserve.co.uk>
Ken Tilton <···········@optonline.net> writes:

> 
> (macrolet ((mvb (bs f &body bod) `(multiple-value-bind ,bs ,f ,@bod)))
>    (let ((seconds (floor (get-internal-real-time) 
> internal-time-units-per-second)))
>      (mvb (tot-min sec) (floor seconds 60)
>        (mvb (tot-hr min) (floor tot-min 60)
>          (mvb (day hr) (floor tot-hr 24)
>            (values day hr min sec))))))
> 

A nest like that cries out for a recursive macro

CL-USER> (defmacro base-bind (unit-var amount (&rest var-and-radix) &body code)
           (if (endp var-and-radix)
               `(let ((,unit-var ,amount)) ,@code)
               (let ((transfer (gensym)))
                 `(multiple-value-bind (,transfer ,unit-var)
                   (floor ,amount ,(cadar var-and-radix))
                   (base-bind ,(caar var-and-radix) ,transfer ,(cdr var-and-radix)
                     ,@code)))))

CL-USER> (base-bind pence 1000 ((shillings 12)(pounds 20))
           (list pounds shillings pence))
=> (4 3 4)

CL-USER> (base-bind seconds 100000 ((minutes 60)(hours 60)(days 24))
           (values days hours minutes seconds))
1
3
46
40

Alan Crowe
Edinburgh
Scotland
From: Ken Tilton
Subject: Re: I Gavino have hacked my first clisp program, believe it or not.
Date: 
Message-ID: <47f3bbe0$0$5612$607ed4bc@cv.net>
Alan Crowe wrote:
> Ken Tilton <···········@optonline.net> writes:
> 
> 
>>(macrolet ((mvb (bs f &body bod) `(multiple-value-bind ,bs ,f ,@bod)))
>>   (let ((seconds (floor (get-internal-real-time) 
>>internal-time-units-per-second)))
>>     (mvb (tot-min sec) (floor seconds 60)
>>       (mvb (tot-hr min) (floor tot-min 60)
>>         (mvb (day hr) (floor tot-hr 24)
>>           (values day hr min sec))))))
>>
> 
> 
> A nest like that cries out for a recursive macro

Because we expect to be needing something like this the next time gavino 
writes some code? :)

I think this falls into the category I threaded recently of stuff that 
seems like a good idea at the time but by the time it ever comes up 
again we forgot we did it. And write it again because it still seems 
like a good idea.

kenny

ps. Nice anyway. :) k

> 
> CL-USER> (defmacro base-bind (unit-var amount (&rest var-and-radix) &body code)
>            (if (endp var-and-radix)
>                `(let ((,unit-var ,amount)) ,@code)
>                (let ((transfer (gensym)))
>                  `(multiple-value-bind (,transfer ,unit-var)
>                    (floor ,amount ,(cadar var-and-radix))
>                    (base-bind ,(caar var-and-radix) ,transfer ,(cdr var-and-radix)
>                      ,@code)))))
> 
> CL-USER> (base-bind pence 1000 ((shillings 12)(pounds 20))
>            (list pounds shillings pence))
> => (4 3 4)
> 
> CL-USER> (base-bind seconds 100000 ((minutes 60)(hours 60)(days 24))
>            (values days hours minutes seconds))
> 1
> 3
> 46
> 40
> 
> Alan Crowe
> Edinburgh
> Scotland

-- 
http://smuglispweeny.blogspot.com/
http://www.theoryyalgebra.com/

"In the morning, hear the Way;
  in the evening, die content!"
                     -- Confucius
From: Leslie P. Polzer
Subject: Re: I Gavino have hacked my first clisp program, believe it or not.
Date: 
Message-ID: <8bef92bc-0087-4e24-92c4-f933da807048@a22g2000hsc.googlegroups.com>
Congratulations. I wonder what kept you from actually hacking for so
long.

Consider isolating bits of functionality:

> (let ((days (floor (/ seconds (* 3600 24)))))
> ; ...

becomes

(let ((days (seconds->days seconds))
; ...

with

(defun seconds->days (s)
  (floor (/ seconds (* 3600 24))))

or even

(defun seconds->hours (s)
  (floor (/ seconds 3600)))

(defun seconds->days (s)
  (floor (/ seconds (* (seconds->hours s) 24))))

But the whole GENERATE-HMS function seems pretty complicated to me.
Why scale down seconds to days and then use days as a base to
calculate the rest? This leads us to another thing you forgot: adding
documentation to non-obvious functions.

  HTH,

    Leslie
From: j.oke
Subject: Re: I Gavino have hacked my first clisp program, believe it or not.
Date: 
Message-ID: <5406c66d-674f-4370-b329-f6b7c018f5cb@c26g2000prf.googlegroups.com>
On 1 Apr 2008, from 03:03:03 to 03:09:12, gavino wrote code.

CL isn't lazy enough for you:

(or 'Arc 'Haskell nil) ; plz don't remove the quotes, otherwise you'll
have to evaluate!
From: gavino
Subject: Re: I Gavino have hacked my first clisp program, believe it or not.
Date: 
Message-ID: <3d44fdf2-4c72-4d61-b027-51ca5c8b6756@i12g2000prf.googlegroups.com>
On Apr 1, 4:18 am, "j.oke" <········@gmail.com> wrote:
> On 1 Apr 2008, from 03:03:03 to 03:09:12, gavino wrote code.
>
> CL isn't lazy enough for you:
>
> (or 'Arc 'Haskell nil) ; plz don't remove the quotes, otherwise you'll
> have to evaluate!

lol
 for sure!!

I am lazy!!
haskell seems lazy as hell but lisp has macros which could enable even
more lazyness by having programs write programs FOR me so lisp is the
way......forth also has a place in my heart....
From: John Thingstad
Subject: Re: I Gavino have hacked my first clisp program, believe it or not.
Date: 
Message-ID: <op.t8x21esxut4oq5@pandora.alfanett.no>
P� Tue, 01 Apr 2008 18:17:25 +0200, skrev gavino <·········@gmail.com>:

> On Apr 1, 4:18 am, "j.oke" <········@gmail.com> wrote:
>> On 1 Apr 2008, from 03:03:03 to 03:09:12, gavino wrote code.
>>
>> CL isn't lazy enough for you:
>>
>> (or 'Arc 'Haskell nil) ; plz don't remove the quotes, otherwise you'll
>> have to evaluate!
>
> lol
>  for sure!!
>
> I am lazy!!
> haskell seems lazy as hell but lisp has macros which could enable even
> more lazyness by having programs write programs FOR me so lisp is the
> way......forth also has a place in my heart....

Check out Liskell. Haskell with Lisp syntax and macroes.
The lazy mans choice :)

--------------
John Thingstad
From: Ken Tilton
Subject: Re: I Gavino have hacked my first clisp program, believe it or not.
Date: 
Message-ID: <47f214ee$0$5647$607ed4bc@cv.net>
gavino wrote:
> #!/usr/bin/clisp
> 
> (defun generate-hms(seconds)
>     (let ((days (floor (/ seconds (* 3600 24)))))
>         (let ((hours (floor (/ (- seconds (* days 3600 24)) 3600))))
>             (let ((minutes (floor (/ (- seconds (* days 3600 24) (*
> hours 3600)) 60))))
>                 (let ((secs (- seconds (* days 3600 24 ) (* hours
> 3600) (* minutes 60))))
>                     (values days hours minutes secs))))))
> 
> (defun show-hms-time(seconds)
>     (multiple-value-bind (d h m s) (generate-hms seconds)
>         (format t "Uptime: ~a days, ~a hours, ~a minutes, ~a seconds"
> d h m s)))

Says hms. Does dhms. Both. Why?
From: gavino
Subject: Re: I Gavino have hacked my first clisp program, believe it or not.
Date: 
Message-ID: <45daf705-1167-4881-aa58-e9e71874eafb@s13g2000prd.googlegroups.com>
On Apr 1, 3:56 am, Ken Tilton <···········@optonline.net> wrote:
> gavino wrote:
> > #!/usr/bin/clisp
>
> > (defun generate-hms(seconds)
> >     (let ((days (floor (/ seconds (* 3600 24)))))
> >         (let ((hours (floor (/ (- seconds (* days 3600 24)) 3600))))
> >             (let ((minutes (floor (/ (- seconds (* days 3600 24) (*
> > hours 3600)) 60))))
> >                 (let ((secs (- seconds (* days 3600 24 ) (* hours
> > 3600) (* minutes 60))))
> >                     (values days hours minutes secs))))))
>
> > (defun show-hms-time(seconds)
> >     (multiple-value-bind (d h m s) (generate-hms seconds)
> >         (format t "Uptime: ~a days, ~a hours, ~a minutes, ~a seconds"
> > d h m s)))
>
> Says hms. Does dhms. Both. Why?

I took it from here
http://clisp.wiki.sourceforge.net/shell+scripting
and modified it....the rename would be nice I admit.
Of course someone has modified this now to add load avg and some
goodies.
It originally read as:
#!/usr/bin/clisp

(defun generate-hms(seconds)
    (let ((hours (floor (/ seconds 3600))))
        (let ((minutes (floor (/ (- seconds (* hours 3600)) 60))))
            (let ((secs (- seconds (* hours 3600) (* minutes 60))))
                (values hours minutes secs)))))

(defun show-hms-time(seconds)
    (multiple-value-bind (h m s) (generate-hms seconds)
        (format t "Uptime: ~a hours, ~a minutes, ~a seconds" h m s)))

(defun parse-proc-uptime(line)
    (let ((text-first-number (subseq line 0 (search " " line))))
        (subseq text-first-number 0 (search "." text-first-number))))

(with-open-file (s "/proc/uptime" :direction :input)
    (let ((line (read-line s)))
        (show-hms-time (parse-integer (parse-proc-uptime line)))))