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 3 of 4 — ← Prev page 1 2 [3] 4  Next page →


#71322 — Re: Values and objects

FromMarko Rauhamaa <marko@pacujo.net>
Date2014-05-11 18:46 +0300
SubjectRe: Values and objects
Message-ID<87a9aos4gk.fsf@elektro.pacujo.net>
In reply to#71313
Jussi Piitulainen <jpiitula@ling.helsinki.fi>:

> 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.

I must admit I have never used Common Lisp. I can only guess from your
question its symbol-value fetches the value from the global symbol table
-- even if you replaced let with let* (the two x's are not the same
symbol when let is used).

I don't see any practical reason for that limitation. If you allow
setq/setf/set!, you have no reason to disallow symbol-value on a local
variable.


Marko

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


#71341 — Re: Values and objects

FromMarko Rauhamaa <marko@pacujo.net>
Date2014-05-11 22:56 +0300
SubjectRe: Values and objects
Message-ID<87vbtcqech.fsf@elektro.pacujo.net>
In reply to#71322
Marko Rauhamaa <marko@pacujo.net>:

> I don't see any practical reason for that limitation. If you allow
> setq/setf/set!, you have no reason to disallow symbol-value on a local
> variable.

In fact, the reason probably is practical and analogous to the locals()
caveat in Python. If the language made local variables available
indirectly, I'm guessing some optimizations would be much harder or
impossible.

In my own lisp implementation, where performance is not a concern at
all, the local variables are both lexically scoped and offer access to
symbol-value.


Marko

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


#71314 — Re: Values and objects

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2014-05-11 12:51 +0000
SubjectRe: Values and objects
Message-ID<536f723c$0$29980$c3e8da3$5496439d@news.astraweb.com>
In reply to#71308
On Sun, 11 May 2014 11:26:41 +0300, 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.

I'm not sure if you are agreeing or disagreeing that variables are values 
in Common Lisp or not. First you say they are, they you say "maybe not".

The point is, it is *logically impossible* for a language to use 
precisely the same syntax for value-assignment and variable-assignment. 
Consider the variable called "x", which is bound to the value 23. If the 
language has a single assignment operator or statement:

let y := name;

that cannot be used for *both* binding the value 23 to y and binding the 
variable "x" to y (making y an alias for x).

To use Pascal as an example, you cannot use the same declaration for pass-
by-value and pass-by-reference, one or the other must use different 
syntax.

function foo(x: integer, var y: integer): integer;

Given that declaration, and the function call foo(a, b), x is bound to 
the value of a, while y is bound to the variable b.

In the case of Common List, I count at least four different assignment 
forms: 

    set, setq, setf, psetq, let

plus two unbinding forms:

    makunbound, fmakunbound


but I don't know enough about Lisp to tell you which ones implement 
binding-to-values and which binding-to-variables, if any.



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

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


#71317 — Re: Values and objects

FromRustom Mody <rustompmody@gmail.com>
Date2014-05-11 07:12 -0700
SubjectRe: Values and objects
Message-ID<35eb82b8-ca79-438e-bdde-430c6ffbfa3c@googlegroups.com>
In reply to#71314
On Sunday, May 11, 2014 6:21:08 PM UTC+5:30, Steven D'Aprano wrote:

> The point is, it is *logically impossible* for a language to use 
> precisely the same syntax for value-assignment and variable-assignment. 
> Consider the variable called "x", which is bound to the value 23. If the 
> language has a single assignment operator or statement:

Its called set in classic lisp.
Here's an emacs lisp session (the oldest lisp I can lay my hands on)
The semicolons are comments like python's #

*** Welcome to IELM ***  Type (describe-mode) for help.
ELISP> (set (quote d) "Hello World")
"Hello World"
ELISP> (set (quote c) (quote d))
d
ELISP> ; those quote-s are getting boring
ELISP> (set 'b 'c)
c
ELISP> ; once more short-form a very common case
ELISP> (setq a 'b)
b
ELISP> ; Now unfold the chain
ELISP> ; Level 0
ELISP> 'a
a
ELISP> ; Level 1
ELISP> a
b
ELISP> ;Level 2
ELISP> (eval a)
c
ELISP> ;Level 3
ELISP> (eval (eval a))
d
ELISP> ;Level 4
ELISP> (eval (eval (eval a)))
"Hello World"
ELISP> 


IOW set UNIFORMLY evaluates its 2 arguments.
To get usual assignment like behavior of normal programming languages,
one (typically) quotes the first argument.


This is a sufficiently common case that it gets its own 'special
form' -- setq (ie set-quote)

However the more general case in which (the name of)* the variable is
evaluated at run-time is always available.

* "Name of" is strictly not correct because:
ELISP> (symbol-name 'a)
"a"

However if I dont say the "name of..." its hard to speak in
an intelligible way.

Here is the relevant intro from the elisp manual:

A "symbol" in GNU Emacs Lisp is an object with a name.  The symbol name
serves as the printed representation of the symbol.  In ordinary Lisp
use, ... a symbol's name is unique--no two symbols have the same name.

   A symbol can serve as a variable, as a function name, or to hold a
property list.  Or it may serve only to be distinct from all other Lisp
objects, so that its presence in a data structure may be recognized
reliably.  

tl;dr:
Quote-Eval go up and down the 'meta-language' tower
just as Lambda-(function)Apply go up and down the functional tower.

Elaborated further:
http://blog.languager.org/2013/08/applying-si-on-sicp.html

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


#71293 — Re: Values and objects

FromEthan Furman <ethan@stoneleaf.us>
Date2014-05-10 22:42 -0700
SubjectRe: Values and objects
Message-ID<mailman.9877.1399786936.18130.python-list@python.org>
In reply to#71288
On 05/10/2014 10:22 PM, Chris Angelico wrote:
> It's that declaration that creates the variable, not
> changing locals().

A Python variable is a name bound to a value (and values, of course, are objects).  If you don't have both pieces, you 
don't have a Python variable.

--
~Ethan~

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


#71300 — Re: Values and objects

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2014-05-11 06:40 +0000
SubjectRe: Values and objects
Message-ID<536f1b6c$0$29980$c3e8da3$5496439d@news.astraweb.com>
In reply to#71293
On Sat, 10 May 2014 22:42:13 -0700, Ethan Furman wrote:

> On 05/10/2014 10:22 PM, Chris Angelico wrote:
>> It's that declaration that creates the variable, not changing locals().
> 
> A Python variable is a name bound to a value (and values, of course, are
> objects).  If you don't have both pieces, you don't have a Python
> variable.

+1

Well said.


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

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


#71278 — Re: Values and objects

FromChris Angelico <rosuav@gmail.com>
Date2014-05-11 09:18 +1000
SubjectRe: Values and objects
Message-ID<mailman.9869.1399764312.18130.python-list@python.org>
In reply to#71240
On Sun, May 11, 2014 at 5:10 AM, Ethan Furman <ethan@stoneleaf.us> wrote:
> 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.

What about this, though:

ret = int
int = 23

That will *not* net you a NameError, because 'int' exists in an outer
scope (builtins). You can create a new module-scope variable and it
will immediately begin to shadow a builtin; you can delete that
variable and it will immediately cease to shadow that builtin. That's
the difference I'm talking about. With function-local variables, they
all have to exist (as other responses confirmed, that *is* a language
guarantee), even though some of them aren't bound to anything yet.

ChrisA

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


#71283 — Re: Values and objects

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

> On Sun, May 11, 2014 at 5:10 AM, Ethan Furman <ethan@stoneleaf.us>
> wrote:
>> 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.
> 
> What about this, though:
> 
> ret = int
> int = 23
>
> That will *not* net you a NameError, because 'int' exists in an outer
> scope (builtins). You can create a new module-scope variable and it will
> immediately begin to shadow a builtin; you can delete that variable and
> it will immediately cease to shadow that builtin. 

Yes. That's part of documented language behaviour to do with scoping 
search paths. See below.


> That's the difference
> I'm talking about. With function-local variables, they all have to exist
> (as other responses confirmed, that *is* a language guarantee), even
> though some of them aren't bound to anything yet.

Define "exist". 

Just because a slot exists waiting for a variable, doesn't mean that the 
variable which would use that slot exists. Like dicts and lists, function 
locals() are over-allocated: CPython pre-allocates slots for locals based 
on compile-time information, even if those locals are never bound to and 
therefore don't exist:

def demo():
    if False:
        x = 23
    print x  # Fails

You're trying to argue that because there is a slot for x, the variable x 
exists. But I think that is the wrong definition of "exists". If you have 
a list L = [], would you say that L[4] exists because the array is over-
allocated and already has (at least) four slots waiting to be used, but 
L[100] doesn't because it isn't over-allocated that much? What if the pre-
allocation rules change? What if an implementation decides not to bother 
pre-allocating empty lists?

What if an implementation pre-allocates a random number of array slots? 
Would you be comfortable saying that there is a 25% chance that L[4] 
exists and a 1% chance that L[100] exists?

In both these cases, array slots in a list or dict, and locals, we risk 
mistaking implementation details for language features. I think you 
actually are making this error when it comes to locals.

When talking about the implementation, it is relevant to discuss the 
existence of slots. But when talking about the language, about features 
visible from Python code such as variables (a.k.a. name bindings), local 
slots don't matter. Jython and IronPython don't (so far as I know) use 
them, and locals() happens to be writable. Here's an example from 
IronPython 2.6:

>>> def test():
...     if False: spam = None
...     d = locals()
...     d['spam'] = 23
...     return spam
...
>>> test()
23


And a similar example from Jython 2.5:

>>> def test():
...     locals()['spam'] = 42
...     return spam
...     spam = None
...
>>> test()
42


Neither example works in CPython, you get an UnboundLocalError, but 
whether or not locals() is writable is is *explicitly* documented as an 
implementation detail. How implementations store local variables (in a 
dictionary like globals, slots, in the Cloud) is up to them, so long as 
the implementation follows the scoping rules.

Python determines whether a variable is local or not at compile-time:

(1) If a function contains a binding operation (assignment; import; del) 
on that variable, then the variable is defined as a local unless 
otherwise declared as a global or nonlocal (Python 3 only).

(2) Otherwise it is not a local.

(3) Outside of a function, it is a global whether declared as such or not.

(4) Variables (names) don't exist until they have a value bound to them.

I guess you want to challenge #4, and say that local variables exist as 
soon as the slot that holds them exists. I think that is wrong. And 
besides, even CPython 2 doesn't always use slots for locals: consider 
what happens when you use import * inside a function. And try running 
this function in both 2.7 and 3.3 and see if you can explain the 
difference:

def test():
    if False: x = None
    exec("x = 1")
    return x


But I digress.

Name look-ups for locals look only in the local scope. Name lookups for 
everything else search the chain nonlocals:globals:builtins.

Name bindings (assignments, del, imports) for locals write only to the 
local scope. For globals they write only to the global scope and for 
nonlocals they write to the nearest enclosing nonlocal scope that already 
defines that variable.



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

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


#71316 — Re: Values and objects

FromRotwang <sg552@hotmail.co.uk>
Date2014-05-11 14:46 +0100
SubjectRe: Values and objects
Message-ID<lknuv1$3ud$1@dont-email.me>
In reply to#71283
On 11/05/2014 04:11, Steven D'Aprano wrote:
> [...]
>
> And try running
> this function in both 2.7 and 3.3 and see if you can explain the
> difference:
>
> def test():
>      if False: x = None
>      exec("x = 1")
>      return x

I must confess to being baffled by what happens in 3.3 with this 
example. Neither locals() nor globals() has x = 1 immediately before the 
return statement, so what is exec("x = 1") actually doing?

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


#71334 — Re: Values and objects

FromNed Batchelder <ned@nedbatchelder.com>
Date2014-05-11 14:40 -0400
SubjectRe: Values and objects
Message-ID<mailman.9892.1399833638.18130.python-list@python.org>
In reply to#71316
On 5/11/14 9:46 AM, Rotwang wrote:
> On 11/05/2014 04:11, Steven D'Aprano wrote:
>> [...]
>>
>> And try running
>> this function in both 2.7 and 3.3 and see if you can explain the
>> difference:
>>
>> def test():
>>      if False: x = None
>>      exec("x = 1")
>>      return x
>
> I must confess to being baffled by what happens in 3.3 with this
> example. Neither locals() nor globals() has x = 1 immediately before the
> return statement, so what is exec("x = 1") actually doing?
>

The same happens if you try to modify locals():

     >>> def test():
     ...   if 0: x = 1
     ...   locals()['x'] = 13
     ...   return x
     ...
     >>> test()
     Traceback (most recent call last):
       File "<stdin>", line 1, in <module>
       File "<stdin>", line 4, in test
     UnboundLocalError: local variable 'x' referenced before assignment

The doc for exec says:

     Note: The default locals act as described for function locals()
     below: modifications to the default locals dictionary should not be
     attempted. Pass an explicit locals dictionary if you need to see
     effects of the code on locals after function exec() returns.

The doc for locals says:

     Note: The contents of this dictionary should not be modified;
     changes may not affect the values of local and free variables used
     by the interpreter.

This is a tradeoff of practicality for purity: the interpreter runs 
faster if you don't make locals() a modifiable dict.

-- 
Ned Batchelder, http://nedbatchelder.com

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


#71347 — Re: Values and objects

FromRotwang <sg552@hotmail.co.uk>
Date2014-05-12 00:06 +0100
SubjectRe: Values and objects
Message-ID<lkovpl$mgp$1@dont-email.me>
In reply to#71334
On 11/05/2014 19:40, Ned Batchelder wrote:
> On 5/11/14 9:46 AM, Rotwang wrote:
>> On 11/05/2014 04:11, Steven D'Aprano wrote:
>>> [...]
>>>
>>> And try running
>>> this function in both 2.7 and 3.3 and see if you can explain the
>>> difference:
>>>
>>> def test():
>>>      if False: x = None
>>>      exec("x = 1")
>>>      return x
>>
>> I must confess to being baffled by what happens in 3.3 with this
>> example. Neither locals() nor globals() has x = 1 immediately before the
>> return statement, so what is exec("x = 1") actually doing?
>>
>
> The same happens if you try to modify locals():
>
>      >>> def test():
>      ...   if 0: x = 1
>      ...   locals()['x'] = 13
>      ...   return x
>      ...
>      >>> test()
>      Traceback (most recent call last):
>        File "<stdin>", line 1, in <module>
>        File "<stdin>", line 4, in test
>      UnboundLocalError: local variable 'x' referenced before assignment
>
> The doc for exec says:
>
>      Note: The default locals act as described for function locals()
>      below: modifications to the default locals dictionary should not be
>      attempted. Pass an explicit locals dictionary if you need to see
>      effects of the code on locals after function exec() returns.
>
> The doc for locals says:
>
>      Note: The contents of this dictionary should not be modified;
>      changes may not affect the values of local and free variables used
>      by the interpreter.
>
> This is a tradeoff of practicality for purity: the interpreter runs
> faster if you don't make locals() a modifiable dict.

Thanks.

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


#71280 — Re: Values and objects

FromEthan Furman <ethan@stoneleaf.us>
Date2014-05-10 18:28 -0700
SubjectRe: Values and objects
Message-ID<mailman.9871.1399773079.18130.python-list@python.org>
In reply to#71240
On 05/10/2014 04:18 PM, Chris Angelico wrote:
> On Sun, May 11, 2014 at 5:10 AM, Ethan Furman <ethan@stoneleaf.us> wrote:
>> 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.
>
> What about this, though:
>
> ret = int
> int = 23
>
> That will *not* net you a NameError, because 'int' exists in an outer
> scope (builtins). You can create a new module-scope variable and it
> will immediately begin to shadow a builtin; you can delete that
> variable and it will immediately cease to shadow that builtin. That's
> the difference I'm talking about. With function-local variables, they
> all have to exist (as other responses confirmed, that *is* a language
> guarantee), even though some of them aren't bound to anything yet.

Well, with function variables they have to exist *when you use them*. ;)

This seems like more of a scoping issue than a "can we create variables in Python" issue.

I am curious, though, what other python's do with respect to function variables.

--
~Ethan~

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


#71305 — Re: Values and objects

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2014-05-11 07:24 +0000
SubjectRe: Values and objects
Message-ID<536f2595$0$29980$c3e8da3$5496439d@news.astraweb.com>
In reply to#71280
On Sat, 10 May 2014 18:28:43 -0700, Ethan Furman wrote:

> On 05/10/2014 04:18 PM, Chris Angelico wrote:
>> On Sun, May 11, 2014 at 5:10 AM, Ethan Furman <ethan@stoneleaf.us>
>> wrote:
>>> 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.
>>
>> What about this, though:
>>
>> ret = int
>> int = 23
>>
>> That will *not* net you a NameError, because 'int' exists in an outer
>> scope (builtins). You can create a new module-scope variable and it
>> will immediately begin to shadow a builtin; you can delete that
>> variable and it will immediately cease to shadow that builtin. That's
>> the difference I'm talking about. With function-local variables, they
>> all have to exist (as other responses confirmed, that *is* a language
>> guarantee), even though some of them aren't bound to anything yet.
> 
> Well, with function variables they have to exist *when you use them*. ;)
> 
> This seems like more of a scoping issue than a "can we create variables
> in Python" issue.

Correct. The first line "ret = int" does a name lookup for "int", finds 
it in the built-ins, and binds it to "ret". The second line "int = 23" 
binds the object 23 to the name "int" in the current namespace, i.e. the 
globals. It has nothing to do with how variables are created.

By default, you can't do that inside a function because function scoping 
is special, not because function locals are kept inside slots. (1) They 
aren't always, not even in CPython, and (2) even if they are, an 
implementation could hide that fact and provide the same behaviour.

I say "by default" because with byte-code hacking you can. Suppose I 
write the function:

def special():
    spam = spam
    process(spam)

Under normal circumstances, this will fail, because the assignment 
"spam = ..." tells the compiler that spam is a local, and so the lookup 
for "... = spam" does a LOAD_FAST which fails. But if I hack the byte 
code, I can turn that LOAD_FAST into a LOAD_GLOBAL, which then gives 
behaviour just like Lua:

    spam (the local variable) = spam (the global variable)


Of course, this isn't a feature of Python the language. But with 
sufficient byte-code hacking skills, it is possible.


> I am curious, though, what other python's do with respect to function
> variables.

As far as I know, Jython and IronPython store them in a dict namespace, 
just like globals. See my previous responses to Chris.



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

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


#71281 — Re: Values and objects

FromChris Angelico <rosuav@gmail.com>
Date2014-05-11 11:59 +1000
SubjectRe: Values and objects
Message-ID<mailman.9872.1399773915.18130.python-list@python.org>
In reply to#71240
On Sun, May 11, 2014 at 11:28 AM, Ethan Furman <ethan@stoneleaf.us> wrote:
> Well, with function variables they have to exist *when you use them*. ;)
>
> This seems like more of a scoping issue than a "can we create variables in
> Python" issue.
>
> I am curious, though, what other python's do with respect to function
> variables.

Variables exist in scope. Apart from assembly language, where
registers have universal scope, every language I know of has some
concept of scope. (REXX is very different from most, in that
"PROCEDURE EXPOSE" isn't at all your classic notion of scoping, but
there's still the concept that there can be two variables with the
same name.) When you create one, you create it in a particular scope,
and that's how it must be.

ChrisA

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


#71306 — Re: Values and objects

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

> On Sun, May 11, 2014 at 11:28 AM, Ethan Furman <ethan@stoneleaf.us>
> wrote:
>> Well, with function variables they have to exist *when you use them*.
>> ;)
>>
>> This seems like more of a scoping issue than a "can we create variables
>> in Python" issue.
>>
>> I am curious, though, what other python's do with respect to function
>> variables.
> 
> Variables exist in scope. Apart from assembly language, where registers
> have universal scope, every language I know of has some concept of
> scope. 

BASIC.


> (REXX is very different from most, in that "PROCEDURE EXPOSE"
> isn't at all your classic notion of scoping, but there's still the
> concept that there can be two variables with the same name.) When you
> create one, you create it in a particular scope, and that's how it must
> be.

Yes. But when do you create it? At declaration time, or when a value is 
bound to it?


# Ensure spam does not exist.
try:
    del spam
except NameError:
    pass
assert "spam" not in globals()

# Declare spam.
global spam
print ("spam" in globals())  # prints False
print (spam)  # raises NameError


The same applies to locals. Whether a slot is pre-allocated or not, the 
variable doesn't exist until there is a value bound to the name.


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

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


#71292 — Re: Values and objects

FromEthan Furman <ethan@stoneleaf.us>
Date2014-05-10 21:46 -0700
SubjectRe: Values and objects
Message-ID<mailman.9876.1399786897.18130.python-list@python.org>
In reply to#71240
[accidentally went off-list; sorry]

On 05/10/2014 02:03 PM, Devin Jeanpierre wrote:
>
> spam is referring to a local variable that has not been bound. This is
> not an implementation detail.

The implementation detail is that in cpython there is a spot already reserved for what will be the 'spam' variable, as 
opposed to the module level where no such spots are reserved.

> Because module level variables work differently from local variables.

Not by language definition.  There are pythons where modifying function locals works, but the working or not-working is 
not a language guarantee.

--
~Ethan~

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


#71294 — Re: [Python-Dev] Values and objects

FromChris Angelico <rosuav@gmail.com>
Date2014-05-11 16:08 +1000
SubjectRe: [Python-Dev] Values and objects
Message-ID<mailman.9878.1399788497.18130.python-list@python.org>
In reply to#71240
[ I think you meant for this to go to python-list, not python-dev.
Sending this to python-list. ]

On Sun, May 11, 2014 at 3:27 PM, Ethan Furman <ethan@stoneleaf.us> wrote:
> Seriously though, error messages are chosen to provide a simple and clear
> description that will help the user track down what went wrong, not for
> enshrining in exact detail the language semantics.  Would you really rather
> have:
>
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
>   File "<stdin>", line 2, in func
> UnboundLocalError: the name 'not_here' does not yet exist as you have not
> yet assigned anything to it so there is currently no variable by that name
> although at some point (in the future of this function, or perhaps in a
> branch that has been passed and did not execute) you will or did assign
> something to it so it will exist in the future of this function or may exist
> at this point in a future run of this function.
>
> or:
>
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
>   File "<stdin>", line 2, in func
> UnboundLocalError: local variable 'not_here' referenced before assignment

The way I'd say it is: The error text should be brief, and can leave
stuff out, but should not actively *conflict* with language semantics.
So if it says there's a local variable that hasn't been assigned, I
would expect it to mean that there is, according to language
semantics, a local variable that can be in a state of
not-being-assigned to. If that's not the case, the message definitely
needs to be changed, because it's actively misleading.

ChrisA

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


#71695 — Re: Values and objects

Fromalbert@spenarnc.xs4all.nl (Albert van der Horst)
Date2014-05-17 14:26 +0000
SubjectRe: Values and objects
Message-ID<5377717e$0$27137$e4fe514c@dreader35.news.xs4all.nl>
In reply to#71240
In article <536decca$0$29980$c3e8da3$5496439d@news.astraweb.com>,
<SNIP>
>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.

You're talking about Algol, but there is a great distinction between
Algol60 and Algol68. Algol68 through the ref keyword goes a long
way towards making variables first class citizens.
E.g. although `` int i'' in Algol68 means practically the same as in
C, it is defined as being an abbreviation of
'ref' 'int' i = 'loc' 'int';

This means so much that i is a reference to an otherwise unnamed int
that is allocated locally. Furthermore you can't break the tie between
i and that int (because you use =, you could have used := )
Because I refers to that location you can change it by
 i:=1;
Note that the left side *must* be a reference. You can't change an
int, you can only change the content of a memory place you can refer
to.

Now you can define
'ref' 'int' pi;
pi := i;

van Wijngaarden and crue pretty much nailed it, IMO.

<SNIP>

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

Groetjes Albert
-- 
Albert van der Horst, UTRECHT,THE NETHERLANDS
Economic growth -- being exponential -- ultimately falters.
albert@spe&ar&c.xs4all.nl &=n http://home.hccnet.nl/a.w.m.van.der.horst

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


#71212 — Re: Values and objects

FromChris Angelico <rosuav@gmail.com>
Date2014-05-10 11:58 +1000
SubjectRe: Values and objects
Message-ID<mailman.9839.1399687129.18130.python-list@python.org>
In reply to#71200
On Sat, May 10, 2014 at 8:34 AM, Marko Rauhamaa <marko@pacujo.net> wrote:
> Right, Python's variables aren't like variables in C. Rather, Python's
> variables are like CPU registers. They cannot hold typed or structured
> objects and you can't pass references to them.

Are you thinking that a Python variable is neither more nor less than
what CPython implements them as? Because I can design you a 100%
compliant Python implementation in which:

* Objects are represented with pieces of paper
* Object types are represented with 150GSM paper so it's easier to
find (note that an object type, being itself an object, must be
represented with paper)
* Named attributes and numeric indices (__[gs]etitem__) are recorded
with ink on the paper
* References, including from an object to its type, are pieces of
string linking an attribute to another object
* None is, in the interests of performance, represented by a piece of
string that dangles
* Functions get compiled down to a byte-code stored on eighty-column
punched card
* Integers and strings are always interned
* The image processing library is stored inside an actual pillowcase
* The 'print' function results in a human being speaking, and 'input'
waits for another human to speak, and constructs a string with what
was said

As far as I know, this could be done, and it would be perfectly
compliant with all of Python. It'd be horrendously slow, but Python's
specs never demand performance. It wouldn't have C-like variables, it
wouldn't have pointers (assigning "a = b" means looking up b, finding
which object the string connects to, gluing another string to that
same object, and severing any previous connection from a), and it
certainly wouldn't have 32-bit or 64-bit integers, or anything like
that. (Not that CPython has anything of the sort, as of 3.0, but it's
perfectly conceivable for a compliant Python to have an optimization
whereby "small" integers are handled more efficiently. Again, the
Python specs don't say either way.)

So what is a "variable" in this Python? Well... exactly what it is in
any other Python, because this is just as much Python as CPython,
Jython, PyPy, or any other.

ChrisA

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


#71231 — Re: Values and objects

FromMarko Rauhamaa <marko@pacujo.net>
Date2014-05-10 10:57 +0300
SubjectRe: Values and objects
Message-ID<874n0yt6am.fsf@elektro.pacujo.net>
In reply to#71212
Chris Angelico <rosuav@gmail.com>:

> On Sat, May 10, 2014 at 8:34 AM, Marko Rauhamaa <marko@pacujo.net> wrote:
>> Right, Python's variables aren't like variables in C. Rather,
>> Python's variables are like CPU registers. They cannot hold typed or
>> structured objects and you can't pass references to them.
>
> Are you thinking that a Python variable is neither more nor less than
> what CPython implements them as?

I was just being more Catholic than the Pope.

To me, a variable is a variable is a variable.


Marko

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


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

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


csiph-web