From: Arne Knut Roev
Subject: Are these two functions equivalent ?
Date: 
Message-ID: <Ft0oB8.Exu@online.no>
Good evening...

I am still studying� Common Lisp, and as part of the process of learning, I
am writing a number of functions related to handling www/html- links. So,
here is the first version of a function I wrote:

(defun get-reference-pair-from-keyboard ()
  (let
      ((web-address "")
       (web-label ""))
    (format t "~&Please type the address of the web page:~%")
    (setf web-address (read-line))
    (format t "~&Please type the label you want displayed for this link:~%")
    (setf web-label (read-line))
    (cons web-address web-label)))

For some reason, I was not satisfied with this version (I didn't like having
to use two lexical variables), and an hour ago, I wrote the following
version:

(defun get-reference-pair-from-keyboard ()
  (cons 
   (progn 
     (format t "~&Please type the address of the web page:~%")
     (read-line))
   (progn
     (format t "~&Please type the label you want displayed for this link:~%")
     (read-line))))

So, my questions are as follows:

1. Are these two versions functionally equivalent ? (Apart, that is, from
   the fact that one of them uses two lexical variables, and the other one
   doesn't.)

2. Does this change imply that I might be "getting" some of the mindset of
   (Common) Lisp ?

-akr

�: A small clarification is in order here: 

    -Yes, I am studying Common Lisp.
    -No, this is not (part of) a formal study.
    -No, I do not have a teacher.
    -Yes, in one sense it can be called homework: I am doing it at home...
    -No, I am not going to get a diploma when I finish this study.

-- 
Arne Knut Roev <······@online.no> Snail: N-6141 ROVDE, Norway
=
The Gates of Hell shall not prevail:
Darkness now; then Light!

From: Martti Halminen
Subject: Re: Are these two functions equivalent ?
Date: 
Message-ID: <38F76229.BCD0B672@solibri.com>
Arne Knut Roev wrote:

> For some reason, I was not satisfied with this version (I didn't like having
> to use two lexical variables), and an hour ago, I wrote the following
> version:
> 
> (defun get-reference-pair-from-keyboard ()
>   (cons
>    (progn
>      (format t "~&Please type the address of the web page:~%")
>      (read-line))
>    (progn
>      (format t "~&Please type the label you want displayed for this link:~%")
>      (read-line))))
> 
> So, my questions are as follows:
> 
> 1. Are these two versions functionally equivalent ? (Apart, that is, from
>    the fact that one of them uses two lexical variables, and the other one
>    doesn't.)

Yes (unless there was a typo somewhere, I didn't bother running
this)

> 2. Does this change imply that I might be "getting" some of the mindset of
>    (Common) Lisp ?

Seems to be going that way. You might think about replacing
those progn parts with something with a little input sanity
checking etc. I'd probably do this by creating some kind of
general user-prompting function, usage something like
(ask-user <stream> <checkfunction> <promptstring> &rest
<promptargs>)
- looping with re-prompting until the read-line returns
something acceptable.
=>
(ask-user t #'url-string-p "Please type the address of the web
page:")
(ask-user t #'acceptable-label-p 
         "Please type the label you want displayed for this
link:")






--
From: Rob Warnock
Subject: Re: Are these two functions equivalent ?
Date: 
Message-ID: <8dbh8c$3jki$1@fido.engr.sgi.com>
Arne Knut Roev  <······@online.no> wrote:
+---------------
| (defun get-reference-pair-from-keyboard ()
|   (let
|       ((web-address "")
|        (web-label ""))
|     (format t "~&Please type the address of the web page:~%")
|     (setf web-address (read-line))
|     (format t "~&Please type the label you want displayed for this link:~%")
|     (setf web-label (read-line))
|     (cons web-address web-label)))
| 
| For some reason, I was not satisfied with this version (I didn't like
| having to use two lexical variables)...
+---------------

Part of it may be that you aren't using lexicals in the natural
functional style. I strongly prefer the following version:

  (defun get-reference-pair-from-keyboard ()
    (format t "~&Please type the address of the web page:~%")
    (let ((web-address (read-line)))
      (format t "~&Please type the label you want displayed for this link:~%")
	(let ((web-label (read-line)))
          (cons web-address web-label))))

Look, ma, no "setq"s!  

[Yes, the final "let" could be replaced by just (cons web-address (read-line)),
but I prefer the additional documentation which naming the value gives you.]

And as <···············@solibri.com> noted about robustness &
modularity/reusability:
+---------------
| I'd probably do this by creating some kind of general user-prompting
| function, usage something like (ask-user <stream> <checkfunction>
| <promptstring> &rest <promptargs>)
| - looping with re-prompting until the read-line returns something acceptable.
| =>
| (ask-user t #'url-string-p "Please type the address of the web page:")
| (ask-user t #'acceptable-label-p 
|          "Please type the label you want displayed for this link:")
+---------------

Once you have "ask-user" (or equiv.), it's even more compact [though I
decided to split those *long* prompt strings out as separate lexvars]:

  (defun get-reference-pair-from-keyboard ()
    (let* ((msg1 "Please type the address of the web page:")
	   (web-address (ask-user t #'url-string-p msg1))
	   (msg2 "Please type the label you want displayed for this link:")
	   (web-label (ask-user t #'acceptable-label-p msg2)))
      (cons web-address web-label)))


-Rob

-----
Rob Warnock, 41L-955		····@sgi.com
Applied Networking		http://reality.sgi.com/rpw3/
Silicon Graphics, Inc.		Phone: 650-933-1673
1600 Amphitheatre Pkwy.		PP-ASEL-IA
Mountain View, CA  94043
From: Tim Bradshaw
Subject: Re: Are these two functions equivalent ?
Date: 
Message-ID: <ey3d7nq44u2.fsf@cley.com>
* Rob Warnock wrote:

>   (defun get-reference-pair-from-keyboard ()
>     (format t "~&Please type the address of the web page:~%")
>     (let ((web-address (read-line)))
>       (format t "~&Please type the label you want displayed for this link:~%")
> 	(let ((web-label (read-line)))
>           (cons web-address web-label))))

Ick!

If you really want to use let do this:

	(let ((address (progn (format ...) (read-line)))
	      (label (progn (format ...) (read-line))))
	  (cons address label))

Your version seems gratuitously over-complex to me.

--tim
From: Rob Warnock
Subject: Re: Are these two functions equivalent ?
Date: 
Message-ID: <8ddth1$f8e7$1@fido.engr.sgi.com>
Tim Bradshaw  <···@cley.com> wrote:
+---------------
| * Rob Warnock wrote:
| 
| >   (defun get-reference-pair-from-keyboard ()
| >     (format t "~&Please type the address of the web page:~%")
| >     (let ((web-address (read-line)))
| >       (format t "~&Please type the label you want displayed for this link:~%")
| > 	(let ((web-label (read-line)))
| >           (cons web-address web-label))))
| 
| Ick!  If you really want to use let do this:
| 
| 	(let ((address (progn (format ...) (read-line)))
| 	      (label (progn (format ...) (read-line))))
| 	  (cons address label))
| 
| Your version seems gratuitously over-complex to me.
+---------------

Oh yeah?!?  Then why didn't you write your version *WITHOUT* those
oh-so-convenient-but-non-working ellipses, hmmm??? Doesn't look so
good now, does it?

 	(let ((address (progn (format t "~&Please type the address of the web page:~%") (read-line)))
 	      (label (progn (format t "~&Please type the label you want displayed for this link:~%") (read-line))))
 	  (cons address label))


-Rob

-----
Rob Warnock, 41L-955		····@sgi.com
Applied Networking		http://reality.sgi.com/rpw3/
Silicon Graphics, Inc.		Phone: 650-933-1673
1600 Amphitheatre Pkwy.		PP-ASEL-IA
Mountain View, CA  94043
From: Tim Bradshaw
Subject: Re: Are these two functions equivalent ?
Date: 
Message-ID: <ey37ldxdtwf.fsf@cley.com>
* Rob Warnock wrote:
> Oh yeah?!?  Then why didn't you write your version *WITHOUT* those
> oh-so-convenient-but-non-working ellipses, hmmm??? Doesn't look so
> good now, does it?

Well, I wasn't proposing using LET, I said if you really *want* to use
it do it that way.  And I also forgot to put an explicit `in my
opinion' for which I'm sorry -- this whole thing is clearly a matter
of taste (so obviously a really good opportunity for people to scream
at each other on newsgroups).

For what it's worth I would *still* prefer the fully prognified one if
I had to use LET.

--tim
From: Barry Margolin
Subject: Re: Are these two functions equivalent ?
Date: 
Message-ID: <om1K4.6$Mv3.56@burlma1-snr2>
In article <··········@online.no>, Arne Knut Roev  <······@online.no> wrote:
>Good evening...
>For some reason, I was not satisfied with this version (I didn't like having
>to use two lexical variables), and an hour ago, I wrote the following
>version:

What's wrong with lexical variables?  IMHO, the style of the first function
is better.  The variable names let the reader of the program know what's
going on.  With only two variables it doesn't make much difference, but
expand your application to a dozen (replacing CONS with LIST or
MAKE-INSTANCE) and the version with variables becomes much more readable.

-- 
Barry Margolin, ······@genuity.net
Genuity, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.