From: dlarkin
Subject: trouble learning LISP
Date: 
Message-ID: <eh1dbj$56h$1@news-int.gatech.edu>
Can an IF statement in lisp execute multiple expressions if it tests false.
For example:

(if (null expression) nil     ;;if nil then skip the else part
    ((expression1)            ;; else do expression 1 and expression 2
    (expression2)) 

From: Ralph Allan Rice
Subject: Re: trouble learning LISP
Date: 
Message-ID: <1161051168.299847.91670@h48g2000cwc.googlegroups.com>
I believe you can use UNLESS:

(unless (null expression)
  (progn
    (expression1)
    (expression2)))

--
Ralph



dlarkin wrote:
> Can an IF statement in lisp execute multiple expressions if it tests false.
> For example:
>
> (if (null expression) nil     ;;if nil then skip the else part
>     ((expression1)            ;; else do expression 1 and expression 2
>     (expression2))
From: Ari Johnson
Subject: Re: trouble learning LISP
Date: 
Message-ID: <m2zmbvejcb.fsf@hermes.theari.com>
"Ralph Allan Rice" <··········@gmail.com> writes:

> I believe you can use UNLESS:
>
> (unless (null expression)
>   (progn
>     (expression1)
>     (expression2)))

Only if you like being redundant.

(unless X
  Y
  Z)

is equivalent to

(if (not X)
  (progn
    Y
    Z))
From: Ralph Allan Rice
Subject: Re: trouble learning LISP
Date: 
Message-ID: <1161054639.946698.265200@b28g2000cwb.googlegroups.com>
Ahh.. touché. You are correct.  Thank you.

--
Ralph



Ari Johnson wrote:
> "Ralph Allan Rice" <··········@gmail.com> writes:
>
> > I believe you can use UNLESS:
> >
> > (unless (null expression)
> >   (progn
> >     (expression1)
> >     (expression2)))
>
> Only if you like being redundant.
>
> (unless X
>   Y
>   Z)
> 
> is equivalent to
> 
> (if (not X)
>   (progn
>     Y
>     Z))
From: ··@homeunix.net
Subject: Re: trouble learning LISP
Date: 
Message-ID: <ccSdneJUJo1BwanYnZ2dnUVZ_vmdnZ2d@comcast.com>
dlarkin wrote:
> Can an IF statement in lisp execute multiple expressions if it tests false.
> For example:
> 
> (if (null expression) nil     ;;if nil then skip the else part
>     ((expression1)            ;; else do expression 1 and expression 2
>     (expression2)) 
> 
> 

I believe Emacs Lisp will allow this.

In common Lisp you might want to use cond:

(cond
   (test expression)
   (t
     expression1
     expression2))

You could also use a macro to create
your own IF.  Such as this:

(defmacro if+ (test then-form &rest else-forms)
   `(cond
     (,test ,then-form)
     (t ,@else-forms)))
From: Pascal Bourguignon
Subject: Re: trouble learning LISP
Date: 
Message-ID: <87fydn76su.fsf@thalassa.informatimago.com>
··@homeunix.net writes:

> dlarkin wrote:
>> Can an IF statement in lisp execute multiple expressions if it tests false.
>> For example:
>> (if (null expression) nil     ;;if nil then skip the else part
>>     ((expression1)            ;; else do expression 1 and expression 2
>>     (expression2)) 
>
> I believe Emacs Lisp will allow this.

Well the syntax is different, but indeed, emacs lisp allows several
expressions in the else branch:

  #+emacs (if condition 
                then-expression
             else-expression-1
             else-expression-2
             ...
             else-expression-n)



> In common Lisp you might want to use cond:
>
> (cond
>   (test expression)
>   (t
>     expression1
>     expression2))
>
> You could also use a macro to create
> your own IF.  Such as this:
>
> (defmacro if+ (test then-form &rest else-forms)
>   `(cond
>     (,test ,then-form)
>     (t ,@else-forms)))

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

IMPORTANT NOTICE TO PURCHASERS: The entire physical universe,
including this product, may one day collapse back into an
infinitesimally small space. Should another universe subsequently
re-emerge, the existence of this product in that universe cannot be
guaranteed.
From: Pascal Bourguignon
Subject: Re: trouble learning LISP
Date: 
Message-ID: <87k62z7ksf.fsf@thalassa.informatimago.com>
"dlarkin" <········@mail.gatech.edu> writes:

> Can an IF statement in lisp execute multiple expressions if it tests false.

No it cannot.


> For example:
>
> (if (null expression) nil     ;;if nil then skip the else part
>     ((expression1)            ;; else do expression 1 and expression 2
>     (expression2)) 

This is meaningless in Common Lisp.

If you want to program in lisp, why don't you just read some lisp
tutorial instead of trying to invent some funny syntax?



If you want to do expression1 and expression2 only when expression is
not nil, why don't you just say so?

(when expression
   expression1
   expression2)


If you don't want to do expression1 and expressions unless expression
is nil, why don't you just say so?

(unless (null expression)
   expression1
   expression2)




Also, if you want the two branches of a IF, you have the same problem
than in Pascal, and the same solution.  Only, a BEGIN ... END block is
written (PROGN ...) in lisp.

(if condition
    (progn 
        ...)
    (progn
        ...))

But most often, you don't need to use progn, because you'll be using a
let or some other form that takes several expressions as body.

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

"This statement is false."            In Lisp: (defun Q () (eq nil (Q)))
From: ········@gmail.com
Subject: Re: trouble learning LISP
Date: 
Message-ID: <1161058502.376619.191480@i42g2000cwa.googlegroups.com>
Pascal Bourguignon wrote:
> If you want to program in lisp, why don't you just read some lisp
> tutorial instead of trying to invent some funny syntax?

Get up on the wrong side of the bed this morning, eh Pascal? I thought
that ranting at the poor noobs was Kenny's job....  :-)
From: Ken Tilton
Subject: Re: trouble learning LISP
Date: 
Message-ID: <Uo2Zg.316$Xg6.53@newsfe11.lga>
········@gmail.com wrote:
> Pascal Bourguignon wrote:
> 
>>If you want to program in lisp, why don't you just read some lisp
>>tutorial instead of trying to invent some funny syntax?
> 
> 
> Get up on the wrong side of the bed this morning, eh Pascal? I thought
> that ranting at the poor noobs was Kenny's job....  :-)
> 

Ah, the trolls win. The only "noob"s I torture are trolls who pose as 
noobs with seeming questions about Lisp that are nothing more than 
attempts to start language flame wars. The test is whether any of these 
clowns ever post again when they get stuck on actual work in Lisp, and 
-- surprise! surprise! -- they never do. (One can then attempt the 
contortion by which someone discovers the Unbearable Powewrfulness of 
Lisp and then abandons it because Kenny was mean to them, but that just 
makes you look stupider.) One also knows they are trolls by their quick 
jump to "hostile community" (c-o-m-m-u-n-i-t-y apparently being the 
alternative spelling for "Kenny") and their attempt to recast 
troll-bashing as noob-bashing, something that repeated often 
enough...apparently works.

PB is right. The subject "trouble learning Lisp" says it all. The only 
trouble is that the OP is not in fact trying to learn Lisp -- if they 
were, they would find all the info they need on-line -- they are trying 
to get Lisp to be some other language they already know. The only help 
the OP needs is a whack from a stick to get them to let go of their last 
language and remember they are supposed to be learning a new one. 
Instead the denizens of c.l.l (other than PB) are helping the OP with 
syntax. Nah....

kt

-- 
Cells: http://common-lisp.net/project/cells/

"I'll say I'm losing my grip, and it feels terrific."
    -- Smiling husband to scowling wife, New Yorker cartoon
From: Rob Thorpe
Subject: Re: trouble learning LISP
Date: 
Message-ID: <1161098177.578688.34550@e3g2000cwe.googlegroups.com>
Ken Tilton wrote:
> ········@gmail.com wrote:
> > Pascal Bourguignon wrote:
> >
> >>If you want to program in lisp, why don't you just read some lisp
> >>tutorial instead of trying to invent some funny syntax?
> >
> >
> > Get up on the wrong side of the bed this morning, eh Pascal? I thought
> > that ranting at the poor noobs was Kenny's job....  :-)
> >
>
> Ah, the trolls win. The only "noob"s I torture are trolls who pose as
> noobs with seeming questions about Lisp that are nothing more than
> attempts to start language flame wars.

I don't think that is common.  The questions I see here are not that
different to those posted on comp.programming or comp.lang.c.

I think you're just a bit paranoid about this.
From: Pascal Bourguignon
Subject: Re: trouble learning LISP
Date: 
Message-ID: <87wt6z5go3.fsf@thalassa.informatimago.com>
Ken Tilton <·········@gmail.com> writes:

> [...] The
> only help the OP needs is a whack from a stick to get them to let go
> of their last language and remember they are supposed to be learning a
> new one. 

If only we could whack thru the Internet...


> Instead the denizens of c.l.l (other than PB) are helping the
> OP with syntax. Nah....


Lisp has not syntax.  Lisp has no parentheses.  Lisp as no lists.

Well, it has, some, but not at the same level the other languages have
or haven't them.


Lisp has no syntax.

Indeed, since the sources are but syntactic trees, there's no concrete
syntax for list.  Or at least, not a single one.  We tend to write
nodes of these trees with the "list" syntax: '(' item ... ')', but
actually there are a lot of other ways to build this syntactic tree
(DAG actually), including various reader or normal macros.

But inside a program, There is no syntax, eg. for a complex number, no
#c(1.2 3.4); there are only complex numbers, with values such as
1.2+3.4*i.



Lisp has no parentheses.  

Indeed, just try it:

(map nil (function print) '(a b c))

A 
B 
C 
--> NIL

0 parentheses in (a b c).


In lisp _sources_, there are no parentheses.  Of course, actually
there are parentheses at the level of the characters reads by the
standard lisp reader.  But they could very easily disappear:

(set-syntax-from-char #\[ #\()
(set-syntax-from-char #\] #\))
(set-macro-character #\[ (lambda (stream char) (read-delimited-list #\] stream t)))

Et hop!  No parentheses anymore:

[map nil [function print] '[a b c]]

A 
B 
C 
--> NIL

Or we could write a macro or a parser, that would generate some code
with a lot of tree nodes, that could be printed by the standard lisp
printer with a lot of conventional parentheses, but which wouldn't
contain any parenthese in the source (of the macro, or the parsed
text).


Lisp has no list.

Again, just ask it:

(type-of '(a b c)) --> CONS
(type-of '())      --> NULL

See?  No type LIST here.
List is not a primitive lisp type.  
The primitive non-atomic Lisp type is the CONS cell.
And lists are but a pun on cons cells, at a higher level of abstraction.

Above the level of the CONS cells, we build an abstraction named LIST.
So we define FIRST = CAR, REST = CDR, ENDP = NULL, 
and LIST = (CONS (CONS ...)).

But above this level of "lists", that are actually just cons cells,
we build an abstraction named syntactic tree.  So we define:
OPERATOR = FIRST; ARGUMENTS = REST; EMPTYP = ENDP and MAKE-NODE = CONS.

OPERATOR  being the _label_ of the tree node, and
ARGUMENTS being the _children_ of the tree node.




The _sources_ of a lisp program are just syntactic trees, at a higher
level of abstraction relatively to the textual input that may (or may
not) be used to build the tree.


Of course, at this higher level, there is some 'syntax'. After all,
they're called syntactic tree.  But it's an "abstract" syntax, epured
from mundane details such as what character to put here or there.
What remains is only the label of the node, the operator, and an
ordered list of children, the arguments.

       label: +      children: 1 2 3
       label: IF     children: <condition> <then-clause> <else-clause>
       label: PROGN  children: <expression>...


You need to know the order of the children, what child to put at what
position, because this is what is significant.  Happily, there are
some conventions (eg in the order of the arguments to macros, we
usually put the name of the thing declared, or the name of the
variables first, while the body or the other variable-in-number
clauses come last), and there are some tools like keyword arguments
that allow to get free from this ordering constraint.


We don't need, and it would be ridiculous from the point of view of
list, to specify a grammar rule with a pair of characters and a syntax
like in C:

     block ::= '{' { statement ';' } '}' .

or even, to specify some BEGIN and END tokens like in Pascal:

     block ::= 'BEGIN' [ statement { ';' statement } ] 'END' .

(note the artificial difference in _syntax_!  Blocks, both in Pascal
and in C are parsed the same, into a syntactic tree such as:

      label: BLOCK  children: <statement>...

and this is all that matters.  Well, in lisp, we just put:

      label: BLOCK  children: <statement>...

in the source.

For example, by way of the READER (and therefore, using the characters
to which the reader macro to build symbol lists is bound to):

(map nil (function print)
         (read-from-string "(BLOCK <statement1> <statement2> <statement3>)"))

BLOCK 
<STATEMENT1> 
<STATEMENT2> 
<STATEMENT3> 
--> NIL

But we could also build the syntactic tree node by way of an expression:

(map nil (function print)
         (cons 'BLOCK  (append (list '<statement1> '<statement2>)
                               (cons '<statement3> '()))))

BLOCK 
<STATEMENT1> 
<STATEMENT2> 
<STATEMENT3> 
--> NIL



That's why things like ((expression1) (expression2)) are antithetic to
the lisp way, and trying to write something like this only shows that
the writer hasn't acquired the 'B' of the B-A-BA of lisp.




-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
Until real software engineering is developed, the next best practice
is to develop with a dynamic system that has extreme late binding in
all aspects. The first system to really do this in an important way
is Lisp. -- Alan Kay
From: ········@gmail.com
Subject: Re: Pole Position Switcher Conversion
Date: 
Message-ID: <1161096050.315627.211320@m7g2000cwm.googlegroups.com>
Google groups is massively broken!

Hi, y'all over on games.video.arcade.collecting, I'm from
comp.lang.lisp, but Google apparently doesn't think so! I just replied
to a message on c.l.l. and was handed, instead, the below to reply to.
I've never read g.v.a.c in my life. This isn't the first time that this
has happened to me, but in the past I've simply canceled the reply. I'm
only bothering to actually post this this time in order to document the
problem. (I'm also really curious what Google's going to do with the
fact that I've added c.l.l to the post response list ... maybe it'll
actually put this in the right conversation? Unlikely. Should be
interesting....) Anyway, sorry to interrupt your conversation with this
bug. Now if google actually had anything called "support" I could
actually report it to them.

Have a good day.



WEade wrote:
> Damn!  I should put it on my website!
>
> I have a copy of the document and made it into a PDF.  Dunno if my ISP would
> like the hits.  :)
>
> Bill
>
> > Some one was kind enough to send me a PDF from Startech Journal that
> showed
> > how to convert to a Switcher power Suppply but I lost it somehow......
> Does
> > anyone have a PDF or anything that I could get showing how this is done?
> > Thanks  a LOT
> > Darren A.
> >
> >
From: Espen Vestre
Subject: Re: trouble learning LISP
Date: 
Message-ID: <m14pu3b2hk.fsf@doduo.vestre.net>
Pascal Bourguignon <···@informatimago.com> writes:

> If only we could whack thru the Internet...

Well, if they're ignorant enough, you can probably (w)hack their pc ;)

> Lisp has not syntax.  Lisp has no parentheses.  Lisp as no lists.

nice :-)
-- 
  (espen)
From: Robert Uhl
Subject: Re: trouble learning LISP
Date: 
Message-ID: <m3ods9elxg.fsf@NOSPAMgmail.com>
Ken Tilton <·········@gmail.com> writes:
>
> Ah, the trolls win. The only "noob"s I torture are trolls who pose as
> noobs with seeming questions about Lisp that are nothing more than
> attempts to start language flame wars.

But of course there's only your word that they are actually trolls and
not newbies...

> The test is whether any of these clowns ever post again when they get
> stuck on actual work in Lisp, and -- surprise! surprise! -- they never
> do. (One can then attempt the contortion by which someone discovers
> the Unbearable Powewrfulness of Lisp and then abandons it because
> Kenny was mean to them, but that just makes you look stupider.)

There are other reasons to abandon Lisp, or rather to forego its use in
a particular project or other.  Lack of ready-made libraries, for one
thing.

> One also knows they are trolls by their quick jump to "hostile
> community" (c-o-m-m-u-n-i-t-y apparently being the alternative
> spelling for "Kenny") and their attempt to recast troll-bashing as
> noob-bashing, something that repeated often enough...apparently works.

Of course, a newbie will also see your bashing as newbie-bashing.  And I
daresay he'd also be quick to complain about the community, too,
especially given that Lisp has a bad reputation in that regard.

Why not just be nice & pleasant?  One catches more flies with honey than
with vinegar.

-- 
Robert Uhl <http://public.xdi.org/=ruhl>
I have heard it said that the reason M$ is choosing to work with the
government of .ng in stopping 419 scammers is that it's easier to
rebuild the Nigerian government and economy than to fix the bugs in
M$ code.                                             --Mike Andrews
From: Rajappa Iyer
Subject: Re: trouble learning LISP
Date: 
Message-ID: <86mz7t1si2.fsf@panix.com>
Robert Uhl <·········@NOSPAMgmail.com> writes:

> Of course, a newbie will also see your bashing as newbie-bashing.  And I
> daresay he'd also be quick to complain about the community, too,
> especially given that Lisp has a bad reputation in that regard.

The quality and helpfulness of much of the commentary in this group is
so astonishingly good that one would have to be a complete and
irredeemable moron to ignore it in favor of sulking about a few rough
words.  Such easily discouraged "noobs" are no loss to either the
community or the group, I'd say.

rsi
-- 
<···@panix.com> a.k.a. Rajappa Iyer.
	Absinthe makes the tart grow fonder. 
From: Ken Tilton
Subject: Re: trouble learning LISP
Date: 
Message-ID: <2MuZg.17$Kh.4@newsfe09.lga>
Robert Uhl wrote:
> Ken Tilton <·········@gmail.com> writes:
> 
>>Ah, the trolls win. The only "noob"s I torture are trolls who pose as
>>noobs with seeming questions about Lisp that are nothing more than
>>attempts to start language flame wars.
> 
> 
> But of course there's only your word that they are actually trolls and
> not newbies...
> 
> 
>>The test is whether any of these clowns ever post again when they get
>>stuck on actual work in Lisp, and -- surprise! surprise! -- they never
>>do. (One can then attempt the contortion by which someone discovers
>>the Unbearable Powewrfulness of Lisp and then abandons it because
>>Kenny was mean to them, but that just makes you look stupider.)
> 
> 
> There are other reasons to abandon Lisp, or rather to forego its use in
> a particular project or other.  Lack of ready-made libraries, for one
> thing.
> 
> 
>>One also knows they are trolls by their quick jump to "hostile
>>community" (c-o-m-m-u-n-i-t-y apparently being the alternative
>>spelling for "Kenny") and their attempt to recast troll-bashing as
>>noob-bashing, something that repeated often enough...apparently works.
> 
> 
> Of course, a newbie will also see your bashing as newbie-bashing.  And I
> daresay he'd also be quick to complain about the community, too,
> especially given that Lisp has a bad reputation in that regard.
> 
> Why not just be nice & pleasant?  One catches more flies with honey than
> with vinegar.
> 

Wow, how hostile can you get, lecturing an established member of c.l.l 
community on his manners? You are smug, self-righteous, condescending, 
and holier-than-thou -- nice object lesson in cathing flies, Robert. 
Anyway...

Your entire argument hangs on the trolls not being trolls. (Well, 
actually, i think you just wanted to climb up on the soapbox and pose as 
Mr. Affable, but...) Now where in your post did you establish that? Oh, 
here it is: you explained away the mysterious post flamewar 
disappearance of trolls as "There are other reasons to abandon Lisp... 
Lack of ready-made libraries, for one thing."

Let me make sure I have this right. Well-meaning noobs ask heartfelt, 
sincere questions, Kenny flames them, they respond with a week of 
vitriol and /simultaneously/ discover Lisp has no libraries and /without 
mentioning that/ disappear to use Python instead. Apologies in advance 
if I made your argument sound too stupid.

I have an idea. If you are right, you should be able to point to a 
troll/noob I flamed who was not a troll. I mean an actual case. Name(s), 
you must provide name(s). Otherwise... what are you blathering about?

The trolls win. The trolls always win.

:)

kt

-- 
Cells: http://common-lisp.net/project/cells/

"I'll say I'm losing my grip, and it feels terrific."
    -- Smiling husband to scowling wife, New Yorker cartoon
From: Bob Felts
Subject: Re: trouble learning LISP
Date: 
Message-ID: <1hnfcvr.fuqp4ly56vqaN%wrf3@stablecross.com>
Ken Tilton <·········@gmail.com> wrote:

> 
> The trolls win. The trolls always win.
> 

Who was it who said, "Never argue with an idiot.  They just drag you
down to their level then beat you with experience"?
From: verec
Subject: Re: trouble learning LISP
Date: 
Message-ID: <4536ac0a$0$626$5a6aecb4@news.aaisp.net.uk>
On 2006-10-18 19:54:54 +0100, Ken Tilton <·········@gmail.com> said:

> The trolls win. The trolls always win.

And the "Master" pontificates.
--
JFB
From: Ken Tilton
Subject: Re: trouble learning LISP
Date: 
Message-ID: <N4AZg.1259$tT6.26@newsfe12.lga>
verec wrote:
> On 2006-10-18 19:54:54 +0100, Ken Tilton <·········@gmail.com> said:
> 
>> The trolls win. The trolls always win.
> 
> 
> And the "Master" pontificates.

And then we have pathetic Lisp groupies who hang around c.l.l never 
writing any Lisp thinking just hanging out with real Lispniks somehow 
makes you cool.

Maybe you should shut up and write some code and then you could be a 
real Lispnik instead of just a lame hanger-on.

hth, kenny

-- 
Cells: http://common-lisp.net/project/cells/

"I'll say I'm losing my grip, and it feels terrific."
    -- Smiling husband to scowling wife, New Yorker cartoon
From: verec
Subject: Re: trouble learning LISP
Date: 
Message-ID: <4536da96$0$628$5a6aecb4@news.aaisp.net.uk>
On 2006-10-19 01:59:01 +0100, Ken Tilton <·········@gmail.com> said:

> verec wrote:
>> On 2006-10-18 19:54:54 +0100, Ken Tilton <·········@gmail.com> said:
>> 
>>> The trolls win. The trolls always win.
>> 
>> 
>> And the "Master" pontificates.
> 
> And then we have pathetic Lisp groupies who hang around c.l.l never 
> writing any Lisp thinking just hanging out with real Lispniks somehow 
> makes you cool.

Ken Tilton the "Real Lispmik" with whom it is an "Honour to Hang About"

Yep. You made my day,

Tilton, you are so drowning in your suffisance, that if I were
you, I would seriously consider suicide. Point blank.

The only one I have to prove anything to is _me_. Got it?

Can you understand how littel significance your mediocre self can have?

No. You cam't. And you're always going to come back with some
"noble goal" to defend your point, but, seriously, Tilton ...

... YOU are part of the noise in c.l.l TOO

> Maybe you should shut up and write some code and then you could be a 
> real Lispnik instead of just a lame hanger-on.

Shutting up?

That's an idea!

An extremely good one!

Want to give it a try?
--
JFB
From: Bill Atkins
Subject: Re: trouble learning LISP
Date: 
Message-ID: <m2bqo9f2qx.fsf@bertrand.local>
verec <·····@mac.com> writes:

> Tilton, you are so drowning in your suffisance, that if I were

Yikes, harsh.

I think?
From: Ken Tilton
Subject: Re: trouble learning LISP
Date: 
Message-ID: <t9CZg.85$QA4.48@newsfe10.lga>
Bill Atkins wrote:
> verec <·····@mac.com> writes:
> 
> 
>>Tilton, you are so drowning in your suffisance, that if I were

wow, looks like a good one, gotta go google that one up now that poor 
verec sleeps with the fish in my killfile.

I'll just search on suffisance. :)

kt

-- 
Cells: http://common-lisp.net/project/cells/

"I'll say I'm losing my grip, and it feels terrific."
    -- Smiling husband to scowling wife, New Yorker cartoon
From: Ken Tilton
Subject: Re: trouble learning LISP
Date: 
Message-ID: <1MCZg.148$md7.26@newsfe11.lga>
Bill Atkins wrote:
> verec <·····@mac.com> writes:
> 
> 
>>Tilton, you are so drowning in your suffisance, that if I were
> 
> 
> Yikes, harsh.

The suggestion I kill myself? Nice touch, shades of Erik. But 
jean_francois set the bar pretty high on day one:

>> Social skills? PWUAHAHA. Your mistake is thinking we give a rat's ass
>> about being liked by trolls like verec.
> 
> Does "verec" give "a rat's ass" about being liked by God Kenny Tilton?
> 
> "verec" doesn't think that posts made by Kenny Tilton had any relevance
> to the thread, and would, thus, qualify His Majesty Tilton, Kelly, hopefully
> first and only, not as a troll but as real life deprived, and thus
> needing to exist by rambling on usenet.
> 
> "verec" by his conspicuous absence of regular posts, shows, at least,
> that he has other things to do in life than not responding to questions
> that arrise, here and then.
> 
> Real Programmers ... program. They don't haunt usenet as Saint Tilton does.
> 
> A few years back, here in c.l.l, we had a bug called "Naggum". I just wonder
> if Tilton, Kelly Fish is not just his re-incarnation?
> 
> Not too good for your carma, Sir Tilton.
> 
> Being an arrogant imbecile uttering "troll! troll! troll!" three times
> a sentence doesn't bode too well... Show us your (setq ...) and (defmacro ...)
> instead.
> 
> And if you can't stand seeing your little toy being "attacked" by "trolls",
> just get out of here: there's nothing for you.... unless that's the only
> thing you've got in life, which I wouldn't find that surprising.
> 
> Good Bye Mr Tilton. Hope to not see you soon. 

"Kelly Fish"?

:)

kt


-- 
Cells: http://common-lisp.net/project/cells/

"I'll say I'm losing my grip, and it feels terrific."
    -- Smiling husband to scowling wife, New Yorker cartoon
From: Bill Atkins
Subject: Re: trouble learning LISP
Date: 
Message-ID: <m28xjckuq7.fsf@weedle-24.dynamic.rpi.edu>
Ken Tilton <·········@gmail.com> writes:

> Bill Atkins wrote:
>> verec <·····@mac.com> writes:
>>
>>
>>>Tilton, you are so drowning in your suffisance, that if I were
>>
>>
>> Yikes, harsh.
>
> The suggestion I kill myself? Nice touch, shades of Erik. But
> jean_francois set the bar pretty high on day one:

No, verec's accusation that you were "so drowning in your suffisance."
From: Ken Tilton
Subject: Re: trouble learning LISP
Date: 
Message-ID: <9CRZg.33$SK2.3@newsfe11.lga>
Bill Atkins wrote:
> Ken Tilton <·········@gmail.com> writes:
> 
> 
>>Bill Atkins wrote:
>>
>>>verec <·····@mac.com> writes:
>>>
>>>
>>>
>>>>Tilton, you are so drowning in your suffisance, that if I were
>>>
>>>
>>>Yikes, harsh.
>>
>>The suggestion I kill myself? Nice touch, shades of Erik. But
>>jean_francois set the bar pretty high on day one:
> 
> 
> No, verec's accusation that you were "so drowning in your suffisance."

Ah. No, not drowning in my suffisance. That is the backstroke I am 
doing, needs polish I guess.

kt

-- 
Cells: http://common-lisp.net/project/cells/

"I'll say I'm losing my grip, and it feels terrific."
    -- Smiling husband to scowling wife, New Yorker cartoon
From: dlarkin
Subject: Re: trouble learning LISP
Date: 
Message-ID: <eh2m3m$ksf$1@news-int.gatech.edu>
I take it that the IF statement is not popular in LISP. The IF statement 
just makes easier reading for me as I have not worked with LISP for very 
long.

I did look in several books, I have one in paper version and several digital 
books downloaded from the internet. But I could not find where it 
specifically said IF could only handle one expression per condition. I am 
asking instead of reading becuase I am looking fir context as well as 
syntax.

I am trying to think more in terms of LISP then the other languages.

I started using the COND statement, and will probably strike 'IF' out of my 
vocabulary.

thanks, I appreciate the BLUF.

"Pascal Bourguignon" <···@informatimago.com> wrote in message 
···················@thalassa.informatimago.com...
> "dlarkin" <········@mail.gatech.edu> writes:
>
>> Can an IF statement in lisp execute multiple expressions if it tests 
>> false.
>
> No it cannot.
>
>
>> For example:
>>
>> (if (null expression) nil     ;;if nil then skip the else part
>>     ((expression1)            ;; else do expression 1 and expression 2
>>     (expression2))
>
> This is meaningless in Common Lisp.
>
> If you want to program in lisp, why don't you just read some lisp
> tutorial instead of trying to invent some funny syntax?
>
>
>
> If you want to do expression1 and expression2 only when expression is
> not nil, why don't you just say so?
>
> (when expression
>   expression1
>   expression2)
>
>
> If you don't want to do expression1 and expressions unless expression
> is nil, why don't you just say so?
>
> (unless (null expression)
>   expression1
>   expression2)
>
>
>
>
> Also, if you want the two branches of a IF, you have the same problem
> than in Pascal, and the same solution.  Only, a BEGIN ... END block is
> written (PROGN ...) in lisp.
>
> (if condition
>    (progn
>        ...)
>    (progn
>        ...))
>
> But most often, you don't need to use progn, because you'll be using a
> let or some other form that takes several expressions as body.
>
> -- 
> __Pascal Bourguignon__                     http://www.informatimago.com/
>
> "This statement is false."            In Lisp: (defun Q () (eq nil (Q))) 
From: Rob Thorpe
Subject: Re: trouble learning LISP
Date: 
Message-ID: <1161093076.168544.24740@f16g2000cwb.googlegroups.com>
dlarkin wrote:
> I take it that the IF statement is not popular in LISP. The IF statement
> just makes easier reading for me as I have not worked with LISP for very
> long.
>
> I did look in several books, I have one in paper version and several digital
> books downloaded from the internet. But I could not find where it
> specifically said IF could only handle one expression per condition. I am
> asking instead of reading becuase I am looking fir context as well as
> syntax.
>
> I am trying to think more in terms of LISP then the other languages.
>
> I started using the COND statement, and will probably strike 'IF' out of my
> vocabulary.

I use 'if' from time to time, I use cond quite a lot too.

Questions about things like this can be answered with the Common Lisp
HyperSpec.  This is online at
http://www.lispworks.com/documentation/HyperSpec/Front/index.htm .

See the master index for 'if'.  The CLHS is rather complex and not good
to use for learning from, but its good for reference when learning.

Similarily for Emacs lisp type C-h f if in Emacs which shows that the
Emacs version is slightly different.
From: ··@homeunix.net
Subject: Re: trouble learning LISP
Date: 
Message-ID: <2sSdnTkQMZ3ReqnYnZ2dnUVZ_oadnZ2d@comcast.com>
dlarkin wrote:
> I take it that the IF statement is not popular in LISP. The IF statement 
> just makes easier reading for me as I have not worked with LISP for very 
> long.
> 
> I did look in several books, I have one in paper version and several digital 
> books downloaded from the internet. But I could not find where it 
> specifically said IF could only handle one expression per condition. I am 
> asking instead of reading becuase I am looking fir context as well as 
> syntax.
> 
> I am trying to think more in terms of LISP then the other languages.
> 
> I started using the COND statement, and will probably strike 'IF' out of my 
> vocabulary.

Well, sometimes the IF statement could be a lot clearer to
use and because of the functional style of programming
possible in Lisp you will find it unnecessary to use more
than one expression per branch.
From: Thomas A. Russ
Subject: Re: trouble learning LISP
Date: 
Message-ID: <ymiu022x2p8.fsf@sevak.isi.edu>
"dlarkin" <········@mail.gatech.edu> writes:

> I take it that the IF statement is not popular in LISP. The IF statement 
> just makes easier reading for me as I have not worked with LISP for very 
> long.

Actually, this is a matter of personal style.  Some of the really old
folks around here (like me) learned lisp before the advent of the IF
form and only really had COND to deal with.

I've since moved on, and typically will use IF as long as there are only
two options, and (generally) the options are single forms.  I find that
once you start having to put PROGNs into the IF clauses, that COND
starts looking a lot nicer.

> I did look in several books, I have one in paper version and several digital 
> books downloaded from the internet. But I could not find where it 
> specifically said IF could only handle one expression per condition. I am 
> asking instead of reading becuase I am looking fir context as well as 
> syntax.

I suppose it depends on exactly which dialect of Lisp you are talking
about.

Common Lisp allows only a single expression for THEN and ELSE.
Emacs Lisp allows multiple expressions for the ELSE part of IF.
Other lisps (and some Common Lisp extensions?) also allow multiple else
clauses, so they have an implicit PROGN for the else part.

All Lisps allow you to leave off the ELSE part, although for cases of
only a single option, I prefer to use WHEN or UNLESS, since it makes it
clearer that there is only one branch.

> I am trying to think more in terms of LISP then the other languages.
> 
> I started using the COND statement, and will probably strike 'IF' out of my 
> vocabulary.

It's really up to you.  IF + PROGN works just fine, but it can get a bit
tedious.  It does have the advantage that it tells you there are only
two clauses that are coming.

Now what would be hideous, style-wise, would be cascading IF statements,
especially since that leads to increasing indentation.  That is where
COND really shines:

(if (a)
    (b)
    (if (c)
        (d)
        (if (e)
            (progn (f) (g) (h))
            (progn (f) (g)))))

Except that most function names are much longer. ;)

> thanks, I appreciate the BLUF.
> 
> "Pascal Bourguignon" <···@informatimago.com> wrote in message 
> ···················@thalassa.informatimago.com...
> > "dlarkin" <········@mail.gatech.edu> writes:
> >
> >> Can an IF statement in lisp execute multiple expressions if it tests 
> >> false.
> >
> > No it cannot.
> >
> >
> >> For example:
> >>
> >> (if (null expression) nil     ;;if nil then skip the else part
> >>     ((expression1)            ;; else do expression 1 and expression 2
> >>     (expression2))

The problem here is that ((expression1) (expression2)) is not legal
Common Lisp syntax.  You would instead need to use
 (progn (expression1) (expression2))

-- 
Thomas A. Russ,  USC/Information Sciences Institute
From: ········@gmail.com
Subject: Re: trouble learning LISP
Date: 
Message-ID: <1161117105.389140.28550@e3g2000cwe.googlegroups.com>
Thomas A. Russ wrote:
> Actually, this is a matter of personal style.  Some of the really old
> folks around here (like me) learned lisp before the advent of the IF
> form and only really had COND to deal with.

You had COND?! When I learned Lisp we only had AND and OR! (And used
nested nils for numbers! ;-)
From: dlarkin
Subject: Re: trouble learning LISP
Date: 
Message-ID: <eh3lji$4pk$1@news-int2.gatech.edu>
Here is a specific example it is code from one of the online books I 
downloaded.



(defun flatten (tree)

    (cond ((atom tree) (list tree))

        (t (append (flatten (car tree))

                    (flatten (cdr tree))))))



What I have been trying to do is to add stuff like: (format t "Tree : ~A ~%" 
tree) into the COND (originally the IF) statement.



(defun flatten (tree)

    (cond ((atom tree) (list tree))

        (t (append (flatten (car tree))

                    (flatten (cdr tree)))

(format t "Tree : ~A ~%" tree)  ;;; like here after the append but part of 
the cond t)

)))



 Nothing to complex, I want to see the recursion as it occurs. It was really 
giving me trouble with the IF statement or messing with the return values of 
the function with the COND. I managed to work around this by using SETF and 
creating more variables but things get sloppy that way.



Thanks to all the posts, I now understand a lot more, about what is going on 
but I still have not found an easy way to trace the values as they change.


"Thomas A. Russ" <···@sevak.isi.edu> wrote in message 
····················@sevak.isi.edu...
> "dlarkin" <········@mail.gatech.edu> writes:
>
>> I take it that the IF statement is not popular in LISP. The IF statement
>> just makes easier reading for me as I have not worked with LISP for very
>> long.
>
> Actually, this is a matter of personal style.  Some of the really old
> folks around here (like me) learned lisp before the advent of the IF
> form and only really had COND to deal with.
>
> I've since moved on, and typically will use IF as long as there are only
> two options, and (generally) the options are single forms.  I find that
> once you start having to put PROGNs into the IF clauses, that COND
> starts looking a lot nicer.
>
>> I did look in several books, I have one in paper version and several 
>> digital
>> books downloaded from the internet. But I could not find where it
>> specifically said IF could only handle one expression per condition. I am
>> asking instead of reading becuase I am looking fir context as well as
>> syntax.
>
> I suppose it depends on exactly which dialect of Lisp you are talking
> about.
>
> Common Lisp allows only a single expression for THEN and ELSE.
> Emacs Lisp allows multiple expressions for the ELSE part of IF.
> Other lisps (and some Common Lisp extensions?) also allow multiple else
> clauses, so they have an implicit PROGN for the else part.
>
> All Lisps allow you to leave off the ELSE part, although for cases of
> only a single option, I prefer to use WHEN or UNLESS, since it makes it
> clearer that there is only one branch.
>
>> I am trying to think more in terms of LISP then the other languages.
>>
>> I started using the COND statement, and will probably strike 'IF' out of 
>> my
>> vocabulary.
>
> It's really up to you.  IF + PROGN works just fine, but it can get a bit
> tedious.  It does have the advantage that it tells you there are only
> two clauses that are coming.
>
> Now what would be hideous, style-wise, would be cascading IF statements,
> especially since that leads to increasing indentation.  That is where
> COND really shines:
>
> (if (a)
>    (b)
>    (if (c)
>        (d)
>        (if (e)
>            (progn (f) (g) (h))
>            (progn (f) (g)))))
>
> Except that most function names are much longer. ;)
>
>> thanks, I appreciate the BLUF.
>>
>> "Pascal Bourguignon" <···@informatimago.com> wrote in message
>> ···················@thalassa.informatimago.com...
>> > "dlarkin" <········@mail.gatech.edu> writes:
>> >
>> >> Can an IF statement in lisp execute multiple expressions if it tests
>> >> false.
>> >
>> > No it cannot.
>> >
>> >
>> >> For example:
>> >>
>> >> (if (null expression) nil     ;;if nil then skip the else part
>> >>     ((expression1)            ;; else do expression 1 and expression 2
>> >>     (expression2))
>
> The problem here is that ((expression1) (expression2)) is not legal
> Common Lisp syntax.  You would instead need to use
> (progn (expression1) (expression2))
>
> -- 
> Thomas A. Russ,  USC/Information Sciences Institute 
From: Javier
Subject: Re: trouble learning LISP
Date: 
Message-ID: <1161131541.602676.226770@i3g2000cwc.googlegroups.com>
dlarkin ha escrito:

> Here is a specific example it is code from one of the online books I
> downloaded.
>
>
>
> (defun flatten (tree)
>
>     (cond ((atom tree) (list tree))
>
>         (t (append (flatten (car tree))
>
>                     (flatten (cdr tree))))))
>
>
>
> What I have been trying to do is to add stuff like: (format t "Tree : ~A ~%"
> tree) into the COND (originally the IF) statement.
>
>
>
> (defun flatten (tree)
>
>     (cond ((atom tree) (list tree))
>
>         (t (append (flatten (car tree))
>
>                     (flatten (cdr tree)))
>
> (format t "Tree : ~A ~%" tree)  ;;; like here after the append but part of
> the cond t)
>
> )))
>
>
>
>  Nothing to complex, I want to see the recursion as it occurs. It was really
> giving me trouble with the IF statement or messing with the return values of
> the function with the COND. I managed to work around this by using SETF and
> creating more variables but things get sloppy that way.
>
>
>
> Thanks to all the posts, I now understand a lot more, about what is going on
> but I still have not found an easy way to trace the values as they change.

Lisp can surprise you. Just use the "trace" utility:

CL-USER> (trace flatten)
(FLATTEN)
CL-USER> (flatten '((a) b c))
  0: (FLATTEN ((A) B C))
    1: (FLATTEN (A))
      2: (FLATTEN A)
      2: FLATTEN returned (A)
      2: (FLATTEN NIL)
      2: FLATTEN returned (NIL)
    1: FLATTEN returned (A NIL)
    1: (FLATTEN (B C))
      2: (FLATTEN B)
      2: FLATTEN returned (B)
      2: (FLATTEN (C))
        3: (FLATTEN C)
        3: FLATTEN returned (C)
        3: (FLATTEN NIL)
        3: FLATTEN returned (NIL)
      2: FLATTEN returned (C NIL)
    1: FLATTEN returned (B C NIL)
  0: FLATTEN returned (A NIL B C NIL)
(A NIL B C NIL)

You can easily see the bug now.
A correct version, also using the trace utility:

(defun flatten (lst)
  (cond
    ((null lst) lst)
    ((listp (car lst)) (append (car lst) (flatten (cdr lst))))
    (t (cons (car lst) (flatten (cdr lst))))))

CL-USER> (trace flatten)
WARNING: FLATTEN is already TRACE'd, untracing it first.
(FLATTEN)
CL-USER> (flatten '((a) b c))
  0: (FLATTEN ((A) B C))
    1: (FLATTEN (B C))
      2: (FLATTEN (C))
        3: (FLATTEN NIL)
        3: FLATTEN returned NIL
      2: FLATTEN returned (C)
    1: FLATTEN returned (B C)
  0: FLATTEN returned (A B C)
(A B C)
From: ········@gmail.com
Subject: Re: trouble learning LISP
Date: 
Message-ID: <1161131892.188420.121130@k70g2000cwa.googlegroups.com>
> (defun flatten (tree)
>     (cond ((atom tree) (list tree))
>              (t (append (flatten (car tree))
>                             (flatten (cdr tree)))
>
> (format t "Tree : ~A ~%" tree)  ;;; like here after the append but part of
> the cond t)

You don't really want to do this; it doesn't make any sense because
when the recursive call returns, TREE is the same as when the recursive
call went in, so putting the format before, or after, the recrusive
call makes no difference, and won't tell you what you want to know
anyway.

What to do:

Frist, (TRACE flatten)

Next: Wrap a (print ...) around the recursive append call (or anything
that youu want to see the value of). PRINT returns its argument's value
(after printing it), so it's a no-op as far as the computation is
concerned. Unfortunately you can only put one value into it in this
sense.

Example:

   ...
   (t (print (append (flatten (car tree))
                           (flatten (cdr tree)))))
   ...


For more complex sorts of tracing you can make effective use of PROG
(as mentioned elsewhere), and even better: PROG1 which returns the
FIRST value instead of the last.

Example:

   ...
   (t (prog1 (append (flatten (car tree))
                           (flatten (cdr tree)))
                (format "Tree is ~s~%" tree)))
   ...

[Although, as noted above, this isn't going to give you what you want!]

Next try more interesting sorts of debugging macros of your own design.


Example:

(defmacro fancy-trace (expr)
   (let ((tempvar (gentemp)))
      `(let ((,tempvar ,expr))
           (format t "Value returned by ~s is ~s~%" ',expr ,tempvar)
           ,tempvar)))

(fancy-trace (+ 1 2))
Value returned by (+ 1 2) is 3
3

With your example:

(defun flatten (tree)
    (cond ((atom tree) (list tree))
             (t (fancy-trace (append (flatten (car tree))
                            (flatten (cdr tree)))))))

 (flatten '((this (is (deeply) nested))))
Value returned by (APPEND (FLATTEN (CAR TREE)) (FLATTEN (CDR TREE))) is
(DEEPLY NIL)
Value returned by (APPEND (FLATTEN (CAR TREE)) (FLATTEN (CDR TREE))) is
(NESTED NIL)
Value returned by (APPEND (FLATTEN (CAR TREE)) (FLATTEN (CDR TREE))) is
(DEEPLY NIL NESTED NIL)
Value returned by (APPEND (FLATTEN (CAR TREE)) (FLATTEN (CDR TREE))) is
(IS DEEPLY NIL NESTED NIL)
Value returned by (APPEND (FLATTEN (CAR TREE)) (FLATTEN (CDR TREE))) is
(IS DEEPLY NIL NESTED NIL NIL)
Value returned by (APPEND (FLATTEN (CAR TREE)) (FLATTEN (CDR TREE))) is
(THIS IS DEEPLY NIL NESTED NIL NIL)
Value returned by (APPEND (FLATTEN (CAR TREE)) (FLATTEN (CDR TREE))) is
(THIS

 IS

 DEEPLY

 NIL

 NESTED

 NIL

 NIL

 NIL)
(THIS IS DEEPLY NIL NESTED NIL NIL NIL)

[By the way, your code is wrong, but I'll leave that to you!]
From: ······@earthlink.net
Subject: Re: trouble learning LISP
Date: 
Message-ID: <1161132095.990861.260380@e3g2000cwe.googlegroups.com>
dlarkin wrote:
> (defun flatten (tree)
>
>     (cond ((atom tree) (list tree))
>
>         (t (append (flatten (car tree))
>
>                     (flatten (cdr tree)))
>
> (format t "Tree : ~A ~%" tree)  ;;; like here after the append but part of
> the cond t)
>
> )))
>  Nothing to complex, I want to see the recursion as it occurs. It was really
> giving me trouble with the IF statement or messing with the return values of
> the function with the COND.

The value of the cond is ALWAYS the value of the last expression in the
selected branch.  If you change that expression, you change the value
of the cond.

I'm curious - what language works the way that you seem to think that
lisp would work?  For example, "{ return a; printf(a); }" doesn't print
anything in c.

If you want to see the recursion as it occurs, print BEFORE the cond
or before the recursive call.  (Both are positions that are not the
value
of the cond or the value of the function call.)  Or, if you want to
print
the value that the cond will return and still return it, you can do
something
like

(defun flatten (tree)
     (cond ((atom tree) (list tree))
              (t (foo (append (flatten (car tree))
                             (flatten (cdr tree)))))))

(defun foo (l)
   (print l)
   l)

Or, you could use "(foo (cond ....))".  (Yes, you could also write an
explicit
let which looks a lot like foo's definition.)

> Thanks to all the posts, I now understand a lot more, about what is going on
> but I still have not found an easy way to trace the values as they change.

Umm, the values aren't changing....  none of trees' change in any
of this code.  (You do know that there are lots of different instances
of
tree, one for each recursive call, right?  When the recursive call
occurs,
a new "tree" is created and given a value.  flatten returns some
function
of that value, an operation that may involve a recursive call.)

-andy
From: dlarkin
Subject: Re: trouble learning LISP
Date: 
Message-ID: <eh45it$b3o$1@news-int2.gatech.edu>
Yes about a week ago someone straightened me out about the non-destructive 
power of LISP. Most of its functions do not change the values. The value of 
TREE is changed only for the duration of the recursion. Once all the 
recursion is done it is the same old TREE I started with.



With the FLATTEN function I was thoroughly confused as to why it did not 
stop once the condition of ATOM TREE evaluated to true the first time. Once 
I added the FORMAT t commands and thought about it very hard I was able to 
figure out how the recursion was working. Here is the code and the output.



(defun flatten (tree)

  (cond ((atom tree) (list tree)

         (format t "1 Atom tree: ~A Tree ~A ~%" (atom tree) tree))

        (t  (format t "   2 Atom tree: ~A Tree ~A ~%" (atom tree) tree)

           (append (flatten (car tree))

                   (flatten (cdr tree)))

           (format t "       3 Atom tree: ~A Tree ~A ~%" (atom tree) tree)

)))



Here is the output.



CG-USER(16): (FLATTEN '((A B) (C) (D E (F))))

   2 Atom tree: NIL Tree ((A B) (C) (D E (F)))

   2 Atom tree: NIL Tree (A B)

1 Atom tree: T Tree A

   2 Atom tree: NIL Tree (B)

1 Atom tree: T Tree B

1 Atom tree: T Tree NIL

       3 Atom tree: NIL Tree (B)

       3 Atom tree: NIL Tree (A B)

   2 Atom tree: NIL Tree ((C) (D E (F)))

   2 Atom tree: NIL Tree (C)

1 Atom tree: T Tree C

1 Atom tree: T Tree NIL

       3 Atom tree: NIL Tree (C)

   2 Atom tree: NIL Tree ((D E (F)))

   2 Atom tree: NIL Tree (D E (F))

1 Atom tree: T Tree D

   2 Atom tree: NIL Tree (E (F))

1 Atom tree: T Tree E

   2 Atom tree: NIL Tree ((F))

   2 Atom tree: NIL Tree (F)

1 Atom tree: T Tree F

1 Atom tree: T Tree NIL

       3 Atom tree: NIL Tree (F)

1 Atom tree: T Tree NIL

       3 Atom tree: NIL Tree ((F))

       3 Atom tree: NIL Tree (E (F))

       3 Atom tree: NIL Tree (D E (F))

1 Atom tree: T Tree NIL

       3 Atom tree: NIL Tree ((D E (F)))

       3 Atom tree: NIL Tree ((C) (D E (F)))

       3 Atom tree: NIL Tree ((A B) (C) (D E (F)))

NIL



The only problem is the function returns NIL instead of the flattened list, 
however if I remove all the FORMAT t lines the function returns:



(A B NIL C NIL D E F NIL NIL ...)



Below is an example of showing that TRACE does not help me. It does not show 
any of the recursion. (flatten2 is flatten without the format lines)



CG-USER(20): (trace (flatten2))

(FLATTEN2)

CG-USER(21): (FLATTEN2 '((A B) (C) (D E (F))))

 0[6]: (FLATTEN2 ((A B) (C) (D E (F))))

 0[6]: returned (A B NIL C NIL D E F NIL NIL NIL)

(A B NIL C NIL D E F NIL NIL ...)

CG-USER(22):



Am I missing something with TRACE or is there an easier way of doing this?
<······@earthlink.net> wrote in message 
·····························@e3g2000cwe.googlegroups.com...
> dlarkin wrote:
>> (defun flatten (tree)
>>
>>     (cond ((atom tree) (list tree))
>>
>>         (t (append (flatten (car tree))
>>
>>                     (flatten (cdr tree)))
>>
>> (format t "Tree : ~A ~%" tree)  ;;; like here after the append but part 
>> of
>> the cond t)
>>
>> )))
>>  Nothing to complex, I want to see the recursion as it occurs. It was 
>> really
>> giving me trouble with the IF statement or messing with the return values 
>> of
>> the function with the COND.
>
> The value of the cond is ALWAYS the value of the last expression in the
> selected branch.  If you change that expression, you change the value
> of the cond.
>
> I'm curious - what language works the way that you seem to think that
> lisp would work?  For example, "{ return a; printf(a); }" doesn't print
> anything in c.
>
> If you want to see the recursion as it occurs, print BEFORE the cond
> or before the recursive call.  (Both are positions that are not the
> value
> of the cond or the value of the function call.)  Or, if you want to
> print
> the value that the cond will return and still return it, you can do
> something
> like
>
> (defun flatten (tree)
>     (cond ((atom tree) (list tree))
>              (t (foo (append (flatten (car tree))
>                             (flatten (cdr tree)))))))
>
> (defun foo (l)
>   (print l)
>   l)
>
> Or, you could use "(foo (cond ....))".  (Yes, you could also write an
> explicit
> let which looks a lot like foo's definition.)
>
>> Thanks to all the posts, I now understand a lot more, about what is going 
>> on
>> but I still have not found an easy way to trace the values as they 
>> change.
>
> Umm, the values aren't changing....  none of trees' change in any
> of this code.  (You do know that there are lots of different instances
> of
> tree, one for each recursive call, right?  When the recursive call
> occurs,
> a new "tree" is created and given a value.  flatten returns some
> function
> of that value, an operation that may involve a recursive call.)
>
> -andy
> 
From: Pascal Bourguignon
Subject: Re: trouble learning LISP
Date: 
Message-ID: <871wp65mso.fsf@thalassa.informatimago.com>
"dlarkin" <········@mail.gatech.edu> writes:

> The only problem is the function returns NIL instead of the flattened list, 
> however if I remove all the FORMAT t lines the function returns:
>
> (A B NIL C NIL D E F NIL NIL ...)

So you have:

(defun flatten (tree)
   (cond ((atom tree) (list tree))
         (t           (append (flatten (car tree)) (flatten (cdr tree))))))


To understand the trace, you must reconciliate the output of trace
with the code of the function.

[663]> (flatten '((A B) (C) (D E (F))))
 1. Trace: (FLATTEN '((A B) (C) (D E (F))))
  2. Trace: (FLATTEN '(A B))
   3. Trace: (FLATTEN 'A)    
   3. Trace: FLATTEN ==> (A) 
                               Why flatten returns (A) here?
                               Because A was an atom and (list tree) = (A) 
                               is returned (first branch).
   3. Trace: (FLATTEN '(B))
    4. Trace: (FLATTEN 'B)     Why (flatten 'B) is called here?
    4. Trace: FLATTEN ==> (B)
    4. Trace: (FLATTEN 'NIL)   Why (flatten 'NIL) is called here?

                               They are called because '(B) is not an atom
                               and therefore (flatten (car tree)) and
                               (flatten (cdr tree)) are called.

    4. Trace: FLATTEN ==> (NIL)
                               Why is (NIL) returned here?
                               Because NIL is an atom and (list tree) = (NIL).

   3. Trace: FLATTEN ==> (B NIL)

                               Why is (B NIL) returned here?
                               Because (append '(B) '(NIL)) == (B NIL).

  2. Trace: FLATTEN ==> (A B NIL)
                               etc

So where is the bug?

To me, it looks like the bug is in calling flatten on (cdr tree) when
(cdr tree) is NIL (when it's the end of the list).


You are mixing two different data types: lists and cons cells.
append works on lists.
car and cdr work on cons cells.

Let's try to use lists:

(defun flatten (tree)
   (cond ((atom tree) (list tree))
         (t           (append (flatten (first tree)) (flatten (rest tree))))))

Do you see the problem?

(first tree) is an element, while
(rest tree) is a list of elements.

Therefore (flatten (first tree)) will return a flattened element, while
(flatten (rest tree)) will return a list of flattened elements.

If you want to go on with these lists, you'll have to write something like:

(defun flatten (tree)
   (cond ((atom tree) (list tree))
         (t           (mapcan (function flatten) tree))))

There we consider tree as a list (given to mapcan), and we apply
flatten on each element of this list, and finally concatenate all the
flattened results. MAPCAN = MAP CAr coNcatenate.


And by the way, I find it more readable as:

(defun flatten (tree)
  (if (atom tree) 
     (list tree)
     (mapcan (function flatten) tree)))


-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

READ THIS BEFORE OPENING PACKAGE: According to certain suggested
versions of the Grand Unified Theory, the primary particles
constituting this product may decay to nothingness within the next
four hundred million years.
From: Thomas A. Russ
Subject: Re: trouble learning LISP
Date: 
Message-ID: <ymi4pu1wlpr.fsf@sevak.isi.edu>
"dlarkin" <········@mail.gatech.edu> writes:
> Below is an example of showing that TRACE does not help me. It does not show 
> any of the recursion. (flatten2 is flatten without the format lines)
> 
> 
> 
> CG-USER(20): (trace (flatten2))
> 
> (FLATTEN2)
> 
> CG-USER(21): (FLATTEN2 '((A B) (C) (D E (F))))
> 
>  0[6]: (FLATTEN2 ((A B) (C) (D E (F))))
> 
>  0[6]: returned (A B NIL C NIL D E F NIL NIL NIL)
> 
> (A B NIL C NIL D E F NIL NIL ...)

OK.  The reason for this is that the (default) optimization level of
your compiler is set just a bit too high, and you are using a Lisp
implementation that compiles all of its code.  The compiler is very
helpfully optimizing the recursion and therefore the TRACE function
doesn't work very well.

You will need to try using some declarations to get around this.  I
don't recall which lisp implementation you are using, but I would try
the following as a first cut to see if you get better tracing:

(declaim (optimize (speed 0) (space 0) (safety 3) (debug 3)))

Then try the trace function.  You will need to redefine the function
after this DECLAIM, since it won't affect already compiled code.



If that still doesn't work, you may need to add the following
declaration to your function:

(defun flatten2 (tree)
  (declare (notinline flatten2))
  ....<body of function>
)


 

-- 
Thomas A. Russ,  USC/Information Sciences Institute
From: ··@homeunix.net
Subject: Re: trouble learning LISP
Date: 
Message-ID: <yqydnQxUZ7tLFajYnZ2dnUVZ_tOdnZ2d@comcast.com>
dlarkin wrote:
> Here is a specific example it is code from one of the online books I 
> downloaded.
> 
> 
> 
> (defun flatten (tree)
> 
>     (cond ((atom tree) (list tree))
> 
>         (t (append (flatten (car tree))
> 
>                     (flatten (cdr tree))))))
> 
> 
> 
> What I have been trying to do is to add stuff like: (format t "Tree : ~A ~%" 
> tree) into the COND (originally the IF) statement.
> 
> 
> 
> (defun flatten (tree)
> 
>     (cond ((atom tree) (list tree))
> 
>         (t (append (flatten (car tree))
> 
>                     (flatten (cdr tree)))
> 
> (format t "Tree : ~A ~%" tree)  ;;; like here after the append but part of 
> the cond t)
> 
> )))
> 
> 
> 
>  Nothing to complex, I want to see the recursion as it occurs. It was really 
> giving me trouble with the IF statement or messing with the return values of 
> the function with the COND. I managed to work around this by using SETF and 
> creating more variables but things get sloppy that way.
> 
> 

Sometimes trying to see the recursion as it occurs will
get you more confused than anything else.  Sometimes
it's better to look at recursion as a definition of
a function.

For example:

A a function flatten list is defined

1. if the list is null then nil

2. if the first of the list is an atom then
    the resulting list is a list with the
    atom as first element of the flatten rest
    of the original list.

3. if the first of the list is not an atom
    then the resulting list can be defined
    as the concatenation if the flatten first
    element (a list) and the flatten rest of list.

4. if the element to flatten is not a list then the
    function is undefined.  (throw some exception)


(defun flatten (list)
   (cond
     ((null list) nil)
     ((atom (first list))
      (cons (first list)
	   (flatten (rest list))))
     (t
      (append (flatten (first list))
	     (flatten (rest list))))))
From: Ken Tilton
Subject: Re: trouble learning LISP
Date: 
Message-ID: <RH7Zg.15$18.9@newsfe10.lga>
dlarkin wrote:
> I take it that the IF statement is not popular in LISP.

I have somewhat under a thousand in one hundred fifty source files in my 
working development tree.

> The IF statement 
> just makes easier reading for me as I have not worked with LISP for very 
> long.

This then is the wrong time to be agonizing over how things look. Shut 
up and code. When things look crappy in two months you can worry about it.

> 
> I did look in several books, I have one in paper version and several digital 
> books downloaded from the internet. But I could not find where it 
> specifically said IF could only handle one expression per condition.

Why the hell would you ever want more than one expression per condition 
in a functional language? (Hint.)

> I am 
> asking instead of reading becuase I am looking fir context as well as 
> syntax.
> 
> I am trying to think more in terms of LISP then the other languages.
> 
> I started using the COND statement, and will probably strike 'IF' out of my 
> vocabulary.

As per the above hint, The Real Problem is that you are programming in 
an imperative style. I know because only the last expression in your 
hoped-for multi-expression branch would have its value returned. Of 
course you do not care about its value being returned (and likely are 
unaware that all Lisp forms return values), you only care about the 
/effect/ of the expression, because... (cont'd at begininning of this 
paragraph).

kt

-- 
Cells: http://common-lisp.net/project/cells/

"I'll say I'm losing my grip, and it feels terrific."
    -- Smiling husband to scowling wife, New Yorker cartoon
From: dlarkin
Subject: Re: trouble learning LISP
Date: 
Message-ID: <eh34fp$rip$1@news-int2.gatech.edu>
I am starting to see the light.

On most of the branch statements I was adding a line to output to the 
monitor so I can watch and see what is going on inside the functions.

Here is a simplified example

(defun example (input)
    cond ((testfor nil) exit)
            (testfor cond1 (calculate recursive-value)     ;; if cond1 then 
do this and the next line
                (format t "my value ~A:" my-return-value))
            (t (otherwise calculate diffrent recursive-value))

The problem I was missing is that the "format t" line is messing up my 
return value for the function. I have put the output line in several 
diffrent locations all with interesting results but not what I wanted.

I believe the DTRACE command will solve this problem but I am using the 
Alegro Free LISP that does not seem to support this command. They have TRACE 
command but that does not show enough for me.

thanks

"Ken Tilton" <·········@gmail.com> wrote in message 
··················@newsfe10.lga...
>
>
> dlarkin wrote:
>> I take it that the IF statement is not popular in LISP.
>
> I have somewhat under a thousand in one hundred fifty source files in my 
> working development tree.
>
>> The IF statement just makes easier reading for me as I have not worked 
>> with LISP for very long.
>
> This then is the wrong time to be agonizing over how things look. Shut up 
> and code. When things look crappy in two months you can worry about it.
>
>>
>> I did look in several books, I have one in paper version and several 
>> digital books downloaded from the internet. But I could not find where it 
>> specifically said IF could only handle one expression per condition.
>
> Why the hell would you ever want more than one expression per condition in 
> a functional language? (Hint.)
>
>> I am asking instead of reading becuase I am looking fir context as well 
>> as syntax.
>>
>> I am trying to think more in terms of LISP then the other languages.
>>
>> I started using the COND statement, and will probably strike 'IF' out of 
>> my vocabulary.
>
> As per the above hint, The Real Problem is that you are programming in an 
> imperative style. I know because only the last expression in your 
> hoped-for multi-expression branch would have its value returned. Of course 
> you do not care about its value being returned (and likely are unaware 
> that all Lisp forms return values), you only care about the /effect/ of 
> the expression, because... (cont'd at begininning of this paragraph).
>
> kt
>
> -- 
> Cells: http://common-lisp.net/project/cells/
>
> "I'll say I'm losing my grip, and it feels terrific."
>    -- Smiling husband to scowling wife, New Yorker cartoon 
From: Thomas A. Russ
Subject: Re: trouble learning LISP
Date: 
Message-ID: <ymihcy2wxf9.fsf@sevak.isi.edu>
"dlarkin" <········@mail.gatech.edu> writes:

> I am starting to see the light.
> 
> On most of the branch statements I was adding a line to output to the 
> monitor so I can watch and see what is going on inside the functions.
> 
> Here is a simplified example
> 
> (defun example (input)
>     cond ((testfor nil) exit)
>             (testfor cond1 (calculate recursive-value)     ;; if cond1 then 
> do this and the next line
>                 (format t "my value ~A:" my-return-value))
>             (t (otherwise calculate diffrent recursive-value))

This is perhaps a bit too simplified, since it doesn't look like it
would be runnable code.  Please post something that illustrates the
problem and that actually runs.  It makes it much harder to provide
guidance when all we have to go on is non-functioning pseudo code.

You can also get a lot of leverage out of the interactive nature of Lisp
by building small pieces of your code (individual functions) and trying
them out in the REPL to see what they return.  You don't need to 


> The problem I was missing is that the "format t" line is messing up my 
> return value for the function. 

Yes, well.  There are ways around that as well.

But as Kenny Tilton did mention, one of the really fundamental
differences in Lisp style is based on the fact that ALL[*] forms in lisp
return a value.  In part that is why lisp only has (IF ...) and other
inferior languages have to have both statement "if ... then ... else"
and expression forms "... ?  ... : ...".  In Lisp everything is an
expression.

That is also why one will more typically see something like this which
doesn't use assignment at all

  (compute-final-result (compute-intermediate-result-1 x y)
                        (compute-intermediate-result-2 y z)
                        (compute-time-of-day))

instead of

   r1 = computeIntermediateResult1(x,y);
   r2 = computeIntermediateResult2(y,z);
   time = computeTimeOfDay()
   return computeFinalResult(r1,r2,time);

It isn't as if one couldn't use a binding style in Lisp or the
functional style in C/Java, but it is just more conventional to use such
a style in Lisp.

> I have put the output line in several 
> diffrent locations all with interesting results but not what I wanted.

Ah, the permutation approach to programming.
Perhaps if you showed more code we could provide some guidance.

> I believe the DTRACE command will solve this problem but I am using the 
> Alegro Free LISP that does not seem to support this command. They have TRACE 
> command but that does not show enough for me.

I'm not familiar with DTRACE.  What is it supposed to do?  What don't
you like about TRACE?



[*] To a first approximation.  Ignore (values) for now.
-- 
Thomas A. Russ,  USC/Information Sciences Institute
From: Ken Tilton
Subject: Re: trouble learning LISP
Date: 
Message-ID: <6L8Zg.36$Jc3.10@newsfe09.lga>
dlarkin wrote:
> I am starting to see the light.
> 
> On most of the branch statements I was adding a line to output to the 
> monitor so I can watch and see what is going on inside the functions.

A worthy goal. I use something like:

(defmacro echo(ekx-id &rest body)
   (let ((result (gensym)))
     `(let ((,result (,@body)))
        (format t "~&~a -> ~a"
           ,(string-downcase (symbol-name ekx-id)) ,result)
        ,result)))

(if (zerop (random 2))
     (echo sum + 1 2)
   (echo product * 1 2))

Evaluate to see variously:

sum -> 3
product -> 2

The design of ekx2 is meant to let you add/remove diagnostics without 
balancing parens. But the result can be hard to parse. Left as an 
exercise is echo2, where one would:

     (echo2 the-sum-is (+ 1 2))

Observe that this has nothing to do with IF. One can need ekx2 just as 
well like this:

     (+ (echo the-troublesome-addend-is (big-long x y z) 42)

hth, kt

-- 
Cells: http://common-lisp.net/project/cells/

"I'll say I'm losing my grip, and it feels terrific."
    -- Smiling husband to scowling wife, New Yorker cartoon
From: Thomas A. Russ
Subject: Re: trouble learning LISP
Date: 
Message-ID: <ymid58qwxdf.fsf@sevak.isi.edu>
Ken Tilton <·········@gmail.com> writes:

> dlarkin wrote:
> > I am starting to see the light.
> > On most of the branch statements I was adding a line to output to the
> > monitor so I can watch and see what is going on inside the functions.
> 
> 
> A worthy goal. I use something like:

....
I advise Mr. or Ms. Larkin to ignore this post.  It will only generate
confusion.



(Sorry, Kenny, but I think this goes a bit too far, too fast).

-- 
Thomas A. Russ,  USC/Information Sciences Institute
From: Ken Tilton
Subject: Re: trouble learning LISP
Date: 
Message-ID: <n8bZg.230$tT6.131@newsfe12.lga>
Thomas A. Russ wrote:
> Ken Tilton <·········@gmail.com> writes:
> 
> 
>>dlarkin wrote:
>>
>>>I am starting to see the light.
>>>On most of the branch statements I was adding a line to output to the
>>>monitor so I can watch and see what is going on inside the functions.
>>
>>
>>A worthy goal. I use something like:
> 
> 
> ....
> I advise Mr. or Ms. Larkin to ignore this post.  It will only generate
> confusion.
> 
> 
> 
> (Sorry, Kenny, but I think this goes a bit too far, too fast).
> 

And I think you miss the point, which is why you keep trying to help the 
OP with syntax. You think it has to do with IF. It does not. The OP has 
already clarified that they want to trace certain untraceable forms. 
That (as I explained had you been listening) can happen anywhere in Lisp 
code, not just IF branches. Meanwhile you are still agonizing over 
"style diffferences" between IF and COND.

Meanwhile, "too fast"? I feel a naggum coming on. When you see me 
teaching, please assume I know what I am doing and that any apparent 
shortcoming reflects your own pedagogic incompetence: sometimes big 
leaps like that can light a noob's fire, even if they are not ready for 
it. Like showing a Bruce Lee movie to a beginner in karate struggling 
with simple moves.

Providing the code (which is why nothing was "too far too fast") solved 
the OP's problem, motivated them to learn more, explained the great 
mystery of macros, and allowed them to get back to work. Like I need to.

hth, kenny

-- 
Cells: http://common-lisp.net/project/cells/

"I'll say I'm losing my grip, and it feels terrific."
    -- Smiling husband to scowling wife, New Yorker cartoon
From: Steven E. Harris
Subject: Re: trouble learning LISP
Date: 
Message-ID: <q944pu1val1.fsf@chlorine.gnostech.com>
Ken Tilton <·········@gmail.com> writes:

> Providing the code (which is why nothing was "too far too fast")
> solved the OP's problem, motivated them to learn more, explained the
> great mystery of macros, and allowed them to get back to work.

I wasn't even following the thread out of interest in the OP's
question, but I paused to study your ECHO macro and found it to be a
clever solution to a problem I have run into several times:
temporarily wrapping a particular form to trace its arguments or
return values.

Whether or not you helped the OP, you've helped others. Intent in
writing may count less than what the reader is hoping to get out of
your replies.

-- 
Steven E. Harris
From: Ken Tilton
Subject: Re: trouble learning LISP
Date: 
Message-ID: <zYuZg.18$Kh.0@newsfe09.lga>
Steven E. Harris wrote:
> Ken Tilton <·········@gmail.com> writes:
> 
> 
>>Providing the code (which is why nothing was "too far too fast")
>>solved the OP's problem, motivated them to learn more, explained the
>>great mystery of macros, and allowed them to get back to work.
> 
> 
> I wasn't even following the thread out of interest in the OP's
> question, but I paused to study your ECHO macro and found it to be a
> clever solution to a problem I have run into several times:
> temporarily wrapping a particular form to trace its arguments or
> return values.

I must give full credit to one Mark Lindeman who worked with me on that 
big CliniSys project and came up with the idea, which I loved at first 
sight.

The verbose form of echo, btw, is used like this:

   (echo ("banner this" x y z) (actual-app-code ...))

Jamming a literal NIL (not a variable that evaluates to nil) in front of 
"banner this" causes just the application code to appear in the 
expansion, ie, it disables the debugging completely. Easy to pop those 
in and out when you have the kind of code that repeatedly gives one trouble.

kt


-- 
Cells: http://common-lisp.net/project/cells/

"I'll say I'm losing my grip, and it feels terrific."
    -- Smiling husband to scowling wife, New Yorker cartoon
From: Bernd Schmitt
Subject: Re: trouble learning LISP
Date: 
Message-ID: <45356dba$0$4307$9b622d9e@news.freenet.de>
On 17.10.2006 21:33, Thomas A. Russ wrote:
> Ken Tilton <·········@gmail.com> writes:
>> [interesting stuff]
> (Sorry, Kenny, but I think this goes a bit too far, too fast).
Sorry Thomas, I have to dessent.
To me (learning lisp) this is very interesting.


Bernd
From: choppa
Subject: Re: trouble learning LISP
Date: 
Message-ID: <1161631750.175594.111270@e3g2000cwe.googlegroups.com>
Ken Tilton schrieb:

> Evaluate to see variously:
>
> sum -> 3
> product -> 2
>

This one is really nice. I started to insert print statements like

(if (zerop (random 2))
     (print (sum + 1 2))
   (print (product * 1 2)))

which gives me the value returned but not the symbol-name. Really nice
:-)
From: John Thingstad
Subject: Re: trouble learning LISP
Date: 
Message-ID: <op.thkj0xfvpqzri1@pandora.upc.no>
On Tue, 17 Oct 2006 15:33:39 +0200, dlarkin <········@mail.gatech.edu>  
wrote:

> I take it that the IF statement is not popular in LISP. The IF statement
> just makes easier reading for me as I have not worked with LISP for very
> long.
>

The if* macro shipped with Allegro CL and avilable from their cite is
a alternative.

(if* (test)
  then
    (statement1)
    (statement2)
     ...
  elseif (test)
    (statement1)
    (statement2)
     ...
  else
     (statement1)
     (statement2)
     ...)

http://www.franz.com/support/documentation/8.0/doc/operators/excl/if_s.htm

also unless and when macroes as others have mentioned.

-- 
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
From: Espen Vestre
Subject: Re: trouble learning LISP
Date: 
Message-ID: <m1y7reai75.fsf@doduo.vestre.net>
"John Thingstad" <··············@chello.no> writes:

> The if* macro shipped with Allegro CL and avilable from their cite is
> a alternative.

Ouch! Careful with that flamethrower, Eugene!
-- 
  (espen)
From: Takehiko Abe
Subject: Re: trouble learning LISP
Date: 
Message-ID: <keke-1810060033320001@192.168.1.2>
> The if* macro shipped with Allegro CL and avilable from their cite is
> a alternative.
> 
> (if* (test)
>   then
>     (statement1)
>     (statement2)
>      ...
>   elseif (test)
>     (statement1)
>     (statement2)
>      ...
>   else
>      (statement1)
>      (statement2)
>      ...)

barf
From: Pascal Bourguignon
Subject: Re: trouble learning LISP
Date: 
Message-ID: <87irii5ola.fsf@thalassa.informatimago.com>
"John Thingstad" <··············@chello.no> writes:

> On Tue, 17 Oct 2006 15:33:39 +0200, dlarkin <········@mail.gatech.edu>
> wrote:
>
>> I take it that the IF statement is not popular in LISP. The IF statement
>> just makes easier reading for me as I have not worked with LISP for very
>> long.
>>
>
> The if* macro shipped with Allegro CL and avilable from their cite is
> a alternative.
>
> (if* (test)
>  then
>    (statement1)
>    (statement2)
>     ...
>  elseif (test)
>    (statement1)
>    (statement2)
>     ...
>  else
>     (statement1)
>     (statement2)
>     ...)

Which is HORRIBLE, makes the code twice as long and much more
unreadable than any other alternative.  DO NOT USE IT!

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
Grace personified,
I leap into the window.
I meant to do that.
From: John Thingstad
Subject: Re: trouble learning LISP
Date: 
Message-ID: <op.thlreogwpqzri1@pandora.upc.no>
On Wed, 18 Oct 2006 04:45:21 +0200, Pascal Bourguignon  
<···@informatimago.com> wrote:

>
> Which is HORRIBLE, makes the code twice as long and much more
> unreadable than any other alternative.  DO NOT USE IT!
>

At leat it is consistent with the other branching instructions
in that it accepts multiple statements.
Also the difference between the if and else part are visually louder.
So I find it more readable. Adding 10 characters compared to if
dosn't make it twice as long. Well to each his own.

-- 
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
From: Bill Atkins
Subject: Re: trouble learning LISP
Date: 
Message-ID: <m2mz7u9lxi.fsf@bertrand.local>
"John Thingstad" <··············@chello.no> writes:

> On Wed, 18 Oct 2006 04:45:21 +0200, Pascal Bourguignon
> <···@informatimago.com> wrote:
>
>>
>> Which is HORRIBLE, makes the code twice as long and much more
>> unreadable than any other alternative.  DO NOT USE IT!
>>
>
> At leat it is consistent with the other branching instructions
> in that it accepts multiple statements.
> Also the difference between the if and else part are visually louder.
> So I find it more readable. Adding 10 characters compared to if
> dosn't make it twice as long. Well to each his own.

Why do you press return after every sentence instead of after every
paragraph?
From: Peder O. Klingenberg
Subject: Re: trouble learning LISP
Date: 
Message-ID: <ksodsbc9x2.fsf@beto.netfonds.no>
"dlarkin" <········@mail.gatech.edu> writes:

> I take it that the IF statement is not popular in LISP.

Wrong conclusion.

IF is perfect when you have to choose between exactly two
alternatives[*].

If you are considering taking an action or not doing anything, WHEN
and UNLESS are good candidates, and if you have to choose between more
than two branches, COND is your friend.

Don't exclude random bits of the language based on practically zero
experience.

> But I could not find where it specifically said IF could only handle
> one expression per condition.

http://www.lispworks.com/documentation/HyperSpec/Body/s_if.htm#if

"Syntax:
if test-form then-form [else-form] => result*
Arguments and Values:
Test-form---a form.
Then-form---a form.
Else-form---a form."

The term "form" is defined in the glossary, but basically, it means a
single thing to be evaluated.  If you want to evaluate more than one
thing in each of the subforms that make up an IF form, you need to
cram all the things you want to evaluate into a single form.  This is
most commonly achieved with PROGN.

WHEN, UNLESS and COND make use of a mechanism called "implicit PROGN",
also defined in the glossary of the Hyperspec, so you can give them
more than one thing to be evaluated without explicitly surrounding
them with PROGN.  IF doesn't have implicit PROGN, because that's not
the way it was defined.  (emacs lisp, on the other hand, has an
explicit progn in the else-branch, if I remember correctly.  Different
language, different design choice.)

[*] "Perfect" may be too strong a word.  People with more experience
    than you have taken serious exception to the syntax of IF, but
    let's not revisit that particular flame war.

...Peder...
-- 
I wish a new life awaited _me_ in some off-world colony.
From: Robert Maas, see http://tinyurl.com/uh3t
Subject: Re: trouble learning LISP
Date: 
Message-ID: <REM-2006oct22-002@Yahoo.Com>
> From: ····@news.klingenberg.no (Peder O. Klingenberg)
> > I take it that the IF statement is not popular in LISP.
> Wrong conclusion.
> IF is perfect when you have to choose between exactly two
> alternatives[*].

Also, I find IF just right when I want to implement a small decision
tree and I want the nested structure of the LISP source to match the
nesting of the tree. Something like this:
(if Test1...
  (if Test2a...
    ActionYY
    ActionYN)
  (if Test2b...
    ActionNY
    ActionNN))

> if you have to choose between more than two branches, COND is your
> friend.

Actually COND is for when you are exhausting cases, where if not case 1
then try case 2, and if neither of those then try case 3, etc., i.e. a
long chain of additional tests upon failure of all prior tests, i.e.
great depth of the all-failures branch of the tree but no depth on any
of the success branches. On the other hand, if you have a *flat*
multi-way decision, something like CASE may be best.

> Don't exclude random bits of the language based on practically zero
> experience.

I agree. Maybe don't actually use random bits of the language in
practical programs until you find an appropriate use where they seem to
be the best way to express that part of your algorithm, but don't
dismiss any random bit of the language as something you are pretty sure
you'll never ever find a use for.

> If you want to evaluate more than one thing in each of the subforms
> that make up an IF form, you need to cram all the things you want to
> evaluate into a single form.  This is most commonly achieved with
> PROGN.

Yes. Note that PROGN returns the value of the *last* form only,
discarding all earlier returns. If you need PROGN, then presumably you
are either printing diagnostic information before returning, or doing
side effects. Sometimes you might want to compute the return value and
*then* do the printing or side effect just before actually returning,
in which case you might use PROG1 instead, or use LET to bind the
return value.

> People with more experience than you have taken serious exception to
> the syntax of IF, but let's not revisit that particular flame war.

Indeed let's not visit it. I personally like the syntax of IF for
summetric 2-way decisions or binary decision trees. If somebody wants
to complain about un-LISP syntax, complain about the LOOP macro!
(Or better, just don't use it yourself and don't complain when others
use it or advocate its use, and don't complain when your lack of use of
it makes your programming task harder.)
From: Pascal Bourguignon
Subject: Re: trouble learning LISP
Date: 
Message-ID: <87k62sur00.fsf@thalassa.informatimago.com>
·······@Yahoo.Com (Robert Maas, see http://tinyurl.com/uh3t) writes:

>> From: ····@news.klingenberg.no (Peder O. Klingenberg)
>> > I take it that the IF statement is not popular in LISP.
>> Wrong conclusion.
>> IF is perfect when you have to choose between exactly two
>> alternatives[*].
>
> Also, I find IF just right when I want to implement a small decision
> tree and I want the nested structure of the LISP source to match the
> nesting of the tree. Something like this:
> (if Test1...
>   (if Test2a...
>     ActionYY
>     ActionYN)
>   (if Test2b...
>     ActionNY
>     ActionNN))

If course, if you have a lot of them you can write a macro such as:


(defun gen-decision-tree (conditions actions continuation)
  (if (null (cdr conditions))
      (funcall continuation
               `(if ,(car conditions) 
                    ,(first actions)
                    ,(second actions))
               (cddr actions))
      (gen-decision-tree (cdr conditions)
                         actions
                         (lambda (then-form else-actions)
                           (gen-decision-tree (cdr conditions)
                                              else-actions 
                                              (lambda (else-form other-actions)
                                                (funcall continuation
                                                         `(if ,(car conditions)
                                                              ,then-form
                                                              ,else-form)
                                                         other-actions)))))))


(defmacro decision-tree (conditions &body actions)
  (let ((vconditions (mapcar (lambda (x) (declare (ignore x)) (gensym)) conditions)))
    `(let ,(mapcar (lambda (var val) (list var val)) vconditions conditions)
       ,(gen-decision-tree vconditions actions
                           (lambda (form other-actions) 
                             (assert (null other-actions))
                             form)))))



(gen-decision-tree '(a b c) '(1 2 3 4 5 6 7 8)
                   (lambda (f a) (assert (null a)) f))
-->
(IF A (IF B (IF C 1 2) (IF C 3 4)) (IF B (IF C 5 6) (IF C 7 8)))


(macroexpand '(decision-tree (a b c) 1 2 3 4 5 6 7 8))
-->
(LET ((#1=#:G13862 A) (#2=#:G13863 B) (#3=#:G13864 C))
 (IF #1# (IF #2# (IF #3# 1 2) (IF #3# 3 4)) 
         (IF #2# (IF #3# 5 6) (IF #3# 7 8)))) ;
T




-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
You never feed me.
Perhaps I'll sleep on your face.
That will sure show you.
From: jurgen_defurne
Subject: Re: trouble learning LISP
Date: 
Message-ID: <1161154980.047013.157760@m7g2000cwm.googlegroups.com>
dlarkin wrote:
> I take it that the IF statement is not popular in LISP. The IF statement
> just makes easier reading for me as I have not worked with LISP for very
> long.
>
> I did look in several books, I have one in paper version and several digital
> books downloaded from the internet. But I could not find where it
> specifically said IF could only handle one expression per condition. I am
> asking instead of reading becuase I am looking fir context as well as
> syntax.
>
> I am trying to think more in terms of LISP then the other languages.
>
> I started using the COND statement, and will probably strike 'IF' out of my
> vocabulary.
>
> thanks, I appreciate the BLUF.
>
> "Pascal Bourguignon" <···@informatimago.com> wrote in message
> ···················@thalassa.informatimago.com...
> > "dlarkin" <········@mail.gatech.edu> writes:
> >
> >> Can an IF statement in lisp execute multiple expressions if it tests
> >> false.
> >
> > No it cannot.
> >
> >
> >> For example:
> >>
> >> (if (null expression) nil     ;;if nil then skip the else part
> >>     ((expression1)            ;; else do expression 1 and expression 2
> >>     (expression2))
> >
> > This is meaningless in Common Lisp.
> >
> > If you want to program in lisp, why don't you just read some lisp
> > tutorial instead of trying to invent some funny syntax?
> >
> >
> >
> > If you want to do expression1 and expression2 only when expression is
> > not nil, why don't you just say so?
> >
> > (when expression
> >   expression1
> >   expression2)
> >
> >
> > If you don't want to do expression1 and expressions unless expression
> > is nil, why don't you just say so?
> >
> > (unless (null expression)
> >   expression1
> >   expression2)
> >
> >
> >
> >
> > Also, if you want the two branches of a IF, you have the same problem
> > than in Pascal, and the same solution.  Only, a BEGIN ... END block is
> > written (PROGN ...) in lisp.
> >
> > (if condition
> >    (progn
> >        ...)
> >    (progn
> >        ...))
> >
> > But most often, you don't need to use progn, because you'll be using a
> > let or some other form that takes several expressions as body.
> >
> > --
> > __Pascal Bourguignon__                     http://www.informatimago.com/
> >
> > "This statement is false."            In Lisp: (defun Q () (eq nil (Q)))

The best thing to do is to experiment and have the Common Lisp Hyper
Spec handy.

It is voluminous, but it pays off to learn how to read it.

E.g.

Special Operator IF

Syntax:

if test-form then-form [else-form] => result

By browsing further in the CLHS, you can reference the definitions
through the hyperlinks.

At first I did not understand it very well either, but if you take some
time to study a definition when you need it, you will find you can get
really up to speed.

And in the definitions, the * always gives a clue :

form                             1 form (whatever-function arguments)
form*                            multiple forms (a whole lot of the
previous after each other without any special construct)

Regards,

Jurgen
From: Robert Uhl
Subject: Re: trouble learning LISP
Date: 
Message-ID: <m3k62xelfv.fsf@NOSPAMgmail.com>
"dlarkin" <········@mail.gatech.edu> writes:

> I take it that the IF statement is not popular in LISP.

Well, WHEN & UNLESS are often used for single-branch conditionals, and
COND for multi-branches.  But IF is used for dual-branch conditionals a
bunch as well.

> I did look in several books, I have one in paper version and several digital 
> books downloaded from the internet. But I could not find where it 
> specifically said IF could only handle one expression per condition. I am 
> asking instead of reading becuase I am looking fir context as well as 
> syntax.

The context is this: IF takes three sub-expressions: it evaluates the
first; if that is true then it executes the second, otherwise it
executes the third.  Thus if you want to do multiple things in one of
the expressions you use one of the standard ways to do so, e.g. with
LET, DO &c. or as a fallback PROGN.

> I am trying to think more in terms of LISP then the other languages.

That helps.  WHEN and UNLESS are really nice once you've gotten used to
them; they make the source read more cleanly.

> I started using the COND statement, and will probably strike 'IF' out of my 
> vocabulary.

Well, IF has its place, as does COND.

-- 
Robert Uhl <http://public.xdi.org/=ruhl>
We're going to Moe's.  If we're not back, avenge our deaths.
                                            --Homer Simpson
From: bradb
Subject: Re: trouble learning LISP
Date: 
Message-ID: <1161188727.010063.226500@e3g2000cwe.googlegroups.com>
> That helps.  WHEN and UNLESS are really nice once you've gotten used to
> them; they make the source read more cleanly.
>
> > I started using the COND statement, and will probably strike 'IF' out of my
> > vocabulary.
>
> Well, IF has its place, as does COND.

When I first started with Lisp, I was a bit concerned that there were
so many ways to branch:
IF, WHEN, UNLESS, COND, CASE, etc, etc.

But then I read SICP and Novig's "Lisp Style" paper [1]
>From SICP: "Programs are meant to be read (by the programmer), and only
incidentally executed"
>From Norvig: "Be explicit"

After reading that, I stopped worrying about the multitude of different
branching statements; just use the one that most suits what you mean
and you will actually convey more information to whomever reads your
code later.

Cheers
Brad


[1] http://www.cs.umd.edu/~nau/cmsc421/norvig-lisp-style.pdf
From: Simon Brooke
Subject: Re: trouble learning LISP
Date: 
Message-ID: <0ane04-apk.ln1@gododdin.internal.jasmine.org.uk>
in message <············@news-int.gatech.edu>, dlarkin
(·········@mail.gatech.edu') wrote:

> Can an IF statement in lisp execute multiple expressions if it tests
> false. For example:
> 
> (if (null expression) nil     ;;if nil then skip the else part
>     ((expression1)            ;; else do expression 1 and expression 2
>     (expression2))

That's not LISP, for very good reason. It's LISP /language/ but it isn't
LISP /idiom/. To think in LISP you first have to accept that LISP is a
foreign language, not a subset of English. The semantics of 'if' do not
translate well to LISP. This is LISP:

(cond
    ((not expression) nil)
    ((expression1)(expression2)))

If expression evaluates to nil, (not expression) evaluates to t, so the
first clause is selected, expression1 is not evaluated, and the cond
expression returns nil. 

If, however, expression evaluates to non-nil, expression1 is evaluated,
and, if it returns non-nil, the cond expression returns the value of
expression2; otherwise, the cond expression returns nil.

So the above is logically equivalent to

(cond 
    ((and expression expression1)(expression2)))

or, again equivalent but with slightly greater clarity

(cond 
    ((and expression expression1)(expression2))
    (t nil))

-- 
·····@jasmine.org.uk (Simon Brooke) http://www.jasmine.org.uk/~simon/

        I shall continue to be an impossible person so long as those
        who are now possible remain possible      -- Michael Bakunin
        
From: George Neuner
Subject: Re: trouble learning LISP
Date: 
Message-ID: <7rfaj2hncne5jsudejr9ff4nnmmd3idv32@4ax.com>
On Mon, 16 Oct 2006 21:58:12 -0400, "dlarkin"
<········@mail.gatech.edu> wrote:

>Can an IF statement in lisp execute multiple expressions if it tests false.
>For example:
>
>(if (null expression) nil     ;;if nil then skip the else part
>    ((expression1)            ;; else do expression 1 and expression 2
>    (expression2)) 
>

You can't simply evaluate multiple expressions in a branch because IF
is defined as taking a single form for each branch.  However, the
single form can be a PROGN (or variant) which can evaluate multiple
expressions.

So you can write what you want as

(if (null expression) 
  nil
  (progn
     (expression1)
     (expression2)))

or conversely

(if (not (null expression)) 
  (progn
     (expression1)
     (expression2))
  nil)


But, as several people have stated, in the case where one branch of
the IF is empty or nil, it is preferable to use WHEN or UNLESS.

George
--
for email reply remove "/" from address