Hi,
sorry if this is old hat to all but I have a problem writing a simple
recursive function.
Suppose I am modelling a simple dice game.
The rules are:
1) record each die roll as a list
2) if the die comes up 6, roll twice.
Ie,, assuming a function d()=y
Then y should return (1) , (3 2), (2 4 5) etc.
I'm having a hell of a time writing a function that doesn't return ( 2 (4
5))
What I've got so far:
(defun D (/ DICE)
(list
(setq
DICE (RollDie)
DICE (if (= DICE 6)
(list (D)
(D)
) ;_ end of list
DICE
) ;_ end of if
) ;_ end of setq
) ;_ end of list
) ;_ end of defun
Some return values:
(5)
(((3) (((1) (1)))))
(2)
(5)
(5)
Any ideas?
Thank you,
Kevin Hayward
-----= Posted via Newsfeeds.Com, Uncensored Usenet News =-----
http://www.newsfeeds.com - The #1 Newsgroup Service in the World!
-----== Over 80,000 Newsgroups - 16 Different Servers! =-----
"Kevin Hayward" <············@hotmail.com> writes:
> Hi,
>
> sorry if this is old hat to all but I have a problem writing a simple
> recursive function.
>
> Suppose I am modelling a simple dice game.
>
> The rules are:
>
> 1) record each die roll as a list
>
> 2) if the die comes up 6, roll twice.
>
> Ie,, assuming a function d()=y
>
> Then y should return (1) , (3 2), (2 4 5) etc.
>
> I'm having a hell of a time writing a function that doesn't return ( 2 (4
> 5))
look at cons instead of list, and here is an iterative solution:
(defun roll ()
(1+ (floor (random 6))))
(defun dice (count )
(let (list roll)
(dotimes ( i count)
(setf roll (roll))
(if (= roll 6)
(push (list roll (roll)) list)
(push roll list)))
(reverse list)))
If you want to do hris recursively, smells like homework, think
about the problem.
lets take out the 6 is special rule for now
if number of rolls left is < 1 stop anf return nil
else
roll dice
add to return list
1- from count to roll
call function wit new count
end
also look at the difference between
(cons 4 (cons 5 (cons 6 ())))
and
(list 4 (list 5 (list 6 ())))
then answer the wuestion why do they
look so different, review the definition
of a proper list and a cons cell
marc
ps the code below is ugly and hard to read,
you might want to fix that
(defun D (/ DICE)
(list
(setq
DICE (RollDie)
DICE (if (= DICE 6)
(list (D)(D))
DICE))))
marc
>
> What I've got so far:
>
> (defun D (/ DICE)
> (list
> (setq
> DICE (RollDie)
> DICE (if (= DICE 6)
> (list (D)
> (D)
> ) ;_ end of list
> DICE
> ) ;_ end of if
> ) ;_ end of setq
> ) ;_ end of list
> ) ;_ end of defun
>
> Some return values:
>
> (5)
> (((3) (((1) (1)))))
> (2)
> (5)
> (5)
>
> Any ideas?
>
> Thank you,
>
> Kevin Hayward
>
>
>
>
>
> -----= Posted via Newsfeeds.Com, Uncensored Usenet News =-----
> http://www.newsfeeds.com - The #1 Newsgroup Service in the World!
> -----== Over 80,000 Newsgroups - 16 Different Servers! =-----
"Kevin Hayward" <············@hotmail.com> wrote in message
···············@corp.newsgroups.com...
> Hi,
>
> sorry if this is old hat to all but I have a problem writing a simple
> recursive function.
>
> Suppose I am modelling a simple dice game.
>
> The rules are:
>
> 1) record each die roll as a list
>
> 2) if the die comes up 6, roll twice.
>
> Ie,, assuming a function d()=y
>
> Then y should return (1) , (3 2), (2 4 5) etc.
>
> I'm having a hell of a time writing a function that doesn't return ( 2 (4
> 5))
>
> What I've got so far:
>
> (defun D (/ DICE)
> (list
> (setq
> DICE (RollDie)
> DICE (if (= DICE 6)
> (list (D)
> (D)
> ) ;_ end of list
> DICE
> ) ;_ end of if
> ) ;_ end of setq
> ) ;_ end of list
> ) ;_ end of defun
>
> Some return values:
>
> (5)
> (((3) (((1) (1)))))
> (2)
> (5)
> (5)
>
> Any ideas?
>
> Thank you,
Thanks Coby and Mark,
in the end I worked it out by:
a) Using a RESULT variable.
b) Not using a return value from the die roll function
(defun D ( / DICE)
(setq
DICE (ROLL)
RESULT
(append
(if
(= DICE 6)
(progn
(D)
(D)
NIL
) ;_ end of progn
(list DICE)
) ;_ end of if
RESULT
) ;_ end of append
) ;_ end of setq
) ;_ end of defun
Many thanks, again,
Kevin Hayward
-----= Posted via Newsfeeds.Com, Uncensored Usenet News =-----
http://www.newsfeeds.com - The #1 Newsgroup Service in the World!
-----== Over 80,000 Newsgroups - 16 Different Servers! =-----
Kevin Hayward <············@hotmail.com> wrote:
> Thanks Coby and Mark,
> in the end I worked it out by:
> a) Using a RESULT variable.
> b) Not using a return value from the die roll function
> (defun D ( / DICE)
> (setq
> DICE (ROLL)
> RESULT
> (append
> (if
> (= DICE 6)
> (progn
> (D)
> (D)
> NIL
> ) ;_ end of progn
> (list DICE)
> ) ;_ end of if
> RESULT
> ) ;_ end of append
> ) ;_ end of setq
> ) ;_ end of defun
You might want to seriously consider adopting the style used by other
posters here. "end of X" comments aren't necessary because the
indentation shows that. Similar with the trailing parens on a separate
line. It makes your code longer and it looks like some kind of demonic
C/Lisp hybrid. All decent lisp environments automatically indent to
match the semantic structure of your program's expressions, so that kind
of comment is purely a crutch. Get used to reading code without it, it
won't take long for that to be *easier*.
It's also fairly standard to use all lower case except when trying to
highlight something unusual. There's no real need to highlight
variables v. functions -- you can always tell a function call by its
place in the form, or a passed function by "#'". I suppose this is
slightly less transparent in Scheme or some other lisp-1, but I don't
know any scheme people who do that either. I think all lower case
became the norm because 1. It's easier to type, and 2. Typical lisp
environments print results in all upper case, so they become easily
distinguishable from code. Since CL code is not case-sensitive, case is
purely a formatting issue.
Michael
"Michael Sullivan" <···@panix.com> wrote in message
·······························@panix.com...
> Kevin Hayward <············@hotmail.com> wrote:
>
> > Thanks Coby and Mark,
>
> > in the end I worked it out by:
>
> > a) Using a RESULT variable.
>
> > b) Not using a return value from the die roll function
>
> > (defun D ( / DICE)
> > (setq
> > DICE (ROLL)
> > RESULT
> > (append
> > (if
> > (= DICE 6)
> > (progn
> > (D)
> > (D)
> > NIL
> > ) ;_ end of progn
> > (list DICE)
> > ) ;_ end of if
> > RESULT
> > ) ;_ end of append
> > ) ;_ end of setq
> > ) ;_ end of defun
>
What version of Lisp are you using (/ Dice) why
is a / inside the argument List.
Is this CommonLisp, or XLisp?
The (/ DICE) is rather weird to me because / is never
used in the function D.
I've used Lisp for a long time and never saw a
parameter list like that--could you tell me what
it does, Thanx
"Franz Kafka" <Symbolics _ XL1201 _ Sebek _ Budo _ Kafka @ hotmail . com>
wrote in message ····················@news02.roc.ny.frontiernet.net...
<snip>
> > (defun D ( / DICE)
...
> > ) ;_ end of defun
> What version of Lisp are you using (/ Dice) why
> is a / inside the argument List.
>
> Is this CommonLisp, or XLisp?
>
> The (/ DICE) is rather weird to me because / is never
> used in the function D.
>
> I've used Lisp for a long time and never saw a
> parameter list like that--could you tell me what
> it does, Thanx
>
I'm using AutoLISP.
In AutoLISP, the form (defun ( x / y) ...) as a list of defun parameters
indicates that (x) is the value(s) passed to the function, while (y) is a
list of local variables.
Also, in response to many comments about coding style, I'm writing code for
myself, so I can read it. If somebody wants to pay me to write code, then
I'll write it any way they tell me to. For the moment, trailing parens make
reading my code easier (for me, anyway).
BTW, is reading code without comments *really* easier? Again, I want ease of
readability, so I use any and all crutches I can.
Thank you,
Kevin Hayward
-----= Posted via Newsfeeds.Com, Uncensored Usenet News =-----
http://www.newsfeeds.com - The #1 Newsgroup Service in the World!
-----== Over 80,000 Newsgroups - 16 Different Servers! =-----
On Tue, May 20, 2003 at 03:05:38PM -0700, Kevin Hayward wrote:
> In AutoLISP, the form (defun ( x / y) ...) as a list of defun parameters
> indicates that (x) is the value(s) passed to the function, while (y) is a
> list of local variables.
Hmm. I don't know whether you're trying to just learn Lisp, or trying to write
some kind of AutoCAD extension. If the former, I highly recommend against
using AutoLisp, and if the latter, there are some AutoCAD specific newsgroups
which might be of more use.
Common Lisp is preferred over AutoLisp here because it is meant to be a real
programming language, rather than an extension language, and it has a much more
modern design. Very little AutoLisp discussion takes place here, mostly enough
to redirect people to the proper newsgroups.
> Also, in response to many comments about coding style, I'm writing code for
> myself, so I can read it. If somebody wants to pay me to write code, then
> I'll write it any way they tell me to. For the moment, trailing parens make
> reading my code easier (for me, anyway).
You have a good point, except that your assumption is false. You are posting
code on a newsgroup for other people to critique. You should take pains to
accomodate their wishes, otherwise they may decide to simply dismiss it as a
waste of time.
> BTW, is reading code without comments *really* easier? Again, I want ease of
> readability, so I use any and all crutches I can.
Well, if you do want tips on readability, then I can offer a few:
Use a proper code editor such as Emacs, vim, Jabberwocky, or anything with a
Lisp plug-in.
This will give you: automatic indentation, parenthesis matching, syntax
highlighting, tab-completion of names, inspection of objects, online help,
keybindings for incremental compilation and evaluation, a nicer debugger, etc etc.
The first two are the most important, really. With these, you will not need to
space out the closing parenthesis nor will you need to put comment tags on
them. Your style of coding is ugly, hard-to-read, and a waste of screen space.
You should use indentation as your guide, and let the editor handle the
parenthesis.
(defun foo ()
(let ((a 1)
(b 2))
(setq a 3
b 4)
(call-a-procedure a b)
(if (< (compute-something a)
(compute-another-thing b))
"yes"
"no")))
With indentation, I can see that A and B are defined within a certain block of
code, I can see the arguments to the function <, I can see the arguments to the
special operator IF.
URLs:
http://www.cliki.net/
http://www.lisp.org/
http://www.cc.gatech.edu/computing/classes/cs2360/ghall/style/Good-Lisp-Style.ps
http://cl-cookbook.sourceforge.net/
--
; Matthew Danish <·······@andrew.cmu.edu>
; OpenPGP public key: C24B6010 on keyring.debian.org
; Signed or encrypted mail welcome.
; "There is no dark side of the moon really; matter of fact, it's all dark."
"Kevin Hayward" <············@hotmail.com> writes:
> BTW, is reading code without comments *really* easier? Again, I want ease of
> readability, so I use any and all crutches I can.
It all depends on the structure and size of the function.
Under about 10 lines, there's really no need for them.
Above a window-height worth of lines of code, when I've good heavily
nested code, I find useful to comment the end of some important
control structures. But not all of them! Usually, you have related
control structures: you often have a final control structure inside a
let inside a if, a cond or a lambda, then you just label the topmost
structure: )));;cond, or you if you have several ifs imbricated, you
don't need to label each end if, just the enclosing one: ))));;if
Personnaly, I've got the convention to repeat the name of the function
at the end, which I respect scrupulously even for one-liners.
(defun small-fun ()
;;
);;small-fun
This convention is very nice when you've got biffer functions, because
it let you see to what function pertains code that's scrolling off the
window.
--
__Pascal_Bourguignon__ http://www.informatimago.com/
----------------------------------------------------------------------
Do not adjust your mind, there is a fault in reality.
Pascal Bourguignon <····@thalassa.informatimago.com> writes:
> Personnaly, I've got the convention to repeat the name of the function
> at the end, which I respect scrupulously even for one-liners.
>
> (defun small-fun ()
> ;;
> );;small-fun
>
> This convention is very nice when you've got biffer functions, because
> it let you see to what function pertains code that's scrolling off the
> window.
It can create a maintenance problem, though, since if you change the name you
have to just as scrupulously maintain those comments. What if someone not as
scrupulous as you is the next maintainer of the code?
An inaccurate comment is worse than no comment at all.
For me, I prefer to do not the extra work at all. When in doubt, the name of
the method is just few keystrokes away in Emacs.
--
Cheers, The Rhythm is around me,
The Rhythm has control.
Ray Blaak The Rhythm is inside me,
········@STRIPCAPStelus.net The Rhythm has my soul.
Ray Blaak <········@STRIPCAPStelus.net> writes:
> Pascal Bourguignon <····@thalassa.informatimago.com> writes:
> > Personnaly, I've got the convention to repeat the name of the function
> > at the end, which I respect scrupulously even for one-liners.
> >
> > (defun small-fun ()
> > ;;
> > );;small-fun
> >
> > This convention is very nice when you've got biffer functions, because
> > it let you see to what function pertains code that's scrolling off the
> > window.
>
> It can create a maintenance problem, though, since if you change the name you
> have to just as scrupulously maintain those comments. What if someone not as
> scrupulous as you is the next maintainer of the code?
>
> An inaccurate comment is worse than no comment at all.
>
> For me, I prefer to do not the extra work at all. When in doubt, the name of
> the method is just few keystrokes away in Emacs.
Thanks to emacs, it's automatically updated each time I save a buffer:
(defun update-def-names ()
"
DO: Update comments at the end of each defmacro,defun,defwhatever
that stands on serveral lines.
"
(interactive)
(goto-char (point-min))
(forward-sexp)
(while (< (point) (point-max))
(let ((start (point))
end)
(backward-sexp)
(setq end (point))
(let ((sexp (sexp-at-point)))
(forward-sexp)
(when (and
(< 1 (count-lines start end))
(consp sexp)
(symbolp (car sexp))
(string-equal
(upcase (substring (symbol-name (car sexp)) 0 3)) "DEF"))
(delete-region (point) (progn (end-of-line) (point)))
(insert (format ";;%s" (second sexp))))))
(forward-sexp))
);;update-def-names
(defadvice save-buffer
(before pjb-update-eof-save-buffer (&optional ARGS))
"This advice updates the eof comment before saving the buffer."
(interactive "p")
(when (memq major-mode '(lisp-mode emacs-lisp-mode scheme-mode))
(update-def-names))
(pjb-update-eof t)
);;save-buffer
(ad-activate 'save-buffer)
--
__Pascal_Bourguignon__ http://www.informatimago.com/
----------------------------------------------------------------------
Do not adjust your mind, there is a fault in reality.
"Franz Kafka" <Symbolics _ XL1201 _ Sebek _ Budo _ Kafka @ hotmail . com>
wrote in message ····················@news02.roc.ny.frontiernet.net...
<snip>
> > (defun D ( / DICE)
...
> > ) ;_ end of defun
> What version of Lisp are you using (/ Dice) why
> is a / inside the argument List.
>
> Is this CommonLisp, or XLisp?
>
> The (/ DICE) is rather weird to me because / is never
> used in the function D.
>
> I've used Lisp for a long time and never saw a
> parameter list like that--could you tell me what
> it does, Thanx
>
I'm using AutoLISP.
In AutoLISP, the form (defun ( x / y) ...) as a list of defun parameters
indicates that (x) is the value(s) passed to the function, while (y) is a
list of local variables.
Also, in response to many comments about coding style, I'm writing code for
myself, so I can read it. If somebody wants to pay me to write code, then
I'll write it any way they tell me to. For the moment, trailing parens make
reading my code easier (for me, anyway).
BTW, is reading code without comments *really* easier? Again, I want ease of
readability, so I use any and all crutches I can.
Thank you,
Kevin Hayward
-----= Posted via Newsfeeds.Com, Uncensored Usenet News =-----
http://www.newsfeeds.com - The #1 Newsgroup Service in the World!
-----== Over 80,000 Newsgroups - 16 Different Servers! =-----
"Franz Kafka" <Symbolics _ XL1201 _ Sebek _ Budo _ Kafka @ hotmail . com>
wrote in message ····················@news02.roc.ny.frontiernet.net...
<snip>
> > (defun D ( / DICE)
...
> > ) ;_ end of defun
> What version of Lisp are you using (/ Dice) why
> is a / inside the argument List.
>
> Is this CommonLisp, or XLisp?
>
> The (/ DICE) is rather weird to me because / is never
> used in the function D.
>
> I've used Lisp for a long time and never saw a
> parameter list like that--could you tell me what
> it does, Thanx
>
I'm using AutoLISP.
In AutoLISP, the form (defun ( x / y) ...) as a list of defun parameters
indicates that (x) is the value(s) passed to the function, while (y) is a
list of local variables.
Also, in response to many comments about coding style, I'm writing code for
myself, so I can read it. If somebody wants to pay me to write code, then
I'll write it any way they tell me to. For the moment, trailing parens make
reading my code easier (for me, anyway).
BTW, is reading code without comments *really* easier? Again, I want ease of
readability, so I use any and all crutches I can.
Thank you,
Kevin Hayward
-----= Posted via Newsfeeds.Com, Uncensored Usenet News =-----
http://www.newsfeeds.com - The #1 Newsgroup Service in the World!
-----== Over 80,000 Newsgroups - 16 Different Servers! =-----
"Kevin Hayward" <············@hotmail.com> writes:
> Also, in response to many comments about coding style, I'm writing
> code for myself, so I can read it. If somebody wants to pay me to
> write code, then I'll write it any way they tell me to. For the
> moment, trailing parens make reading my code easier (for me,
> anyway).
>
> BTW, is reading code without comments *really* easier? Again, I want
> ease of readability, so I use any and all crutches I can.
I think the short answer is "yes". Or it should be. But it may take
practice to get there.
Do you remember those ads they used to have on TV for a system where
you could learn to play guitar in a week? The one's I'm thinking of
came with a complete set of stickers you were supposed to paste all
over the fretboard to make things "easier". No doubt they do make
things easier for the beginner who hasn't developed muscle memory nor
a theoretical conception of the fretboard. But I haven't noticed any
really good guitar players with colored stickers on their fretboards.
While you can, as you point out, code however you want when no one is
paying you, you might consider that crutches are meant to be thrown
away, the sooner the better.
The point of the prevailing style is that you should be able to see at
a glance the structure of your code based on the indentation. If you
*can't* see it; i.e. you don't have the "muscle memory" you have two
choices. One is gunk up the code with comments and idiosyncratic
formatting that make the structure more apparent to you. Or you can
start now learning to just see it. Obviously when you are a beginner
you may need to think consciously about it (and use your editor to
help you with proper indentation and to see which parens match) but if
you make the attempt I predict it will soon become second nature and
you can turn your mind to more important issues.
Just my $.02.
-Peter
--
Peter Seibel ·····@javamonkey.com
Lisp is the red pill. -- John Fraser, comp.lang.lisp
Many apologies for 3 (three! count them!) copies of the same message being
posted.
My news reader crashed while trying to send and, I guess, made a mess.
Again, I apologise,
Kevin Hayward - (Dobby for the day)
-----= Posted via Newsfeeds.Com, Uncensored Usenet News =-----
http://www.newsfeeds.com - The #1 Newsgroup Service in the World!
-----== Over 80,000 Newsgroups - 16 Different Servers! =-----
"Michael Sullivan" <···@panix.com> wrote in message
·······························@panix.com...
> distinguishable from code. Since CL code is not case-sensitive, case is
> purely a formatting issue.
<nitpick>
CL code is, of course, case-sensitive. It is the reader that, normally by
default, is case insensitve.
--
Coby Beck
(remove #\Space "coby 101 @ bigpond . com")
"Kevin Hayward" <············@hotmail.com> wrote in message
···············@corp.newsgroups.com...
> Hi,
>
> sorry if this is old hat to all but I have a problem writing a simple
> recursive function.
>
> Suppose I am modelling a simple dice game.
>
> The rules are:
>
> 1) record each die roll as a list
>
> 2) if the die comes up 6, roll twice.
>
> Ie,, assuming a function d()=y
>
> Then y should return (1) , (3 2), (2 4 5) etc.
Your specs are a little fuzzy, but guessing at what you might want, here is
something that should do it or give you the building blocks:
CL-USER 80 > (defun roll-die (&optional (dice 2) (sides 6))
(loop for i below dice
collect (1+ (random sides))))
ROLL-DIE
CL-USER 81 > (defun d (&optional (magic-number 6) (dice 2) (sides
magic-number))
(let ((roll (roll-die dice sides)))
(if (= magic-number (apply #'+ roll))
(append (list roll) (d magic-number dice sides))
(list roll))))
CL-USER 82 > (dotimes (i 10) (print (d)))
((3 2))
((5 2))
((1 5) (6 4))
((1 3))
((6 1))
((6 2))
((4 3))
((2 2))
((6 2))
((2 2))
NIL
CL-USER 83 > (dotimes (i 10) (print (d 3)))
((1 3))
((3 3))
((1 1))
((1 1))
((2 2))
((1 1))
((2 1) (3 3))
((3 1))
((1 2) (3 2))
((2 3))
NIL
> What I've got so far:
>
> (defun D (/ DICE)
> (list
> (setq
> DICE (RollDie)
> DICE (if (= DICE 6)
> (list (D)
> (D)
> ) ;_ end of list
> DICE
> ) ;_ end of if
> ) ;_ end of setq
> ) ;_ end of list
> ) ;_ end of defun
Many style issues here. More idiomatic are identifiers like roll-die rather
than RollDie. Don't put dangling parens on seperate lines like that. You
do not use the dice argument passed in, so why pass it?
> Any ideas?
>
> Thank you,
>
HTH
--
Coby Beck
(remove #\Space "coby 101 @ bigpond . com")