I'm just starting to get into using pads,
and I'm not sure I understand new_pad.
Specifically, why does it take an int?
It seems to me, that 9 times out of 10,
you're going to want to create a new
pad at the next lower depth than the
one before.
So, two questions:
1. Should there be a new_pad that takes
no arguments to do this, so we don't
have to keep count manually?
2. When would you NOT want to use
new_pad (current_depth+1) ?
Sincerely,
Michal J Wallace
Sabren Enterprises, Inc.
-------------------------------------
contact: mic...@sabren.com
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--------------------------------------
Remember, the pad depth reflects lexical scope nesting,
not dynamic scoping. So if you mean "current_depth" as
"current compile-time depth" above, then you're right,
but the VM would have no way to tell. If you mean
run-time depth, which the compiler could know
about... A top-level sub should not create a new pad at
depth + 1, since that would put it inside its caller's
lexical scope, which would just be weird.
/s
> Remember, the pad depth reflects lexical scope nesting,
> not dynamic scoping. So if you mean "current_depth" as
> "current compile-time depth" above, then you're right,
> but the VM would have no way to tell. If you mean
> run-time depth, which the compiler could know
> about... A top-level sub should not create a new pad at
> depth + 1, since that would put it inside its caller's
> lexical scope, which would just be weird.
Okay, I definitely need some help understanding this.
Here's some python code that defines a closure:
def make_adder(base):
def adder(x):
return base+x
return adder
h = make_adder(10)
print h(5)
When I run this in python 2.2, it prints "15".
When I run it through pirate, I get this:
-scratch_pad: too deep
Now, in my mind:
depth 0 has: make_adder, h
depth 1 has: base, adder
depth 2 has: x
The top level .sub should start with 'new_pad 0'
The make_adder .pcc_sub should start with 'new_pad 1'
The adder .pcc_sub should start with 'new_pad 2'
I think the error happens because I'm calling a depth 2
function from depth 0, but if I change adder's new_pad
depth to 1, it can't find "base".
I don't know how to get this to work the way I want.
Can anyone help me out here?
(Generated code follows - note the "GETS HERE" line)
Sincerely,
Michal J Wallace
Sabren Enterprises, Inc.
-------------------------------------
contact: mic...@sabren.com
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--------------------------------------
.sub __main__
new_pad 0
setline 2
newsub $P0, .Sub, _sub0
store_lex -1, 'make_adder', $P0
.local object h
.local object arg0
arg0 = new PerlInt
arg0 = 10
find_lex $P5, 'make_adder'
newsub $P6, .Continuation, ret0
.pcc_begin non_prototyped
.arg arg0
.pcc_call $P5, $P6
ret0:
.result h
.pcc_end
store_lex -1, 'h', h
.local object arg1
arg1 = new PerlInt
arg1 = 5
find_lex $P8, 'h'
newsub $P9, .Continuation, ret1
.pcc_begin non_prototyped
.arg arg1
.pcc_call $P8, $P9
ret1:
.result $P7
.pcc_end
.arg $P7
call __py__print
print "\n"
end
.end
.include 'pirate.imc'
# make_adder from line 2
.pcc_sub _sub0 non_prototyped
.param object base
new_pad 1
store_lex -1, 'base', base
setline 3
newsub $P1, .Sub, _sub1
store_lex -1, 'adder', $P1
.local object res1
find_lex res1, 'adder'
pop_pad
.pcc_begin_return
.return res1
.pcc_end_return
.end
# adder from line 3
.pcc_sub _sub1 non_prototyped
print "GETS HERE!\n" ########
new_pad 2
print "WON'T GET HERE!\n" ########
.param object x
store_lex -1, 'x', x
.local object res0
find_lex $P2, 'base'
find_lex $P3, 'x'
$P4 = new PerlUndef
$P4 = $P2 + $P3
res0 = $P4
pop_pad
.pcc_begin_return
.return res0
.pcc_end_return
.end
Okay, I definitely did a suboptimal job trying to
clarify...
> Here's some python code that defines a closure:
>
> def make_adder(base):
> def adder(x):
> return base+x
> return adder
> h = make_adder(10)
> print h(5)
>
> When I run this in python 2.2, it prints "15".
>
> When I run it through pirate, I get this:
>
> -scratch_pad: too deep
>
> Now, in my mind:
>
> depth 0 has: make_adder, h
> depth 1 has: base, adder
> depth 2 has: x
This sounds right.
> The top level .sub should start with 'new_pad 0'
> The make_adder .pcc_sub should start with 'new_pad 1'
> The adder .pcc_sub should start with 'new_pad 2'
Right.
> I think the error happens because I'm calling a depth 2
> function from depth 0, but if I change adder's new_pad
> depth to 1, it can't find "base".
>
> I don't know how to get this to work the way I want.
> Can anyone help me out here?
> ...
> # make_adder from line 2
> .pcc_sub _sub0 non_prototyped
> .param object base
> new_pad 1
> store_lex -1, 'base', base
> setline 3
> newsub $P1, .Sub, _sub1
The problem is that when adder() gets returned, it
needs to remember the enclosing pad. So this needs to
be
newsub $P1, .Closure, _sub1
which (IIRC) will save the lexical environment in which
it was created (see closure.pmc), then restore that
when it is invoked.
/s
> The problem is that when adder() gets returned, it
> needs to remember the enclosing pad. So this needs to
> be
>
> newsub $P1, .Closure, _sub1
>
> which (IIRC) will save the lexical environment in which
> it was created (see closure.pmc), then restore that
> when it is invoked.
Thanks! I see the light. :)
I just made all python routines closures for now,
and all my tests passed.