I have a program....
(defun f (a b)
(defvar x)
(defvar y)
(setq x a)
(setq y b)
(cond ((> a 0)
(progn (format t "start ~d ~d~%" x y)
(f (- a 1) (- b 1))
(format t "end ~d ~d~%" x y)
)
)
)
)
when I call it by ( f 3 4)
the output is
start 3 4
start 2 3
start 1 2
end 0 1
end 0 1
end 0 1
that mean the value of x and y in a upper level will be changed by those in
the lower level of recusion.
I want to ask if there is any method to prevent the lower level from change
x y in the upper level??
i e the output will be
start 3 4
start 2 3
start 1 2
end 1 2
end 2 3
end 3 4
Thanks~
Herman
> I want to ask if there is any method to prevent the lower level from change
> x y in the upper level??
> i e the output will be
> start 3 4
> start 2 3
> start 1 2
> end 1 2
> end 2 3
> end 3 4
Original code:
(defun f (a b)
(defvar x)
(defvar y)
(setq x a)
(setq y b)
(cond ((> a 0)
(progn (format t "start ~d ~d~%" x y)
(f (- a 1) (- b 1))
(format t "end ~d ~d~%" x y)
)
)
)
)
Minor code rearrangement and correction:
1) Use Lisp indentation conventions. Your code looks like your cat
was walking on the keyboard or something.
2) Don't use defvar except at the top level. Think of defvar as a way
to declare global variables.
3) Use let for local variables.
4) You don't need progn with cond.
(defun f (a b)
(let ((x a)
(y b))
(cond ((> a 0)
(format t "start ~d ~d~%" x y)
(f (- a 1) (- b 1))
(format t "end ~d ~d~%" x y)))))
Output:
* (f 3 4)
start 3 4
start 2 3
start 1 2
end 1 2
end 2 3
end 3 4
NIL
*
You don't even need the local variables, since the arguments are also
local variables.
(defun f (a b)
(cond ((> a 0)
(format t "start ~d ~d~%" a b)
(f (- a 1) (- b 1))
(format t "end ~d ~d~%" a b))))
* (f 3 4)
start 3 4
start 2 3
start 1 2
end 1 2
end 2 3
end 3 4
NIL
*
You could also use when instead of cond, since you only have one
condition (but your instructor might not let you).
(defun f (a b)
(when (> a 0)
(format t "start ~d ~d~%" a b)
(f (- a 1) (- b 1))
(format t "end ~d ~d~%" a b)))
There are numerous misconceptions implied by the original code, and
I'm not sure how to address them.
Generally you only need setf when you want to make a `sticky change',
one that persists in some fashion. But you didn't want to make a
persistent change. So you shouldn't use setf.
A lot of people get confused with recursion. One way to think about
it is that once you've *started* defining a function (and not just
after you've finished defining it), that function becomes available to
call just like any other function.
Or you could imagine it like this:
(defun f (a b)
(cond ((> a 0)
(format t "start ~d ~d~%" a b)
(foo (- a 1) (- b 1)) ;;; <<<<<<
(format t "end ~d ~d~%" a b))))
So you are calling this function named foo that you intend to write
later, that does the right thing.
Once you are done writing the definition of f, you can just go back
and change the call to foo back to a call to f, and things will work,
since it turns out that f is the function named foo that you intended
to write later.
I hope this helps.
--
Fred Gilham ······@csl.sri.com
The density of a textbook must be inversely proportional to the
density of the students using it. --- Dave Stringer-Calvert
Fred Gilham wrote:
> Minor code rearrangement and correction:
>
> 1) Use Lisp indentation conventions. Your code looks like your cat
> was walking on the keyboard or something.
Also: write your code in Emacs, which is aware of Lisp indentation
conventions and moves the cursor to the correct column when you
press the tab key (and helps you to match parentheses).
Le Hibou
--
Dalinian: Lisp. Java. Which one sounds sexier?
RevAaron: Definitely Lisp. Lisp conjures up images of hippy coders,
drugs,
sex, and rock & roll. Late nights at Berkeley, coding in Lisp fueled by
LSD.
Java evokes a vision of a stereotypical nerd, with no life or social
skills.
Donald Fisk wrote:
> Fred Gilham wrote:
>
>
>>Minor code rearrangement and correction:
>>
>>1) Use Lisp indentation conventions. Your code looks like your cat
>> was walking on the keyboard or something.
>
>
> Also: write your code in Emacs, which is aware of Lisp indentation
> conventions and moves the cursor to the correct column when you
> press the tab key (and helps you to match parentheses).
There are other editors as well that are aware of Lisp indentation. Some
commercial Lisp implementations (including their free/reduced
trial/personal/educational versions) come with IDEs that also support
Lisp-aware source editing.
Both Lisp and Emacs take some time to learn, so if you are new to both
you might not want to learn them simultaneously. Of course, your (and
other people's) mileage may vary...
Pascal
"�p�Х�Tiny Tin" <·······@cuhk.edu.hk> writes:
> I have a program....
>
> (defun f (a b)
> (defvar x)
> (defvar y)
> (setq x a)
> (setq y b)
> (cond ((> a 0)
> (progn (format t "start ~d ~d~%" x y)
> (f (- a 1) (- b 1))
> (format t "end ~d ~d~%" x y)
> )
> )
> )
> )
>
DEFVAR establishes a dynamic variable and is usually only used at top
level. By calling (DEFVAR X), you are telling the compiler that you
want the variable X to be visible throughout your program, not just
within the function F.
SETQ modifies the value of a variable. Since the X is a dynamic
variable, the modification is visible everywhere. While every call to
F establishes new bindings for the variables A and B, you have
instructed the compiler to use the old bindings of X and Y, and
furthermore to modify the values of X and Y.
> when I call it by ( f 3 4)
> the output is
> start 3 4
> start 2 3
> start 1 2
> end 0 1
> end 0 1
> end 0 1
>
> that mean the value of x and y in a upper level will be changed by those in
> the lower level of recusion.
Exactly so. The DEFVAR says that you want to share X and Y across levels,
and the SETQ does the change.
> I want to ask if there is any method to prevent the lower level from change
> x y in the upper level??
Yes. Instead of DEFVAR, use a binding construct such as LET.
(defun f (a b)
(let ((x a)
(y b))
....))
Unless you arrange for it otherwise, a new binding for X and Y are
created each time and initialized to the values of A and B respectively.
But why not use A and B directly?
(defun f (a b)
(when (plusp a)
(format t "start ~d ~d~%" a b)
(f (1- a) (1- b))
(format t "end ~d ~d~%" a b)))
Joe Marshall wrote:
> "�p�Х�Tiny Tin" <·······@cuhk.edu.hk> writes:
>
>
>>I have a program....
>>
>>(defun f (a b)
>> (defvar x)
>> (defvar y)
>> (setq x a)
>> (setq y b)
>> (cond ((> a 0)
>> (progn (format t "start ~d ~d~%" x y)
>> (f (- a 1) (- b 1))
>> (format t "end ~d ~d~%" x y)
>> )
>> )
>> )
>>)
>>
>
>
<snip>
>>I want to ask if there is any method to prevent the lower level from change
>>x y in the upper level??
>
>
> Yes. Instead of DEFVAR, use a binding construct such as LET.
>
> (defun f (a b)
> (let ((x a)
> (y b))
> ....))
>
And the cool thing I hinted at earlier is that the above works even if x
and y are defvars. I mention this because the OP mentioned C, in which
many a time I had to take a local copy of a global one wishes to alter
temporarily and then restore before exiting.
kenny
clinisys
If you read up on defvar you will see why lower level changes to x and y
are seen at the upper level; that is part of what defvar is all about.
There is one cool way to avoid that and still use defvar, but why are
you using x and y at all? I ask because there may be more confusion here
than meets the eye.
kenny
clinisys
�p�Х�Tiny Tin wrote:
> I have a program....
>
> (defun f (a b)
> (defvar x)
> (defvar y)
> (setq x a)
> (setq y b)
> (cond ((> a 0)
> (progn (format t "start ~d ~d~%" x y)
> (f (- a 1) (- b 1))
> (format t "end ~d ~d~%" x y)
> )
> )
> )
> )
>
> when I call it by ( f 3 4)
> the output is
> start 3 4
> start 2 3
> start 1 2
> end 0 1
> end 0 1
> end 0 1
>
> that mean the value of x and y in a upper level will be changed by those in
> the lower level of recusion.
> I want to ask if there is any method to prevent the lower level from change
> x y in the upper level??
> i e the output will be
> start 3 4
> start 2 3
> start 1 2
> end 1 2
> end 2 3
> end 3 4
>
> Thanks~
> Herman
>
>
>
Kenny Tilton <·······@nyc.rr.com> writes:
> If you read up on defvar you will see why lower level changes to x and y
> are seen at the upper level; that is part of what defvar is all about.
> There is one cool way to avoid that and still use defvar, but why are
> you using x and y at all? I ask because there may be more confusion here
> than meets the eye.
I'm guessing that the original poster doesn't know about LET, and
thinks that DEFVAR is supposed to do what LET actually does. I'm
further guessing that this is a contrived example for debugging.
> kenny
> clinisys
>
> �p�Х�Tiny Tin wrote:
> > I have a program....
> >
> > (defun f (a b)
> > (defvar x)
> > (defvar y)
> > (setq x a)
> > (setq y b)
> > (cond ((> a 0)
> > (progn (format t "start ~d ~d~%" x y)
> > (f (- a 1) (- b 1))
> > (format t "end ~d ~d~%" x y)
...
--
Thomas A. Russ, USC/Information Sciences Institute ···@isi.edu
My feeling is that, even had it been homework, the question included an
obviously original (read "novice") brave effort, and he asked a specific
question about why it was not working, as opposed to simply asking us to
provide the solution, so all that is fine.
hey, I am just glad to hear Lisp is alive and well and being taught in
Hong Kong. :)
kenny
clinisys
(I am thinking if I reply to everything written by folks in last week's
Top Ten I could even win this week!)
Will Deakin wrote:
> Hmmm. I smell homework. It's that time again.
>
> :)w
>
Kenny Tilton wrote:
> My feeling is that, even had it been homework, the question included an
> obviously original (read "novice") brave effort, and he asked a specific
> question about why it was not working, as opposed to simply asking us to
> provide the solution, so all that is fine.
You are absolutely correct. My response was somewhat in jest however.
Unfortunately, it was not funny and as it was the initial reply and so
on consideration I should have waited -- or perhaps never posted -- my
half-arsed reply.
> hey, I am just glad to hear Lisp is alive and well and being taught in
> Hong Kong. :)
Cool isn't it.
:)w
Kenny Tilton wrote:
> (I am thinking if I reply to everything written by folks in last week's
> Top Ten I could even win this week!)
(But this is *war*! I will now have to reply to everyone of your replies
to my replies. This could either involve a complex programming solution
or get rather silly...)
Yes,It's an AI course.
"Kenny Tilton" <·······@nyc.rr.com> ���g��l��s�D
·················@nyc.rr.com...
> My feeling is that, even had it been homework, the question included an
> obviously original (read "novice") brave effort, and he asked a specific
> question about why it was not working, as opposed to simply asking us to
> provide the solution, so all that is fine.
>
> hey, I am just glad to hear Lisp is alive and well and being taught in
> Hong Kong. :)
>
> kenny
> clinisys
>
> (I am thinking if I reply to everything written by folks in last week's
> Top Ten I could even win this week!)
>
> Will Deakin wrote:
> > Hmmm. I smell homework. It's that time again.
> >
> > :)w
> >
>
yes, I am doing homework ,but the program I wrote is not part of it.
I come across this problem when I wrote a program to find the exit of a
maze.
It used recusion.
However I can't fix the bug that similar to the program I wrote...
I have learnt lisp for several days only...
if you don't want to answer my question, could you please give me some links
that talk about my question? so I can have a look on it,
Thanks
Herman
"Will Deakin" <···········@hotmail.com> ���g��l��s�D
·············@newsreaderm1.core.theplanet.net...
> Hmmm. I smell homework. It's that time again.
>
> :)w
>
Tiny Tin wrote:
> yes, I am doing homework ,but the program I wrote is not part of it.
Sure. My concern is that at this time of year many courses start and
that this can lead to a flood of thinly disguised homework assignments
being posted with demands for answers.
> However I can't fix the bug that similar to the program I wrote...
> I have learnt lisp for several days only...
Well, enjoy. IMHO it is the best programming language there is.
> if you don't want to answer my question, could you please give me some links
> that talk about my question? so I can have a look on it,
I am no trying to put off your search for knowledge. However, it is
not my intention to do or encourage others to do your homework for you.
Meanwhile, Raymond Wiker in his excellent posting has already answered
your question. (I will claim[1] that the points he makes about
indentation, use of defvar to bind variables and the use of cond
rather than when or if are exactly the same as the ones I was about to
make.)
I realise that it may now be a bit scary, but it would be also
worthwhile to look at the online hyperspec and the online version of
common lisp, the language (cltl2)[2]. (I would now like to thank all
involved in making these excellent resources available on the web.)
:)w
[1] at least to save further embarasment...
[2] www.lispworks.com/reference/HyperSpec/Front/index.htm
[3] for example: www.ida.liu.se/imported/cltl/clm/clm.html
�p�Х�Tiny Tin wrote:
> I have a program....
[...]
> that mean the value of x and y in a upper level will be changed by those in
> the lower level of recusion.
> I want to ask if there is any method to prevent the lower level from change
> x y in the upper level??
You seem to get several fundamental concepts wrong at the moment,
especially the difference between "binding" and "assignment".
Consider to read a tutorial on Common Lisp, for example "Successful
Lisp" (http://www.psg.com/~dlamkins/sl/cover.html, especially chapter
3), or "ANSI Common Lisp" by Paul Graham.
All the best,
Pascal
--
Pascal Costanza University of Bonn
···············@web.de Institute of Computer Science III
http://www.pascalcostanza.de R�merstr. 164, D-53117 Bonn (Germany)
> You seem to get several fundamental concepts wrong at the moment,
> especially the difference between "binding" and "assignment".
Yes, as I have started learning lisp for a few days only...
> Consider to read a tutorial on Common Lisp, for example "Successful
> Lisp" (http://www.psg.com/~dlamkins/sl/cover.html, especially chapter
> 3), or "ANSI Common Lisp" by Paul Graham.
In fact I have watched this , however I am still not clear about blinding or
assignment.
lisp is so differernt form C or JAVA!!
Herman
"�p�Х�Tiny Tin" <·······@cuhk.edu.hk> writes:
>
> lisp is so differernt form C or JAVA!!
It only looks that way at first. Here is an analagous program in C:
void f (int a, int b)
{
static int x; /* (DEFVAR X) */
static int y;
x = a; /* (SETQ X A) */
y = b;
if (a > 0) {
/* (PROGN ...) */
{
printf ("start %d %d\n", x, y);
f (a - 1, b - 1);
printf ("end %d %d\n", x, y);
}
} else {};
}
The DEFVAR is analagous to the static declaration,
then the assignment to the static X and Y.
A one-conditional COND statement is somewhat like the
IF ELSE with a null ELSE --- very odd looking.
The PROGN is as unnecessary in the COND as the extra
set of braces in the IF.
OH~I don't have time to make a C version. :p
"Kenny Tilton" <·······@nyc.rr.com> ���g��l��s�D
·················@nyc.rr.com...
>
>
> �p�Х�Tiny Tin wrote:
> > lisp is so differernt form C or JAVA!!
>
> Great idea. Show us your C version, we can work from that to the Lisp.
>
> kenny
> clinisys
>
"�p�Х�Tiny Tin" <·······@cuhk.edu.hk> wrote:
> In fact I have watched this , however I am still not clear about blinding or
> assignment.
Figure those out and you'll be /way/ ahead.
--
(concatenate 'string "cbbrowne" ·@acm.org")
http://www3.sympatico.ca/cbbrowne/lisp.html
This Bloody Century
"Early this century there was a worldwide socialist revolution. The
great battles were then between International Socialism, National
Socialism, and Democratic Socialism. Democratic Socialism won because
the inertia of democracy prevented the socialism from doing as much
damage here. Capitalism first reemerged from the ashes of National
Socialism, in Germany and Japan. It is now reemerging from the ashes
of International Socialism. Next?
After all, inertia works both ways..."
-- Mark Miller
�p�Х�Tiny Tin wrote:
>>You seem to get several fundamental concepts wrong at the moment,
>>especially the difference between "binding" and "assignment".
>
> Yes, as I have started learning lisp for a few days only...
>
>>Consider to read a tutorial on Common Lisp, for example "Successful
>>Lisp" (http://www.psg.com/~dlamkins/sl/cover.html, especially chapter
>>3), or "ANSI Common Lisp" by Paul Graham.
>
> In fact I have watched this , however I am still not clear about blinding or
> assignment.
>
> lisp is so differernt form C or JAVA!!
Yes, it is. Therefore, you shouldn't try to imitate Java or C in Lisp,
but rather you should try to imitate what you see in those Lisp
tutorials. Read those tutorials carefully (!), do the exercises you find
there and, above all, remember that it takes time to learn a new
language, especially when it's so different from the mainstream. Be patient.
Pascal
--
Pascal Costanza University of Bonn
···············@web.de Institute of Computer Science III
http://www.pascalcostanza.de R�merstr. 164, D-53117 Bonn (Germany)
"�p�Х�Tiny Tin" <·······@cuhk.edu.hk> writes:
> I have a program....
>
> (defun f (a b)
> (defvar x)
> (defvar y)
> (setq x a)
> (setq y b)
> (cond ((> a 0)
> (progn (format t "start ~d ~d~%" x y)
> (f (- a 1) (- b 1))
> (format t "end ~d ~d~%" x y)
> )
> )
> )
> )
First of all, it is _not_ a good idea to format Lisp code in
this way. The canonical way looks (something like) this:
(defun f (a b)
(defvar x)
(defvar y)
(setq x a)
(setq y b)
(cond ((> a 0)
(progn
(format t "start ~d ~d~%" x y)
(f (- a 1) (- b 1))
(format t "end ~d ~d~%" x y)))))
Second, Lisp has plenty of conditionals, and in this case you
should probably use "when" or "if":
(defun f (a b)
(defvar x)
(defvar y)
(setq x a)
(setq y b)
(when (> a 0)
(format t "start ~d ~d~%" x y)
(f (- a 1) (- b 1))
(format t "end ~d ~d~%" x y)))
Finally, your problem is that you use "defvar" instead of
"let". "defvar" is used to declare something very similar to a global
variable, which is clearly not what you want.
(defun f (a b)
(let ((x a)
(y b))
(when (> x 0)
(format t "start ~d ~d~%" x y)
(f (- a 1) (- b 1))
(format t "end ~d ~d~%" x y))))
* (f 3 4)
start 3 4
start 2 3
start 1 2
end 1 2
end 2 3
end 3 4
NIL
*
--
Raymond Wiker Mail: ·············@fast.no
Senior Software Engineer Web: http://www.fast.no/
Fast Search & Transfer ASA Phone: +47 23 01 11 60
P.O. Box 1677 Vika Fax: +47 35 54 87 99
NO-0120 Oslo, NORWAY Mob: +47 48 01 11 60
Try FAST Search: http://alltheweb.com/
Thank you so much~
As this is my first lisp program, there is lots of things that I am not
clear.
I will do my best to fixed the bug~
Herman
"Raymond Wiker" <·············@fast.no> ���g��l��s�D
···············@raw.grenland.fast.no...
> "�p�Х�Tiny Tin" <·······@cuhk.edu.hk> writes:
>
> > I have a program....
> >
> > (defun f (a b)
> > (defvar x)
> > (defvar y)
> > (setq x a)
> > (setq y b)
> > (cond ((> a 0)
> > (progn (format t "start ~d ~d~%" x y)
> > (f (- a 1) (- b 1))
> > (format t "end ~d ~d~%" x y)
> > )
> > )
> > )
> > )
>
> First of all, it is _not_ a good idea to format Lisp code in
> this way. The canonical way looks (something like) this:
>
> (defun f (a b)
> (defvar x)
> (defvar y)
> (setq x a)
> (setq y b)
> (cond ((> a 0)
> (progn
> (format t "start ~d ~d~%" x y)
> (f (- a 1) (- b 1))
> (format t "end ~d ~d~%" x y)))))
>
> Second, Lisp has plenty of conditionals, and in this case you
> should probably use "when" or "if":
>
> (defun f (a b)
> (defvar x)
> (defvar y)
> (setq x a)
> (setq y b)
> (when (> a 0)
> (format t "start ~d ~d~%" x y)
> (f (- a 1) (- b 1))
> (format t "end ~d ~d~%" x y)))
>
> Finally, your problem is that you use "defvar" instead of
> "let". "defvar" is used to declare something very similar to a global
> variable, which is clearly not what you want.
>
> (defun f (a b)
> (let ((x a)
> (y b))
> (when (> x 0)
> (format t "start ~d ~d~%" x y)
> (f (- a 1) (- b 1))
> (format t "end ~d ~d~%" x y))))
>
> * (f 3 4)
> start 3 4
> start 2 3
> start 1 2
> end 1 2
> end 2 3
> end 3 4
> NIL
> *
>
> --
> Raymond Wiker Mail: ·············@fast.no
> Senior Software Engineer Web: http://www.fast.no/
> Fast Search & Transfer ASA Phone: +47 23 01 11 60
> P.O. Box 1677 Vika Fax: +47 35 54 87 99
> NO-0120 Oslo, NORWAY Mob: +47 48 01 11 60
>
> Try FAST Search: http://alltheweb.com/