From: David Bakhash
Subject: what *should* happen here...
Date: 
Message-ID: <cxjd873mtif.fsf@engc.bu.edu>
hey,

So I have a package.  Call it `pk'.  In package pk I defvar a variable 
called *var* which is simply a list of objects, say of length 100.

A function in pk called `func' uses the *var*.

Now, I'm at the Lisp prompt, and I do go to my package `pk'

USER: (in-package pk)

and now I'm there.  I want to call func, but I want func to operate on 
a truncated version of *var*.  Is this valid?

PK: (let ((*var* (loop for i below 10 collect (nth i *var*))))
      (func))

i.e. will that do the right thing?  by "do the right thing" I mean:

	1) will the value of *var* be no more than the first 10
	   elements of the original value of *var* throughout the call 
	   of `func'?
	2) will the value of *var* be restored to its original value
	   after this let finishes?

lastly, I just wanted to know if there are any subtlties that might be 
useful to know about here, e.g. regarding packages, exported
variables, etc.

thanks,
dave

From: Tim Bradshaw
Subject: Re: what *should* happen here...
Date: 
Message-ID: <ey3u30ftrcl.fsf@todday.aiai.ed.ac.uk>
* David Bakhash wrote:
> PK: (let ((*var* (loop for i below 10 collect (nth i *var*))))
>       (func))

> i.e. will that do the right thing?  by "do the right thing" I mean:

> 	1) will the value of *var* be no more than the first 10
> 	   elements of the original value of *var* throughout the call 
> 	   of `func'?
> 	2) will the value of *var* be restored to its original value
> 	   after this let finishes?

Yes in both cases.
From: Barry Margolin
Subject: Re: what *should* happen here...
Date: 
Message-ID: <VX%%1.17$KS2.359595@burlma1-snr1.gtei.net>
In article <···············@engc.bu.edu>, David Bakhash  <·····@bu.edu> wrote:
>lastly, I just wanted to know if there are any subtlties that might be 
>useful to know about here, e.g. regarding packages, exported
>variables, etc.

The package system is completely irrelevant to what you wrote.  Function
and variable bindings don't live in packages.  Those are attributes of
symbols, which exist mostly independently of the package system.  Packages
simply map symbol names to symbols -- they primarily affect input/output.

-- 
Barry Margolin, ······@bbnplanet.com
GTE Internetworking, Powered by BBN, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Don't bother cc'ing followups to me.
From: Marco Antoniotti
Subject: Re: what *should* happen here...
Date: 
Message-ID: <lwww5buwds.fsf@copernico.parades.rm.cnr.it>
Barry Margolin <······@bbnplanet.com> writes:

> In article <···············@engc.bu.edu>, David Bakhash  <·····@bu.edu> wrote:
> >lastly, I just wanted to know if there are any subtlties that might be 
> >useful to know about here, e.g. regarding packages, exported
> >variables, etc.
> 
> The package system is completely irrelevant to what you wrote.  Function
> and variable bindings don't live in packages.  Those are attributes of
> symbols, which exist mostly independently of the package system.  Packages
> simply map symbol names to symbols -- they primarily affect input/output.
> 

Good point.  Now I have a question.

Can you have a symbol with two 'typographical' names?  I.e. can you
have two packages map two 'names' to the same (i.e. #'eq) symbol?

Cheers


-- 
Marco Antoniotti ===========================================
PARADES, Via San Pantaleo 66, I-00186 Rome, ITALY
tel. +39 - (0)6 - 68 10 03 16, fax. +39 - (0)6 - 68 80 79 26
http://www.parades.rm.cnr.it
From: Barry Margolin
Subject: Re: what *should* happen here...
Date: 
Message-ID: <SN302.42$KS2.474771@burlma1-snr1.gtei.net>
In article <··············@copernico.parades.rm.cnr.it>,
Marco Antoniotti  <·······@copernico.parades.rm.cnr.it> wrote:
>Can you have a symbol with two 'typographical' names?  I.e. can you
>have two packages map two 'names' to the same (i.e. #'eq) symbol?

I.e. could it be possible for (eq 'a::foo 'b::bar) to be true?  No.  The
name of a symbol is an intrinsic, unchangeable attribute of the symbol
itself, and when you intern a symbol in a package it creates a mapping of
that name to the symbol.

-- 
Barry Margolin, ······@bbnplanet.com
GTE Internetworking, Powered by BBN, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Don't bother cc'ing followups to me.
From: Marco Antoniotti
Subject: Re: what *should* happen here...
Date: 
Message-ID: <lwhfweo4dy.fsf@copernico.parades.rm.cnr.it>
Barry Margolin <······@bbnplanet.com> writes:

> In article <··············@copernico.parades.rm.cnr.it>,
> Marco Antoniotti  <·······@copernico.parades.rm.cnr.it> wrote:
> >Can you have a symbol with two 'typographical' names?  I.e. can you
> >have two packages map two 'names' to the same (i.e. #'eq) symbol?
> 
> I.e. could it be possible for (eq 'a::foo 'b::bar) to be true?  No.  The
> name of a symbol is an intrinsic, unchangeable attribute of the symbol
> itself, and when you intern a symbol in a package it creates a mapping of
> that name to the symbol.
> 

Therefore you admit that when you speak of a 'name' the symbol
associated to it is uniquely identified. Therefore, since 'variables
bindings' in CL are mappings from 'symbols' to 'values', by
transitivity, they are also mappings from 'names' (typographical
entities) to 'values'. The same goes - with a useful twist - for
'functions'.  If we are allowed to speak about 'variables' (and
'functions') in lieu of 'variable bindings' and 'function bindings'
then we can make the extra step and say that 'names' are the right
handle to manipulate values (and functions).

Maybe we cannot, but it sure is very confortable to do so.

Cheers

-- 
Marco Antoniotti ===========================================
PARADES, Via San Pantaleo 66, I-00186 Rome, ITALY
tel. +39 - (0)6 - 68 10 03 16, fax. +39 - (0)6 - 68 80 79 26
http://www.parades.rm.cnr.it
From: Barry Margolin
Subject: Re: what *should* happen here...
Date: 
Message-ID: <Wbl02.58$KS2.818978@burlma1-snr1.gtei.net>
In article <··············@copernico.parades.rm.cnr.it>,
Marco Antoniotti  <·······@copernico.parades.rm.cnr.it> wrote:
>
>Barry Margolin <······@bbnplanet.com> writes:
>
>> In article <··············@copernico.parades.rm.cnr.it>,
>> Marco Antoniotti  <·······@copernico.parades.rm.cnr.it> wrote:
>> >Can you have a symbol with two 'typographical' names?  I.e. can you
>> >have two packages map two 'names' to the same (i.e. #'eq) symbol?
>> 
>> I.e. could it be possible for (eq 'a::foo 'b::bar) to be true?  No.  The
>> name of a symbol is an intrinsic, unchangeable attribute of the symbol
>> itself, and when you intern a symbol in a package it creates a mapping of
>> that name to the symbol.
>> 
>
>Therefore you admit that when you speak of a 'name' the symbol
>associated to it is uniquely identified. Therefore, since 'variables
>bindings' in CL are mappings from 'symbols' to 'values', by
>transitivity, they are also mappings from 'names' (typographical
>entities) to 'values'. The same goes - with a useful twist - for
>'functions'.  If we are allowed to speak about 'variables' (and
>'functions') in lieu of 'variable bindings' and 'function bindings'
>then we can make the extra step and say that 'names' are the right
>handle to manipulate values (and functions).

I'm not sure what you're getting at.  You can have A::FOO and B::FOO that
are distinct.  Each of them has the name "FOO", but they're listed in
different packages.  So the name "FOO" does not uniquely identify a symbol;
it's a one-to-many relationship, and packages resolve the ambiguity.

If you're including the package prefix as part of the name you refer to,
then it is unique.  In this case it's a many-to-one relationship: A::FOO
and C::FOO could both refer to the same symbol, whild B::FOO could be
different.  What I was pointing out in my earlier post was that C::BAR (and
any name where the part after the :: isn't "FOO") *must* be different.

The reason it's important to remember this distinction about packages is
because many Lisp programmers have incorrect preconceptions about the
package system.  Consider what happens if you want to provide your own
arithmetic implementation, so you shadow the symbols +, *, etc. in your
package.  Although you only intended to replace the functions by these
names, because packages work on symbols rather than bindings, you also end
up shadowing the top-level variables with the same names (the ones used by
the Read-Eval-Print loop to record recent input and output).

-- 
Barry Margolin, ······@bbnplanet.com
GTE Internetworking, Powered by BBN, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Don't bother cc'ing followups to me.
From: Marco Antoniotti
Subject: Re: what *should* happen here...
Date: 
Message-ID: <lwpvb0vin6.fsf@copernico.parades.rm.cnr.it>
Barry Margolin <······@bbnplanet.com> writes:

> In article <··············@copernico.parades.rm.cnr.it>,
> Marco Antoniotti  <·······@copernico.parades.rm.cnr.it> wrote:
> >
> >Barry Margolin <······@bbnplanet.com> writes:
> >
> >> In article <··············@copernico.parades.rm.cnr.it>,
> >> Marco Antoniotti  <·······@copernico.parades.rm.cnr.it> wrote:
> >> >Can you have a symbol with two 'typographical' names?  I.e. can you
> >> >have two packages map two 'names' to the same (i.e. #'eq) symbol?
> >> 
> >> I.e. could it be possible for (eq 'a::foo 'b::bar) to be true?  No.  The
> >> name of a symbol is an intrinsic, unchangeable attribute of the symbol
> >> itself, and when you intern a symbol in a package it creates a mapping of
> >> that name to the symbol.
> >> 
> >
> >Therefore you admit that when you speak of a 'name' the symbol
> >associated to it is uniquely identified. Therefore, since 'variables
> >bindings' in CL are mappings from 'symbols' to 'values', by
> >transitivity, they are also mappings from 'names' (typographical
> >entities) to 'values'. The same goes - with a useful twist - for
> >'functions'.  If we are allowed to speak about 'variables' (and
> >'functions') in lieu of 'variable bindings' and 'function bindings'
> >then we can make the extra step and say that 'names' are the right
> >handle to manipulate values (and functions).
> 
> I'm not sure what you're getting at.  You can have A::FOO and B::FOO that
> are distinct.  Each of them has the name "FOO", but they're listed in
> different packages.  So the name "FOO" does not uniquely identify a symbol;
> it's a one-to-many relationship, and packages resolve the ambiguity.
> 
> If you're including the package prefix as part of the name you refer to,
> then it is unique.  In this case it's a many-to-one relationship: A::FOO
> and C::FOO could both refer to the same symbol, whild B::FOO could be
> different.  What I was pointing out in my earlier post was that C::BAR (and
> any name where the part after the :: isn't "FOO") *must* be
> different.
> 
> The reason it's important to remember this distinction about packages is
> because many Lisp programmers have incorrect preconceptions about the
> package system.  Consider what happens if you want to provide your own
> arithmetic implementation, so you shadow the symbols +, *, etc. in your
> package.  Although you only intended to replace the functions by these
> names, because packages work on symbols rather than bindings, you also end
> up shadowing the top-level variables with the same names (the ones used by
> the Read-Eval-Print loop to record recent input and output).
> 

I understand this very well and I see your point.  We might have a
terminology problem. Still I believe that insisting on the distinction
between 'names' and 'symbols', while explaining basic CL programming
techniques, confuses the issues more than it clarifies them.
Insisting instead on the fact that a 'symbol' is fully qualified only
when its package is spelled out has, IMHO, more pedagogical value. The
distinction between a variable and a function is an orthogonal issue
in explaining the language.

I had a day long email discussion with Tim Bradshaw on this subject
and we drifted on the question:

	"When is a symbol GCable?"

Let's see how much debate we generate. :)

Cheers

-- 
Marco Antoniotti ===========================================
PARADES, Via San Pantaleo 66, I-00186 Rome, ITALY
tel. +39 - (0)6 - 68 10 03 16, fax. +39 - (0)6 - 68 80 79 26
http://www.parades.rm.cnr.it
From: Barry Margolin
Subject: Re: what *should* happen here...
Date: 
Message-ID: <2bI02.122$KS2.1395934@burlma1-snr1.gtei.net>
In article <··············@copernico.parades.rm.cnr.it>,
Marco Antoniotti  <·······@copernico.parades.rm.cnr.it> wrote:
>I understand this very well and I see your point.  We might have a
>terminology problem. Still I believe that insisting on the distinction
>between 'names' and 'symbols', while explaining basic CL programming
>techniques, confuses the issues more than it clarifies them.

I agree.  Most of the time, the package system can be completely ignored
when discussing basic CL stuff.  But the original post in this thread
specifically asked how packages impacted his code, and a proper
understanding of these relationships is necessary to understand why it
doesn't have much impact at all (he was actually asking about those "basic
CL programming techniques").

-- 
Barry Margolin, ······@bbnplanet.com
GTE Internetworking, Powered by BBN, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Don't bother cc'ing followups to me.
From: Sunil Mishra
Subject: Re: what *should* happen here...
Date: 
Message-ID: <efyr9vj2muf.fsf@hustle.cc.gatech.edu>
David Bakhash <·····@bu.edu> writes:

Well, others have answered your question, but a little detail:
> PK: (let ((*var* (loop for i below 10 collect (nth i *var*))))
>       (func))
> 

There is no reason to use this O(n^2) procedure. Try:

(let ((*var* (subseq *var* 0 10)))
  (func))

Sunil
From: David Bakhash
Subject: Re: what *should* happen here...
Date: 
Message-ID: <cxjk91bp1zh.fsf@engc.bu.edu>
Sunil Mishra <·······@hustle.cc.gatech.edu> writes:

> David Bakhash <·····@bu.edu> writes:
> 
> Well, others have answered your question, but a little detail:
> > PK: (let ((*var* (loop for i below 10 collect (nth i *var*))))
> >       (func))
> > 
> 
> There is no reason to use this O(n^2) procedure. Try:
> 
> (let ((*var* (subseq *var* 0 10)))
>   (func))

cool! forgot about subseq (I used it at some point).  But how is the
loop way O(n^2)?  Looks like it's O(n) to me.

dave
From: Steve Gonedes
Subject: Re: what *should* happen here...
Date: 
Message-ID: <m24ssfnmkg.fsf@KludgeUnix.com>
David Bakhash <·····@bu.edu> writes:

< Sunil Mishra <·······@hustle.cc.gatech.edu> writes:
< 
< > David Bakhash <·····@bu.edu> writes:
< > 
< > Well, others have answered your question, but a little detail:
< > > PK: (let ((*var* (loop for i below 10 collect (nth i *var*))))
< > >       (func))
< > > 
< > 
< > There is no reason to use this O(n^2) procedure. Try:
< > 
< > (let ((*var* (subseq *var* 0 10)))
< >   (func))
< 
< cool! forgot about subseq (I used it at some point).  But how is the
< loop way O(n^2)?  Looks like it's O(n) to me.

Maybe with strings?

I'm not very knowledgable with the big-O notation, so I might be
wrong. I think the ^2, is because for each `i' below 10, you must
traverse the list `i' places. I would think O(i^2) in this case would
be better - but this is probably not standard big-O notation.
From: Lyman S. Taylor
Subject: Re: what *should* happen here...
Date: 
Message-ID: <71qmqb$hl9@pravda.cc.gatech.edu>
In article <···············@engc.bu.edu>, David Bakhash  <·····@bu.edu> wrote:
>Sunil Mishra <·······@hustle.cc.gatech.edu> writes:
>
>> David Bakhash <·····@bu.edu> writes:
>> 
>> Well, others have answered your question, but a little detail:
>> > PK: (let ((*var* (loop for i below 10 collect (nth i *var*))))
>> >       (func))
...
>
>cool! forgot about subseq (I used it at some point).  But how is the
>loop way O(n^2)?  Looks like it's O(n) to me.

   Nonformal illustration....

   Where  N is index you are staying below of. 
   Each call to NTH takes on average  n/2 time.  You do this N times 
   that (n^2)/2 (i.e.  O(n^2) ).

   not a big deal in this case since the index is fixed at 10. 

   Purely in the context of the index fixed at 10 the above is O(1)  
   It doesn't matter how long the *var* list is.   However, you are
   "wasting time" passing over the prefix of *var* over and over again. 
   The subsequence call passing over once collecting result as it goes.

   Lists are not arrays  so  (nth i list ) is not like doing  (aref arr i).



-- 
					
Lyman S. Taylor          "The Borg --  party poopers of the Galaxy. "
(·····@cc.gatech.edu)                 EMH Doctor  Star Trek Voyager. 
From: Lyman S. Taylor
Subject: Re: what *should* happen here...
Date: 
Message-ID: <71quto$i4j@pravda.cc.gatech.edu>
In article <··········@pravda.cc.gatech.edu>,
Lyman S. Taylor <·····@cc.gatech.edu> wrote:
...
>>> David Bakhash <·····@bu.edu> writes:
...
>>> > PK: (let ((*var* (loop for i below 10 collect (nth i *var*))))
...
>   The subsequence call passing over once collecting result as it goes.

   SEBSEQ passes over the list once while collecting the result. Yeah, that's 
   marginally better. :-)
   

 P.S. 
      Collecting with the loop would go like:

              (loop   for i below 10 
                      for e  in   *var*
                      collect e )

     Which, like subseq, will abbreviate this prefix if *var* is shorter
     than 10 ( unless you wanted the result padded out to 10 elements 
     long with NILs).  The following will pad. 

             (loop   for i below 10 
                     for e = *var*  then (rest e )
                     collect (first e ))

     This second clearly illustrates that this dependent up the i 
     index for running time. (so does the first, but it that's
     more of an upper bound). 

-- 
					
Lyman S. Taylor          "The Borg --  party poopers of the Galaxy. "
(·····@cc.gatech.edu)                 EMH Doctor  Star Trek Voyager. 
From: Tim Bradshaw
Subject: Re: what *should* happen here...
Date: 
Message-ID: <ey3r9vitaad.fsf@todday.aiai.ed.ac.uk>
* David Bakhash wrote:
>> > PK: (let ((*var* (loop for i below 10 collect (nth i *var*))))
>> >       (func))
>> > 

> cool! forgot about subseq (I used it at some point).  But how is the
> loop way O(n^2)?  Looks like it's O(n) to me.

It's n^2 because each call to NTH takes time I, and there are N
and I is, on average N/2.

You could do it in O(N) with LOOP using

	(loop for e in *var*
	      repeat 10
	      collect e)

--tim