From: Padu
Subject: Beginner question
Date: 
Message-ID: <TXNyc.16176$1L4.10646@okepread02>
First let me put my question in context. As you may guess I'm starting to
learn Lisp as a requirement of a graduate artificial intelligence class I'm
taking. I am also a software engineer with 10+ years of programming
experience in Pascal, C and C++ (big paradigm breakthrough). My assignment
is to create a Mancala game as a final project for the class. Lisp is not
part of the course, the professor only put this requirement to make the game
in lisp and suggested a book (wilensky). The book is very good, but it only
teaches the basic concepts separatedly, but when you get to glue the pieces
togheter...

I have all the algorithms done, but translating the simplest algorithms into
lisp is becoming a problem. Here is the function I've came up with:

(defun put-stones-to-strip (strip stones)
  (cond
    ((> stones 0)
     (
       (let *
         (
           (cur_pit (car strip))
           (cur_pit (+ cur_pit 1))
         )
         (rplaca strip cur_pit)
         (print strip)
         (let*
           (
             (stones (- stones 1))
           )
           (put-stones-to-strip (cdr strip) stones)
         ) ;second let
       ) ;first let
     ) ;expression of first condition
    ) ;1st condition
  ) ;cond
) ;defun

imagine strip as a list of integers, for exemple (1 2 3 4 5 6)
here is what I expect from this function:
>(setq x '(1 2 3 4 5 6))
>(put-stones-to-strip x 3)
(2 3 4 4 5 6)

I'm running into all sorts of error, what makes me think I'm going to the
wrong direction and thinking too much like I would in a regular language...
I have plenty of other functions like this to develop, so if you know a
simpler way for this function, it would teach me how to do the others.

Basically I'm having troubles with the concept of not having local variables
freely available to change in a sequential manner...


Thanks a lot and wish me luck on my quest
(if anybody is interested, I may publish the code of my project somewhere
when I'm done...)

Padu

From: Barry Margolin
Subject: Re: Beginner question
Date: 
Message-ID: <barmar-1FB458.21494812062004@comcast.dca.giganews.com>
In article <·····················@okepread02>,
 "Padu" <····@merlotti.com> wrote:

> Basically I'm having troubles with the concept of not having local variables
> freely available to change in a sequential manner...

You create local variables with LET, and can change them with SETQ.

(let ((var 3))
  ...
  (setq var (1+ var))
  ...)

-- 
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
From: Padu
Subject: Re: Beginner question
Date: 
Message-ID: <uqqdnVtfTc-nV1DdRVn2jg@iswest.net>
"Barry Margolin" wrote
> > Basically I'm having troubles with the concept of not having local
variables
> > freely available to change in a sequential manner...
>
> You create local variables with LET, and can change them with SETQ.
>
> (let ((var 3))
>   ...
>   (setq var (1+ var))
>   ...)


Bingo! I mistakenly thought setq was used only to set global variables...
thanks
From: Kenny Tilton
Subject: Re: Beginner question
Date: 
Message-ID: <sZPyc.180314$WA4.147249@twister.nyc.rr.com>
Padu wrote:
> First let me put my question in context. As you may guess I'm starting to
> learn Lisp as a requirement of a graduate artificial intelligence class I'm
> taking. I am also a software engineer with 10+ years of programming
> experience in Pascal, C and C++ (big paradigm breakthrough). My assignment
> is to create a Mancala game as a final project for the class. Lisp is not
> part of the course, the professor only put this requirement to make the game
> in lisp and suggested a book (wilensky). The book is very good, but it only
> teaches the basic concepts separatedly, but when you get to glue the pieces
> togheter...
> 
> I have all the algorithms done, but translating the simplest algorithms into
> lisp is becoming a problem. Here is the function I've came up with:
> 
> (defun put-stones-to-strip (strip stones)
>   (cond

Are you expecting more conditions? If you have just one, just use WHEN.

>     ((> stones 0)
>      (

The above left parens seems to be an extra.

>        (let *
>          (
>            (cur_pit (car strip))
>            (cur_pit (+ cur_pit 1))
>          )
>          (rplaca strip cur_pit)
>          (print strip)
>          (let*
>            (
>              (stones (- stones 1))

Shucks, this let could have been with the others.

>            )
>            (put-stones-to-strip (cdr strip) stones)

This parens labelling suggests to me you are not using a lisp-aware 
editor, or have not learned to trust the one you have. If the former, 
let us know what your whole environment is and folks will suggest a good 
editor, possibly from a free commercial Lisp such as Lispworks or AllegroCL.

>          ) ;second let
>        ) ;first let
>      ) ;expression of first condition
>     ) ;1st condition
>   ) ;cond
> ) ;defun

Making all those changes, we get:

(defun put-stones-to-strip (strip stones)
    (when (> stones 0)
      (let* ((cur_pit (car strip))
             (cur_pit (+ cur_pit 1))
             (stones (- stones 1)))
        (rplaca strip cur_pit)
        (print strip)
        (put-stones-to-strip (cdr strip) stones))))

(put-stones-to-strip (list 1 2 3 4 5 6) 3))
=>
(2 2 3 4 5 6)
(3 3 4 5 6)
(4 4 5 6)
NIL

Not good. Now a couple of minor points which will not help at all, 
because this code does the same thing:

(defun put-stones-to-strip (strip stones)
    (when (> stones 0)
      (incf (car strip)) ; treat (car strip) as if it were a local var
      (print strip)
      (put-stones-to-strip (cdr strip) (1- stones)))) ; just pass it 
(and use (1- ...) for fun)

But it gives the same result. Let's enhance the print statements:

(defun put-stones-to-strip (strip stones)
   (print (list :in stones strip))
   (when (> stones 0)
     (incf (car strip))
     (print (list :modified stones strip))
     (put-stones-to-strip (cdr strip) (1- stones))))

(:IN 3 (1 2 3 4 5 6))
(:MODIFIED 3 (2 2 3 4 5 6))
(:IN 2 (2 3 4 5 6))
(:MODIFIED 2 (3 3 4 5 6))
(:IN 1 (3 4 5 6))
(:MODIFIED 1 (4 4 5 6))
(:IN 0 (4 5 6))
NIL

The deepest call is passed zero and does nothing (according to plan) but 
returns nothing. Well, since you are destructively modifying (mutating?) 
the list, maybe you are down with that. But destructive Lisp functions 
as a convenience do return the mutated object. You could just do:

(defun put-stones-to-strip (strip stones)
   (print (list :in stones strip))
   (when (> stones 0)
     (incf (car strip))
     (print (list :modified stones strip))
     (put-stones-to-strip (cdr strip) (1- stones)))
   strip)

(:IN 3 (1 2 3 4 5 6))
(:MODIFIED 3 (2 2 3 4 5 6))
(:IN 2 (2 3 4 5 6))
(:MODIFIED 2 (3 3 4 5 6))
(:IN 1 (3 4 5 6))
(:MODIFIED 1 (4 4 5 6))
(:IN 0 (4 5 6))
  0[1]: returned (2 3 4 4 5 6)
(2 3 4 4 5 6)

Recursion is fun, but Lisp has a lot of ways to iterate: dotimes, do, 
loop, and more.

(defun put-stones-to-strip (strip stones)
   (dotimes (n stones strip)
     (incf (elt strip n))))

Again a seeming function (ELT...) can also be treated as a place, like a 
local variable. that takes some getting used to. here is a version using 
LOOP:


(defun put-stones-to-strip (strip stones)
   (loop repeat stones
         for rest on strip
         do (incf (car rest))
         finally (return strip)))

Finally, it /is/ unusual destructively modifying the list. If that is 
the source of some of your errors, make a new list:

(defun put-stones-to-strip (strip stones)
   (loop for item in strip
       for n upfrom 0
       collecting (+ item (if (< n stones)
                              1 0))))

I would not have beat around the bush so much, but you said:

> I have plenty of other functions like this to develop, so if you know a
> simpler way for this function, it would teach me how to do the others.

That's my excuse, anyway. :) Good luck with the game.

kenny

-- 
Home? http://tilton-technology.com
Cells? http://www.common-lisp.net/project/cells/
Cello? http://www.common-lisp.net/project/cello/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
Your Project Here! http://alu.cliki.net/Industry%20Application
From: André Thieme
Subject: Re: Beginner question
Date: 
Message-ID: <cahj6i$mb5$1@ulric.tng.de>
Kenny Tilton schrieb:

> (defun put-stones-to-strip (strip stones)
>   (print (list :in stones strip))
>   (when (> stones 0)
>     (incf (car strip))
>     (print (list :modified stones strip))
>     (put-stones-to-strip (cdr strip) (1- stones)))
>   strip)
> 
> (:IN 3 (1 2 3 4 5 6))
> (:MODIFIED 3 (2 2 3 4 5 6))
> (:IN 2 (2 3 4 5 6))
> (:MODIFIED 2 (3 3 4 5 6))
> (:IN 1 (3 4 5 6))
> (:MODIFIED 1 (4 4 5 6))
> (:IN 0 (4 5 6))
>  0[1]: returned (2 3 4 4 5 6)
> (2 3 4 4 5 6)
> 
> Recursion is fun, but Lisp has a lot of ways to iterate: dotimes, do, 
> loop, and more.

When I saw this I had an idea:
put-stones-to-strip returned (4 5 6), then (4 4 5 6), then (3 4 4 5 6) 
and then the final result (2 3 4 4 5 6).
But as an end result only the last return value is returned.
With a trace I confirmed my theory.

Would one use VALUES if one wanted all results?
How would such a version look like if I wanted to see all the function 
returns?


Andr�
--
From: Kenny Tilton
Subject: Re: Beginner question
Date: 
Message-ID: <9YZyc.121071$Nn4.26004271@twister.nyc.rr.com>
Andr� Thieme wrote:
> Kenny Tilton schrieb:
> 
>> (defun put-stones-to-strip (strip stones)
>>   (print (list :in stones strip))
>>   (when (> stones 0)
>>     (incf (car strip))
>>     (print (list :modified stones strip))
>>     (put-stones-to-strip (cdr strip) (1- stones)))
>>   strip)
>>
>> (:IN 3 (1 2 3 4 5 6))
>> (:MODIFIED 3 (2 2 3 4 5 6))
>> (:IN 2 (2 3 4 5 6))
>> (:MODIFIED 2 (3 3 4 5 6))
>> (:IN 1 (3 4 5 6))
>> (:MODIFIED 1 (4 4 5 6))
>> (:IN 0 (4 5 6))
>>  0[1]: returned (2 3 4 4 5 6)
>> (2 3 4 4 5 6)
>>
>> Recursion is fun, but Lisp has a lot of ways to iterate: dotimes, do, 
>> loop, and more.
> 
> 
> When I saw this I had an idea:
> put-stones-to-strip returned (4 5 6), then (4 4 5 6), then (3 4 4 5 6) 
> and then the final result (2 3 4 4 5 6).
> But as an end result only the last return value is returned.
> With a trace I confirmed my theory.

Careful. The trace did not make apparent that all the apparently 
different return values were just different stretches of the exact same 
structure. ie, if you took the four values and then mutated, say, the 
shortest one, then all the other values would be changed as well, again 
because they are all just different stretches of the same list.

So you /are/ getting all four values back in (2 3 4 4 5 6). :)
> 
> Would one use VALUES if one wanted all results?

No, values is for returning information ancillary to the main result. 
Here you are changing the spec so that the main result is a list of lists.

> How would such a version look like if I wanted to see all the function 
> returns?

What's this? The student assigning exercises to the teacher?! Howse 
about you turn this in by 9am EDT tomorrow? :)

I dumped answers on the OP only because they had clearly fought the good 
fight and just needed equivalent variations to move them along the 
learning curve. I sense time pressure, so I did not do the Socratic 
thing. Well, in a way I did, because the OP still has to work out how 
the variations work, especially stuff like (setf (car list) 42) where 
car is both a reader function and a writer function.

kenny


-- 
Home? http://tilton-technology.com
Cells? http://www.common-lisp.net/project/cells/
Cello? http://www.common-lisp.net/project/cello/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
Your Project Here! http://alu.cliki.net/Industry%20Application
From: Padu
Subject: Re: Beginner question
Date: 
Message-ID: <QK6dnR-idIlSU1DdRVn2hQ@iswest.net>
"Kenny Tilton" wrote
> > (defun put-stones-to-strip (strip stones)
> >   (cond
>
> Are you expecting more conditions? If you have just one, just use WHEN.

Not in this case, I'm gonna change it. Thanks for the suggestion

> This parens labelling suggests to me you are not using a lisp-aware
> editor, or have not learned to trust the one you have. If the former,
> let us know what your whole environment is and folks will suggest a good
> editor, possibly from a free commercial Lisp such as Lispworks or
AllegroCL.

That was a major issue for me (and I guess it still is). I started with
notepad, then I figure out that I had to get more productivity. Downloaded
EMACS, but as I'm used to Win32 environment, EMACS although having excellent
parent matching features, was kind of cumbersome to me. Then I tried
something more windows, like codewright and multiedit. Excellent editors,
but they lack lisp specific features (parent matching), although they have a
custom language editor that perhaps would do the trick, but I don't have
much time to learn a macro language for a text editor right now...
A perfect editor in my case would be one that has a Win32 style and is lisp
aware.

> But it gives the same result. Let's enhance the print statements:
>
> (defun put-stones-to-strip (strip stones)
>    (print (list :in stones strip))
>    (when (> stones 0)
>      (incf (car strip))
>      (print (list :modified stones strip))
>      (put-stones-to-strip (cdr strip) (1- stones))))
>
> (:IN 3 (1 2 3 4 5 6))
> (:MODIFIED 3 (2 2 3 4 5 6))
> (:IN 2 (2 3 4 5 6))
> (:MODIFIED 2 (3 3 4 5 6))
> (:IN 1 (3 4 5 6))
> (:MODIFIED 1 (4 4 5 6))
> (:IN 0 (4 5 6))
> NIL

Definitely it looks much cleaner! Although my other functions are already
working, I'll try to rewrite them using some of the concepts you presented
here.

> Finally, it /is/ unusual destructively modifying the list. If that is
> the source of some of your errors, make a new list:

Yes, when I was reading about rplaca, the author of the book raised all the
necessary red flags about functions that actually modify the data and the
consequences for other places that have pointers to that modified data, what
forced me to think about using it or not. In this case I guess it is ok
given how my program works as a whole.

> I would not have beat around the bush so much, but you said:
>
> > I have plenty of other functions like this to develop, so if you know a
> > simpler way for this function, it would teach me how to do the others.
>
> That's my excuse, anyway. :) Good luck with the game.


As I said in other post, this help is of great help for me! I guess I can
get good knowledge from the books, but practical information like this is
invaluable.

Thanks again

Padu
From: Kenny Tilton
Subject: Re: Beginner question
Date: 
Message-ID: <4fkzc.79067$mX.26571155@twister.nyc.rr.com>
Padu wrote:
>>This parens labelling suggests to me you are not using a lisp-aware
>>editor, or have not learned to trust the one you have. If the former,
>>let us know what your whole environment is and folks will suggest a good
>>editor, possibly from a free commercial Lisp such as Lispworks or
> 
> AllegroCL.
> 
> That was a major issue for me (and I guess it still is). I started with
> notepad, then I figure out that I had to get more productivity. Downloaded
> EMACS, but as I'm used to Win32 environment, EMACS although having excellent
> parent matching features, was kind of cumbersome to me. Then I tried
> something more windows, like codewright and multiedit. Excellent editors,
> but they lack lisp specific features (parent matching), although they have a
> custom language editor that perhaps would do the trick, but I don't have
> much time to learn a macro language for a text editor right now...
> A perfect editor in my case would be one that has a Win32 style and is lisp
> aware.

Download the AllegroCL Trial Edition from www.franz.com. I am pretty 
sure the default editor mode is "host", which i think has standard win32 
  bindings such as Control-C for Copy. If not, you can set that under:

     Tools>Options>Editor

They also offer an emacs mode if you want to learn the emacs versions of 
the basic win32 editing commands.

kenny

-- 
Home? http://tilton-technology.com
Cells? http://www.common-lisp.net/project/cells/
Cello? http://www.common-lisp.net/project/cello/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
Your Project Here! http://alu.cliki.net/Industry%20Application
From: Brian Downing
Subject: Re: Beginner question
Date: 
Message-ID: <7Mlzc.35008$eu.29049@attbi_s02>
In article <······················@iswest.net>, Padu <····@merlotti.com> wrote:
> Yes, when I was reading about rplaca, the author of the book raised all the
> necessary red flags about functions that actually modify the data and the
> consequences for other places that have pointers to that modified data, what
> forced me to think about using it or not. In this case I guess it is ok
> given how my program works as a whole.

As a style comment, it's considered much better style nowadays to use
SETF instead of specialized setters like RPLACA and RPLACD.  SETF lets
you treat most arbitrary places just like variables:

> (defparameter *list* (list 'a 'b 'c 'd 'e))
*LIST*

> *list*
(A B C D E)

> (car *list*)
A

> (setf (car *list*) 'the-car)
THE-CAR

> *list*
(THE-CAR B C D E)

> (setf (cdr *list*) (list 'the-rest))
(THE-REST)

> *list*
(THE-CAR THE-REST)

-bcd
-- 
*** Brian Downing <bdowning at lavos dot net> 
From: André Thieme
Subject: Re: Beginner question
Date: 
Message-ID: <caksgq$v32$1@ulric.tng.de>
Padu schrieb:

> A perfect editor in my case would be one that has a Win32 style
 > and is lisp aware.

http://www.lispworks.com

(free personal version)
From: Kenny Tilton
Subject: Re: Beginner question
Date: 
Message-ID: <jNnzc.79276$mX.26617773@twister.nyc.rr.com>
Andr� Thieme wrote:
> Padu schrieb:
> 
>> A perfect editor in my case would be one that has a Win32 style
> 
>  > and is lisp aware.
> 
> http://www.lispworks.com

Out of the box the Lispworks editor is not win32 style. I am told it is 
like Hemlock, the little-used (it seems) cmucl editor, which I think 
works much like Emacs.

Is there some way to get Lispworks editors to work like win32? If so, 
yep, this is another fine alternative.

kenny

-- 
Home? http://tilton-technology.com
Cells? http://www.common-lisp.net/project/cells/
Cello? http://www.common-lisp.net/project/cello/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
Your Project Here! http://alu.cliki.net/Industry%20Application
From: André Thieme
Subject: Re: Beginner question
Date: 
Message-ID: <cal2sm$41i$1@ulric.tng.de>
Kenny Tilton schrieb:

> Andr� Thieme wrote:
> 
>> Padu schrieb:
>>
>>> A perfect editor in my case would be one that has a Win32 style
>>
>>
>>  > and is lisp aware.
>>
>> http://www.lispworks.com
> 
> 
> Out of the box the Lispworks editor is not win32 style. I am told it is 
> like Hemlock, the little-used (it seems) cmucl editor, which I think 
> works much like Emacs.
> 
> Is there some way to get Lispworks editors to work like win32? If so, 
> yep, this is another fine alternative.

You go to Tools->Preferences and click on "Emulation".
There you can select "Editor Keys like Emacs" or, for Padu,
"Editor Keys like Windows".

I personally selected the Emacs variant to learn to work with these 
keybindings. When working with Emacs under unix/gnu linux I would be 
more used to it.


Andr�
--
From: Padu
Subject: Re: Beginner question
Date: 
Message-ID: <vdydnQhSuPJii1PdRVn2jw@iswest.net>
"Andr� Thieme" wrote
> > Is there some way to get Lispworks editors to work like win32? If so,
> > yep, this is another fine alternative.
>
> You go to Tools->Preferences and click on "Emulation".
> There you can select "Editor Keys like Emacs" or, for Padu,
> "Editor Keys like Windows".
>
> I personally selected the Emacs variant to learn to work with these
> keybindings. When working with Emacs under unix/gnu linux I would be
> more used to it.

Yes, already downloaded it and set it up to win32 style... I'm going to try
it for a few days. So far the only complain is the lack of smart tabs and
smart indentation, but that may be some configuration I'm missing. But the
parenthesis highlight is fundamental in list....
From: Brian Downing
Subject: Re: Beginner question
Date: 
Message-ID: <iIpzc.23868$Hg2.10378@attbi_s04>
In article <······················@iswest.net>, Padu <····@merlotti.com> wrote:
> Yes, already downloaded it and set it up to win32 style... I'm going to try
> it for a few days. So far the only complain is the lack of smart tabs and
> smart indentation, but that may be some configuration I'm missing. But the
> parenthesis highlight is fundamental in list....

It should default to doing automatic indentation and syntax
highlighting.  This includes what I assume you mean by "smart tabs."
Make sure in the modeline (the gray bar near the bottom of the screen)
that it says "(Lisp)" and not "(Fundamental)".

Lines don't indent when you hit return by default.  To indent a line,
hit TAB.  You can be anywhere in the line to do this.  This will indent
the beginning of the line to where it should go.  Hitting TAB multiple
times should not move the line more than once.  If the line does not
look like it's going where it should, check your parens, they're
probably wrong.

(One default that's a bit strange for CL in Lispworks is the indentation
for IF.  It indents the true clause by four spaces, but the false clause
by only two.  Most CL programmers I've seen indent them the same.  This
is adjustable somehow, but I don't know off the top of my head.)

If it does say "(Fundamental)", you are in the wrong mode.  Try saving
the file with the extension ".lisp" or ".lsp" and opening it again.
There's a more direct way to fix this, but in a couple minutes of trying
I have no idea how to run an extended command with the Win32
keybindings.

(Learning how to use Emacs is probably a worthwhile use of your time
when you can some to spend on it.  Emacs has some powerful sexp movement
and manipulation commands that let you edit your program by structure
and not just by characters.)

-bcd
-- 
*** Brian Downing <bdowning at lavos dot net> 
From: Edi Weitz
Subject: Re: Beginner question
Date: 
Message-ID: <87pt81s3g7.fsf@bird.agharta.de>
On Mon, 14 Jun 2004 17:33:44 -0700, "Padu" <····@merlotti.com> wrote:

> I was expecting it to indent when I hit enter... old habits...

As I said: You can modify it to do exactly that.
From: Edi Weitz
Subject: Re: Beginner question
Date: 
Message-ID: <87y8mpdcd4.fsf@bird.agharta.de>
On Mon, 14 Jun 2004 14:21:30 -0700, "Padu" <····@merlotti.com> wrote:

> Yes, already downloaded it and set it up to win32 style... I'm going
> to try it for a few days. So far the only complain is the lack of
> smart tabs

We usually don't use/need tabs in Lisp code.

> and smart indentation

With the Emacs key bindings this is done with the TAB key (the
"Indent" function of the editor).

As the LW editor is an Emacs clone it is of course fully programmable
(even in real Common Lisp, not in Emacs Lisp) so you can modify it to
behave the way you want it to.

Edi.
From: Kenny Tilton
Subject: Re: Beginner question
Date: 
Message-ID: <0rpzc.79283$mX.26656402@twister.nyc.rr.com>
Edi Weitz wrote:

> On Mon, 14 Jun 2004 14:21:30 -0700, "Padu" <····@merlotti.com> wrote:
> 
> 
>>Yes, already downloaded it and set it up to win32 style... I'm going
>>to try it for a few days. So far the only complain is the lack of
>>smart tabs
> 
> 
> We usually don't use/need tabs in Lisp code.
> 
> 
>>and smart indentation
> 
> 
> With the Emacs key bindings this is done with the TAB key (the
> "Indent" function of the editor).

Now that I have been steered to the win32 emulation mode, I see even in 
win32 mode the Lispworks editor correctly treats TAB as an 
auto-indentation command. Or is "smart indentation" something else?

kenny

-- 
Home? http://tilton-technology.com
Cells? http://www.common-lisp.net/project/cells/
Cello? http://www.common-lisp.net/project/cello/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
Your Project Here! http://alu.cliki.net/Industry%20Application
From: Thomas F. Burdick
Subject: Re: Beginner question
Date: 
Message-ID: <xcvllipe6ys.fsf@famine.OCF.Berkeley.EDU>
Kenny Tilton <·······@nyc.rr.com> writes:

> Now that I have been steered to the win32 emulation mode, I see even in 
> win32 mode the Lispworks editor correctly treats TAB as an 
> auto-indentation command. Or is "smart indentation" something else?

Probably he meant "smart indentation" to mean Return does
newline-and-indent.  Incidentally, I always bind Return to
newline-and-indent in my various Emacsi, for programming modes at
least.  It's less important if you always do balanced editing, but
sometimes it comes up.
From: Edi Weitz
Subject: Re: Beginner question
Date: 
Message-ID: <87pt816ep2.fsf@bird.agharta.de>
On Mon, 14 Jun 2004 20:21:35 GMT, Kenny Tilton <·······@nyc.rr.com> wrote:

> Is there some way to get Lispworks editors to work like win32?

Sure:

  <http://www.lispworks.com/reference/lw43/EDUG-W/html/eduser-w-114.htm>
From: Marco Baringer
Subject: Re: Beginner question
Date: 
Message-ID: <m2zn76t015.fsf@convey.it>
"Padu" <····@merlotti.com> writes:

> That was a major issue for me (and I guess it still is). I started with
> notepad, then I figure out that I had to get more productivity. Downloaded
> EMACS, but as I'm used to Win32 environment, EMACS although having excellent
> parent matching features, was kind of cumbersome to me. 

if it's the key bindings that are getting to you you should try
cua-mode. it should be included in fairly recent emacs.

-- 
-Marco
Ring the bells that still can ring.
Forget your perfect offering.
There is a crack in everything.
That's how the light gets in.
     -Leonard Cohen
From: André Thieme
Subject: Re: Beginner question
Date: 
Message-ID: <cagenq$tvs$1@ulric.tng.de>
Padu schrieb:
> First let me put my question in context. As you may guess I'm starting to
> learn Lisp as a requirement of a graduate artificial intelligence class I'm
> taking. I am also a software engineer with 10+ years of programming
> experience in Pascal, C and C++ (big paradigm breakthrough). My assignment
> is to create a Mancala game as a final project for the class. Lisp is not
> part of the course, the professor only put this requirement to make the game
> in lisp and suggested a book (wilensky). The book is very good, but it only
> teaches the basic concepts separatedly, but when you get to glue the pieces
> togheter...
> 
> I have all the algorithms done, but translating the simplest algorithms into
> lisp is becoming a problem. Here is the function I've came up with:
> 
> (defun put-stones-to-strip (strip stones)
>   (cond
>     ((> stones 0)
>      (
>        (let *
>          (
>            (cur_pit (car strip))
>            (cur_pit (+ cur_pit 1))
>          )
>          (rplaca strip cur_pit)
>          (print strip)
>          (let*
>            (
>              (stones (- stones 1))
>            )
>            (put-stones-to-strip (cdr strip) stones)
>          ) ;second let
>        ) ;first let
>      ) ;expression of first condition
>     ) ;1st condition
>   ) ;cond
> ) ;defun
> 
> imagine strip as a list of integers, for exemple (1 2 3 4 5 6)
> here is what I expect from this function:
> 
>>(setq x '(1 2 3 4 5 6))
>>(put-stones-to-strip x 3)
> 
> (2 3 4 4 5 6)
> 
> I'm running into all sorts of error, what makes me think I'm going to the
> wrong direction and thinking too much like I would in a regular language...
> I have plenty of other functions like this to develop, so if you know a
> simpler way for this function, it would teach me how to do the others.
> 
> Basically I'm having troubles with the concept of not having local variables
> freely available to change in a sequential manner...

One thing I could suggest you is to try to indent your code in a 
different way and making it more readable by this.
In Lisp it is not very usual to have a single closing paren in one line. 
Also usually one doesn't comment what such a paren is closing.
Here are two essays which will help you:
1) http://www.lisp.org/table/style.htm
2) http://www.norvig.com/luv-slides.ps

(it might also be a good idea to surf a bit around on Norvigs page, 
perhaps looking at some code of him)

To the first let in your code: I think you meant let* instead of let *.


Andr�
--
From: Padu
Subject: Re: Beginner question
Date: 
Message-ID: <zOWdnb_e28BxV1DdRVn2iw@iswest.net>
"Andr� Thieme" wrote:
> One thing I could suggest you is to try to indent your code in a
> different way and making it more readable by this.
> In Lisp it is not very usual to have a single closing paren in one line.
> Also usually one doesn't comment what such a paren is closing.
> Here are two essays which will help you:
> 1) http://www.lisp.org/table/style.htm
> 2) http://www.norvig.com/luv-slides.ps
>
> (it might also be a good idea to surf a bit around on Norvigs page,
> perhaps looking at some code of him)

Downloaded the pdf, thanks! The point is I was trying to make it more
readable and deal with the parenthesis hell, but I recognize that it didn't
help a lot...

> To the first let in your code: I think you meant let* instead of let *.

Yes, it was a typo
From: Padu
Subject: Re: Beginner question
Date: 
Message-ID: <hrKdnURqxNXBVFDdRVn2hQ@iswest.net>
I was quick-reading all the posts and I felt amazed on the good will of
everybody. Sincere thanks! I'll try to digest every post you guys wrote, but
definitely there is much more valuable information in here than in the first
3 chapters of any introductory book on lisp.

I really wish I had more time to formally learn the language before I had to
do a project on it, but I guess doing the project *is* the best way to learn
a new language. I just have to switch gears on my mind as some of the core
concepts are unique to lisp.

Padu
From: Joe Marshall
Subject: Re: Beginner question
Date: 
Message-ID: <u0xet8h0.fsf@ccs.neu.edu>
"Padu" <····@merlotti.com> writes:

> I was quick-reading all the posts and I felt amazed on the good will of
> everybody. 

For heaven's sake don't tell anyone!  We have a reputation to maintain
here.
From: Padu
Subject: Re: Beginner question
Date: 
Message-ID: <hdqdnadB6o8LT1DdRVn2uQ@iswest.net>
"Joe Marshall" wrote
> > I was quick-reading all the posts and I felt amazed on the good will of
> > everybody.
>
> For heaven's sake don't tell anyone!  We have a reputation to maintain
> here.

:-D

Now, the funny thing is how people have no idea of what lisp is about. Well,
have to include myself in this list before I had the introduction on lisp,
but one of my colleagues (keep in mind that both he and I are experienced
software engineers with 10+ years of experience in "traditional" languages)
told me that lisp is nothing more than a sophisticated hp12c calculator!!!
From: Gareth McCaughan
Subject: Re: Beginner question
Date: 
Message-ID: <871xkh3i65.fsf@g.mccaughan.ntlworld.com>
"Padu" <····@merlotti.com> writes:

> Now, the funny thing is how people have no idea of what lisp is about. Well,
> have to include myself in this list before I had the introduction on lisp,
> but one of my colleagues (keep in mind that both he and I are experienced
> software engineers with 10+ years of experience in "traditional" languages)
> told me that lisp is nothing more than a sophisticated hp12c calculator!!!

I wonder whether he was thinking of FORTH, a language
sometimes grouped with Lisp (for what are, to my mind,
not entirely convincing reasons) and a little more like
an HP calculator than Lisp is. His claim would be
painfully false even then. :-)

-- 
Gareth McCaughan
.sig under construc
From: Brian Downing
Subject: Re: Beginner question
Date: 
Message-ID: <IVpzc.42489$0y.21581@attbi_s03>
In article <··············@g.mccaughan.ntlworld.com>,
Gareth McCaughan  <················@pobox.com> wrote:
> I wonder whether he was thinking of FORTH, a language sometimes
> grouped with Lisp (for what are, to my mind, not entirely convincing
> reasons) and a little more like an HP calculator than Lisp is. His
> claim would be painfully false even then. :-)

My memory is fuzzy, but:

Some of the later HP calculators are programmed in RPL, which is
supposed to stand for Reverse-polish Lisp.  It does have some lispy
features, like rich datatypes (RPL programs are first-class objects and
can be constructed with code), and (if I recall correctly) a concept of
object identity.  I do not believe there are any kind of lexical
closures, though.  The language's scoping more closely resembles
dynamic.  For example:

42 << -> a << << a + >> >> >> EVAL 
  yields << a + >>

("<< ... >>" indicate a program object, "-> locals << >>" is a kind of
local scope)

Calling it Lisp is perhaps stretching a little far, though.

-bcd
-- 
*** Brian Downing <bdowning at lavos dot net> 
From: Peter Seibel
Subject: Re: Beginner question
Date: 
Message-ID: <m3acz6nmkd.fsf@javamonkey.com>
"Padu" <····@merlotti.com> writes:

> I was quick-reading all the posts and I felt amazed on the good will of
> everybody. Sincere thanks! I'll try to digest every post you guys wrote, but
> definitely there is much more valuable information in here than in the first
> 3 chapters of any introductory book on lisp.

I'd be delighted if you could take a look at the first three chapters
of my book-in-progress, _Practical Common Lisp_ at:

  <http://www.gigamonkeys.com/book/>

and if you still feel that way to shoot me an email with some comments
on why. I'm always looking for feedback and feedback from Lisp
newbies--my target audience--about what they find clear and what they
find confusing is particularly valuable.

-Peter


-- 
Peter Seibel                                      ·····@javamonkey.com

         Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: Padu
Subject: Re: Beginner question
Date: 
Message-ID: <roOdnQqWl5ktTFDd4p2dnA@iswest.net>
I will certainly do that.
From: Wade Humeniuk
Subject: Re: Beginner question
Date: 
Message-ID: <Tolzc.19063$lN.4517@edtnps84>
Padu wrote:

> 
> (defun put-stones-to-strip (strip stones)
>   (cond
>     ((> stones 0)


Another possible way of doing it is:

(defun put-stones-to-strip (strip stones)
   (mapcar (lambda (place)
             (if (zerop stones) place
               (prog1 (1+ place) (decf stones))))
           strip))

Wade
From: Padu
Subject: Re: Beginner question
Date: 
Message-ID: <35qdnTAjXYaU_VPdRVn3tw@iswest.net>
Thanks to everybody's comments (and specially Paul Foley), I re-tought my
function and came up with another version of it:

(defun put-stones-to-strip (strip stones)
  (let* (
         (i 0))
    (loop
     (when (zerop stones) (return))
     (when (> i 11)
       (setq i 0))
     (incf (nth i strip))
     (incf i)
     (decf stones))
    (values strip)))

If the number of stones is greater than the number of pits (12) then contine
distributing stones from the start of the strip again until there are no
stones left to distribute. I think in this case it is ok to hardcode the
number of pits as mancala is always played with such board, or else I'd use
a (lenght strip) I guess?)

I'm starting to get the feeling...
From: Wade Humeniuk
Subject: Re: Beginner question
Date: 
Message-ID: <7TEzc.54171$%i1.31278@edtnps89>
Padu wrote:


> (defun put-stones-to-strip (strip stones)
>   (let* (
>          (i 0))
>     (loop
>      (when (zerop stones) (return))
>      (when (> i 11)
>        (setq i 0))
>      (incf (nth i strip))
>      (incf i)
>      (decf stones))
>     (values strip)))
> 
> If the number of stones is greater than the number of pits (12) then contine
> distributing stones from the start of the strip again until there are no
> stones left to distribute. I think in this case it is ok to hardcode the
> number of pits as mancala is always played with such board, or else I'd use
> a (lenght strip) I guess?)
> 
> I'm starting to get the feeling...
> 
> 

(defun put-stones-to-strip (strip stones)
   (multiple-value-bind (evenly-layed-stones remainder)
       (floor stones (length strip))
     (mapcar (lambda (pit)
               (if (zerop remainder) (+ pit evenly-layed-stones)
                 (prog1 (+ pit evenly-layed-stones 1)
                   (decf remainder))))
             strip)))

CL-USER 4 > (put-stones-to-strip (list 1 2 3 4 5 6) 3)
(2 3 4 4 5 6)

CL-USER 5 > (put-stones-to-strip (list 1 2 3 4 5 6) 10)
(3 4 5 6 6 7)

CL-USER 6 > (put-stones-to-strip (list 1 2 3 4 5 6) 200)
(35 36 36 37 38 39)

CL-USER 7 > (put-stones-to-strip (list 1 2 3 4 5 6) 7)
(3 3 4 5 6 7)

CL-USER 8 >

Wade
From: André Thieme
Subject: Re: Beginner question
Date: 
Message-ID: <can7p1$hjm$1@ulric.tng.de>
Padu schrieb:
> Thanks to everybody's comments (and specially Paul Foley), I re-tought my
> function and came up with another version of it:
> 
> (defun put-stones-to-strip (strip stones)
>   (let* (
>          (i 0))
>     (loop
>      (when (zerop stones) (return))
>      (when (> i 11)
>        (setq i 0))
>      (incf (nth i strip))
>      (incf i)
>      (decf stones))
>     (values strip)))
> 

Just a little comment: LET should also work here I think.
As long you don't introduce another lexical variable which you want to 
initilize relative to a different one LET* does the same as LET does.


Andr�
--
From: Padu
Subject: Re: Beginner question
Date: 
Message-ID: <8Imdnfliq44au1LdRVn2jg@iswest.net>
"Andr� Thieme" wrote
> > (defun put-stones-to-strip (strip stones)
> >   (let* (
> >          (i 0))
> >     (loop
> >      (when (zerop stones) (return))
> >      (when (> i 11)
> >        (setq i 0))
> >      (incf (nth i strip))
> >      (incf i)
> >      (decf stones))
> >     (values strip)))
>
> Just a little comment: LET should also work here I think.
> As long you don't introduce another lexical variable which you want to
> initilize relative to a different one LET* does the same as LET does.


I'm in that primate stage of mimicking with no complete understanding of
why... my professor used (let* in one example and I'm not sure of the
difference... so I'm using let*.... I guess it has to do with how let is
going to assign or initialize the variables, am I right?

Padu
From: Marco Baringer
Subject: Re: Beginner question
Date: 
Message-ID: <m2hdtc93dn.fsf@convey.it>
"Padu" <····@merlotti.com> writes:

> I'm in that primate stage of mimicking with no complete understanding of
> why... my professor used (let* in one example and I'm not sure of the
> difference... so I'm using let*.... I guess it has to do with how let is
> going to assign or initialize the variables, am I right?

LET binds in parralel, LET* binds sequentially. example:

(defvar a :global)

(let ((a :local)
      (b a))
  (values a b))
==> :local :global

(let* ((a :local)
       (b a))
  (values a b))
==> :local :local

conceptually you can consider let* to expand to nested lets:

(let* ((a :local))
      ((b a))
  ...)
===
(let ((a :local))
  (let ((b a))
    ...)

-- 
-Marco
Ring the bells that still can ring.
Forget your perfect offering.
There is a crack in everything.
That's how the light gets in.
     -Leonard Cohen
From: Thomas A. Russ
Subject: Re: Beginner question
Date: 
Message-ID: <ymiisdrqo8o.fsf@sevak.isi.edu>
"Padu" <····@merlotti.com> writes:

> 
> Thanks to everybody's comments (and specially Paul Foley), I re-tought my
> function and came up with another version of it:
> 
> (defun put-stones-to-strip (strip stones)
>   (let* (
>          (i 0))
>     (loop
>      (when (zerop stones) (return))
>      (when (> i 11)
>        (setq i 0))
>      (incf (nth i strip))
>      (incf i)
>      (decf stones))
>     (values strip)))

OK, let me try to move this a bit closer to Lisp style programming.
I would note that you only need the VALUES form when you are returning
more than one value from the function.  There isn't a need to
specify anything specially, since forms in Lisp almost always
return some value, typically the last subform.

Non-loop macro version:

(defun put-stones-to-strip (strip stones)
  (let ((i 0))
    (dotimes (count stones)
       (declare (ignore count))
       (incf (nth i strip))
       (if (> i 10)
         (setq i 0)
         (incf i)))
    strip))


Full loop macro version:

(defun put-stones-to-strip (strip stones)
  (loop repeat stones
        for i = 0 then (mod (+ i 1) 12)
	do (incf (nth i strip)))
  strip)

Note that these are both destructive of the STRIP
argument. 

-- 
Thomas A. Russ,  USC/Information Sciences Institute
From: Pascal Bourguignon
Subject: Re: Beginner question
Date: 
Message-ID: <87k6y76qii.fsf@thalassa.informatimago.com>
···@sevak.isi.edu (Thomas A. Russ) writes:
> "Padu" <····@merlotti.com> writes:
> 
> > 
> > Thanks to everybody's comments (and specially Paul Foley), I re-tought my
> > function and came up with another version of it:
> > 
> > (defun put-stones-to-strip (strip stones)
> >   (let* (
> >          (i 0))
> >     (loop
> >      (when (zerop stones) (return))
> >      (when (> i 11)
> >        (setq i 0))
> >      (incf (nth i strip))
> >      (incf i)
> >      (decf stones))
> >     (values strip)))
> 
> OK, let me try to move this a bit closer to Lisp style programming.
> I would note that you only need the VALUES form when you are returning
> more than one value from the function.  There isn't a need to
> specify anything specially, since forms in Lisp almost always
> return some value, typically the last subform.
> 
> Non-loop macro version:
> 
> (defun put-stones-to-strip (strip stones)
>   (let ((i 0))
>     (dotimes (count stones)
>        (declare (ignore count))
>        (incf (nth i strip))
>        (if (> i 10)
>          (setq i 0)
>          (incf i)))
>     strip))
> 
> 
> Full loop macro version:
> 
> (defun put-stones-to-strip (strip stones)
>   (loop repeat stones
>         for i = 0 then (mod (+ i 1) 12)
> 	do (incf (nth i strip)))
>   strip)
> 
> Note that these are both destructive of the STRIP
> argument. 

But you're not doing the same thing.  Better use do than loop:


(defun put-stones-to-strip-i (strip stones)
  (do ((current strip (or (cdr current) strip))
       (remains stones (1- remains)))
      ((< remains 0) strip)
    (incf (car current))))



On the other hand, stones is often enough much greater than (length
strip), it would be more efficient to do:


(defun put-stones-to-strip-a (strip stones)
  (multiple-value-bind (stone/slot remainder) (truncate stones (length strip))
    (do ((current strip (cdr current)))
        ((null current) strip)
      (if (< 0 remainder)
        (progn (decf remainder)
               (incf (car current) (1+ stone/slot)))
        (incf (car current) stone/slot)))))


-- 
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?