Nested function scope problem

D

Dennis Lee Bieber

There's maybe a point in comparing Python variables to C pointers. But it
lacks in the respect that a C programmer is used to modify memory locations
through pointers. A Python programmer isn't used to modify memory locations
in the first place, and simple objects don't get modified at all. There's
no Python equivalent to "int*p=345; *p++;". (There's no need for that in
Python; I'm not saying this shows a superiority of C. It just shows a
different concept of what "variable" means.)
Python

c = c + 100

pseudo-C (where I use _p to indicate explicit pointer; and all data
objects are a structure of the form: int ref_count; <object type> data)

scratch_p = malloc()
scratch_p->data = c_p->data + 100
scratch_p->ref_count = 1
c_p->ref_count--
if !c_p->ref_count
free(c_p)
c_p = scratch_p

-------
b = a
is
b = a
b->ref_count++


For me, the point of this discussion was that it makes sense to look at it
/differently/. Once you've done that, there's no problem in continuing to
use the (vaguely defined) term "variable".

Think the above is "different" enough <G>
--
Wulfraed Dennis Lee Bieber KD6MOG
(e-mail address removed) (e-mail address removed)
HTTP://wlfraed.home.netcom.com/
(Bestiaria Support Staff: (e-mail address removed))
HTTP://www.bestiaria.com/
 
A

Antoon Pardon

Python

c = c + 100

pseudo-C (where I use _p to indicate explicit pointer; and all data
objects are a structure of the form: int ref_count; <object type> data)

scratch_p = malloc()
scratch_p->data = c_p->data + 100
scratch_p->ref_count = 1
c_p->ref_count--
if !c_p->ref_count
free(c_p)
c_p = scratch_p

-------
b = a
is
b = a
b->ref_count++




Think the above is "different" enough <G>

The above are implementation details.

Suppose I write a C-interpreter and then would translate a statement
like "c = c + 100" into actions the interpreter would have to take in
order to excute that statement. Something like:

c-addr_p = GetAddress("c");
c-value = *c-addr_p;
sum = c-value + 100;
*c-addr_p = sum;

That look different enough from just "c = c + 100". So maybe C
has no variables either.
 
D

Dennis Lee Bieber

Suppose I write a C-interpreter and then would translate a statement
like "c = c + 100" into actions the interpreter would have to take in
order to excute that statement. Something like:

c-addr_p = GetAddress("c");
c-value = *c-addr_p;
sum = c-value + 100;
*c-addr_p = sum;
If this is what your interpreter generates/executes for a C-language
assignment, then the source language is no longer C... After all,
Python's most common implementation IS in C.

In C, the difference between "c" as a pointer, and "*c" as what it
points to is explicitly exposed to the user... The two views can be
separately manipulated. "c" as a variable can be manipulated -- c++
changes c to "point to" an object (of the type of "c") that is presumed
to follow the existing object -- whether such exists or not.

Python does not expose that to the user... You have a name and you
have an object. The name exists, or it doesn't, independent of the
object. Not in C -- while the object may not exist, the name, to be used
at all, has to exist and has storage space assigned to it; storage the
programmer is able to manipulate without an object.

--
Wulfraed Dennis Lee Bieber KD6MOG
(e-mail address removed) (e-mail address removed)
HTTP://wlfraed.home.netcom.com/
(Bestiaria Support Staff: (e-mail address removed))
HTTP://www.bestiaria.com/
 
A

Antoon Pardon

If this is what your interpreter generates/executes for a C-language
assignment, then the source language is no longer C...

How do you come to that decision?
After all, Python's most common implementation IS in C.

In C, the difference between "c" as a pointer, and "*c" as what it
points to is explicitly exposed to the user... The two views can be
separately manipulated. "c" as a variable can be manipulated -- c++
changes c to "point to" an object (of the type of "c") that is presumed
to follow the existing object -- whether such exists or not.

Python does not expose that to the user... You have a name and you
have an object. The name exists, or it doesn't, independent of the
object. Not in C -- while the object may not exist, the name, to be used
at all, has to exist and has storage space assigned to it; storage the
programmer is able to manipulate without an object.

And how is this all relevant in deciding that the source language for
the above interpreter actions isn't C? What the interpreter does is
the following:

Get the addres of the variable c
Get the value that is at that address.
Add 100 to this value
Store the new value at that address.

Please explain what is wrong in this sequence of actions
for an interpretation of the C statement: "c = c + 100;"
 
D

Dennis Lee Bieber

And how is this all relevant in deciding that the source language for
the above interpreter actions isn't C? What the interpreter does is
the following:

Get the addres of the variable c
Get the value that is at that address.
Add 100 to this value
Store the new value at that address.

Please explain what is wrong in this sequence of actions
for an interpretation of the C statement: "c = c + 100;"

What interpretation will your hypothetical give for:

c = &c + 1
c++

and

d = *(1000) #I'll concede this one may be a bit invalid
#I don't recall if a cast is needed
--
Wulfraed Dennis Lee Bieber KD6MOG
(e-mail address removed) (e-mail address removed)
HTTP://wlfraed.home.netcom.com/
(Bestiaria Support Staff: (e-mail address removed))
HTTP://www.bestiaria.com/
 
A

Antoon Pardon

What interpretation will your hypothetical give for:

c = &c + 1
c++

and

d = *(1000) #I'll concede this one may be a bit invalid
#I don't recall if a cast is needed

Why should I answer this? You stated that my interpreter couldn't
be interpreting the C-language. You did that before you asked these
questions. So it seems your decision for your statement is not
dependend om my answer for these questions. So please clarify
how you came to your decision.
 
S

Slawomir Nowaczyk

On Sun, 30 Jul 2006 11:18:10 -0300

#> In any case, the following doesn't seem to be implementation detail
#> (and rather a part of the language), but it's not really
#> understandable with a C++ concept of "variable":
#>
#> >>> a=3
#> >>> id(a)
#> 3368152
#> >>> b=a
#> >>> id(b)
#> 3368152
#> >>> b=4
#> >>> id(b)
#> 3368140

How about that?

int main()
{
int three = 3;
int four = 4;
int *a, *b;
a = &three;
printf("%i %i\n",a,*a);
b = a;
printf("%i %i\n",b,*b);
b = &four;
printf("%i %i\n",b,*b);
return 0;
}

Just in case you don't have C compiler at hand, it prints:

1244896 3
1244896 3
1244888 4

#> You don't expect the "identity" of the variable b to change with a simple
#> assignment from a C/C++ point of view.

That depends on your definition of "identity", of course.

#> You also don't expect the "identity" of a and b to be the same
#> after assigning one to the other.

Don't I?

--
Best wishes,
Slawomir Nowaczyk
( (e-mail address removed) )

You can tell a bigot, but you can't tell him much.
 
D

Dennis Lee Bieber

int main()
{
int three = 3;
int four = 4;
int *a, *b;
a = &three;
printf("%i %i\n",a,*a);
b = a;
printf("%i %i\n",b,*b);
b = &four;
printf("%i %i\n",b,*b);
return 0;
}

Just in case you don't have C compiler at hand, it prints:

1244896 3
1244896 3
1244888 4
Ah... but notice that YOU had to differentiate by explicitly taking
the address of the constants, and by explicitly derefencing the pointers
to show the values.

What does &a, &b reveal? BEFORE anything has been "assigned" to them
<G> You can't get the address of the name "a" in Python, but you can in
C.

--
Wulfraed Dennis Lee Bieber KD6MOG
(e-mail address removed) (e-mail address removed)
HTTP://wlfraed.home.netcom.com/
(Bestiaria Support Staff: (e-mail address removed))
HTTP://www.bestiaria.com/
 
G

Gerhard Fiedler

#> In any case, the following doesn't seem to be implementation detail
#> (and rather a part of the language), but it's not really
#> understandable with a C++ concept of "variable":
#>
#> >>> a=3
#> >>> id(a)
#> 3368152
#> >>> b=a
#> >>> id(b)
#> 3368152
#> >>> b=4
#> >>> id(b)
#> 3368140

How about that?

int main()
{
int three = 3;
int four = 4;
int *a, *b;
a = &three;
printf("%i %i\n",a,*a);
b = a;
printf("%i %i\n",b,*b);
b = &four;
printf("%i %i\n",b,*b);
return 0;
}

Just in case you don't have C compiler at hand, it prints:

I don't have to :)

But seriously, for my comment this seems off-topic. I did not say that you
can't create Python behavior with C (of course you can, you can do
/everything/ in C :). You can build constructs made up of C variables that
simulate everything that any Python construct does. That's not the point.
The point is how the simple, built-in language variable behaves.
#> You don't expect the "identity" of the variable b to change
#> with a simple assignment from a C/C++ point of view.

That depends on your definition of "identity", of course.

Right. "Identity" is not defined in C, but most C programmers would
probably take the address of a variable as the closest to a variable's
identity.
#> You also don't expect the "identity" of a and b to be the same
#> after assigning one to the other.

Don't I?

I don't know. Try replacing your printf statements with something like
"printf("%x %i %i\n",&a,a,*a);" and watch the first column. The address
operator is probably for a C programmer the closest to what the id()
function is to a Python programmer.

Gerhard
 
S

Slawomir Nowaczyk

On Sat, 05 Aug 2006 02:55:03 -0700

#> Gerhard Fiedler wrote:
#> > There's no Python equivalent to "int*p=345; *p++;".
#>
#> Sure there is:
#>
#> os.kill(os.getpid(), signal.SIGSEGV)

LOL... that's a good one :)

--
Best wishes,
Slawomir Nowaczyk
( (e-mail address removed) )

90% of the time I'm right, so why worry about the other 3%?
 
E

enigmadude

I agree with the previous comments that this approach is "bad form".
But if you absolutely *must* modify an enclosing function's variables
with an inner function, all you need to do is remember that a Python
function is an object too, so it can be assigned attributes. ;-)

def outer():
outer.x = 1
print outer.x

def inner():
outer.x = 2

inner()
print outer.x
 
G

Gabriel Genellina

At said:
I agree with the previous comments that this approach is "bad form".
But if you absolutely *must* modify an enclosing function's variables
with an inner function, all you need to do is remember that a Python
function is an object too, so it can be assigned attributes. ;-)

def outer():
outer.x = 1
print outer.x

def inner():
outer.x = 2

inner()
print outer.x

I see two problems:
- Concurrency: two or more threads executing the same function,
writing to this "global"
- Can't be used (easily) on methods

> def addTok():
> if len(tok) > 0:
> ls.append(tok)
> tok = ''
>
>

class mylist(list)
def addTok(self, tok):
if len(tok)>0:
self.append(tok)
tok = ''
return tok

ls = mylist()
and use: tok = ls.addTok(tok) whenever the original code says addTok(tok)



Gabriel Genellina
Softlab SRL





__________________________________________________
Preguntá. Respondé. Descubrí.
Todo lo que querías saber, y lo que ni imaginabas,
está en Yahoo! Respuestas (Beta).
¡Probalo ya!
http://www.yahoo.com.ar/respuestas
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,164
Latest member
quinoxflush
Top