Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #70985 > unrolled thread

Re: Pass variable by reference

Started byNed Batchelder <ned@nedbatchelder.com>
First post2014-05-06 16:31 -0400
Last post2014-05-07 01:14 +0000
Articles 20 on this page of 67 — 16 participants

Back to article view | Back to comp.lang.python

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Re: Pass variable by reference Ned Batchelder <ned@nedbatchelder.com> - 2014-05-06 16:31 -0400
    Re: Pass variable by reference Mark H Harris <harrismh777@gmail.com> - 2014-05-06 16:00 -0500
      Re: Pass variable by reference Ned Batchelder <ned@nedbatchelder.com> - 2014-05-06 17:27 -0400
      Re: Pass variable by reference Chris Angelico <rosuav@gmail.com> - 2014-05-07 09:46 +1000
        Re: Pass variable by reference Rustom Mody <rustompmody@gmail.com> - 2014-05-06 19:18 -0700
          Re: Pass variable by reference Chris Angelico <rosuav@gmail.com> - 2014-05-07 12:39 +1000
            Re: Pass variable by reference Rustom Mody <rustompmody@gmail.com> - 2014-05-06 19:54 -0700
              Re: Pass variable by reference Steven D'Aprano <steve@pearwood.info> - 2014-05-07 04:59 +0000
        Re: Pass variable by reference Mark H Harris <harrismh777@gmail.com> - 2014-05-07 13:11 -0500
          Re: Pass variable by reference Marko Rauhamaa <marko@pacujo.net> - 2014-05-08 00:22 +0300
            Values and objects [was Re: Pass variable by reference] Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-05-08 01:08 +0000
              Re: Values and objects [was Re: Pass variable by reference] Mark H Harris <harrismh777@gmail.com> - 2014-05-09 16:56 -0500
                Re: Values and objects Marko Rauhamaa <marko@pacujo.net> - 2014-05-10 01:34 +0300
                  Re: Values and objects Ben Finney <ben@benfinney.id.au> - 2014-05-10 10:24 +1000
                  Re: Values and objects Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-05-10 01:01 +0000
                    Re: Values and objects Rustom Mody <rustompmody@gmail.com> - 2014-05-09 19:19 -0700
                      Re: Values and objects Chris Angelico <rosuav@gmail.com> - 2014-05-10 12:33 +1000
                        Re: Values and objects Rustom Mody <rustompmody@gmail.com> - 2014-05-09 20:05 -0700
                          Re: Values and objects Mark H Harris <harrismh777@gmail.com> - 2014-05-09 23:15 -0500
                        Re: Values and objects Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-05-10 06:15 +0000
                          Re: Values and objects Chris Angelico <rosuav@gmail.com> - 2014-05-10 17:21 +1000
                            Re: Values and objects Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-05-10 09:09 +0000
                              Re: Values and objects Chris Angelico <rosuav@gmail.com> - 2014-05-10 19:32 +1000
                              Re: Values and objects Ethan Furman <ethan@stoneleaf.us> - 2014-05-10 12:10 -0700
                              Re: Values and objects MRAB <python@mrabarnett.plus.com> - 2014-05-10 20:22 +0100
                              Re: Values and objects Ethan Furman <ethan@stoneleaf.us> - 2014-05-10 12:28 -0700
                              Re: Values and objects Terry Reedy <tjreedy@udel.edu> - 2014-05-10 16:16 -0400
                              Re: Values and objects Terry Reedy <tjreedy@udel.edu> - 2014-05-10 16:24 -0400
                              Re: Values and objects Devin Jeanpierre <jeanpierreda@gmail.com> - 2014-05-10 14:03 -0700
                                Re: Values and objects Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-05-11 03:17 +0000
                                  Re: Values and objects Chris Angelico <rosuav@gmail.com> - 2014-05-11 13:30 +1000
                                    Re: Values and objects Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-05-11 05:11 +0000
                                      Re: Values and objects Chris Angelico <rosuav@gmail.com> - 2014-05-11 15:22 +1000
                                        Re: Values and objects Rustom Mody <rustompmody@gmail.com> - 2014-05-10 22:31 -0700
                                          Re: Values and objects Marko Rauhamaa <marko@pacujo.net> - 2014-05-11 09:21 +0300
                                            Re: Values and objects Rustom Mody <rustompmody@gmail.com> - 2014-05-10 23:48 -0700
                                              Re: Values and objects Marko Rauhamaa <marko@pacujo.net> - 2014-05-11 18:10 +0300
                                            Re: Values and objects Jussi Piitulainen <jpiitula@ling.helsinki.fi> - 2014-05-11 11:26 +0300
                                              Re: Values and objects Rustom Mody <rustompmody@gmail.com> - 2014-05-11 01:48 -0700
                                                Re: Values and objects Jussi Piitulainen <jpiitula@ling.helsinki.fi> - 2014-05-11 15:22 +0300
                                                  Re: Values and objects Marko Rauhamaa <marko@pacujo.net> - 2014-05-11 18:46 +0300
                                                    Re: Values and objects Marko Rauhamaa <marko@pacujo.net> - 2014-05-11 22:56 +0300
                                              Re: Values and objects Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-05-11 12:51 +0000
                                                Re: Values and objects Rustom Mody <rustompmody@gmail.com> - 2014-05-11 07:12 -0700
                                      Re: Values and objects Ethan Furman <ethan@stoneleaf.us> - 2014-05-10 22:42 -0700
                                        Re: Values and objects Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-05-11 06:40 +0000
                              Re: Values and objects Chris Angelico <rosuav@gmail.com> - 2014-05-11 09:18 +1000
                                Re: Values and objects Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-05-11 03:11 +0000
                                  Re: Values and objects Rotwang <sg552@hotmail.co.uk> - 2014-05-11 14:46 +0100
                                    Re: Values and objects Ned Batchelder <ned@nedbatchelder.com> - 2014-05-11 14:40 -0400
                                      Re: Values and objects Rotwang <sg552@hotmail.co.uk> - 2014-05-12 00:06 +0100
                              Re: Values and objects Ethan Furman <ethan@stoneleaf.us> - 2014-05-10 18:28 -0700
                                Re: Values and objects Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-05-11 07:24 +0000
                              Re: Values and objects Chris Angelico <rosuav@gmail.com> - 2014-05-11 11:59 +1000
                                Re: Values and objects Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-05-11 07:29 +0000
                              Re: Values and objects Ethan Furman <ethan@stoneleaf.us> - 2014-05-10 21:46 -0700
                              Re: [Python-Dev] Values and objects Chris Angelico <rosuav@gmail.com> - 2014-05-11 16:08 +1000
                              Re: Values and objects albert@spenarnc.xs4all.nl (Albert van der Horst) - 2014-05-17 14:26 +0000
                  Re: Values and objects Chris Angelico <rosuav@gmail.com> - 2014-05-10 11:58 +1000
                    Re: Values and objects Marko Rauhamaa <marko@pacujo.net> - 2014-05-10 10:57 +0300
                      Re: Values and objects Jussi Piitulainen <jpiitula@ling.helsinki.fi> - 2014-05-10 11:06 +0300
                  Re: Values and objects Dennis Lee Bieber <wlfraed@ix.netcom.com> - 2014-05-10 12:07 -0400
          Re: Pass variable by reference Chris Angelico <rosuav@gmail.com> - 2014-05-08 11:31 +1000
            Re: Pass variable by reference Mark H Harris <harrismh777@gmail.com> - 2014-05-09 17:30 -0500
              Abstractions [was Re: Pass variable by reference] Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-05-10 00:58 +0000
                Re: Abstractions [was Re: Pass variable by reference] Mark H Harris <harrismh777@gmail.com> - 2014-05-09 21:17 -0500
    Re: Pass variable by reference Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-05-07 01:14 +0000

Page 2 of 4 — ← Prev page 1 [2] 3 4  Next page →


#71228 — Re: Values and objects

FromChris Angelico <rosuav@gmail.com>
Date2014-05-10 17:21 +1000
SubjectRe: Values and objects
Message-ID<mailman.9843.1399706518.18130.python-list@python.org>
In reply to#71224
On Sat, May 10, 2014 at 4:15 PM, Steven D'Aprano
<steve+comp.lang.python@pearwood.info> wrote:
> On Sat, 10 May 2014 12:33:28 +1000, Chris Angelico wrote:
>> 1) Passing them as parameters. You can pass a pointer to a variable,
>> which is effectively the same as passing a variable to a function.
>
> No it is not. It is nothing like passing a variable to a function. You
> are passing a pointer, which is itself a value. True, it is a value which
> you, the author, gives meaning as a pointer to a variable, but that need
> not be the case. It might be a pointer to a part of an array, or a
> record, or to some random address in memory, or a dangling pointer. C
> allows you to perform arithmetic on pointers, which means you can
> construct pointers to nothing in particular.

I think at this point it's arguable, in that you can get so close to
"passing a variable to a function" that it doesn't really matter about
the distinction. But as I explained further down, it really just shows
that "patch of memory" can be passed around, and that a variable can
be backed by such a patch of memory.

> Rather than *creating* patches of memory, malloc merely allocates it from
> pre-existing memory.

I disagree. On a modern system with memory management, malloc can grab
memory from the system, thus making it available to your process.
Sure, physical memory will normally have to have been installed in the
system, but conceptually you could have a malloc function that
actually freezes the program, asks the user to build a new computer
and turn it on, connects to a new service on that computer, and
allocates memory from there. As far as your program's concerned,
malloc actually does (attempt to) give you more room than you had.

> Python variables aren't first-class either, but in fact we can get a bit
> closer to first-class than either C or Pascal.
>
> Creating new variables is trivial. Since they don't need to be declared,
> you create a new variable just by assigning to it:
>
> try:
>     spam
> except NameError:
>     spam = 23

No no no, this is really creating them at compile time. If you do this
inside a function, the name has to be created as a local name before
the function begins execution.

> There are at least two other ways:
>
> globals()['spam'] = 23
> exec('spam = 23')

With exec, you can do anything "at run time". Does that mean that, in
languages with an exec action, absolutely everything is first-class?
I'm not sure that that counts. Maybe I'm wrong.

Subscript-assigning to globals() is actually creating new
(module-level) variables, though. And if Python allowed you to assign
to locals() inside a function, then I would accept that local function
variables can be created and destroyed at run time, but you can't, so
local variables aren't first-class.

ChrisA

[toc] | [prev] | [next] | [standalone]


#71240 — Re: Values and objects

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2014-05-10 09:09 +0000
SubjectRe: Values and objects
Message-ID<536decca$0$29980$c3e8da3$5496439d@news.astraweb.com>
In reply to#71228
On Sat, 10 May 2014 17:21:56 +1000, Chris Angelico wrote:

> On Sat, May 10, 2014 at 4:15 PM, Steven D'Aprano
> <steve+comp.lang.python@pearwood.info> wrote:
>> On Sat, 10 May 2014 12:33:28 +1000, Chris Angelico wrote:
>>> 1) Passing them as parameters. You can pass a pointer to a variable,
>>> which is effectively the same as passing a variable to a function.
>>
>> No it is not. It is nothing like passing a variable to a function. You
>> are passing a pointer, which is itself a value. True, it is a value
>> which you, the author, gives meaning as a pointer to a variable, but
>> that need not be the case. It might be a pointer to a part of an array,
>> or a record, or to some random address in memory, or a dangling
>> pointer. C allows you to perform arithmetic on pointers, which means
>> you can construct pointers to nothing in particular.
> 
> I think at this point it's arguable, in that you can get so close to
> "passing a variable to a function" that it doesn't really matter about
> the distinction. But as I explained further down, it really just shows
> that "patch of memory" can be passed around, and that a variable can be
> backed by such a patch of memory.

No offence Chris, but I think this demonstrates that learning C causes 
brain damage and prevents clear logical thinking :-P

You're not passing a variable to a function. You're passing a pointer, 
which is itself a first-class value. It could be a pointer to ANYTHING, 
or NOTHING at all -- C doesn't even promise to ensure that it is a valid 
pointer, although more modern languages may. There's certainly no 
guarantee that it's a pointer to a variable. And you cannot create new 
variables -- C only allows variables to be created at compile time.

The question is not, "Can I implement some aspects of first-class 
behaviour for variables by hand?" The question is, "Are variables treated 
as first class values in C?"

If you asked, "Does Pascal have an exponentiation or power operator?", 
and I answered "Sure it does! If you want to calculate x squared, you 
just write x*x, if you want x cubed, write x*x*x, and if you want x to 
the power of twelve, x*x*x*x*x*x*x*x*x*x*x*x" you would rightfully slap 
me with a halibut. Being able to manually perform repeated multiplication 
is not the same as having the language support exponentiation. To say 
nothing of fractional exponents. "How about x to the power of one third?"

Being able to manually pass pointers to variables about is not the same 
as having first class variables. It fails on the very first hurdle, "Are 
variables treated the same as other values?"

How do I pass an int to a function? func(some_int)

How do I pass a double to a function? func(some_double)

How do I pass a bool to a function? func(some_bool)

How do I pass a variable to a function? ptr = &some_variable; func(ptr)

Does that look the same to you? The fact that you can do it at all is not 
sufficient to make it first class. It just makes it a work-around for the 
lack of first class variables in the language.

Personally, I don't imagine that there ever could be a language where 
variables were first class values *exactly* the same as ints, strings, 
floats etc. Otherwise, how could you tell the difference between a 
function which operated on the variable itself, and one which operated on 
the value contained by the value? The best you can do is for variables to 
be "second class" -- you can do these things to them, but you need 
special syntax or declarations to tell the compiler you're operating on 
the variable rather than the variable's value. E.g. Pascal and Algol have 
syntax for instructing the compiler when to pass a variable as a value, 
and when to pass the value. C gives you nothing.

I would say that C variables are *third class*. There's no compiler 
support for variables-as-values at all, but you can manually fake it a 
bit by using pointers. There is no way to tell whether the pointer 
actually points to a variable, and since arrays aren't first class 
neither are pointer-to-arrays.

Algol and Pascal are *second class*, since the compiler does allow you to 
pass variables as arguments (var parameters in Pascal, I forget what they 
are called in Algol). Likewise, Python let's you create new variables at 
runtime, or delete them, but you can't pass them around. But still, 
you're quite limited in what the language does for you, compared to what 
you have to do yourself:

x = 23
function("x", globals())  # See, I can pass a variable! Not.


>> Rather than *creating* patches of memory, malloc merely allocates it
>> from pre-existing memory.
> 
> I disagree. On a modern system with memory management, malloc can grab
> memory from the system, thus making it available to your process. Sure,
> physical memory will normally have to have been installed in the system,
> but conceptually you could have a malloc function that actually freezes
> the program, asks the user to build a new computer and turn it on,
> connects to a new service on that computer, and allocates memory from
> there. As far as your program's concerned, malloc actually does (attempt
> to) give you more room than you had.

Ha, well I guess you got me there. Perhaps a less over the top example is 
that you're running in a VM, and malloc can request more information from 
the host (which presumably has unlimited memory). Still impractical, but 
theoretically possible.

Nevertheless, blocks of memory are not *first class* because you don't 
handle blocks of memory like other values. To make a new int variable, 
you declare it: "int foo". To make a new block of memory, there is no 
declaration "block foo". Rather, you call malloc() at runtime. And it 
might fail. "int foo" can never fail.


>> Python variables aren't first-class either, but in fact we can get a
>> bit closer to first-class than either C or Pascal.
>>
>> Creating new variables is trivial. Since they don't need to be
>> declared, you create a new variable just by assigning to it:
>>
>> try:
>>     spam
>> except NameError:
>>     spam = 23
> 
> No no no, this is really creating them at compile time.

It certainly isn't. Here's a slightly different demonstration of the same 
principle, this time inside a function to prove that there's nothing 
special about the global namespace:


py> def demo():
...     print('spam' in locals())
...     spam = 23
...     print('spam' in locals())
...
py> demo()
False
True


> If you do this
> inside a function, the name has to be created as a local name before the
> function begins execution.

An implementation detail. CPython -- but not necessarily other Pythons -- 
use pre-allocated slots for local variables, but tries to hide this fact 
from you (it *almost* succeeds too). But those pre-allocated slots can 
represent unbound variables, i.e. variables which from the perspective of 
Python code don't exist:

py> def demo2():
...     spam = 23
...     print('spam' in locals())
...     del spam
...     print('spam' in locals())
...
py> demo2()
True
False

If you peer under the hood of the CPython implementation, the slot still 
exists, but that's invisible from Python, and just an implementation 
detail. Other implementations may not even have slots at all.


>> There are at least two other ways:
>>
>> globals()['spam'] = 23
>> exec('spam = 23')
> 
> With exec, you can do anything "at run time". Does that mean that, in
> languages with an exec action, absolutely everything is first-class? I'm
> not sure that that counts. Maybe I'm wrong.

No, you're right. That's why I said "Python variables aren't first-class 
either". But they're less second class than C or Pascal.


> Subscript-assigning to globals() is actually creating new (module-level)
> variables, though. And if Python allowed you to assign to locals()
> inside a function, then I would accept that local function variables can
> be created and destroyed at run time, but you can't, so local variables
> aren't first-class.

See above.




-- 
Steven D'Aprano
http://import-that.dreamwidth.org/

[toc] | [prev] | [next] | [standalone]


#71242 — Re: Values and objects

FromChris Angelico <rosuav@gmail.com>
Date2014-05-10 19:32 +1000
SubjectRe: Values and objects
Message-ID<mailman.9847.1399714333.18130.python-list@python.org>
In reply to#71240
On Sat, May 10, 2014 at 7:09 PM, Steven D'Aprano
<steve+comp.lang.python@pearwood.info> wrote:
> On Sat, 10 May 2014 17:21:56 +1000, Chris Angelico wrote:
>
> No offence Chris, but I think this demonstrates that learning C causes
> brain damage and prevents clear logical thinking :-P
>
> You're not passing a variable to a function. You're passing a pointer,
> which is itself a first-class value. It could be a pointer to ANYTHING,
> or NOTHING at all -- C doesn't even promise to ensure that it is a valid
> pointer, although more modern languages may. There's certainly no
> guarantee that it's a pointer to a variable. And you cannot create new
> variables -- C only allows variables to be created at compile time.
>
> The question is not, "Can I implement some aspects of first-class
> behaviour for variables by hand?" The question is, "Are variables treated
> as first class values in C?"

Ehh... good point. I admit my brain damage - which, I have to say, has
earned me a good portion of my life's salaries, so it's not useless :)
Okay. So variables are not first-class in C. I still think memory
blocks are pretty much first class, though; you can declare them at
compile time (usually as an array of char or pointers) or at run time
(with malloc or equivalent), and they can be passed to functions,
returned from functions, etc. The only limitation is that a generic
memory block doesn't maintain its size, so you can't distinguish
between a char[10] and a char[1024].

> Being able to manually pass pointers to variables about is not the same
> as having first class variables. It fails on the very first hurdle, "Are
> variables treated the same as other values?"
>
> How do I pass an int to a function? func(some_int)
>
> How do I pass a double to a function? func(some_double)
>
> How do I pass a bool to a function? func(some_bool)
>
> How do I pass a variable to a function? ptr = &some_variable; func(ptr)
>
> Does that look the same to you? The fact that you can do it at all is not
> sufficient to make it first class. It just makes it a work-around for the
> lack of first class variables in the language.

You can simply say func(&some_variable), but yes, there is that
difference. (This is how "out" parameters usually look in C. You stick
ampersands in front of things.) And that's still passing memory blocks
around, not variables.

>>> Rather than *creating* patches of memory, malloc merely allocates it
>>> from pre-existing memory.
>>
>> I disagree. On a modern system with memory management, malloc can grab
>> memory from the system, thus making it available to your process. Sure,
>> physical memory will normally have to have been installed in the system,
>> but conceptually you could have a malloc function that actually freezes
>> the program, asks the user to build a new computer and turn it on,
>> connects to a new service on that computer, and allocates memory from
>> there. As far as your program's concerned, malloc actually does (attempt
>> to) give you more room than you had.
>
> Ha, well I guess you got me there. Perhaps a less over the top example is
> that you're running in a VM, and malloc can request more information from
> the host (which presumably has unlimited memory). Still impractical, but
> theoretically possible.

Yeah. Completely impractical, but so is "Post-It Note Python" where
everything's done with physical strings and sheets of paper. Thought
experiments don't have to be performant :)

> Nevertheless, blocks of memory are not *first class* because you don't
> handle blocks of memory like other values. To make a new int variable,
> you declare it: "int foo". To make a new block of memory, there is no
> declaration "block foo". Rather, you call malloc() at runtime. And it
> might fail. "int foo" can never fail.

As I mentioned above, you can make a new block of memory with "char
foo[1234]". And that's where a lot of buffer overruns come from,
because someone thinks "1234 is *heaps* of space"... but sometimes you
really can know in advance how long something can be. (Maybe you're
about to ask a file to give you the next 1233 bytes of content.) In
this form, it's as safe as "int foo" - that is to say, safe unless
your stack overflows, in which case all bets are off anyway.

>>> Python variables aren't first-class either, but in fact we can get a
>>> bit closer to first-class than either C or Pascal.
>>>
>>> Creating new variables is trivial. Since they don't need to be
>>> declared, you create a new variable just by assigning to it:
>>>
>>> try:
>>>     spam
>>> except NameError:
>>>     spam = 23
>>
>> No no no, this is really creating them at compile time.
>
> It certainly isn't. Here's a slightly different demonstration of the same
> principle, this time inside a function to prove that there's nothing
> special about the global namespace:
>
>
> py> def demo():
> ...     print('spam' in locals())
> ...     spam = 23
> ...     print('spam' in locals())
> ...
> py> demo()
> False
> True

Tell me, what may this function do in a compliant Python?

def demo():
    ret = spam
    spam = 23
    return ret

In CPython, that'll raise UnboundLocalError, because the local
variable 'spam' does already exist, and currently has no value (no
object bound to it). If a compliant Python implementation is allowed
to have this return the value of a global or builtin spam, then I
would agree that you can create variables at run time. Is
demo.__code__.co_varnames a CPython implementation detail or part of
the language spec?

Ultimately, a variable name must be looked up somehow. If you can
create and destroy them inside an inner scope that shadows an outer
scope, then you should be able to shadow and unshadow them. Is there a
way to do this with exec? I tried this and it failed:

def demo():
    print("spam =",spam)
    exec("spam = 23")
    print("spam =",spam)
    exec("del spam")
    print("spam =",spam)

CPython 3.4, each lookup of spam becomes a LOAD_GLOBAL, so each print
outputs the global value of spam. Is there a way to fiddle with this?

ChrisA

[toc] | [prev] | [next] | [standalone]


#71264 — Re: Values and objects

FromEthan Furman <ethan@stoneleaf.us>
Date2014-05-10 12:10 -0700
SubjectRe: Values and objects
Message-ID<mailman.9860.1399749029.18130.python-list@python.org>
In reply to#71240
On 05/10/2014 02:32 AM, Chris Angelico wrote:
>
> Tell me, what may this function do in a compliant Python?
>
> def demo():
>      ret = spam
>      spam = 23
>      return ret
>
> In CPython, that'll raise UnboundLocalError, because the local
> variable 'spam' does already exist, and currently has no value (no
> object bound to it).

No, it does not exist -- or, more accurately, it does not exist *yet* but will.  The fact that there is a slot waiting 
for what will be spam is a cpython implementation detail.

And if you don't like that argument (although it is a perfectly sound and correct argument), think of the module name space:

ret = spam
spam = 23

will net you a simple NameError, because spam has not yet been created.


>  If a compliant Python implementation is allowed
> to have this return the value of a global or builtin spam, then I
> would agree that you can create variables at run time.

See module example above.  This behavior is not allowed in functions for scope and sanity (mostly sanity) reasons.

--
~Ethan~

[toc] | [prev] | [next] | [standalone]


#71265 — Re: Values and objects

FromMRAB <python@mrabarnett.plus.com>
Date2014-05-10 20:22 +0100
SubjectRe: Values and objects
Message-ID<mailman.9861.1399749735.18130.python-list@python.org>
In reply to#71240
On 2014-05-10 20:10, Ethan Furman wrote:
> On 05/10/2014 02:32 AM, Chris Angelico wrote:
>>
>> Tell me, what may this function do in a compliant Python?
>>
>> def demo():
>>      ret = spam
>>      spam = 23
>>      return ret
>>
>> In CPython, that'll raise UnboundLocalError, because the local
>> variable 'spam' does already exist, and currently has no value (no
>> object bound to it).
>
> No, it does not exist -- or, more accurately, it does not exist *yet* but will.  The fact that there is a slot waiting
> for what will be spam is a cpython implementation detail.
>
> And if you don't like that argument (although it is a perfectly sound and correct argument), think of the module name space:
>
> ret = spam
> spam = 23
>
> will net you a simple NameError, because spam has not yet been created.
>
>
>>  If a compliant Python implementation is allowed
>> to have this return the value of a global or builtin spam, then I
>> would agree that you can create variables at run time.
>
> See module example above.  This behavior is not allowed in functions for scope and sanity (mostly sanity) reasons.
>
UnboundLocalError is like NameError, except that Python knows that the
name is local because somewhere in the function you're binding to that
name and you haven't said that it's global or nonlocal. Having a
different exception for that case makes it clearer to the user what the
problem is.

[toc] | [prev] | [next] | [standalone]


#71268 — Re: Values and objects

FromEthan Furman <ethan@stoneleaf.us>
Date2014-05-10 12:28 -0700
SubjectRe: Values and objects
Message-ID<mailman.9863.1399751488.18130.python-list@python.org>
In reply to#71240
On 05/10/2014 12:22 PM, MRAB wrote:
>
> UnboundLocalError is like NameError, except that Python knows that the
> name is local because somewhere in the function you're binding to that
> name and you haven't said that it's global or nonlocal. Having a
> different exception for that case makes it clearer to the user what the
> problem is.

Absolutely.  At one point NameError was raised in both cases, which could be very confusing to track down.

--
~Ethan~

[toc] | [prev] | [next] | [standalone]


#71272 — Re: Values and objects

FromTerry Reedy <tjreedy@udel.edu>
Date2014-05-10 16:16 -0400
SubjectRe: Values and objects
Message-ID<mailman.9864.1399753025.18130.python-list@python.org>
In reply to#71240
On 5/10/2014 3:10 PM, Ethan Furman wrote:
> On 05/10/2014 02:32 AM, Chris Angelico wrote:
>>
>> Tell me, what may this function do in a compliant Python?
>>
>> def demo():
>>      ret = spam
>>      spam = 23
>>      return ret
>>
>> In CPython, that'll raise UnboundLocalError,

Note:
 >>> issubclass(UnboundLocalError, NameError)
True

I am not sure if adding the specificity is helpful or not.

>> because the local
>> variable 'spam' does already exist, and currently has no value (no
>> object bound to it).
>
> No, it does not exist -- or, more accurately, it does not exist *yet*
> but will.  The fact that there is a slot waiting for what will be spam
> is a cpython implementation detail.
>
> And if you don't like that argument (although it is a perfectly sound
> and correct argument), think of the module name space:
>
> ret = spam
> spam = 23
>
> will net you a simple NameError, because spam has not yet been created.

In other words, those two lines raise a NameError in either case.

-- 
Terry Jan Reedy

[toc] | [prev] | [next] | [standalone]


#71273 — Re: Values and objects

FromTerry Reedy <tjreedy@udel.edu>
Date2014-05-10 16:24 -0400
SubjectRe: Values and objects
Message-ID<mailman.9865.1399753484.18130.python-list@python.org>
In reply to#71240
On 5/10/2014 3:22 PM, MRAB wrote:

> UnboundLocalError is like NameError,

More specifically,
 >>> isinstance(UnboundLocalError(), NameError)
True

This means that 'except NameError:' clauses written before the 
UnboundLocalError subclass was added still work and do not necessarily 
need to be modified. (I am allowing for the possibility that the body of 
the clause tries to separate the specific error from other NameErrors).

-- 
Terry Jan Reedy

[toc] | [prev] | [next] | [standalone]


#71275 — Re: Values and objects

FromDevin Jeanpierre <jeanpierreda@gmail.com>
Date2014-05-10 14:03 -0700
SubjectRe: Values and objects
Message-ID<mailman.9867.1399757236.18130.python-list@python.org>
In reply to#71240
On Sat, May 10, 2014 at 12:10 PM, Ethan Furman <ethan@stoneleaf.us> wrote:
> On 05/10/2014 02:32 AM, Chris Angelico wrote:
>>
>>
>> Tell me, what may this function do in a compliant Python?
>>
>> def demo():
>>      ret = spam
>>      spam = 23
>>      return ret
>>
>> In CPython, that'll raise UnboundLocalError, because the local
>> variable 'spam' does already exist, and currently has no value (no
>> object bound to it).
>
>
> No, it does not exist -- or, more accurately, it does not exist *yet* but
> will.  The fact that there is a slot waiting for what will be spam is a
> cpython implementation detail.

The name of the exception is "UnboundLocalError". And the message says
that we referred to a "local variable".

Also see the language reference:

"When a name is not found at all, a NameError exception is raised. If
the name refers to a local variable that has not been bound, a
UnboundLocalError exception is raised. UnboundLocalError is a subclass
of NameError."

spam is referring to a local variable that has not been bound. This is
not an implementation detail.

> And if you don't like that argument (although it is a perfectly sound and
> correct argument), think of the module name space:
>
>
> ret = spam
> spam = 23
>
> will net you a simple NameError, because spam has not yet been created.

Because module level variables work differently from local variables.

-- Devin

[toc] | [prev] | [next] | [standalone]


#71284 — Re: Values and objects

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2014-05-11 03:17 +0000
SubjectRe: Values and objects
Message-ID<536eebc1$0$29980$c3e8da3$5496439d@news.astraweb.com>
In reply to#71275
On Sat, 10 May 2014 14:03:11 -0700, Devin Jeanpierre wrote:

> On Sat, May 10, 2014 at 12:10 PM, Ethan Furman <ethan@stoneleaf.us>
> wrote:
>> On 05/10/2014 02:32 AM, Chris Angelico wrote:
>>>
>>>
>>> Tell me, what may this function do in a compliant Python?
>>>
>>> def demo():
>>>      ret = spam
>>>      spam = 23
>>>      return ret
>>>
>>> In CPython, that'll raise UnboundLocalError, because the local
>>> variable 'spam' does already exist, and currently has no value (no
>>> object bound to it).
>>
>>
>> No, it does not exist -- or, more accurately, it does not exist *yet*
>> but will.  The fact that there is a slot waiting for what will be spam
>> is a cpython implementation detail.
> 
> The name of the exception is "UnboundLocalError". And the message says
> that we referred to a "local variable".
> 
> Also see the language reference:
> 
> "When a name is not found at all, a NameError exception is raised. If
> the name refers to a local variable that has not been bound, a
> UnboundLocalError exception is raised. UnboundLocalError is a subclass
> of NameError."
> 
> spam is referring to a local variable that has not been bound. This is
> not an implementation detail.

Of course not. What is an implementation detail is that there is a slot 
waiting to be filled for it, just like Ethan said. It's the existence of 
pre-allocated slots for locals which is an implementation detail, not 
whether a name is treated as local or not.


>> And if you don't like that argument (although it is a perfectly sound
>> and correct argument), think of the module name space:
>>
>>
>> ret = spam
>> spam = 23
>>
>> will net you a simple NameError, because spam has not yet been created.
> 
> Because module level variables work differently from local variables.

But that is an implementation detail. IronPython and Jython use an 
ordinary dict for local variable namespaces, just like globals. Consider 
this example from Jython:

>>> spam = 9999
>>> def modify(namespace):
...     namespace['spam'] = 42
...
>>> def demo():
...     modify(locals())
...     spam = spam
...     return spam
...
>>> demo()
42



-- 
Steven D'Aprano
http://import-that.dreamwidth.org/

[toc] | [prev] | [next] | [standalone]


#71285 — Re: Values and objects

FromChris Angelico <rosuav@gmail.com>
Date2014-05-11 13:30 +1000
SubjectRe: Values and objects
Message-ID<mailman.9874.1399779013.18130.python-list@python.org>
In reply to#71284
On Sun, May 11, 2014 at 1:17 PM, Steven D'Aprano
<steve+comp.lang.python@pearwood.info> wrote:
> But that is an implementation detail. IronPython and Jython use an
> ordinary dict for local variable namespaces, just like globals. Consider
> this example from Jython:
>
>>>> spam = 9999
>>>> def modify(namespace):
> ...     namespace['spam'] = 42
> ...
>>>> def demo():
> ...     modify(locals())
> ...     spam = spam
> ...     return spam
> ...
>>>> demo()
> 42

All you're proving here is that, in some Pythons, locals() is
writeable. What happens if you remove the "spam = spam" line? Would
demo() not then return spam from the global scope, because the
variable does not exist at local scope? Every example you've shown is
simply giving a value to something that you've created by the normal
method of having an assignment inside the function.

ChrisA

[toc] | [prev] | [next] | [standalone]


#71288 — Re: Values and objects

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2014-05-11 05:11 +0000
SubjectRe: Values and objects
Message-ID<536f069b$0$29980$c3e8da3$5496439d@news.astraweb.com>
In reply to#71285
On Sun, 11 May 2014 13:30:03 +1000, Chris Angelico wrote:

> On Sun, May 11, 2014 at 1:17 PM, Steven D'Aprano
> <steve+comp.lang.python@pearwood.info> wrote:
>> But that is an implementation detail. IronPython and Jython use an
>> ordinary dict for local variable namespaces, just like globals.
>> Consider this example from Jython:
>>
>>>>> spam = 9999
>>>>> def modify(namespace):
>> ...     namespace['spam'] = 42
>> ...
>>>>> def demo():
>> ...     modify(locals())
>> ...     spam = spam
>> ...     return spam
>> ...
>>>>> demo()
>> 42
> 
> All you're proving here is that, in some Pythons, locals() is writeable.
> What happens if you remove the "spam = spam" line? Would demo() not then
> return spam from the global scope, 

Yes, this. See my previous email, and take careful note of Rule #2: in 
the absence of a binding operation, variables are not treated as local.

> because the variable does not exist at local scope? 

No to this. Consider this example:


>>> spam = 9999
>>> def modify(namespace):
...     namespace['spam'] = 42
...
>>> def demo2():
...     assert 'spam' not in locals()
...     modify(locals())
...     assert 'spam' in locals()
...     return spam
...
>>> demo2()
9999


This proves that the spam variable *does* exist in locals, but it is not 
seen because the "return spam" doesn't check the local scope, so it sees 
the global spam.

Sadly, the version of Jython I have doesn't provide a working dis module, 
but if it did I expect it would show the equivalent of what CPython does: 
the first version uses LOAD_FAST to look up "spam", and the second 
version used LOAD_GLOBAL (a misnomer since it doesn't *just* look up 
globals).


> Every example you've shown is simply giving a value to
> something that you've created by the normal method of having an
> assignment inside the function.

Nonsense. Look at the original examples again, more closely. Here they 
are again, this time with comments:

def test():
    if False: spam = None  # Dead code, never executed.
    d = locals()
    d['spam'] = 23  # Not a normal assignment.
    return spam

def test():
    locals()['spam'] = 42  # Not a normal assignment.
    return spam
    spam = None  # Dead code.


and from my reply to Devin:

def modify(namespace):
    namespace['spam'] = 42

def demo():
    modify(locals())  # Not an ordinary assignment.
    spam = spam  # Where does the initial value of spam come from?
    return spam


The *only* purpose of the dead code in the two test() functions is to 
force the compiler to use LOAD_FAST (or equivalent) rather than 
LOAD_GLOBAL. But they aren't ever executed. At no time do I use normal 
name binding assignment to create local variables. In the demo() 
function, if I expand the line "spam = spam" out:

    temp = spam  # Look up of spam occurs first.
    spam = temp  # Binding occurs second.

the difficulty should be even more obvious. Where does the value of spam 
come from before the binding?

The answer is that it comes from writing directly to the namespace (a 
dict). There is no fixed slot for spam waiting for a value, because 
Jython and IronPython don't use fixed slots. There's only a dict.

If we were using globals, it would be be more obvious what was going on, 
and there would be no argument about whether or not a variable exists 
before you give it a value. The answer would be, of course it doesn't 
exist before it has a value. Python declarations (whether implicit or 
explicit) don't create variables, they just instruct the compiler how to 
perform lookups on them.

# Global scope
print spam  # fails, because there is no spam variable yet
"spam" in globals()  # returns False
globals()['spam'] = 42  # now it exists
spam = spam  # a no-op
print spam


It's only because CPython is special, and locals() is special, that the 
equivalent code is indeterminate inside functions.



-- 
Steven D'Aprano
http://import-that.dreamwidth.org/

[toc] | [prev] | [next] | [standalone]


#71289 — Re: Values and objects

FromChris Angelico <rosuav@gmail.com>
Date2014-05-11 15:22 +1000
SubjectRe: Values and objects
Message-ID<mailman.9875.1399785752.18130.python-list@python.org>
In reply to#71288
On Sun, May 11, 2014 at 3:11 PM, Steven D'Aprano
<steve+comp.lang.python@pearwood.info> wrote:
> Nonsense. Look at the original examples again, more closely. Here they
> are again, this time with comments:
>
> def test():
>     if False: spam = None  # Dead code, never executed.
>     d = locals()
>     d['spam'] = 23  # Not a normal assignment.
>     return spam
>
> def test():
>     locals()['spam'] = 42  # Not a normal assignment.
>     return spam
>     spam = None  # Dead code.
>
>
> The *only* purpose of the dead code in the two test() functions is to
> force the compiler to use LOAD_FAST (or equivalent) rather than
> LOAD_GLOBAL.

In a C-like language, locals are created by a declaration, and
assigned a value separately. In Python, locals are created by the
presence of assignment within the function, which in simple cases
coincides with giving the value to it; but guarding the assignment
with "if False" prevents the giving of the value, while still being an
assignment for the sake of creating a local variable. Same if the
assignment happens further down, or even in the same statement ("spam
= spam"). It's still an assignment, so it has the declarative effect
of telling the compiler "this is now local, unless declared
global/nonlocal". It's that declaration that creates the variable, not
changing locals().

ChrisA

[toc] | [prev] | [next] | [standalone]


#71290 — Re: Values and objects

FromRustom Mody <rustompmody@gmail.com>
Date2014-05-10 22:31 -0700
SubjectRe: Values and objects
Message-ID<3fb2d95e-2fb6-43a5-a725-c6d38444b80c@googlegroups.com>
In reply to#71289
On Saturday, May 10, 2014 2:39:31 PM UTC+5:30, Steven D'Aprano wrote:
> 
> Personally, I don't imagine that there ever could be a language where 
> variables were first class values *exactly* the same as ints, strings, 
> floats etc. Otherwise, how could you tell the difference between a 
> function which operated on the variable itself, and one which operated on 
> the value contained by the value?

Its standard fare in theorem proving languages -
see eg twelf: https://www.cs.cmu.edu/~fp/papers/cade99.pdf
where the distinction is made between variables in the meta-language (ie twelf itself)
and variables in the the object theory

What you mean by *exactly* the same mean, I am not sure...

Also I note that I was not meaning first-classness of variables in C in that
literal sense.  Its just I consider them more first-class than say Pascal but 
less than say Lisp.

[The wikipedia link that Chris posted links to an article that makes the claim that
firstclassness is not really defined but can be used in a vague/relative way ]

[toc] | [prev] | [next] | [standalone]


#71297 — Re: Values and objects

FromMarko Rauhamaa <marko@pacujo.net>
Date2014-05-11 09:21 +0300
SubjectRe: Values and objects
Message-ID<87ppjksum0.fsf@elektro.pacujo.net>
In reply to#71290
Rustom Mody <rustompmody@gmail.com>:

> On Saturday, May 10, 2014 2:39:31 PM UTC+5:30, Steven D'Aprano wrote:
>> 
>> Personally, I don't imagine that there ever could be a language where
>> variables were first class values *exactly* the same as ints,
>> strings, floats etc.
>
> [...]
>
> What you mean by *exactly* the same mean, I am not sure...

Lisp variables (symbols) are on an equal footing with other objects.
IOW, lisp variables are objects in the heap.


Marko

[toc] | [prev] | [next] | [standalone]


#71301 — Re: Values and objects

FromRustom Mody <rustompmody@gmail.com>
Date2014-05-10 23:48 -0700
SubjectRe: Values and objects
Message-ID<9d950f96-3457-4c13-b9e2-8e4e1b20cd54@googlegroups.com>
In reply to#71297
On Sunday, May 11, 2014 11:51:59 AM UTC+5:30, Marko Rauhamaa wrote:
> Rustom Mody :
> 
> 
> 
> > On Saturday, May 10, 2014 2:39:31 PM UTC+5:30, Steven D'Aprano wrote:
> 
> >> 
> 
> >> Personally, I don't imagine that there ever could be a language where
> >> variables were first class values *exactly* the same as ints,
> >> strings, floats etc.
> >
> > [...]
> >
> > What you mean by *exactly* the same mean, I am not sure...
> 
> 
> 
> Lisp variables (symbols) are on an equal footing with other objects.
> IOW, lisp variables are objects in the heap.

But is a symbol a variable??
Sure, by providing a data-structure symbol, lisp provides one of 
the key building blocks for developing language processing systems.

However I would argue that a variable is not a merely a symbol (identifier
in more usual programming language-speak) but a relation between identifiers/symbols
and some 'rhs'

For an (interpreted?) language like python, rhs is naturally value/object
For a C like language it is memory.

[Just invoking the standard denotational semantics fare:
Env : Symbol → Value for interpreted languages
For 'compiled' languages
Env : Symbol → Location (at compile time)
Store : Location → Value  (at run time)

[toc] | [prev] | [next] | [standalone]


#71320 — Re: Values and objects

FromMarko Rauhamaa <marko@pacujo.net>
Date2014-05-11 18:10 +0300
SubjectRe: Values and objects
Message-ID<87eh00s65j.fsf@elektro.pacujo.net>
In reply to#71301
Rustom Mody <rustompmody@gmail.com>:

> On Sunday, May 11, 2014 11:51:59 AM UTC+5:30, Marko Rauhamaa wrote:
>> Lisp variables (symbols) are on an equal footing with other objects.
>> IOW, lisp variables are objects in the heap.
>
> But is a symbol a variable??

Yes. A classic lisp symbol is even more "variable" than most other
variables! It can hold *two* values. One is called a value binding and
the other one the function binding. Scheme has unified the two; scheme
symbols have only one value binding, which can be a function.

> Sure, by providing a data-structure symbol, lisp provides one of the
> key building blocks for developing language processing systems.
>
> However I would argue that a variable is not a merely a symbol
> (identifier in more usual programming language-speak) but a relation
> between identifiers/symbols and some 'rhs'

The lisp symbol really is a data object with several fields: I can think
of name, value, function and properties. They can be accessed with
accessor functions. (Interestingly, scheme doesn't have the
'symbol-value accessor function of lisp's.)

If lisp didn't have a way to rebind symbols (i.e., if it were purely
functional and had no side effects), they wouldn't be so much variables
as substitution spots in the code.

> For an (interpreted?) language like python, rhs is naturally
> value/object For a C like language it is memory.

Symbols in lisp are memory slots, conceptually and physically.


Marko

[toc] | [prev] | [next] | [standalone]


#71308 — Re: Values and objects

FromJussi Piitulainen <jpiitula@ling.helsinki.fi>
Date2014-05-11 11:26 +0300
SubjectRe: Values and objects
Message-ID<qot4n0wd8la.fsf@ruuvi.it.helsinki.fi>
In reply to#71297
Marko Rauhamaa writes:
> Rustom Mody:
> 
> > On Saturday, May 10, 2014 2:39:31 PM UTC+5:30, Steven D'Aprano wrote:
> >> 
> >> Personally, I don't imagine that there ever could be a language
> >> where variables were first class values *exactly* the same as
> >> ints, strings, floats etc.
> >
> > [...]
> >
> > What you mean by *exactly* the same mean, I am not sure...
> 
> Lisp variables (symbols) are on an equal footing with other objects.
> IOW, lisp variables are objects in the heap.

Only some, or only in quite old or special members of the family. But
yes, I suppose when Lisp was still LISP, it was the kind of language
that Steven fails to imagine in the quotation above. Variables really
were symbols, which still are objects that can be passed around and
stored in data structures. Or maybe not - wasn't the essential binding
component (originally an "association list", later a more abstract
"environment", called "namespace" in Python culture) separate from the
symbol even then? Global bindings aside.

But default in Common Lisp is lexical binding, and Scheme has only
lexical bindings. An ordinary lexical variable is not an object in any
reasonable sense that I can see.

(let ((f (let ((x 3)) (lambda () x))))
   ;; The binding of x is still relevant here but not in scope and not
   ;; accessible through the symbol x
   (funcall f)) ;==> 3

# That's (lambda f : f())((lambda x : (lambda : x))(3)) #=> 3
# Roughly, f = (lambda x : (lambda : x))(3) ; f()       #=> 3

[toc] | [prev] | [next] | [standalone]


#71309 — Re: Values and objects

FromRustom Mody <rustompmody@gmail.com>
Date2014-05-11 01:48 -0700
SubjectRe: Values and objects
Message-ID<455a3dc0-c492-498b-9593-d30b8a967898@googlegroups.com>
In reply to#71308
On Sunday, May 11, 2014 1:56:41 PM UTC+5:30, Jussi Piitulainen wrote:
> Marko Rauhamaa writes:
> > Rustom Mody:
> > 
> > > On Saturday, May 10, 2014 2:39:31 PM UTC+5:30, Steven D'Aprano wrote:
> > >> 
> > >> Personally, I don't imagine that there ever could be a language
> > >> where variables were first class values *exactly* the same as
> > >> ints, strings, floats etc.
> 
> > >
> 
> > > [...]
> 
> > >
> 
> > > What you mean by *exactly* the same mean, I am not sure...
> 
> > 
> 
> > Lisp variables (symbols) are on an equal footing with other objects.
> 
> > IOW, lisp variables are objects in the heap.
> 
> 
> Only some, or only in quite old or special members of the family. But
> yes, I suppose when Lisp was still LISP, it was the kind of language
> that Steven fails to imagine in the quotation above. Variables really
> were symbols, which still are objects that can be passed around and
> stored in data structures. Or maybe not - wasn't the essential binding
> component (originally an "association list", later a more abstract
> "environment", called "namespace" in Python culture) separate from the
> symbol even then? Global bindings aside.
> 

A symbol is a first-class data structure in any lisp (that I know)
http://en.wikipedia.org/wiki/Homoiconicity is a defining characteristic of lisp

Environments are first class in many schemes:
http://sicp.ai.mit.edu/Fall-2004/manuals/scheme-7.5.5/doc/scheme_14.html
(The '+'es there indicate its an MIT scheme extension; but its quite common)

In my understanding a symbol can be called a variable only wrt some environment

IOW there is no meaning to the word 'variable' without some notion of scope.

I am not sure what your references to old and new lisps and static vs dynamic
scope has to do with this.

Or are you saying that in the 1960s lisps, a symbol was the string (name)
along with its (dynamic binding) stack??

Python to qualify for this not only would the namespacing of
locals have to be systematic with globals, the nesting structure of environments
would have to be introspectively available as in the scheme example.

Note the functions: environment-parent and environment-bound-names

[toc] | [prev] | [next] | [standalone]


#71313 — Re: Values and objects

FromJussi Piitulainen <jpiitula@ling.helsinki.fi>
Date2014-05-11 15:22 +0300
SubjectRe: Values and objects
Message-ID<qot61lcmrna.fsf@ruuvi.it.helsinki.fi>
In reply to#71309
Rustom Mody writes:
> On Sunday, May 11, 2014 1:56:41 PM UTC+5:30, Jussi Piitulainen wrote:
> > Marko Rauhamaa writes:
> > > Rustom Mody:
> > > 
> > > > On Saturday, May 10, 2014 2:39:31 PM UTC+5:30, Steven D'Aprano wrote:
> > > >> 
> > > >> Personally, I don't imagine that there ever could be a
> > > >> language where variables were first class values *exactly*
> > > >> the same as ints, strings, floats etc.
> > 
> > > > [...]
> > 
> > > > What you mean by *exactly* the same mean, I am not sure...
> > 
> > > Lisp variables (symbols) are on an equal footing with other
> > > objects.  IOW, lisp variables are objects in the heap.
> > 
> > Only some, or only in quite old or special members of the
> > family. But yes, I suppose when Lisp was still LISP, it was the
> > kind of language that Steven fails to imagine in the quotation
> > above. Variables really were symbols, which still are objects that
> > can be passed around and stored in data structures. Or maybe not -
> > wasn't the essential binding component (originally an "association
> > list", later a more abstract "environment", called "namespace" in
> > Python culture) separate from the symbol even then? Global
> > bindings aside.
> 
> A symbol is a first-class data structure in any lisp (that I know)
> http://en.wikipedia.org/wiki/Homoiconicity is a defining characteristic of lisp

I don't see the relevance of these observations.

The claim was that Lisp variables are symbols. What do you write in
Common Lisp in place of the "..." to have the following evaluate to
the the value of the variable x?

    (let ((x (f)) (y 'x)) (... y ...))

No, (eval y) is not an answer, and (symbol-value y) is not an answer:
these do not do the thing at all. To suggest (progn y x) is to concede
my point that there is no way to get the value of x through the symbol
x that is the value of y.

> Environments are first class in many schemes:
> http://sicp.ai.mit.edu/Fall-2004/manuals/scheme-7.5.5/doc/scheme_14.html
> (The '+'es there indicate its an MIT scheme extension; but its quite common)

It's not very common. A couple of top-level environment specifiers are
in the reports (scheme-report-environment, null-environment, and
interaction-environment is optional, if I recall correctly) but the
crucial reifier of an arbitrary lexical environment is not, and
environment specifiers can only be used as an argument to eval.

Even if that were common, it seems to me a joke to say that the symbol
itself is the variable, which is the claim that I responded to. It's
like saying that pairs of integers are first class variables because
they can be interpreted as lexical addresses wrt an environment. You
know, (0, 0) refers to the first variable in the current environment
frame, (3, 1) to the second variable in a specific ancestor frame, and
so on.

> In my understanding a symbol can be called a variable only wrt some
> environment
> 
> IOW there is no meaning to the word 'variable' without some notion
> of scope.

Agreed.

So you consider it reasonable to say that variables are symbols in
Lisp, and then clarify that a symbol means a symbol together with a
first-class lexical environment, as if that was implicit in the
original claim (and as if such environments were widely available in
Lisp)?

If so, I admit I've been fooled, and I've spent far too much time on
this already. At least I was responding in good faith.

> I am not sure what your references to old and new lisps and static
> vs dynamic scope has to do with this.

I'm saying that lexical variables are not accessible through the
symbol that happens to look like the variable in the source code.

And I'm saying that it's the lexical variables that need to be
considered, because they are the default kind even in Lisp today.
Dynamic variables are special. (They are even _called_ special.)

I'm not saying that a dynamic variable cannot be accessed through the
symbol, because that doesn't seem to be true. (I installed a Common
Lisp and experimented a little when I wrote my original response.)

> Or are you saying that in the 1960s lisps, a symbol was the string
> (name) along with its (dynamic binding) stack??

It seems to be the case today, in Common Lisp, that a special variable
is accessible through the symbol. For example, (symbol-value y) would
work in my example above if x had been declared special. The dynamic
environment is implicit.

In the 1960s, before Scheme AFAIUI, things were that way.

> Python to qualify for this not only would the namespacing of locals
> have to be systematic with globals, the nesting structure of
> environments would have to be introspectively available as in the
> scheme example.
> 
> Note the functions: environment-parent and environment-bound-names

If Marko meant MIT Scheme when he said Lisp, and reification of
arbitrary lexical environments when he said symbol, I've responded to
a quite different claim than he intended, and spent far too much
effort on this.

[toc] | [prev] | [next] | [standalone]


Page 2 of 4 — ← Prev page 1 [2] 3 4  Next page →

Back to top | Article view | comp.lang.python


csiph-web