From: Graham
Subject: Loop?
Date: 
Message-ID: <ebd8cee2.0203140256.47a98f7d@posting.google.com>
Can someone please help me with this. I am new to Lisp and I am having
a small problem with a loop. I am storing DEFSTRUCTS (represent a
book) in a list. When I loop through the lisp with just one element in
it it works fine but when I have more then one it gives me the
following error:

"In PLUSP of (NIL) arguments should be of type REAL."

My code is:

; Find the specified book in the list by title and if found 
; decrement it's nnumber of copies by one
(defun sell-a-book()
  (format t "~%Please enter the title of the book you wish to sell: ")
  (let* ((purchase-title (read-line)))
    (dolist (next *books* nil)
      (setf title (book-record-title next))
      (if (> (equal title purchase-title) 0)
          (format t "~%Title found!")
          (setf (book-record-no-of-items next)-1))))
  (sub-menu)
) 

Any help much appreciated.
G

From: Christophe Rhodes
Subject: Re: Loop?
Date: 
Message-ID: <sq1yene6os.fsf@cam.ac.uk>
········@hotmail.com (Graham) writes:

> "In PLUSP of (NIL) arguments should be of type REAL."

Right. What this error message is trying to say is that you have
attempted to call (plusp nil), which doesn't work because plusp only
takes arguments of type real -- that is, a member of the set of real
numbers.

Now...
 
> My code is:
> 
> ; Find the specified book in the list by title and if found 
> ; decrement it's nnumber of copies by one
> (defun sell-a-book()
>   (format t "~%Please enter the title of the book you wish to sell: ")
>   (let* ((purchase-title (read-line)))
>     (dolist (next *books* nil)
>       (setf title (book-record-title next))
>       (if (> (equal title purchase-title) 0)
>           (format t "~%Title found!")
>           (setf (book-record-no-of-items next)-1))))
>   (sub-menu)
> ) 

... your code doesn't have any calls to plusp! How can this be?

Let's look at
(> (equal title purchase-title) 0)
though. This is exactly equivalent to
(plusp (equal title purchase-title))
because (plusp x) for any x returns the same as (> x 0). So a compiler
is fully justified in replacing that call with the equivalent call to
plusp.

So that explains how you can be getting that error. Now, why are you
getting that error? Well, (equal title purchase-title) will return a
boolean (t or nil), not a number of type real, so that call won't ever
work as expected.

There are other issues with this code as written; I'll just mention
one or two matters of style: it's customary to have slightly more
spaces than you're including, and never to have a dangling paren;
also, it's "better" to start format statements with ~& (for a
freshline) rather than ~% (for a newline) unless there is a specific
reason that you absolutely definitely want a newline even if the
output stream is already at the start of a line.

So I would format your code as follows:

;;; Find the specified book in the list by title and if found 
;;; decrement its number of copies by one
(defun sell-a-book ()
  (format t "~&Please enter the title of the book you wish to sell: ")
  (let* ((purchase-title (read-line)))
    (dolist (next *books* nil)
      (setf title (book-record-title next))
      (if (> (equal title purchase-title) 0)
          (format t "~&Title found!~%")
          (setf (book-record-no-of-items next) -1))))
  (sub-menu))

I hope this gives you a start in the debugging process...

Christophe
-- 
Jesus College, Cambridge, CB5 8BL                           +44 1223 510 299
http://www-jcsu.jesus.cam.ac.uk/~csr21/                  (defun pling-dollar 
(str schar arg) (first (last +))) (make-dispatch-macro-character #\! t)
(set-dispatch-macro-character #\! #\$ #'pling-dollar)
From: Christopher C. Stacy
Subject: compiler rewriting your code
Date: 
Message-ID: <ulmcvf60o.fsf@theworld.com>
>>>>> On 14 Mar 2002 02:56:38 -0800, Graham  ("Graham") writes:
 Graham> "In PLUSP of (NIL) arguments should be of type REAL."
 Graham> My code is:
 Graham>       (if (> (equal title purchase-title) 0)
 Graham>           (format t "~%Title found!")

>>>>> On 14 Mar 2002 11:21:07 +0000, Christophe Rhodes ("Christophe") writes:
 Christophe> though. This is exactly equivalent to
 Christophe> (plusp (equal title purchase-title))
 Christophe> because (plusp x) for any x returns the same as (> x 0). 
 Christophe> So a compiler is fully justified in replacing that call
 Christophe> with the equivalent call to plusp.

This is a terribly confusing thing for the compiler to do!
From: Christophe Rhodes
Subject: Re: compiler rewriting your code
Date: 
Message-ID: <sqwuwfcby4.fsf@cam.ac.uk>
······@theworld.com (Christopher C. Stacy) writes:

> >>>>> On 14 Mar 2002 02:56:38 -0800, Graham  ("Graham") writes:
>  Graham> "In PLUSP of (NIL) arguments should be of type REAL."
>  Graham> My code is:
>  Graham>       (if (> (equal title purchase-title) 0)
>  Graham>           (format t "~%Title found!")
> 
> >>>>> On 14 Mar 2002 11:21:07 +0000, Christophe Rhodes ("Christophe") writes:
>  Christophe> though. This is exactly equivalent to
>  Christophe> (plusp (equal title purchase-title))
>  Christophe> because (plusp x) for any x returns the same as (> x 0). 
>  Christophe> So a compiler is fully justified in replacing that call
>  Christophe> with the equivalent call to plusp.
> 
> This is a terribly confusing thing for the compiler to do!

Is it? Is it equally confusing to rewrite (+ x 1) as (1+ x)?

Note that the ANSI standard (Body/f_1pl_1_.htm) encourages
implementors to ensure that the performance of (+ x 1) and (1+ x) are
equivalent. This would be a good thing, I think we'll agree.

The question then becomes how much effort the implementor should go to
to ensure that it does no things that are potentially confusing.

In an implementation which has 30-bit fixnums, consider the following
compiler transform:

[schematic]
(define-compiler-transform (1+ (x (signed-byte 29)))
  `(open-coded-1+-fixnum-result ,x))

Should the implementor be required to maintain also
(define-compiler-transform (+ (x (signed-byte 29)) (y (constant 1)))
  `(open-coded-1+-fixnum-result ,x))
?

Or, in the interests of compiler maintainability, should we just
rewrite the source of (+ x 1) and have one compiler transform, at a
potential cost of confusing someone for a while?

I don't want to claim that I have the one true answer here, mind you;
I can see where you're coming from. I just don't think it's /that/
confusing; and once the newcomer to the language is exposed to the
idea of source transformations I don't think that it is that confusing
after all. Other opinions may, of course, be different.

Christophe
-- 
Jesus College, Cambridge, CB5 8BL                           +44 1223 510 299
http://www-jcsu.jesus.cam.ac.uk/~csr21/                  (defun pling-dollar 
(str schar arg) (first (last +))) (make-dispatch-macro-character #\! t)
(set-dispatch-macro-character #\! #\$ #'pling-dollar)
From: Joe Marshall
Subject: Re: compiler rewriting your code
Date: 
Message-ID: <Aw9k8.23827$44.5599546@typhoon.ne.ipsvc.net>
"Christopher C. Stacy" <······@theworld.com> wrote in message
··················@theworld.com...
> >>>>> On 14 Mar 2002 02:56:38 -0800, Graham  ("Graham") writes:
>  Graham> "In PLUSP of (NIL) arguments should be of type REAL."
>  Graham> My code is:
>  Graham>       (if (> (equal title purchase-title) 0)
>  Graham>           (format t "~%Title found!")
>
> >>>>> On 14 Mar 2002 11:21:07 +0000, Christophe Rhodes ("Christophe")
writes:
>  Christophe> though. This is exactly equivalent to
>  Christophe> (plusp (equal title purchase-title))
>  Christophe> because (plusp x) for any x returns the same as (> x 0).
>  Christophe> So a compiler is fully justified in replacing that call
>  Christophe> with the equivalent call to plusp.
>
> This is a terribly confusing thing for the compiler to do!

You think *that's* bad, my compiler rewrites (> x 0) into

;#x7: 33C0           xor     eax,eax
;#x9: 5A             pop     edx
;#xA: 3BC2           cmp     eax,edx
;#xC: 8B06           mov     eax,[esi]
;#xE: 7D17           jge     0027
From: Christopher C. Stacy
Subject: Re: compiler rewriting your code
Date: 
Message-ID: <uofhqf7mq.fsf@theworld.com>
>>>>> On Thu, 14 Mar 2002 22:30:56 GMT, Joe Marshall ("Joe") writes:

 Joe> "Christopher C. Stacy" <······@theworld.com> wrote in message
 Joe> ··················@theworld.com...
 >> >>>>> On 14 Mar 2002 02:56:38 -0800, Graham  ("Graham") writes:
 Graham> "In PLUSP of (NIL) arguments should be of type REAL."
 Graham> My code is:
 Graham> (if (> (equal title purchase-title) 0)
 Graham> (format t "~%Title found!")
 >> 
 >> >>>>> On 14 Mar 2002 11:21:07 +0000, Christophe Rhodes ("Christophe")
 Joe> writes:
 Christophe> though. This is exactly equivalent to
 Christophe> (plusp (equal title purchase-title))
 Christophe> because (plusp x) for any x returns the same as (> x 0).
 Christophe> So a compiler is fully justified in replacing that call
 Christophe> with the equivalent call to plusp.
 >> 
 >> This is a terribly confusing thing for the compiler to do!

 Joe> You think *that's* bad, my compiler rewrites (> x 0) into

 Joe> ;#x7: 33C0           xor     eax,eax
 Joe> ;#x9: 5A             pop     edx
 Joe> ;#xA: 3BC2           cmp     eax,edx
 Joe> ;#xC: 8B06           mov     eax,[esi]
 Joe> ;#xE: 7D17           jge     0027

But I think that's better, because it doesn't confuse the user into
asking the question, "Why is the system complaining about a function
that I never called?"

O.p. was trying to debug the program he had written, and was confused
that the system was referring to Lisp functions that he didn't call.
I would be happier if it told him, "In RUNTIME-INTERNALS::PLUSP of (NIL)..."
because he would not have gone looking for a call to PLUSP.
From: Kenny Tilton
Subject: Re: compiler rewriting your code
Date: 
Message-ID: <3C938746.3A35F349@nyc.rr.com>
> O.p. was trying to debug the program he had written, and was confused
> that the system was referring to Lisp functions that he didn't call.

:) As if compiler errors ever help! Well, in Lisp they usually do, I
admit.

Reminds me of a newbie programmer who actually humped a C++ listing to
the watering hole where we had become acquainted. He was such a
greenhorn he brought just the source to ask me for help, not the
compiler listing with the 150 errors that had been driving him insane
for /four/ days.

I told him I did not know much C++, but shouldn't the function
definition "MyClass:MyMethod (..." have two colons in there instead of
one? 

Ya shoulda heard the scream....

-- 

 kenny tilton
 clinisys, inc
 ---------------------------------------------------------------
 "You're not being the ball, Danny."
                           - Ty, Caddy Shack
From: Christopher Browne
Subject: Re: compiler rewriting your code
Date: 
Message-ID: <m3ofhoqn27.fsf@chvatal.cbbrowne.com>
In the last exciting episode, Kenny Tilton <·······@nyc.rr.com> wrote::
>> O.p. was trying to debug the program he had written, and was confused
>> that the system was referring to Lisp functions that he didn't call.
>
> :) As if compiler errors ever help! Well, in Lisp they usually do, I
> admit.
>
> Reminds me of a newbie programmer who actually humped a C++ listing to
> the watering hole where we had become acquainted. He was such a
> greenhorn he brought just the source to ask me for help, not the
> compiler listing with the 150 errors that had been driving him insane
> for /four/ days.
>
> I told him I did not know much C++, but shouldn't the function
> definition "MyClass:MyMethod (..." have two colons in there instead of
> one? 
>
> Ya shoulda heard the scream....

I've been in such situations once or twice...

The best one I ever heard of was back in the 8" floppy days where some
CP/M users were having problems running backups, and the tech support
group asked them to send over a copy of the floppy.

They faxed over a _photocopy_ of the disk, which certainly wasn't what
was expected.  In fact, since it was a newfangled double-sized disk,
they photocopied both sides :-).

It was actually useful for the diagnosis; the tech guys, once they
regained their composures, noticed that the write protect tab was
active, which actually explained the problem.
-- 
(reverse (concatenate 'string ···········@" "enworbbc"))
http://www3.sympatico.ca/cbbrowne/spreadsheets.html
You have a tendency to feel you are superior to most computers.
From: Kalle Olavi Niemitalo
Subject: Re: compiler rewriting your code
Date: 
Message-ID: <87elikbqb9.fsf@Astalo.y2000.kon.iki.fi>
"Joe Marshall" <·············@attbi.com> writes:

> You think *that's* bad, my compiler rewrites (> x 0) into
> 
> ;#x7: 33C0           xor     eax,eax
> ;#x9: 5A             pop     edx
> ;#xA: 3BC2           cmp     eax,edx
> ;#xC: 8B06           mov     eax,[esi]
> ;#xE: 7D17           jge     0027

Did you consider size-optimizing that to:

;#x7: 5A             pop     edx
;#x8: 85D2           test    edx,edx
;#xA: 8B06           mov     eax,[esi]
;#xC: 7D17           jge     0025
From: Joe Marshall
Subject: Re: compiler rewriting your code
Date: 
Message-ID: <%DTk8.29818$44.7391794@typhoon.ne.ipsvc.net>
"Kalle Olavi Niemitalo" <···@iki.fi> wrote in message
···················@Astalo.y2000.kon.iki.fi...
> "Joe Marshall" <·············@attbi.com> writes:
>
> > You think *that's* bad, my compiler rewrites (> x 0) into
> >
> > ;#x7: 33C0           xor     eax,eax
> > ;#x9: 5A             pop     edx
> > ;#xA: 3BC2           cmp     eax,edx
> > ;#xC: 8B06           mov     eax,[esi]
> > ;#xE: 7D17           jge     0027
>
> Did you consider size-optimizing that to:
>
> ;#x7: 5A             pop     edx
> ;#x8: 85D2           test    edx,edx
> ;#xA: 8B06           mov     eax,[esi]
> ;#xC: 7D17           jge     0025

The compiler is supposed to work for me, not vice versa!
From: Kalle Olavi Niemitalo
Subject: Re: compiler rewriting your code
Date: 
Message-ID: <87adt6jtak.fsf@Astalo.y2000.kon.iki.fi>
"Joe Marshall" <·············@attbi.com> writes:

> The compiler is supposed to work for me, not vice versa!

You wrote it was your compiler :-)
From: Julian Stecklina
Subject: Re: compiler rewriting your code
Date: 
Message-ID: <87pu23mcha.fsf@blitz.comp.com>
Kalle Olavi Niemitalo <···@iki.fi> writes:

> "Joe Marshall" <·············@attbi.com> writes:
> 
> > You think *that's* bad, my compiler rewrites (> x 0) into
> > 
> > ;#x7: 33C0           xor     eax,eax
> > ;#x9: 5A             pop     edx
> > ;#xA: 3BC2           cmp     eax,edx
> > ;#xC: 8B06           mov     eax,[esi]
> > ;#xE: 7D17           jge     0027
> 
> Did you consider size-optimizing that to:
> 
> ;#x7: 5A             pop     edx
> ;#x8: 85D2           test    edx,edx
> ;#xA: 8B06           mov     eax,[esi]
> ;#xC: 7D17           jge     0025

Why does this need a jump at all? I mean there setXX instructions to
avoid jumps.

Just curious.

Regards,
Julian
-- 
Meine Hompage: http://julian.re6.de

Um meinen oeffentlichen Schluessel zu erhalten:
To get my public key:
http://math-www.uni-paderborn.de/pgp/
From: Joe Marshall
Subject: Re: compiler rewriting your code
Date: 
Message-ID: <hr6l8.30493$44.7917158@typhoon.ne.ipsvc.net>
"Julian Stecklina" <··········@web.de> wrote in message
···················@blitz.comp.com...
> Kalle Olavi Niemitalo <···@iki.fi> writes:
>
> > "Joe Marshall" <·············@attbi.com> writes:
> >
> > > You think *that's* bad, my compiler rewrites (> x 0) into
> > >
> > > ;#x7: 33C0           xor     eax,eax
> > > ;#x9: 5A             pop     edx
> > > ;#xA: 3BC2           cmp     eax,edx
> > > ;#xC: 8B06           mov     eax,[esi]
> > > ;#xE: 7D17           jge     0027
> >
> > Did you consider size-optimizing that to:
> >
> > ;#x7: 5A             pop     edx
> > ;#x8: 85D2           test    edx,edx
> > ;#xA: 8B06           mov     eax,[esi]
> > ;#xC: 7D17           jge     0025
>
> Why does this need a jump at all? I mean there setXX instructions to
> avoid jumps.
>
> Just curious.

I have no idea.  This is output from Corman Common Lisp.
From: Frode Vatvedt Fjeld
Subject: Re: Loop?
Date: 
Message-ID: <2hadtb1jo0.fsf@vserver.cs.uit.no>
········@hotmail.com (Graham) writes:

> (defun sell-a-book()
>   (format t "~%Please enter the title of the book you wish to sell: ")
>   (let* ((purchase-title (read-line)))
>     (dolist (next *books* nil)
>       (setf title (book-record-title next))

The variable title is free in this context, and that is not considered
good style. Either bind title with let, or (since you only use title
once anyway) replace the title variable with the expression
(book-record-title next).

>       (if (> (equal title purchase-title) 0)

This is the form that fails (the compiler probably figures out that
(> x 0) is the same as (plusp x)). Equal returns a boolean. A boolean
is either nil (denoting false) or any other value (denoting
true). Lisp is _not_ like booleans in certain other languages, where
the integer 0 denotes false and any other integer denotes true. Your
test should read:

  (if (equal (book-record-title next) purchase-title) ..)

However, since it is known that purchase-title is a string, you should
probably use a string-specific comparison rather than equal. String=
is case-sensitive while string-equal is not.

-- 
Frode Vatvedt Fjeld