From: Juan Pardillos
Subject: Form that not returns nothing
Date: 
Message-ID: <6278687.0205141442.61b5f1ec@posting.google.com>
Hello,

Is it possible that a form returns nothing?. I have a function
whose single goal is to print a message for the user, and I don't
want that this fuction returns a result (t or nil) mixing with the
message.

E.g:

(defun print-list (list)
   (if (>= (length list) 1)
      (msg (first list))
   )
   (if (> (length list) 1)
      (print-list (rest list))
      (msg " end.")
   )
)

Output for:

(print-list '(A B C))

is:

ABC end.
NIL

But I'd like to be:

ABC end.

Any ideas?. 

Thanks in advance

P.S. Sorry if this question is very easy. I'm a Lisp novice.

From: Thomas F. Burdick
Subject: Re: Form that not returns nothing
Date: 
Message-ID: <xcvvg9qqpfq.fsf@apocalypse.OCF.Berkeley.EDU>
·······@eresmas.com (Juan Pardillos) writes:

> Hello,
> 
> Is it possible that a form returns nothing?. I have a function
> whose single goal is to print a message for the user, and I don't
> want that this fuction returns a result (t or nil) mixing with the
> message.
> 
> E.g:
> 
> (defun print-list (list)
>    (if (>= (length list) 1)
>       (msg (first list))
>    )
>    (if (> (length list) 1)
>       (print-list (rest list))
>       (msg " end.")
>    )
> )

Yuck.  I have no idea where people learn to write Lisp like this.  I
assume the book or tutorial or class you're learning from uses the
cannonical placement of braces and indentation.  Please use that, if
not in your own code, at least when communicating with others:

  (defun print-list (list)
    (if (>= (length list) 1)
        (msg (first list)))
    (if (> (length list) 1)
        (print-list (rest list))
        (msg " end.")))

The value returned by PRINT-LIST is the value of the last form in its
body.  That form is IF.  Most things in Lisp return a single value,
but we do have multiple values:

  * (values 1 2 3)
  1
  2
  3
  * (values)
  * (values 1)
  1

> P.S. Sorry if this question is very easy. I'm a Lisp novice.

No problem.  You should probably go read more on multiple values,
though.  See VALUES, VALUES-LIST, MULTIPLE-VALUE-BIND, and
MULTIPLE-VALUE-CALL.

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: ·······@andrew.cmu.edu
Subject: Re: Form that not returns nothing
Date: 
Message-ID: <20020515173444.A30106@emu>
On Tue, May 14, 2002 at 04:28:57PM -0700, Thomas F. Burdick wrote:
> ·······@eresmas.com (Juan Pardillos) writes:
> 
> > Hello,
> > 
> > Is it possible that a form returns nothing?. I have a function
> > whose single goal is to print a message for the user, and I don't
> > want that this fuction returns a result (t or nil) mixing with the
> > message.
> > 
> > E.g:
> > 
> > (defun print-list (list)
> >    (if (>= (length list) 1)
> >       (msg (first list))
> >    )
> >    (if (> (length list) 1)
> >       (print-list (rest list))
> >       (msg " end.")
> >    )
> > )
> 
> Yuck.  I have no idea where people learn to write Lisp like this.  I
> assume the book or tutorial or class you're learning from uses the
> cannonical placement of braces and indentation.  Please use that, if
> not in your own code, at least when communicating with others:
> 
>   (defun print-list (list)
>     (if (>= (length list) 1)
>         (msg (first list)))
>     (if (> (length list) 1)
>         (print-list (rest list))
>         (msg " end.")))
> 

The placement of parenthesis is one of the lesser problems with the given
example, if you are going to talk about style.  How about:

(defun print-list (list)
  (cond ((consp list)
         (msg (first list))
	 (print-list (rest list)))
	(t (msg " end."))))

Or better yet:

(defun print-list (list)
  (mapc #'msg list)
  (msg " end."))

These are far more readable than the given example, which seems to be an
instance of C programming style in Lisp.  Not to mention they are more
efficient, as the first one is a tail-recursive function and the second one
uses an iterative mapping function.

-- 
; Matthew Danish <·······@andrew.cmu.edu>
; OpenPGP public key: C24B6010 on keyring.debian.org
; Signed or encrypted mail welcome.
; "There is no dark side of the moon really; matter of fact, it's all dark."
From: Thomas F. Burdick
Subject: Re: Form that not returns nothing
Date: 
Message-ID: <xcvwuu56nwl.fsf@conquest.OCF.Berkeley.EDU>
·······@andrew.cmu.edu writes:

> The placement of parenthesis is one of the lesser problems with the given
> example, if you are going to talk about style.

True.  But there's style, and then there's style.  When I was learning
Lisp, I found that I wasn't comfortable reading it until I stopped
seeing the parentheses.  And I learned to write in a Lispy style by
reading other people's code, which was easy once I started reading the
indentation instead of the parentheses.

I've also tried this tact with a friend who learned Lisp.  I had two
friends who didn't know each other, who were learning Lisp at the same
time.  Being experimentally-minded, I tried giving one friend less
style advice, only telling him to do things differently when his code
was hard for me to read.  The other, I gave lots of specific style
advice.  I pointed both in the direction of appropriate parts of the
hyperspec, and to code I thought was written with good style.  The
first got into a Lispy style faster than the second.  Of course, the
sample size here is 2, so it might not mean a thing.

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: dj special ed
Subject: Re: Form that not returns nothing
Date: 
Message-ID: <76be8851.0205142007.3f02f694@posting.google.com>
If a form is evaluated in void context with no one at the interpreter
to witness it, does it really return a value?

Truly one of the great philosophical questions of our time...
-dj


·······@eresmas.com (Juan Pardillos) wrote in message news:<···························@posting.google.com>...
> Hello,
> 
> Is it possible that a form returns nothing?. I have a function
> whose single goal is to print a message for the user, and I don't
> want that this fuction returns a result (t or nil) mixing with the
> message.
> 
> E.g:
> 
> (defun print-list (list)
>    (if (>= (length list) 1)
>       (msg (first list))
>    )
>    (if (> (length list) 1)
>       (print-list (rest list))
>       (msg " end.")
>    )
> )
> 
> Output for:
> 
> (print-list '(A B C))
> 
> is:
> 
> ABC end.
> NIL
> 
> But I'd like to be:
> 
> ABC end.
> 
> Any ideas?. 
> 
> Thanks in advance
> 
> P.S. Sorry if this question is very easy. I'm a Lisp novice.
From: Coby Beck
Subject: Re: Form that not returns nothing
Date: 
Message-ID: <YKgE8.74229$GG6.6521881@news3.calgary.shaw.ca>
Juan Pardillos <·······@eresmas.com> wrote in message
································@posting.google.com...
> Hello,
>
> Is it possible that a form returns nothing?.

CL-USER 1 > (values 1 2)
1
2

CL-USER 2 > (values 1)
1

CL-USER 3 > (values)

CL-USER 4 > (progn
              (format t "hi")
              (values))
hi

CL-USER 5 >


--
Coby Beck
(remove #\Space "coby 101 @ bigpond . com")
From: Kent M Pitman
Subject: Re: Form that not returns nothing
Date: 
Message-ID: <sfwadr2b913.fsf@shell01.TheWorld.com>
"Coby Beck" <·····@mercury.bc.ca> writes:

> Juan Pardillos <·······@eresmas.com> wrote in message
> ································@posting.google.com...
> > Hello,
> >
> > Is it possible that a form returns nothing?.
> 
> CL-USER 1 > (values 1 2)
> 1
> 2
> 
> CL-USER 2 > (values 1)
> 1
> 
> CL-USER 3 > (values)
> 
> CL-USER 4 > (progn
>               (format t "hi")
>               (values))
> hi

In practice, I find this confusing because it makes 'hi' look like it's 
the output of the prior thing, and I end up assuming * is bound to it.
This happens to me a lot:

CL-USER 22 > (pprint '(foo bar))

(FOO BAR)

CL-USER 23 > (length *)
0

And it's darned baffling if you're working late at night.
I prefer to just return T or NIL and get used to it.

I suppose if the REPL were required not to bind * and / when no values
came back, that'd be different.  But then, it'd get messy in other ways
because * and + would be out of alignment.

Further, I always assume (perhaps wrongly -- vendors? correct me if 
needed) that there is more computational overhead in doing
 (values)
than in doing
 NIL
That is, I assume that doing a non-standard number of values requires 
extra setup.  And so I assume I'm slowing my program down needlessly.

But the main reason I don't do it isn't efficiency, it's just debuggability.
From: Duane Rettig
Subject: Re: Form that not returns nothing
Date: 
Message-ID: <4it5q9rh2.fsf@beta.franz.com>
Kent M Pitman <······@world.std.com> writes:

> "Coby Beck" <·····@mercury.bc.ca> writes:
> 
> > CL-USER 4 > (progn
> >               (format t "hi")
> >               (values))
> > hi
> 
> In practice, I find this confusing because it makes 'hi' look like it's 
> the output of the prior thing, and I end up assuming * is bound to it.
> This happens to me a lot:
> 
> CL-USER 22 > (pprint '(foo bar))
> 
> (FOO BAR)
> 
> CL-USER 23 > (length *)
> 0
> 
> And it's darned baffling if you're working late at night.
> I prefer to just return T or NIL and get used to it.

Yeah, I sometimes get confused with things like apropos:

CL-USER(19): (apropos "CADDAR")
CADDAR              [function] (LIST)
CL-USER(20): (symbol-name *)
"NIL"
CL-USER(21): 

> I suppose if the REPL were required not to bind * and / when no values
> came back, that'd be different.  But then, it'd get messy in other ways
> because * and + would be out of alignment.
> 
> Further, I always assume (perhaps wrongly -- vendors? correct me if 
> needed) that there is more computational overhead in doing
>  (values)
> than in doing
>  NIL
> That is, I assume that doing a non-standard number of values requires 
> extra setup.  And so I assume I'm slowing my program down needlessly.

In general, No.  For the specific case of the register-starved x86,
where we have to play tricks and generate the most efficient code
for the most used cases, the answer is Yes.  Here are two examples,
with the first being on LinuxPPC, and the second set of disassembled
code (for the same corresponding sources) on x86.  In both cases, the
only difference is in the indication of how many arguments are being
returned, but in the x86 case, a cleared carry bit is indicating that
one value is being returned (the clear-carry instruction is only one
byte) whereas the return of any other number of values than one requires
the carry bit to be set and the ecx register to have that number of
values in it (for zero values, it takes two instructions for a total
of three bytes, as opposed to one instruction at one byte).

PowerPC:

CL-USER(1): (defun foo () (values))
FOO
CL-USER(2): (defun bar () nil)
BAR
CL-USER(3): (compile **)
FOO
NIL
NIL
CL-USER(4): (compile **)
BAR
NIL
NIL
CL-USER(5): (disassemble **)
;; disassembly of #<Function FOO>
;; formals: 

;; code start: #x40458b44:
   0: 0c300000             twlgti r16,0   	"number of args"
   4: 8252ffff             lwz r18,-1(r18)
   8: 61e30000     [ori]   lr r3,r15     	NIL
  12: 3a000000     [addi]  lil r16,0
  16: 82e10008             lwz r23,8(r1)
  20: 4e800020             blr
CL-USER(6): (disassemble **)
;; disassembly of #<Function BAR>
;; formals: 

;; code start: #x4046b03c:
   0: 0c300000             twlgti r16,0   	"number of args"
   4: 8252ffff             lwz r18,-1(r18)
   8: 61e30000     [ori]   lr r3,r15     	NIL
  12: 3a000001     [addi]  lil r16,1
  16: 82e10008             lwz r23,8(r1)
  20: 4e800020             blr
CL-USER(7): 


And then the last part of the x86 versions:

CL-USER(11): (disassemble **)
;; disassembly of #<Function FOO>
;; formals: 

;; code start: #x71480e14:
   0: e3 02       jcxz	4
   2: cd 61       int	$97             ; EXCL::TRAP-ARGERR
   4: 80 7f 97 00 cmpb	[edi-105],$0    ; SYS::C_INTERRUPT
   8: 74 02       jz	12
  10: cd 64       int	$100            ; EXCL::TRAP-SIGNAL-HIT
  12: 8b c7       movl	eax,edi
  14: 33 c9       xorl	ecx,ecx
  16: f9          stc
  17: 8b 75 fc    movl	esi,[ebp-4]
  20: c3          ret
  21: 90          nop
CL-USER(12): (disassemble **)
;; disassembly of #<Function BAR>
;; formals: 

;; code start: #x714818d4:
   0: e3 02       jcxz	4
   2: cd 61       int	$97             ; EXCL::TRAP-ARGERR
   4: 80 7f 97 00 cmpb	[edi-105],$0    ; SYS::C_INTERRUPT
   8: 74 02       jz	12
  10: cd 64       int	$100            ; EXCL::TRAP-SIGNAL-HIT
  12: 8b c7       movl	eax,edi
  14: f8          clc
  15: 8b 75 fc    movl	esi,[ebp-4]
  18: c3          ret
  19: 90          nop
CL-USER(13): 

-- 
Duane Rettig          Franz Inc.            http://www.franz.com/ (www)
1995 University Ave Suite 275  Berkeley, CA 94704
Phone: (510) 548-3600; FAX: (510) 548-8253   ·····@Franz.COM (internet)
From: Kent M Pitman
Subject: Re: Form that not returns nothing
Date: 
Message-ID: <sfwd6vyb994.fsf@shell01.TheWorld.com>
·······@eresmas.com (Juan Pardillos) writes:

> Hello,
> 
> Is it possible that a form returns nothing?. I have a function
> whose single goal is to print a message for the user, and I don't
> want that this fuction returns a result (t or nil) mixing with the
> message.
> 
> E.g:
> 
> (defun print-list (list)
>    (if (>= (length list) 1)
>       (msg (first list))
>    )
>    (if (> (length list) 1)
>       (print-list (rest list))
>       (msg " end.")
>    )
> )
> 
> Output for:
> 
> (print-list '(A B C))
> 
> is:
> 
> ABC end.
> NIL
> 
> But I'd like to be:
> 
> ABC end.
> 
> Any ideas?. 
> 
> Thanks in advance
> 
> P.S. Sorry if this question is very easy. I'm a Lisp novice.

Is it possible to do what you want?  Yes.

Do I recommend it?  Absolutely not.

Simple examples like this always make it look like you'll need it but
in real applications, you are not interacting with the read-eval-print
loop, so this issue simply does not come up.

Every Lisp novice asks this question and every one labors under the same
misconception that you have--that it will be useful to get around the
return value thing.   It simply is not.  You are not understanding the
'workflow' of Lisp.

It's quite important when you work with value-producing systems that
you see the return value.  It's very hard to debug things you don't see.

==============================================================================
		 DO NOT DO WHAT FOLLOWS -- BAD STYLE
==============================================================================

CL-USER 16 > (defclass photon () ())
#<STANDARD-CLASS PHOTON 205F381C>

CL-USER 17 > (defmethod print-object ((photon photon) stream)
  ;; If you really leave this blank, whether in homework or a
  ;; commercial application, you deserve to lose badly in the way
  ;; that you ultimately will.  DO NOT DO IT.
  )
#<STANDARD-METHOD PRINT-OBJECT NIL (PHOTON T) 205F4A0C>

CL-USER 18 > (defvar *nothing* (make-instance 'photon))
*NOTHING*

CL-USER 19 > (progn (print 'foo) (print 'bar) *nothing*)

FOO 
BAR 

CL-USER 20 > (list *nothing* *nothing* *nothing*)
(  )

CL-USER 21 > (length *)
3

==============================================================================

==============================================================================
From: Joe Marshall
Subject: Re: Form that not returns nothing
Date: 
Message-ID: <BDhE8.4716$Bn5.1729535@typhoon.ne.ipsvc.net>
"Juan Pardillos" <·······@eresmas.com> wrote in message ································@posting.google.com...
> Hello,
>
> Is it possible that a form returns nothing?. I have a function
> whose single goal is to print a message for the user, and I don't
> want that this fuction returns a result (t or nil) mixing with the
> message.

You could return something other than T or NIL.

(defun print-something (args)
   ....
   :no-more-output)