From: Rachel John
Subject: Functions in Lisp
Date: 
Message-ID: <1140542999.419875.92580@g14g2000cwa.googlegroups.com>
Is there any particular order in which functions are executed in Lisp
or the calling function should be after the function that is called

From: Deon Garrett
Subject: Re: Functions in Lisp
Date: 
Message-ID: <87u0asr20a.fsf@clapton.csm.astate.edu>
"Rachel John" <·············@gmail.com> writes:

> Is there any particular order in which functions are executed in Lisp
> or the calling function should be after the function that is called

Nope.  It's completely nondeterministic.  You have no idea how rarely our
programs actually work.  It really is quite frustrating.

But seriously, what are you trying to ask?  Is the question concerning the
order in which you should define the functions?
 
From: Geoffrey Summerhayes
Subject: Re: Functions in Lisp
Date: 
Message-ID: <evJKf.11278$%14.313078@news20.bellglobal.com>
"Deon Garrett" <·········@gmail.com> wrote in message 
···················@clapton.csm.astate.edu...
> "Rachel John" <·············@gmail.com> writes:
>
>> Is there any particular order in which functions are executed in Lisp
>> or the calling function should be after the function that is called
>
> Nope.  It's completely nondeterministic.  You have no idea how rarely our
> programs actually work.  It really is quite frustrating.
>

That's why I prefer coding in Non-deterministic Integrated Knowledge
Elucidator, or NIKE for short, a DWIM language that consists of
only one statement. :)

--
Geoff
From: netytan
Subject: Re: Functions in Lisp
Date: 
Message-ID: <1140578615.588847.40660@g47g2000cwa.googlegroups.com>
If your talking about the order the parameters are evaluated in then I
don't think its defined, they're evaluated before they're applied to
the function of course but aside *shug*.

This said the actual eval order only matters if you're relying on
side-effects and DONT!

Other than that I'm lost as to what you could mean :).

Mark.
From: drewc
Subject: Re: Functions in Lisp
Date: 
Message-ID: <87d5hfin4m.fsf@rift.com>
"netytan" <·······@gmail.com> writes:

> If your talking about the order the parameters are evaluated in then I
> don't think its defined, they're evaluated before they're applied to
> the function of course but aside *shug*.

What you think is not relevant, as the CLHS is the authority on this
matter.

3.1.2.1.2.3 states :

"The subforms in the cdr of the original form are evaluated in
left-to-right order in the current lexical and dynamic
environments. The primary value of each such evaluation becomes an
argument to the named function; any additional values returned by the
subforms are discarded."

The very fact that the operator is called APPLY should hint towards
applicative-order evaluation, and I have a lot of trouble visualising
an implementation of APPLY that does not simply recurse through the
form in left-to-right order. (well, i can visualise it, but it's a little more complex then the applicative solutions). 

>
> This said the actual eval order only matters if you're relying on
> side-effects and DONT!

Why not? This ain't haskell, we have applicative-order evaluation and SETF, so why not take advantage of that fact if it suits the problem space?

drewc

> Other than that I'm lost as to what you could mean :).
>
> Mark.
>

-- 
drewc at tech dot coop
From: netytan
Subject: Re: Functions in Lisp
Date: 
Message-ID: <1140588542.075589.51150@g44g2000cwa.googlegroups.com>
*Shudders*, because the whole idea of functional programming, into
which Lisp fits nicely is to "avoid side effects at all costs". In fact
purely functional languages won't let you *cough* Haskell.

Lisp not being a purely functional language makes it akin to "avoid
side-effects as much as possible".

I personally find it highly unlikely that you, or anyone for that
matter could provide a good enough reason to use setf in as functions
parameter and if you can then maybe you shouldn't.

I'm aware this isn't Haskell but that doesn't mean I would rely on the
order arguments are being evaluated in to propagate some side-effect
before applying some value to a function - it just strikes me as bad
style; a shining testament to inelegantly and a very good way of asking
for trouble.

I think we're all familiar with the benefits gained by using a
functional language so a question for you. Why would you needlessly
push outside of that?

For fun lets assume that you're using some Lisp implementation
evaluated them in a different order*. If this were the case you my
friend would probably have a very nice bug, and one that would be
virtually impossible to track down in a large program. All because you
were assuming that arguments will be evaluated left-to-right.

With this assumption all happy nestled in your head are you going to
think "Oh, maybe it's because of this here and I shouldn't be relying
on this in this way if I can help it" - and you can, so why not?

Do as you wish but I won't be doing anything of the sort until I have
no other choice in the matter, and frankly I doubt that's gonna happen
:).

Night everyone; take care drewc,

Mark.

* This is briefly warned against in "Lisp in Small Pieces", a book on
Lisp internals. As it reads, in some Lisp implementations it can be
useful for optimization to change this order.
From: Peder O. Klingenberg
Subject: Re: Functions in Lisp
Date: 
Message-ID: <ks8xs3ajgv.fsf@beto.netfonds.no>
"netytan" <·······@gmail.com> writes:

> I personally find it highly unlikely that you, or anyone for that
> matter could provide a good enough reason to use setf in as functions
> parameter and if you can then maybe you shouldn't.

I have code that does something like 

(when (and (valid-data-p data)
           (update *global-state* data))
   (notify-users))

Where update will side-effect *global-state* and return nil on failure
to do so.

I'm aware that AND is not a function, but I still rely on the order of
evaluation of the parameters to AND.

> I think we're all familiar with the benefits gained by using a
> functional language so a question for you. Why would you needlessly
> push outside of that?

Because modeling the program after the problem domain is preferrable
to bending over backwards to accommodate a specific programming style?

> For fun lets assume that you're using some Lisp implementation
> evaluated them in a different order*. If this were the case you my
> friend would probably have a very nice bug,

No, the vendor of the Lisp implementation would have a bug.  Common
Lisp has well defined evaluation order.  I feel as comfortable relying
on that as I do relying on that the implementation will have a
function CL:CAR that does what I expect.

...Peder...
-- 
It's not called hacking or trial and error!
It's called rapid prototyping and extreme programming.
  - Kristoffer Gleditsch
From: Frank Buss
Subject: Re: Functions in Lisp
Date: 
Message-ID: <1fn9279o6ssyl$.1w2ay7ywuiuvr.dlg@40tude.net>
Peder O. Klingenberg wrote:

> I have code that does something like 
> 
> (when (and (valid-data-p data)
>            (update *global-state* data))
>    (notify-users))

What's the advantage with your AND compared to this:

(when (valid-data-p data)
  (when (update *global-state* data)
    (notify-users)))

> Where update will side-effect *global-state* and return nil on failure
> to do so.
> 
> I'm aware that AND is not a function, but I still rely on the order of
> evaluation of the parameters to AND.

This is documented: "The macro and evaluates each form one at a time from
left to right."

-- 
Frank Buss, ··@frank-buss.de
http://www.frank-buss.de, http://www.it4-systems.de
From: Peder O. Klingenberg
Subject: Re: Functions in Lisp
Date: 
Message-ID: <ks4q2ragxg.fsf@beto.netfonds.no>
Frank Buss <··@frank-buss.de> writes:

> What's the advantage with your AND compared to this:

Not much, but I like the look of the former better.  I think nested
whens look ugly, but YMMV.

> This is documented: "The macro and evaluates each form one at a time from
> left to right."

Yes.  So is the evaluation order of arguments to functions, as drewc
pointed out.  The point being that evaluation order of arguments
(wether to functions or to AND) is something that I can and do rely
on.

I'm not arguing that such a dependency cannot be avoided - of course
it can.  But there's no point in avoiding it at all costs because of
some hypothetical buggy implementation.  It is actually defined
behaviour.

That said, there's probably a reason why I couldn't immediately come
up with an example of a function (as opposed to AND) from my own code
that relies on the evaluation order of arguments.

...Peder...
-- 
It's not called hacking or trial and error!
It's called rapid prototyping and extreme programming.
  - Kristoffer Gleditsch
From: Espen Vestre
Subject: Re: Functions in Lisp
Date: 
Message-ID: <m1wtfnpwhn.fsf@mordac.netfonds.no>
·····@news.klingenberg.no (Peder O. Klingenberg) writes:

> That said, there's probably a reason why I couldn't immediately come
> up with an example of a function (as opposed to AND) from my own code
> that relies on the evaluation order of arguments.

Defaults to keyword arguments are obvious candidates, and I thought I
used defaults computed from the obligatory parameters all the time,
but I actually only found one example in recent code.
-- 
  (espen)
From: Rob Warnock
Subject: Re: Functions in Lisp
Date: 
Message-ID: <4POdneRIme2x3mHeRVn-pQ@speakeasy.net>
Espen Vestre  <·····@vestre.net> wrote:
+---------------
| ·····@news.klingenberg.no (Peder O. Klingenberg) writes:
| > That said, there's probably a reason why I couldn't immediately come
| > up with an example of a function (as opposed to AND) from my own code
| > that relies on the evaluation order of arguments.
| 
| Defaults to keyword arguments are obvious candidates, and I thought I
| used defaults computed from the obligatory parameters all the time,
| but I actually only found one example in recent code.
+---------------

Oddly enough, I ran across a case of wanting to do exactly that just
last night, when writing a generalization for MAKE-LIST that allows
circular tails [yes, while playing around with the circular lists
mentioned in the "Subject: equal lists" thread] and is also capable
of initialing the elements of the list to a function of their position
[pardon the ugly draft code!]:

    (defun make-list* (size &key initial-element
				 (circular-tail-size 0)
				 (initial-element-function
				  (constantly initial-element)))
      (loop with prefix-length = (- size circular-tail-size)
	     and list = (make-list size)
	     and merge = nil
	    for i below size
	     and node on list
	     and last = nil then node
	do (setf (car node) (funcall initial-element-function i))
	when (= i prefix-length)
	  do (setf merge node)
	finally (when (plusp circular-tail-size)
		  (setf (cdr last) merge))
		(return list)))

The idea being that if you stick to MAKE-LIST args you get MAKE-LIST
semantics, but if not, well:

    cmu> (make-list* 5)

    (NIL NIL NIL NIL NIL)
    cmu> (make-list* 5 :initial-element 'foo)

    (FOO FOO FOO FOO FOO)
    cmu> (make-list* 5 :initial-element-function #'identity)

    (0 1 2 3 4)
    cmu> (make-list* 5 :initial-element-function (lambda (x) (expt 2 x)))

    (1 2 4 8 16)
    cmu> (make-list* 5 :initial-element-function (lambda (x) (expt 2 x))
			 :circular-tail-size 3)

    (1 2 . #1=(4 8 16 . #1#))
    cmu> 

Anyway, somewhere along the way I realized that if the
INITIAL-ELEMENT-FUNCTION argument were made to be the primary
source of initialization instead of INITIAL-ELEMENT [which,
as you'll see above is now used *only* by the default for
INITIAL-ELEMENT-FUNCTION], then by putting the keyword args in
the right order with the right defaults then "the right thing"
would simply happen automagically.  ;-}

[But, no, off hand I can't think of any other code I've written
depending on the keyword arg order quite so strongly...]


-Rob

p.s. Can anyone think of better (shorter, mainly!) names for the
above args than INITIAL-ELEMENT-FUNCTION & CIRCULAR-TAIL-SIZE?
I tried INITIALIZATION-FUNCTION, but that didn't scan as well.

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Steven E. Harris
Subject: Re: Functions in Lisp
Date: 
Message-ID: <q94mzgjpbkm.fsf@chlorine.gnostech.com>
····@rpw3.org (Rob Warnock) writes:

> Can anyone think of better (shorter, mainly!) names for the above
> args than INITIAL-ELEMENT-FUNCTION

Generator.

> & CIRCULAR-TAIL-SIZE?

It's a long shot, but how about clasp-index? That is, turn it around
to specify the first element index that's pointed back to by the
tail. It would default to nil or size, meaning no circularity.

-- 
Steven E. Harris
From: Didier Verna
Subject: Re: Functions in Lisp
Date: 
Message-ID: <muxwtfn8ug1.fsf@uzeb.lrde.epita.fr>
····@rpw3.org (Rob Warnock) wrote:

>     (FOO FOO FOO FOO FOO)
>     cmu> (make-list* 5 :initial-element-function #'identity)

> p.s. Can anyone think of better (shorter, mainly!) names for the
> above args than INITIAL-ELEMENT-FUNCTION & CIRCULAR-TAIL-SIZE?
> I tried INITIALIZATION-FUNCTION, but that didn't scan as well.

What about (make-list* 5 :make-element-with #'identity) ?

(not really convinced myself)

-- 
Didier Verna, ······@lrde.epita.fr, http://www.lrde.epita.fr/~didier

EPITA / LRDE, 14-16 rue Voltaire   Tel.+33 (1) 44 08 01 85
94276 Le Kremlin-Bic�tre, France   Fax.+33 (1) 53 14 59 22   ······@xemacs.org
From: Marcin 'Qrczak' Kowalczyk
Subject: Re: Functions in Lisp
Date: 
Message-ID: <87fym7far9.fsf@qrnik.zagroda>
Espen Vestre <·····@vestre.net> writes:

>> That said, there's probably a reason why I couldn't immediately come
>> up with an example of a function (as opposed to AND) from my own code
>> that relies on the evaluation order of arguments.
>
> Defaults to keyword arguments are obvious candidates, and I thought I
> used defaults computed from the obligatory parameters all the time,
> but I actually only found one example in recent code.

Keyword arguments don't rely on the evaluation order of arguments.
When keywords arguments are parsed, *all* arguments are already
evaluated, so it doesn't matter in which order they have been
evaluated.

Binding them to parameters in a specific order is a different thing.
They are bound in the order of appearing in the lambda list, not in
the order of being provided as arguments.

-- 
   __("<         Marcin Kowalczyk
   \__/       ······@knm.org.pl
    ^^     http://qrnik.knm.org.pl/~qrczak/
From: Pascal Bourguignon
Subject: Re: Functions in Lisp
Date: 
Message-ID: <87slq79nox.fsf@thalassa.informatimago.com>
Marcin 'Qrczak' Kowalczyk <······@knm.org.pl> writes:

> Espen Vestre <·····@vestre.net> writes:
>
>>> That said, there's probably a reason why I couldn't immediately come
>>> up with an example of a function (as opposed to AND) from my own code
>>> that relies on the evaluation order of arguments.
>>
>> Defaults to keyword arguments are obvious candidates, and I thought I
>> used defaults computed from the obligatory parameters all the time,
>> but I actually only found one example in recent code.
>
> Keyword arguments don't rely on the evaluation order of arguments.
> When keywords arguments are parsed, *all* arguments are already
> evaluated, so it doesn't matter in which order they have been
> evaluated.

Espen didn't mention the keyword arguments. He mentioned the DEFAULTS
to keyword arguments.

(defun f (&key (a 1) (b (1+ a)) (c (1+ b))) (list a b c))
(f :a 2) --> (2 3 4)
(f :b 4) --> (1 4 5)


(defun g (&key (a (1+ b)) (b (1+ c)) (c 1)) (list a b c))
(f :a 2) --> *** - EVAL: variable C has no value



That said, this is indeed a something different.

A function itself cannot depend on the order of evaluation of its
_effective_ _arguments_, because they are evaluated before the
function is called.  

But a function could get different values if the order of evaluation
of its arguments wasn't defined.

(let ((i 1)) (/ (incf i) (incf i))) --> ?

If the order of evaluation of the argument is defined as in Common
Lisp, then we get 2/3.  In other classes of languages, you can get whatever.


> Binding them to parameters in a specific order is a different thing.
> They are bound in the order of appearing in the lambda list, not in
> the order of being provided as arguments.

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

THIS IS A 100% MATTER PRODUCT: In the unlikely event that this
merchandise should contact antimatter in any form, a catastrophic
explosion will result.
From: Coby Beck
Subject: Re: Functions in Lisp
Date: 
Message-ID: <xv6Mf.4868$Cp4.1762@edtnps90>
"Marcin 'Qrczak' Kowalczyk" <······@knm.org.pl> wrote in message 
···················@qrnik.zagroda...
> Espen Vestre <·····@vestre.net> writes:
>
>>> That said, there's probably a reason why I couldn't immediately come
>>> up with an example of a function (as opposed to AND) from my own code
>>> that relies on the evaluation order of arguments.
>>
>> Defaults to keyword arguments are obvious candidates, and I thought I
>> used defaults computed from the obligatory parameters all the time,
>> but I actually only found one example in recent code.
>
> Keyword arguments don't rely on the evaluation order of arguments.
> When keywords arguments are parsed, *all* arguments are already
> evaluated, so it doesn't matter in which order they have been
> evaluated.

That doesn't make any sense.
CL-USER 1 > (defun foo (&key a b)
              (if (< a b) "bar" "baz"))
FOO

CL-USER 2 > (defvar i 0)
I

CL-USER 3 > (foo :a (incf i) :b (incf i))
"bar"

CL-USER 4 > (foo :b (incf i) :a (incf i))
"baz"

It does matter in which order they are evaluated and it is defined to be 
from left to right.

-- 
Coby Beck
(remove #\Space "coby 101 @ bigpond . com")
From: ····@unreal.uncom
Subject: Re: Functions in Lisp
Date: 
Message-ID: <ctipv15adfnaqpct4fp306659f90eenifp@4ax.com>
On Wed, 22 Feb 2006 09:45:36 +0100, Frank Buss <··@frank-buss.de>
wrote:

>What's the advantage with your AND compared to this:
>
>(when (valid-data-p data)
>  (when (update *global-state* data)
>    (notify-users)))

(and
   (valid-data-p data)
   (update *global-state* data)
   (notify-users))
From: Frank Buss
Subject: Re: Functions in Lisp
Date: 
Message-ID: <zp4zydv4x085$.1h8gcaueejmmu$.dlg@40tude.net>
····@unreal.uncom wrote:

> (and
>    (valid-data-p data)
>    (update *global-state* data)
>    (notify-users))

nice, like poor mans exception handling :-)

-- 
Frank Buss, ··@frank-buss.de
http://www.frank-buss.de, http://www.it4-systems.de
From: Thomas A. Russ
Subject: Re: Functions in Lisp
Date: 
Message-ID: <ymi64n7cnh8.fsf@sevak.isi.edu>
"netytan" <·······@gmail.com> writes:

> I personally find it highly unlikely that you, or anyone for that
> matter could provide a good enough reason to use setf in as functions
> parameter and if you can then maybe you shouldn't.

Well, you may disagree with this usage, but I have seen this used for
situations where you have a series of attempts to create something, with
failure being signaled by NIL, and a desire to avoid multiple calls to
an expensive function:

(let ((value nil))
  (cond ((setf value (try-to-make-foo arg1 arg2))
         (do-something-with value))
        ((setf value (try-to-make-bar arg1 arg2))
         (do-something-with value))
        ((setf value (try-to-make-bar arg1 arg2))
         (do-something-with value))))

Actually I think it is more common with an argument to a predicate
function, for example

(let ((value nil))
    (cond ((test-value (setf value (big-hairy-expression arg1 arg2)))
           (compute-with value))
          ((test-value (setf value (big-hairy-expression arg2 arg1)))
           (compute-with value))
          ...))

I find the latter to be preferable to

(let ((value nil))
   (setf value (big-hairy-expression arg1 arg2))
   (if (test-value value)
       (compute-with value)
       (progn
          (setf value (big-hairy-expression arg2 arg1))
          (if (test-value value)
              (compute-with value)
              (progn
                 (setf value ...)
                 ...)))))

and to 

(cond ((test-value (big-hairy-expression arg1 arg2))
           (compute-with (big-hairy-expression arg1 arg2)))
          ((test-value (big-hairy-expression arg2 arg1))
           (compute-with (big-hairy-expression arg2 arg1)))
          ...)

But since this is a style question, you may have a different view.

-- 
Thomas A. Russ,  USC/Information Sciences Institute
From: Rob Warnock
Subject: Re: Functions in Lisp
Date: 
Message-ID: <-JOdnW19DJatAmDeRVn-ig@speakeasy.net>
Thomas A. Russ <···@sevak.isi.edu> wrote:
+---------------
| Well, you may disagree with this usage, but I have seen this used for
| situations where you have a series of attempts to create something, with
| failure being signaled by NIL, and a desire to avoid multiple calls to
| an expensive function:
| 
| (let ((value nil))
|   (cond ((setf value (try-to-make-foo arg1 arg2))
|          (do-something-with value))
|         ((setf value (try-to-make-bar arg1 arg2))
|          (do-something-with value))
|         ((setf value (try-to-make-bar arg1 arg2))
|          (do-something-with value))))
+---------------

By analogy to the WHEN-vs-AND subthread, I'd probably write that
[assuming the 2nd BAR should have been BAZ] this way:  ;-}

    (do-something-with (or (try-to-make-foo arg1 arg2)
			   (try-to-make-bar arg1 arg2)
			   (try-to-make-baz arg1 arg2)
			   (error "Mumble...")))


-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: netytan
Subject: Re: Functions in Lisp
Date: 
Message-ID: <1140700271.116651.193530@e56g2000cwe.googlegroups.com>
Rob Warnock wrote:
> Thomas A. Russ <···@sevak.isi.edu> wrote:
> +---------------
> | Well, you may disagree with this usage, but I have seen this used for
> | situations where you have a series of attempts to create something, with
> | failure being signaled by NIL, and a desire to avoid multiple calls to
> | an expensive function:
> |
> | (let ((value nil))
> |   (cond ((setf value (try-to-make-foo arg1 arg2))
> |          (do-something-with value))
> |         ((setf value (try-to-make-bar arg1 arg2))
> |          (do-something-with value))
> |         ((setf value (try-to-make-bar arg1 arg2))
> |          (do-something-with value))))
> +---------------
>
> By analogy to the WHEN-vs-AND subthread, I'd probably write that
> [assuming the 2nd BAR should have been BAZ] this way:  ;-}
>
>     (do-something-with (or (try-to-make-foo arg1 arg2)
> 			   (try-to-make-bar arg1 arg2)
> 			   (try-to-make-baz arg1 arg2)
> 			   (error "Mumble...")))
>
>
> -Rob

Awesome, a very nice concise way of structuring the problem while
avoiding side effects :).

I posted something to this effect which never appeared but I think you
said it more eloquently. I'm thinking I hit Reply to Author instead of
Reply so hopefully  if Thomas replies it'll re-emerge because I can't
remember exactly what I said :$.

In his examples he uses a predicate function to test the validity of
the expressions value. My first example used an AND, assuming the
expression resulted in nil if invalid, which is the simplest reason for
doing this I believe.

I then gave a very simple high-order function to replace and so the
same structure could be used for any single argument predicate to test
an expression while avoiding re-evaluating it as you would using if.

(defun validp (test value)
  (if (funcall test value) value)) ; Each call to validp serves as a
single expression in a cond.

I have to say that what Rob posted was a perfect example of what I
consider to be good style and it was:

  - Far simpler than using side-effects.
  - Easier to follow in my eyes
  - Removes code duplication :D.


Good work; Take care,

Mark.
From: André Thieme
Subject: Re: Functions in Lisp
Date: 
Message-ID: <1140908615.855763.154760@e56g2000cwe.googlegroups.com>
netytan schrieb:

> Rob Warnock wrote:
> >     (do-something-with (or (try-to-make-foo arg1 arg2)
> > 			   (try-to-make-bar arg1 arg2)
> > 			   (try-to-make-baz arg1 arg2)
> > 			   (error "Mumble...")))
> >
>
> Awesome, a very nice concise way of structuring the problem while
> avoiding side effects :).

Why are there no side effects?
To define the functions try-to-make-foo etc. the author used side
effects [defun].
And one could regard (error "Mumble...") also as a side effect.

What I don't understand: first it seemed to me that you want to avoid
to use the order of evaluation but now you find it awesome. So in what
situations is it okay?


André
--
From: netytan
Subject: Re: Functions in Lisp
Date: 
Message-ID: <1141085694.867018.131220@t39g2000cwt.googlegroups.com>
André Thieme wrote:
> netytan schrieb:
>
> > Rob Warnock wrote:
> > >     (do-something-with (or (try-to-make-foo arg1 arg2)
> > > 			   (try-to-make-bar arg1 arg2)
> > > 			   (try-to-make-baz arg1 arg2)
> > > 			   (error "Mumble...")))
> > >
> >
> > Awesome, a very nice concise way of structuring the problem while
> > avoiding side effects :).
>
> Why are there no side effects?
> To define the functions try-to-make-foo etc. the author used side
> effects [defun].
> And one could regard (error "Mumble...") also as a side effect.
>
> What I don't understand: first it seemed to me that you want to avoid
> to use the order of evaluation but now you find it awesome. So in what
> situations is it okay?
>
>
> André
> --

I wanted to avoid the order of evaluation in functions; which isn't
defined by some Lisp dialects however these are Macros not functions.
In fact every example given here used Macros not functions anyway.

Any I/O is a side-effect but I said to avoid side-effects not remove
them entirely; IO side-effects can't be avoided without considerable
work and there's with little benefit in doing so, what's more important
is avoiding state changes in functional programming. Defining a value
isn't a side-effect but changing that value is :).

Later,

Mark.
From: Pascal Costanza
Subject: Re: Functions in Lisp
Date: 
Message-ID: <462otkF932s9U1@individual.net>
netytan wrote:
> *Shudders*, because the whole idea of functional programming, into
> which Lisp fits nicely is to "avoid side effects at all costs". In fact
> purely functional languages won't let you *cough* Haskell.
> 
> Lisp not being a purely functional language makes it akin to "avoid
> side-effects as much as possible".
> 
> I personally find it highly unlikely that you, or anyone for that
> matter could provide a good enough reason to use setf in as functions
> parameter and if you can then maybe you shouldn't.
> 
> I'm aware this isn't Haskell but that doesn't mean I would rely on the
> order arguments are being evaluated in to propagate some side-effect
> before applying some value to a function - it just strikes me as bad
> style; a shining testament to inelegantly and a very good way of asking
> for trouble.
> 
> I think we're all familiar with the benefits gained by using a
> functional language so a question for you. Why would you needlessly
> push outside of that?

Common Lisp is not a functional language, it's a multi-paradigm 
language. I can write functional, imperative and object-oriented code 
with the ANSI-defined operators, and use paradigms by using additional 
libraries.

If you prefer to program in a functional style, and strive to be as pure 
as possible, go ahead, noone is stopping you from doing that. Feel free 
to ignore the evaluation order that is in fact defined in ANSI Common 
Lisp if it doesn't matter to you. I am happy that it is defined, and I 
feel free to take advantage of it when it seems suitable (which is 
admittedly rare).

> For fun lets assume that you're using some Lisp implementation
> evaluated them in a different order*. If this were the case you my
> friend would probably have a very nice bug, and one that would be
> virtually impossible to track down in a large program. All because you
> were assuming that arguments will be evaluated left-to-right.

You don't have to assume that, it is very clearly specified, so you can 
rely on this.

Maybe you were thinking of Scheme which doesn't have a defined 
evaluation order. There were several long threads in comp.lang.scheme 
about that issue, together with examples given by advocates for both 
alternatives (defined vs. explicitly undefined evaluation order). Google 
for "evaluation order" in comp.lang.scheme


Pascal

-- 
My website: http://p-cos.net
Closer to MOP & ContextL:
http://common-lisp.net/project/closer/
From: netytan
Subject: Re: Functions in Lisp
Date: 
Message-ID: <1140626677.741150.194590@g44g2000cwa.googlegroups.com>
In Common Lisp is specifide but I do a lot of moving around between the
different Lisps and yeah, that is mostly Scheme with some NewLisp
thrown in now for fun. You're probably right about my thinking more to
that end Pascal :).

I've got no problem using other paradigms in Lisps when it seems the
most elegant solution. I haven't found that to be the case yet but
maybe I will?

Lisp just fits so nicely into the functional style it seems to me the
bending over backwards would come when doing things like imperative
programming - I've seen it a few times from people just starting out
with Lisp and I can't say it has the same sense elegence, ya know?

I'll take all your posts under advisment but it seems natural to me to
use Lisp functionally, if only loosely - it's not that I was trying
to push functional programming but I am a fan.

Lisps flexibility is also the reason I fell for it and If I ever need
objects then sure but I prefer to just slide. Feels more natural :).

Take care guys, thanks for the interesting posts!

Mark.
From: leonardo77
Subject: Re: Functions in Lisp
Date: 
Message-ID: <1141148032.914954.52150@v46g2000cwv.googlegroups.com>
> Common Lisp is not a functional language, it's a multi-paradigm
> language. I can write functional, imperative and object-oriented code
> with the ANSI-defined operators, and use paradigms by using additional
> libraries. 

Sounds familiar :-)
From: Didier Verna
Subject: Re: Functions in Lisp
Date: 
Message-ID: <mux1wxvaeyi.fsf@uzeb.lrde.epita.fr>
"netytan" <·······@gmail.com> wrote:

> *Shudders*, because the whole idea of functional programming, into which
> Lisp fits nicely is to "avoid side effects at all costs".

        Yes, but Lisp fits nicely into other paradigms as well. Consider that
Lisp *is* a functionnal language is a mistake IMHO. Lisp is an
ultra-liberal[1] laguage and that's why I like it so much. You want to be
functional ? You can but you don't have to. You want OO ? You have it, but you
don't have to use it if you don't want to. You can even be OO without CLOS. 
You want to type your variables ? You can, but again, you don't have to.


Footnotes: 
[1]  please, no political troll :-)

-- 
Didier Verna, ······@lrde.epita.fr, http://www.lrde.epita.fr/~didier

EPITA / LRDE, 14-16 rue Voltaire   Tel.+33 (1) 44 08 01 85
94276 Le Kremlin-Bic�tre, France   Fax.+33 (1) 53 14 59 22   ······@xemacs.org
From: drewc
Subject: Re: Functions in Lisp
Date: 
Message-ID: <878xs3i2om.fsf@rift.com>
"netytan" <·······@gmail.com> writes:

> *Shudders*, because the whole idea of functional programming, into
> which Lisp fits nicely is to "avoid side effects at all costs". 

Just because Common Lisp supports a functional programming style does
not make it a 'functional' programming language. Have you seen
TAGBODY/GO? That's about as "Considered Harmful" as it gets.

> In fact
> purely functional languages won't let you *cough* Haskell.
> Lisp not being a purely functional language makes it akin to "avoid
> side-effects as much as possible".

I agree that it's a good idea to avoid side effects, but the language
itself does not enfore a functional programming style, nor should it
IMO.

>
> I personally find it highly unlikely that you, or anyone for that
> matter could provide a good enough reason to use setf in as functions
> parameter and if you can then maybe you shouldn't.

I've done it in generated code, and it made the macro itself
significantly simpler. I'm not recommending it as an everyday
technique, but it can have uses.

Default values for keyword or &optional arguments can refer to earlier
parameters, and i've (ab)used this a few times as well, knowing that
the order of evaluation is specified.

>
> I'm aware this isn't Haskell but that doesn't mean I would rely on the
> order arguments are being evaluated in to propagate some side-effect
> before applying some value to a function - it just strikes me as bad
> style; a shining testament to inelegantly and a very good way of asking
> for trouble.

It may be inelegant, but there is no trouble. If an implementation
gets this wrong it's buggy.

>
> I think we're all familiar with the benefits gained by using a
> functional language so a question for you. Why would you needlessly
> push outside of that?


a) Because i'm not using a functional language.
b) Because it can make the solution simpler.
c) Because i prefer pragmatism over purity.
d) Because nobody said anything about 'needless'.

Common Lisp is not a shining example of an elegant langauge. It's the
giant mudball of strength. If a specific left-to-right order of
evaluation were not specified, i would not use code that assumes it
is, obviously. But since i can, and it can make a solution simpler, my
question to you is why not use it?

>
> For fun lets assume that you're using some Lisp implementation
> evaluated them in a different order*. If this were the case you my
> friend would probably have a very nice bug, and one that would be
> virtually impossible to track down in a large program. All because you
> were assuming that arguments will be evaluated left-to-right.

For fun lets assume i'm using a C compiler (C does not specify the
order of evaluation). If this were the case my code would not even
compile :). Lisp has historically had an applicative, left-to-right
evaluation (Scheme OTOH does not define this. The "is scheme lisp?"
argument can be left for another time), and it is specified by ANSI.

I wouldn't take advantage of a feature that is undefined (unless it
happens to be defined in my implementation, and i have no plans for
portability), and i did look this up in the CLHS before ever using it.

>
> With this assumption all happy nestled in your head are you going to
> think "Oh, maybe it's because of this here and I shouldn't be relying
> on this in this way if I can help it" - and you can, so why not?

You seem to assume i can't read the documentation of a language before
i begin writing programs in it. I am fully aware that this is
specified, and was simply correcting your factual error in this
matter. In another language where this is not specified, you are
correct that it would be a bad idea to rely on it. That is simply not
the case in common lisp.

>
> Do as you wish but I won't be doing anything of the sort until I have
> no other choice in the matter, and frankly I doubt that's gonna happen
> :).

If you are conciously avoiding it, then you'll probably never run into
a use case. I prefer to match the paradigm to the problem and not
vice-versa. If CL supports it, and it solves my problem, i'm not going
to avoid it because of some theoretical bias.

> Night everyone; take care drewc,

Cheers :), 

drewc


>
> Mark.
>
> * This is briefly warned against in "Lisp in Small Pieces", a book on
> Lisp internals. As it reads, in some Lisp implementations it can be
> useful for optimization to change this order.
>

-- 
drewc at tech dot coop
From: Thomas A. Russ
Subject: Re: Functions in Lisp
Date: 
Message-ID: <ymi1wxvcmx5.fsf@sevak.isi.edu>
drewc <···························@rift.com> writes:

> "netytan" <·······@gmail.com> writes:
> 
> What you think is not relevant, as the CLHS is the authority on this
> matter.
> 
> 3.1.2.1.2.3 states :
> 
> "The subforms in the cdr of the original form are evaluated in
> left-to-right order in the current lexical and dynamic
> environments. The primary value of each such evaluation becomes an
> argument to the named function; any additional values returned by the
> subforms are discarded."

Now, what is not specified, though, is whether arguments are evaluated
before or after the definition of the operator is resolved to its
function.  Also from 3.1.2.1.2.3:

"Although the order of evaluation of the argument subforms themselves is
 strictly left-to-right, it is not specified whether the definition of
 the operator in a function form is lookup up before the evaluation of
 the argument subforms, after the evaluation of the argument subforms,
 or between the evaluation of any two argument subforms if there is more
 than one such argument subform."

This is then followed by a perverse example where the evaulation of an
argument changes the functional definition of the operator that calls
it.

Although this is sanctioned by the standard, I do wonder a bit how you
can tell whether you are dealing with a function, macro or special form
(which is necessary to know how or even whether to evaluate arguments)
before you actually lookup the function value.  But perhaps this was put
in to allow for interleaving of accesses at low level....



-- 
Thomas A. Russ,  USC/Information Sciences Institute
From: Peter Seibel
Subject: Re: Functions in Lisp
Date: 
Message-ID: <m24q2r6s5a.fsf@gigamonkeys.com>
···@sevak.isi.edu (Thomas A. Russ) writes:

> Although this is sanctioned by the standard, I do wonder a bit how
> you can tell whether you are dealing with a function, macro or
> special form (which is necessary to know how or even whether to
> evaluate arguments) before you actually lookup the function value.
> But perhaps this was put in to allow for interleaving of accesses at
> low level....

Presumably the point is that the compiler, after determining that the
symbol in the CAR of the form does not name a macro or special
operator, is then free to generate code that evaluates the arguments
and then does the function lookup or vice versa.

-Peter

-- 
Peter Seibel           * ·····@gigamonkeys.com
Gigamonkeys Consulting * http://www.gigamonkeys.com/
Practical Common Lisp  * http://www.gigamonkeys.com/book/
From: Larry Clapp
Subject: Re: Functions in Lisp
Date: 
Message-ID: <slrndvnm7h.6c0.larry@theclapp.ddts.net>
On 2006-02-21, Rachel John <·············@gmail.com> wrote:
> Is there any particular order in which functions are executed in Lisp
> or the calling function should be after the function that is called

From http://www.lispworks.com/documentation/HyperSpec/Body/03_ababc.htm:

> A function form is evaluated as follows: 
> 
> The subforms in the cdr of the original form are evaluated in
> left-to-right order in the current lexical and dynamic environments.
> The primary value of each such evaluation becomes an argument to the
> named function; any additional values returned by the subforms are
> discarded.

Does that answer your question, or did you mean something else?

-- Larry
From: Kaz Kylheku
Subject: Re: Functions in Lisp
Date: 
Message-ID: <1140628795.878240.43870@g47g2000cwa.googlegroups.com>
Rachel John wrote:
> Is there any particular order in which functions are executed in Lisp
> or the calling function should be after the function that is called

Lisp is a dynamic language. This means that new functions (and that
includes class methods) can be defined even after the software is
running.

It's possible to write calls to functions which do not exist yet, and
consequently, the order in which your funtions are presented to the
Lisp implementation doesn't matter.

Well, not quote. Many Lisp compilers provide useful warnings when
apparently undefined functions are called. Therefore it's better to
write functions in bottom-up order, and also to arrange for modules to
be loaded in dependency order, if possible. Otherwise, you will get
lots of warnings. Disabling those warnings, if possible, is a bad idea,
because they help catch mistakes, right? Sometimes you mis-spell a
function or variable name.

In situations where you have inevitable mutual recursion, there is
something you can do.

There is no "forward declaration" in Lisp, but you could fake it by
defining an empty function, then defining the function which calls it,
and then redefining the function.

;; forward "declaration" (definition, really)
(defun mutually (x) (declare (ignore x)))

(defun recursive (x) (mutually x))

;; real definition
(defun mutually (x) (recursive x))

By the way, the (declare (ignore x)) is the Common Lisp way of telling
the compiler that a variable is intentionally not accessed. Compilers
won't warn if the variable is not accessed, but often will if it /is/
accessed. (In situations where you don't know whether the variable is
accessed and don't want diagnostics either way, you use (declare
(ignorable x)).
From: Juho Snellman
Subject: Re: Functions in Lisp
Date: 
Message-ID: <slrndvpf95.mpi.jsnell@sbz-30.cs.Helsinki.FI>
Kaz Kylheku <········@gmail.com> wrote:
> Well, not quote. Many Lisp compilers provide useful warnings when
> apparently undefined functions are called. Therefore it's better to
> write functions in bottom-up order, and also to arrange for modules to
> be loaded in dependency order, if possible. Otherwise, you will get
> lots of warnings. Disabling those warnings, if possible, is a bad idea,
> because they help catch mistakes, right? Sometimes you mis-spell a
> function or variable name.

I would hope that most implementations that issue undefined-function
warnings would be smart enough to defer the warnings until the end of
the compilation, and not signal them if the missing functions were
defined in the same compilation unit.

> There is no "forward declaration" in Lisp, but you could fake it by
> defining an empty function, then defining the function which calls it,
> and then redefining the function.

Bad idea. The result of defining the same function multiple times in
the same file is undefined (CLHS 3.2.2.3).

-- 
Juho Snellman
From: Pascal Bourguignon
Subject: Re: Functions in Lisp
Date: 
Message-ID: <873bibteac.fsf@thalassa.informatimago.com>
"Kaz Kylheku" <········@gmail.com> writes:
> There is no "forward declaration" in Lisp, but you could fake it by
> defining an empty function, then defining the function which calls it,
> and then redefining the function.
>
> ;; forward "declaration" (definition, really)
> (defun mutually (x) (declare (ignore x)))

What about a  declaimation:

(DECLAIM (FTYPE (FUNCTION (T) T) recursive))

> (defun recursive (x) (mutually x))
>
> ;; real definition
> (defun mutually (x) (recursive x))

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

Pour moi, la grande question n'a jamais �t�: �Qui suis-je? O� vais-je?� 
comme l'a formul� si adroitement notre ami Pascal, mais plut�t: 
�Comment vais-je m'en tirer?� -- Jean Yanne
From: Rob Warnock
Subject: Re: Functions in Lisp
Date: 
Message-ID: <ZNidnS5IifOVOWDenZ2dnUVZ_sKdnZ2d@speakeasy.net>
Pascal Bourguignon  <······@informatimago.com> wrote:
+---------------
| "Kaz Kylheku" <········@gmail.com> writes:
| > There is no "forward declaration" in Lisp...
| 
| What about a  declaimation:
| (DECLAIM (FTYPE (FUNCTION (T) T) recursive))
+---------------

I've actually used that quite a bit to muffle CMUCL's compiler,
which likes to complain [harmlessly, but noisily] about both
forward references and also functions defined in other files
[that are not block-compiled together]. Since the arg & value
"type-spec"s are optional [see CLHS "System Class FUNCTION"],
you can leave off the full signatures and just supply the names
[which is convenient when you have a lot of them]:

    ;;; Shut up fwd-ref & external warnings:
    (declaim (ftype function mmap dump32 r8 r16 r32 w8 w16 w32
			     memcpy memcmp spin-until-change))


-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Pascal Costanza
Subject: Re: Functions in Lisp
Date: 
Message-ID: <463sdvF990hvU1@individual.net>
Kaz Kylheku wrote:

> In situations where you have inevitable mutual recursion, there is
> something you can do.
> 
> There is no "forward declaration" in Lisp, but you could fake it by
> defining an empty function, then defining the function which calls it,
> and then redefining the function.
> 
> ;; forward "declaration" (definition, really)
> (defun mutually (x) (declare (ignore x)))
> 
> (defun recursive (x) (mutually x))
> 
> ;; real definition
> (defun mutually (x) (recursive x))

This may have "unspecified consequences" due to 3.2.2.3 in the 
HyperSpec: "A call within a file to a named function that is defined in 
the same file refers to that function, unless that function has been 
declared notinline. The consequences are unspecified if functions are 
redefined individually at run time or multiply defined in the same file."

You could declare those functions as notinline, but that's not nice 
because you probably want less function call overhead.

Mutually recursive functions typically have one entry function, right? 
So what's wrong with this? (Apart from the fact that it loops forever, 
that is...)

(defun entry-function (x)
   (labels ((mutually (x) (recursive x))
            (recursive (x) (mutually x)))
     (mutually x)))


Pascal

-- 
My website: http://p-cos.net
Closer to MOP & ContextL:
http://common-lisp.net/project/closer/
From: Förster vom Silberwald
Subject: Re: Functions in Lisp
Date: 
Message-ID: <1140698264.626619.191920@g14g2000cwa.googlegroups.com>
Rachel John wrote:
> Is there any particular order in which functions are executed in Lisp
> or the calling function should be after the function that is called

If not already stated in this thread there has been a lengthy
discussion about this on comp.lang.scheme lately. It could be
interesting for you since the discussion was lead by some very
knowledgeable person in the field.

Schneewittchen