From: pereges
Subject: Question regarding functions
Date: 
Message-ID: <553247c7-4951-44c1-9c4d-a22746d76f0f@g38g2000yqd.googlegroups.com>
Hi I'm working out some examples from my tutorial and I came across
following:

(defun x (x) x)

I tried to run this function on clisp:

[3]> (defun x (x) x)
X
[4]> (x 29)
29

There's another function :

(defun z (z z) z)

I tried to run this function on clisp:

[5]> (defun z (z z) z)
Z
[6]> (z 12 24)
24

I just followed examples given but I don't understand :

a) What are these two functions ?

b) How do they work ?

c) Can someone show more examples on how these two work ?

From: Thomas A. Russ
Subject: Re: Question regarding functions
Date: 
Message-ID: <ymitz5nolr2.fsf@blackcat.isi.edu>
pereges <·······@gmail.com> writes:

> Hi I'm working out some examples from my tutorial and I came across
> following:
> 
> (defun x (x) x)
> 
> I tried to run this function on clisp:
> 
> [3]> (defun x (x) x)
> X
> [4]> (x 29)
> 29

> b) How do they work ?
> 
> c) Can someone show more examples on how these two work ?

Well, I think the main benefit of these particular functions is to
illustrate the separate namespaces for functions and variables.  If this
is a bit confusing, perhaps the first example would make more sense if
written with different names like:

  (defun f (x) x)

Is that clearer to you?

All the function does is return its argument.  It is therefore the same
as the built-in IDENTITY function.


-- 
Thomas A. Russ,  USC/Information Sciences Institute
From: Thomas A. Russ
Subject: Re: Question regarding functions
Date: 
Message-ID: <ymir60rokj8.fsf@blackcat.isi.edu>
pereges <·······@gmail.com> writes:
> There's another function :
> 
> (defun z (z z) z)
> 
> I tried to run this function on clisp:
> 
> [5]> (defun z (z z) z)
> Z
> [6]> (z 12 24)
> 24
> 
> I just followed examples given but I don't understand :

My initial reaction upon seeing this example was that this was not
conforming code.  But I wasn't able to find any section in the HyperSpec
that ruled it out.  (Of course, I must may not have been able to find
it.)  The closest statement was that a lambda list is "a list that
specifies a SET of parameters...", which could be interpreted to require
them to be different -- from the standard mathmetical definition that a
set has no repeated elements.

Some experimentation seemed to indicate that implementations differed a
bit on their treatment of this.  ACL takes the form and compiles it,
warning only that the [first] variable Z is not used.  SBCL signals an
error compiling it, complaining that the variable Z appears more than
once in the lambda list.

So:  Is this legal code?




-- 
Thomas A. Russ,  USC/Information Sciences Institute
From: Pascal J. Bourguignon
Subject: Re: Question regarding functions
Date: 
Message-ID: <8763i3n0d6.fsf@galatea.local>
···@sevak.isi.edu (Thomas A. Russ) writes:

> pereges <·······@gmail.com> writes:
>> There's another function :
>> 
>> (defun z (z z) z)
>> 
>> I tried to run this function on clisp:
>> 
>> [5]> (defun z (z z) z)
>> Z
>> [6]> (z 12 24)
>> 24
>> 
>> I just followed examples given but I don't understand :
>
> My initial reaction upon seeing this example was that this was not
> conforming code.  But I wasn't able to find any section in the HyperSpec
> that ruled it out.  (Of course, I must may not have been able to find
> it.)  The closest statement was that a lambda list is "a list that
> specifies a SET of parameters...", which could be interpreted to require
> them to be different -- from the standard mathmetical definition that a
> set has no repeated elements.
>
> Some experimentation seemed to indicate that implementations differed a
> bit on their treatment of this.  ACL takes the form and compiles it,
> warning only that the [first] variable Z is not used.  SBCL signals an
> error compiling it, complaining that the variable Z appears more than
> once in the lambda list.
>
> So:  Is this legal code?

AFAIK, it is conformant code, with specified behavior: the last
binding is the one that is seen in the body.

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

Notice that in the case of &key arguments, it's the first binding
that's seen in the body.

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

-- 
__Pascal Bourguignon__
From: George Neuner
Subject: Re: Question regarding functions
Date: 
Message-ID: <rregs41u62li7o44qubjthvet4djn8mrsj@4ax.com>
On Sat, 21 Mar 2009 02:14:13 +0100, ···@informatimago.com (Pascal J.
Bourguignon) wrote:

>···@sevak.isi.edu (Thomas A. Russ) writes:
>
>> pereges <·······@gmail.com> writes:
>>> There's another function :
>>> 
>>> (defun z (z z) z)
>>> 
>>> I tried to run this function on clisp:
>>> 
>>> [5]> (defun z (z z) z)
>>> Z
>>> [6]> (z 12 24)
>>> 24
>>> 
>>> I just followed examples given but I don't understand :
>>
>> My initial reaction upon seeing this example was that this was not
>> conforming code.

Ditto.

>>  But I wasn't able to find any section in the HyperSpec
>> that ruled it out.  (Of course, I must may not have been able to find
>> it.)  The closest statement was that a lambda list is "a list that
>> specifies a SET of parameters...", which could be interpreted to require
>> them to be different -- from the standard mathmetical definition that a
>> set has no repeated elements.
>>
>> Some experimentation seemed to indicate that implementations differed a
>> bit on their treatment of this.  ACL takes the form and compiles it,
>> warning only that the [first] variable Z is not used.  SBCL signals an
>> error compiling it, complaining that the variable Z appears more than
>> once in the lambda list.
>>
>> So:  Is this legal code?
>
>AFAIK, it is conformant code, with specified behavior: the last
>binding is the one that is seen in the body.
>
>http://www.lispworks.com/documentation/HyperSpec/Body/03_daa.htm
>
>Notice that in the case of &key arguments, it's the first binding
>that's seen in the body.
>
>http://www.lispworks.com/documentation/HyperSpec/Body/03_dad.htm


The hyperspec specifically states that in the case of duplicate
keyword matches, the leftmost (ie. first) keyword argument is used.
AFAICS there is no corresponding statement concerning the behavior of
duplicate required arguments.

George
From: Pascal J. Bourguignon
Subject: Re: Question regarding functions
Date: 
Message-ID: <87skl3fjeo.fsf@galatea.local>
George Neuner <········@comcast.net> writes:

> On Sat, 21 Mar 2009 02:14:13 +0100, ···@informatimago.com (Pascal J.
> Bourguignon) wrote:
>
>>···@sevak.isi.edu (Thomas A. Russ) writes:
>>
>>> pereges <·······@gmail.com> writes:
>>>> There's another function :
>>>> 
>>>> (defun z (z z) z)
>>>> 
>>>> I tried to run this function on clisp:
>>>> 
>>>> [5]> (defun z (z z) z)
>>>> Z
>>>> [6]> (z 12 24)
>>>> 24
>>>> 
>>>> I just followed examples given but I don't understand :
>>>
>>> My initial reaction upon seeing this example was that this was not
>>> conforming code.
>
> Ditto.
>
>>>  But I wasn't able to find any section in the HyperSpec
>>> that ruled it out.  (Of course, I must may not have been able to find
>>> it.)  The closest statement was that a lambda list is "a list that
>>> specifies a SET of parameters...", which could be interpreted to require
>>> them to be different -- from the standard mathmetical definition that a
>>> set has no repeated elements.
>>>
>>> Some experimentation seemed to indicate that implementations differed a
>>> bit on their treatment of this.  ACL takes the form and compiles it,
>>> warning only that the [first] variable Z is not used.  SBCL signals an
>>> error compiling it, complaining that the variable Z appears more than
>>> once in the lambda list.
>>>
>>> So:  Is this legal code?
>>
>>AFAIK, it is conformant code, with specified behavior: the last
>>binding is the one that is seen in the body.
>>
>>http://www.lispworks.com/documentation/HyperSpec/Body/03_daa.htm
>>
>>Notice that in the case of &key arguments, it's the first binding
>>that's seen in the body.
>>
>>http://www.lispworks.com/documentation/HyperSpec/Body/03_dad.htm
>
>
> The hyperspec specifically states that in the case of duplicate
> keyword matches, the leftmost (ie. first) keyword argument is used.
> AFAICS there is no corresponding statement concerning the behavior of
> duplicate required arguments.

Notice also that for optional and key parameters, they are specified
to be bound from left to right, and visible in subsequent bindings:

http://www.lispworks.com/documentation/HyperSpec/Body/03_da.htm
    
    An init-form can be any form. Whenever any init-form is evaluated
    for any parameter specifier, that form may refer to any parameter
    variable to the left of the specifier in which the init-form
    appears, including any supplied-p-parameter variables, and may
    rely on the fact that no other parameter variable has yet been
    bound (including its own parameter variable).


Since there's no initform for required parameters, we can't conclude
anything, and we must say indeed that they could be bound in any
order.

So I agree that with the above definition for z, 

    (z 12 24) --> 12 ; or
    (z 12 24) --> 24

are both valid.

-- 
__Pascal Bourguignon__
From: Pascal J. Bourguignon
Subject: Re: Question regarding functions
Date: 
Message-ID: <87iqm3n9ac.fsf@galatea.local>
pereges <·······@gmail.com> writes:

> Hi I'm working out some examples from my tutorial and I came across
> following:
>
> (defun x (x) x)
>
> I tried to run this function on clisp:
>
> [3]> (defun x (x) x)
> X
> [4]> (x 29)
> 29
>
> There's another function :
>
> (defun z (z z) z)
>
> I tried to run this function on clisp:
>
> [5]> (defun z (z z) z)
> Z
> [6]> (z 12 24)
> 24
>
> I just followed examples given but I don't understand :
>
> a) What are these two functions ?

X is a function that returns its argument.  It's the function IDENTITY.
Z is a function that returns its second argument.  It's a projection.


> b) How do they work ?

There's not much to explain.  

X takes a argument. It binds it to the parameter X.  It then evaluates
X, the value of which is that bound to the parameter X, and since it's
the last expression of its body, it returns this value, that is, the
value of the argument.  

Z takes two arguments.  It binds the first to the parameter Z. It
binds the second to the parameter Z.  It then evaluates Z, the value
of which is that bound to the parameter Z, and since it's the last
expression of its body, it returns this value, that is, the value of
the second argument.  

See, it's rather silly to explain such a simple thing.



> c) Can someone show more examples on how these two work ?

Basically, defun binds to the function slot of the name of the
function a lambda form:

The semantics of (defun x (x) x)  is mostly:

(setf (symbol-function 'x) (lambda (x) (block x x)))

The semantics of (defun z (z z) z)  is mostly:

(setf (symbol-function 'z) (lambda (z z) (block z z)))



When calling (x 42) and (z 24 42), we may substitute the lambda
expression to get the equivalent lambda forms:

((lambda (x) (block x x)) 42)
((lambda (z z) (block z z)) 24 42)


These are also basically equivalent to:

(let ((x 42))
  (block x
     x))
(let ((z 24)
      (z 42))
  (block z
     z))

Note that the later LET is also basically equivalent to:

(let ((#1=#:G0 24))
  (let ((#2=#:G1 42))
    (let ((z #1#))
      (let ((z #2#))
        (block z
           z)))))

Now, the problem is to explain what (let ((x 42)) ...) means, but the
most basic construct is actually lambda, it means ((lambda (x) ...) 42).
So the above form actually means:

((lambda (#1=#:G0)
     ((lambda (#2=#:G1)
          ((lambda (z)
               ((lambda (z)
                    (block z
                      z))
                #2#))
           #1#)) 
      42))
 24)

Actually this is a little simplier than (defun z (z z) z) since once
put in this lambda-calculus form, you can apply the substitution rules
to see how it works:

((lambda (#1=#:G0)
     ((lambda (#2=#:G1)
          ((lambda (z)
               ((lambda (z)
                    (block z
                      z))
                #2#))
           #1#)) 
      42))
 24)

<=>

     ((lambda (#2=#:G1)
          ((lambda (z)
               ((lambda (z)
                    (block z
                      z))
                #2#))
           24)) 
      42)

<=>

          ((lambda (z)
               ((lambda (z)
                    (block z
                      z))
                42))
           24)) 

<=>                                    (*)

               ((lambda (z)
                    (block z
                      z))
                42))

<=>

               ((lambda (z)
                    (block z
                      z))
                42))

<=>

                      42


The <=> marked with (*) may be hard to understand.  It's because when
lambda introduces a new binding, it should work whatever the binding
is; you can rename the parameter as you want.  So:

          ((lambda (z)
               ((lambda (z)
                    (block z
                      z))
                42))
           24)) 

<=>
          ((lambda (z)
               ((lambda (w)
                    (block z
                      w))
                42))
           24)) 

And since z appears nowhere, when evaluating the lambda that has z as
parameter nothing is substituted, hence 24 disappears.


http://en.wikipedia.org/wiki/Lambda_calculus
http://www.lispworks.com/documentation/HyperSpec/Front/index.htm

-- 
__Pascal Bourguignon__
From: Kaz Kylheku
Subject: Re: Question regarding functions
Date: 
Message-ID: <20090329051455.351@gmail.com>
On 2009-03-20, pereges <·······@gmail.com> wrote:
> Hi I'm working out some examples from my tutorial and I came across
> following:
>
> (defun x (x) x)
>
> I tried to run this function on clisp:
>
> [3]> (defun x (x) x)
> X
> [4]> (x 29)
> 29
>
> There's another function :
>
> (defun z (z z) z)
>
> I tried to run this function on clisp:
>
> [5]> (defun z (z z) z)

This is a stupidity to include in a newbie tutorial. The function's lambda list
is repeating a parameter, which is degenerate syntax.

> Z
> [6]> (z 12 24)
> 24

Unfortunately, I in five minutes of searching, I haven't been able to confirm
from the Common Lisp HyperSpec that the above behavior is required when a
parameter name is repeated.

That doesn't mean the behavior /isn't/ defined. But maybe writing such things
is not such a hot idea.

Section 3.1.1 says 

``Bindings in an environment are partitioned into namespaces. A single name can
simultaneously have more than one associated binding per environment, but can
have only one associated binding per namespace.''

But that doesn't mean that repeated names in a binding construct are not
allowed; just that maybe only one of them can ``win'' the ambiguity.

We've had past discussions about this and the concensus, IIRC, was that it's
not specified.

So the best advice is: use unique names in a binding construct: do not repeat a
symbol in a LET, or a function lambda list, etc. Do not write things like
(defun z (z z) z).  If your tutorial encourages such use, throw the tutorial
out.  There is enough learning material for Lisp that you don't have to stick
with tutorials that teach unspecified, pathological constructs.

> I just followed examples given but I don't understand :
>
> a) What are these two functions ?

That is a very open-ended question.

> b) How do they work ?

The most detailed answers would be this:

How a compound form is evaluated:

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

How a compound form is evaluated which is a function call:

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

How an expression which is a symbol is evaluated, i.e. the last x
in (defun x (x) x):

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

How defun works:

  http://www.lispworks.com/documentation/HyperSpec/Body/m_defun.htm
From: ·····@theclapp.org
Subject: Re: Question regarding functions
Date: 
Message-ID: <254267b9-28dd-4eb4-ae25-53eafe18349a@f19g2000yqh.googlegroups.com>
On Mar 20, 5:34 pm, pereges <·······@gmail.com> wrote:
> Hi I'm working out some examples from my tutorial and I came across
> following:
>
> (defun x (x) x)
[snip]

Does your tutorial discuss Common Lisp or Scheme?
From: Pascal J. Bourguignon
Subject: Re: Question regarding functions
Date: 
Message-ID: <87zlfbg958.fsf@galatea.local>
·····@theclapp.org writes:

> On Mar 20, 5:34�pm, pereges <·······@gmail.com> wrote:
>> Hi I'm working out some examples from my tutorial and I came across
>> following:
>>
>> (defun x (x) x)
> [snip]
>
> Does your tutorial discuss Common Lisp or Scheme?

In scheme it would be (define (x x) x) or (define x (lambda (x) x)).

-- 
__Pascal Bourguignon__