|
Prev: Earn 25 US$ in just 5 minutes . . .
Next: Creating symbols from strings and their use as slot names
From: cametan on 22 Jun 2008 03:47 I don't know where to post, then please let me post this here. I am using clisp 2.45 on Windows XP, and I found something strange. On Common Lisp, I believe that the S-expression below (cons '(a b c d) nil) or something like below (cons '(a b c d) '()) is evaluated like this. ((a b c d)) However, when I wrote a script like this: (defun pack (ls) (labels ((foo (ls0 ls1 ls2) (let ((x (car ls0)) (y (car ls1))) (cond ((null ls0) (reverse (cons ls1 ls2))) ;;;This returns result of its calculation ((eq x y) (foo (cdr ls0) (cons x ls1) ls2)) (t (foo (cdr ls0) (cons x nil) (cons ls1 ls2)))))));;;Does the 2nd args of recursive have some problem? (foo ls '() '()))) and made it run; for instance, it gave CL-USER> (pack '(a a a a b c c a a d e e e e)) (NIL (A A A A) (B) (C C) (A A) (D) (E E E E)) and cons of the list seemed to have unnecessary NIL. I'm not sure if it is a bug on clisp. Please give me some advice. Sorry about my strange English. (I'm not a native speaker)
From: Kojak on 22 Jun 2008 04:43 Le Sun, 22 Jun 2008 00:47:24 -0700 (PDT), cametan <Masashi.Kameda(a)gmail.com> a écrit : > However, when I wrote a script like this: > (defun pack (ls) > [...] > ) > > and made it run; for instance, it gave > > CL-USER> (pack '(a a a a b c c a a d e e e e)) > (NIL (A A A A) (B) (C C) (A A) (D) (E E E E)) > > and cons of the list seemed to have unnecessary NIL. It seems that you try to do some RLE encoding related stuff. Have a look on something like '99 lisp problems' with your favorite search engine. ;-) -- Jacques.
From: Tayssir John Gabbour on 22 Jun 2008 05:01 On Jun 22, 9:47 am, cametan <Masashi.Kam...(a)gmail.com> wrote: > I don't know where to post, then please let me post this here. No problem! > CL-USER> (pack '(a a a a b c c a a d e e e e)) > (NIL (A A A A) (B) (C C) (A A) (D) (E E E E)) > > and cons of the list seemed to have unnecessary NIL. Try to see what the function FOO is doing, using TRACE. Let's refactor out FOO into its own function: (defun pack-helper (ls0 ls1 ls2) (let ((x (car ls0)) (y (car ls1))) (cond ((null ls0) ;; This returns result of its calculation (reverse (cons ls1 ls2))) ((eq x y) (pack-helper (cdr ls0) (cons x ls1) ls2)) (t (pack-helper (cdr ls0) (cons x nil) (cons ls1 ;; Does the 2nd args of recursive ;; have some problem? ls2)))))) (defun pack (ls) (pack-helper ls '() '())) CL-USER> (trace pack-helper) (PACK-HELPER) CL-USER> (pack '(a a a a b c c a a d e e e e)) ;;; ... here it should become clear ... > I'm not sure if it is a bug on clisp. > Please give me some advice. Yes, whenever I stop trusting software, because it was hard to install or something, I start thinking the bug lies with the underlying software. ;) Tayssir
From: Tayssir John Gabbour on 22 Jun 2008 05:17 On Jun 22, 11:01 am, Tayssir John Gabbour <tayssir.j...(a)googlemail.com> wrote: > Try to see what the function FOO is doing, using TRACE. Let's refactor > out FOO into its own function: > > (defun pack-helper (ls0 ls1 ls2) > (let ((x (car ls0)) > (y (car ls1))) Argh, I poorly indented that! ;) Tayssir
From: Pascal J. Bourguignon on 22 Jun 2008 05:33 cametan <Masashi.Kameda(a)gmail.com> writes: > I don't know where to post, then please let me post this here. > > I am using clisp 2.45 on Windows XP, and I found something strange. So you want us to debug your code... > However, when I wrote a script like this: > > (defun pack (ls) > (labels ((foo (ls0 ls1 ls2) > (let ((x (car ls0)) > (y (car ls1))) > (cond ((null ls0) > (reverse (cons ls1 ls2))) ;;;This returns result > of its calculation > ((eq x y) > (foo (cdr ls0) (cons x ls1) ls2)) > (t > (foo (cdr ls0) (cons x nil) (cons ls1 > ls2)))))));;;Does the 2nd args of recursive have some problem? > (foo ls '() '()))) > > and made it run; for instance, it gave > > CL-USER> (pack '(a a a a b c c a a d e e e e)) > (NIL (A A A A) (B) (C C) (A A) (D) (E E E E)) > > and cons of the list seemed to have unnecessary NIL. > > I'm not sure if it is a bug on clisp. > Please give me some advice. > > Sorry about my strange English. (I'm not a native speaker) One debugging problem you have here is in the use of LABELS. You cannot use CL:TRACE on local functions. You have the choice between moving (temporarily) the FOO function to global scope (define it with DEFUN instead of LABELS), or using a macro like TRACE-LABELS instead of LABELS. Then it is obvious where the problem comes from: ;; From http://darcs.informatimago.com/public/lisp/common-lisp/ C/USER[37]> (use-package :com.informatimago.common-lisp.utility) T C/USER[38]> (defun pack (ls) (tracing-labels ((foo (ls0 ls1 ls2) (let ((x (car ls0)) (y (car ls1))) (cond ((null ls0) ;; This returns result of its calculation (reverse (cons ls1 ls2))) ((eq x y) (foo (cdr ls0) (cons x ls1) ls2)) (t ;; Does the 2nd args of recursive have some problem? (foo (cdr ls0) (cons x nil) (cons ls1 ls2))))))) (foo ls '() '()))) PACK C/USER[39]> (pack '(a a b c c)) Entering FOO (:LS0 (A A B C C) :LS1 NIL :LS2 NIL) Entering FOO (:LS0 (A B C C) :LS1 (A) :LS2 (NIL)) ; <<-- Here. Entering FOO (:LS0 (B C C) :LS1 (A A) :LS2 (NIL)) Entering FOO (:LS0 (C C) :LS1 (B) :LS2 ((A A) NIL)) Entering FOO (:LS0 (C) :LS1 (C) :LS2 ((B) (A A) NIL)) Entering FOO (:LS0 NIL :LS1 (C C) :LS2 ((B) (A A) NIL)) Exiting FOO --> (NIL (A A) (B) (C C)) Unwinding FOO Exiting FOO --> (NIL (A A) (B) (C C)) Unwinding FOO Exiting FOO --> (NIL (A A) (B) (C C)) Unwinding FOO Exiting FOO --> (NIL (A A) (B) (C C)) Unwinding FOO Exiting FOO --> (NIL (A A) (B) (C C)) Unwinding FOO Exiting FOO --> (NIL (A A) (B) (C C)) Unwinding FOO (NIL (A A) (B) (C C)) C/USER[40]> So when we (cons ls1 ls2) the first time, ls1 is NIL and this is wrong. C/USER[40]> (defun pack (ls) (tracing-labels ((foo (ls0 ls1 ls2) (let ((x (car ls0)) (y (car ls1))) (cond ((null ls0) ;; This returns result of its calculation (reverse (if ls1 (cons ls1 ls2) ls2))) ((eq x y) (foo (cdr ls0) (cons x ls1) ls2)) (t ;; Does the 2nd args of recursive have some problem? (foo (cdr ls0) (cons x nil) (if ls1 (cons ls1 ls2) ls2))))))) (foo ls '() '()))) PACK C/USER[41]> (pack '(a a b c c)) Entering FOO (:LS0 (A A B C C) :LS1 NIL :LS2 NIL) Entering FOO (:LS0 (A B C C) :LS1 (A) :LS2 NIL) Entering FOO (:LS0 (B C C) :LS1 (A A) :LS2 NIL) Entering FOO (:LS0 (C C) :LS1 (B) :LS2 ((A A))) Entering FOO (:LS0 (C) :LS1 (C) :LS2 ((B) (A A))) Entering FOO (:LS0 NIL :LS1 (C C) :LS2 ((B) (A A))) Exiting FOO --> ((A A) (B) (C C)) Unwinding FOO Exiting FOO --> ((A A) (B) (C C)) Unwinding FOO Exiting FOO --> ((A A) (B) (C C)) Unwinding FOO Exiting FOO --> ((A A) (B) (C C)) Unwinding FOO Exiting FOO --> ((A A) (B) (C C)) Unwinding FOO Exiting FOO --> ((A A) (B) (C C)) Unwinding FOO ((A A) (B) (C C)) C/USER[42]> > On Common Lisp, I believe that the S-expression below > > (cons '(a b c d) nil) > > or something like below > > (cons '(a b c d) '()) > > is evaluated like this. > > ((a b c d)) This is correct. But you are calling (cons '() nil) --> (nil) and then: (cons '(a a a) '(nil)) --> ((a a a) nil) -- __Pascal Bourguignon__ http://www.informatimago.com/ Nobody can fix the economy. Nobody can be trusted with their finger on the button. Nobody's perfect. VOTE FOR NOBODY.
|
Next
|
Last
Pages: 1 2 3 Prev: Earn 25 US$ in just 5 minutes . . . Next: Creating symbols from strings and their use as slot names |