From: Andrew Cooke
Subject: Newbie Q: let/setf and testing
Date: 
Message-ID: <7q9mj6$s03$1@nnrp1.deja.com>
Hi,

I have two functions, which should be executed in turn (the second
takes the results of the first as an argument) and, if both are
non-nil, I want to do something with the results of the second.
That sounds obscure, but it's quite common, at least in C-like
code (sorry! :-)

if (r1 = f1(a, b, c) && r2 = f2(r1, d, e)) {
 ...
}

Now in Lisp I am using (I'm writing this in a browser with no
bracket macthing, so forgive typos)

(let ((r1 (f1 a b c)))
  (when r1
    (let ((r2 (f2 r1 d e)))
      (when r2 (....)))))

or

(let ((r1 nil)
      (r2 nil))
  (when (and (setf r1 (f1 a b c)) (setf r2 (f2 r1 d e)))) (...)))

Is there a better way, and if not which of the two above is
considered better style?  I prefer the latter for compactness, but
it may not be a standard idiom to use and in that way in Lisp (it
may be that I should be using some other function than "and").  On
the other hand, the "setf" seems gratuitous given my (minimal)
experience of functional programming.

Please reply here or email to ······@intertrader.com - the
free-online mail server seems to be dead at the moment.

Thanks,
Andrew



Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.

From: Rainer Joswig
Subject: Re: Newbie Q: let/setf and testing
Date: 
Message-ID: <joswig-2908990130280001@194.163.195.67>
In article <············@nnrp1.deja.com>, Andrew Cooke <······@andrewcooke.free-online.co.uk> wrote:

> Now in Lisp I am using (I'm writing this in a browser with no
> bracket macthing, so forgive typos)
> 
> (let ((r1 (f1 a b c)))
>   (when r1
>     (let ((r2 (f2 r1 d e)))
>       (when r2 (....)))))

I'd like this one better.

If it's a common idiom for you, you could write a macro
(hey, it's even a recursive macro):


(defmacro let*-and (clauses &body body)
  (if clauses
    (destructuring-bind (var expression) (first clauses)
      `(let ((,var ,expression))
         (when ,var
           (let*-and ,(rest clauses) ,@body))))
    `(progn ,@body)))


Example:

(let*-and ((r1 (> (random 1.0) 0.5))
           (r2 (and r1 (> (random 1.0) 0.5))))
  (random 0.5))
From: Rolf-Thomas Happe
Subject: Re: Newbie Q: let/setf and testing
Date: 
Message-ID: <r5671y1s7z.fsf@bonnie.mathematik.uni-freiburg.de>
Rainer Joswig writes:
> If it's a common idiom for you, you could write a macro
> (hey, it's even a recursive macro):
[...]
> Example:
> 
> (let*-and ((r1 (> (random 1.0) 0.5))
>            (r2 (and r1 (> (random 1.0) 0.5))))
>   (random 0.5))

A similar macro, though for Scheme, is described by

   http://srfi.schemers.org/srfi-2/srfi-2.html

There it's named AND-LET*.  So, those interested in conservative
naming may prefer (the name) AND-LET* to (the name) LET*-AND.

rthappe
From: Rainer Joswig
Subject: Re: Newbie Q: let/setf and testing
Date: 
Message-ID: <joswig-2908991922030001@194.163.195.67>
In article <··············@bonnie.mathematik.uni-freiburg.de>, Rolf-Thomas Happe <·······@bonnie.mathematik.uni-freiburg.de> wrote:

> Rainer Joswig writes:
> > If it's a common idiom for you, you could write a macro
> > (hey, it's even a recursive macro):
> [...]
> > Example:
> > 
> > (let*-and ((r1 (> (random 1.0) 0.5))
> >            (r2 (and r1 (> (random 1.0) 0.5))))
> >   (random 0.5))
> 
> A similar macro, though for Scheme, is described by
> 
>    http://srfi.schemers.org/srfi-2/srfi-2.html
> 
> There it's named AND-LET*.  So, those interested in conservative
> naming may prefer (the name) AND-LET* to (the name) LET*-AND.
> 
> rthappe

Interesting. Thanks.
From: Arthur Lemmens
Subject: Re: Newbie Q: let/setf and testing
Date: 
Message-ID: <37C99CC5.A36E5BCF@simplex.nl>
Rolf-Thomas Happe wrote:

> A similar macro, though for Scheme, is described by
> 
>    http://srfi.schemers.org/srfi-2/srfi-2.html
> 
> There it's named AND-LET*.  So, those interested in conservative
> naming may prefer (the name) AND-LET* to (the name) LET*-AND.

Paul Graham calls it WHEN-BIND* in 'On Lisp'.

--
Arthur Lemmens
From: Erik Naggum
Subject: Re: Newbie Q: let/setf and testing
Date: 
Message-ID: <3144908662537112@naggum.no>
* Andrew Cooke
| I have two functions, which should be executed in turn (the second takes
| the results of the first as an argument) and, if both are non-nil, I want
| to do something with the results of the second.  That sounds obscure, but
| it's quite common, at least in C-like code (sorry! :-)
| 
| if (r1 = f1(a, b, c) && r2 = f2(r1, d, e)) {
|  ...
| }

  what happens to r1 and r2 in the body and after it?

| Is there a better way, and if not which of the two above is considered
| better style?

  I think I might have used non-local returns like this:

(block nil
  (let* ((r1 (or (f1 a b c) (return)))
	 (r2 (or (f2 r1 d e) (return))))
    ...))

  note that this idiom is a lot more powerful than to just testing for a
  boolean return value.  being able to return from a function or block
  anywhere within it can be used to create both readable and efficient
  code, but it will be out of reach for C programmers and others who think
  that non-local returns are bad or somehow a different kind of language
  construct (which it is in C).

| On the other hand, the "setf" seems gratuitous given my (minimal)
| experience of functional programming.

  well, it isn't lack of SETF or SETQ that makes a program functional, it's
  the lack of side effects.  this is the same argument as GOTO, which some
  people believe they can't use in structured programs.  if you assign a
  value to a variable once and you don't use the binding, what you're
  looking at is a failure of the language to capture the binding forms you
  need, just as GOTO may be necessary to write well-structured programs in
  languages that don't support the control structures you need.

  I have a problem with the "false purity" of various approaches to writing
  code.  it's as if people would cringe at code that is semantically in the
  style they want, and embrace code that is not, because some syntactic
  aspect of the code violates some prejudice that makes it "impure".  e.g.,
  you can write worse spaghetti code with a lot of boolean variables that
  try to do what a few well-placed goto's could have done very elegantly.
  you can write dysfunctional code (pardon the pun) in a functional style.

#:Erik
-- 
  save the children: just say NO to sex with pro-lifers
From: Gareth McCaughan
Subject: Re: Newbie Q: let/setf and testing
Date: 
Message-ID: <86btbqebyg.fsf@g.local>
Erik Naggum wrote:

>   well, it isn't lack of SETF or SETQ that makes a program functional, it's
>   the lack of side effects.  this is the same argument as GOTO, which some
>   people believe they can't use in structured programs.  if you assign a
>   value to a variable once and you don't use the binding, what you're
>   looking at is a failure of the language to capture the binding forms you
>   need, just as GOTO may be necessary to write well-structured programs in
>   languages that don't support the control structures you need.
[etc]

There's a nice look at some issues of this kind in Knuth's article
"Structured programming with go to statements", reprinted as part
of his book titled "Literate Programming". It's quite old now (as
one could probably tell from the spelling of "go to"), but still
makes interesting reading.

-- 
Gareth McCaughan  ················@pobox.com
sig under construction
From: Andrew Cooke
Subject: Re: Newbie Q: let/setf and testing
Date: 
Message-ID: <7qdavr$6fm$1@nnrp1.deja.com>
Thanks for the useful replies.  I was checking bookstores for
"On Lisp" last week - looks like it might be a good book to
invest in.  As for (that use of) setf being functional, I realise
that, but it "felt" ugly (as I said, my functional programming
experience is minimal, so that does not mean much) - to be honest I
thought there might have been something already in the language that I
was missing.

Cheers,
Andrew


In article <············@nnrp1.deja.com>,
  Andrew Cooke <······@andrewcooke.free-online.co.uk> wrote:
> I have two functions, which should be executed in turn (the second
> takes the results of the first as an argument) and, if both are
> non-nil, I want to do something with the results of the second.
> That sounds obscure, but it's quite common, at least in C-like
> code (sorry! :-)
>


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
From: William Deakin
Subject: Re: Newbie Q: let/setf and testing
Date: 
Message-ID: <37CB9EB7.A9CBE348@pindar.com>
Andrew Cooke wrote:

> Thanks for the useful replies.  I was checking bookstores for "On Lisp"
> last week - looks like it might be a good book to invest in.

If you can find a copy in this country, that doesn't require a 6-10 week
wait, let me know.

Best Regards,

:-) will
From: Duncan Harvey
Subject: Re: Newbie Q: let/setf and testing
Date: 
Message-ID: <1dxexwg.1vekvkjc0hjcfN@hubris2.demon.co.uk>
William Deakin <·····@pindar.com> wrote:

> Andrew Cooke wrote:
> 
> > I was checking bookstores for "On Lisp" last week - looks like it might
> > be a good book to invest in.
> 
> If you can find a copy in this country, that doesn't require a 6-10 week
> wait, let me know.

I found "On Lisp" in the big Dillion's-- <sigh> I mean the recently
renamed big Waterstone's on Gower Street in London.  It was right next
to "ANSI Common Lisp" (one copy of each).  Elsewhere, they had
"Structure and Interpretation of Computer Programs" too.

<rustle, rustle, checks receipt>  This was on the 16th July (when it
*was* a Dillons).

-- 
Duncan Harvey,
'Just be yourself' -- exceedingly poor advice to give a sociopath.