Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

why new_pad *INT*?

1 view
Skip to first unread message

Michal Wallace

unread,
Aug 9, 2003, 4:42:04 AM8/9/03
to perl6-i...@perl.org

Hey all,

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


Sean O'Rourke

unread,
Aug 9, 2003, 10:46:25 AM8/9/03
to Michal Wallace, perl6-i...@perl.org
Michal Wallace <mic...@sabren.com> writes:
> 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) ?

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

Michal Wallace

unread,
Aug 9, 2003, 6:28:30 PM8/9/03
to Sean O'Rourke, perl6-i...@perl.org
On Sat, 9 Aug 2003, Sean O'Rourke wrote:

> 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


Sean O'Rourke

unread,
Aug 9, 2003, 7:38:20 PM8/9/03
to Michal Wallace, perl6-i...@perl.org
Michal Wallace <mic...@sabren.com> writes:
> Okay, I definitely need some help understanding this.

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

Michal Wallace

unread,
Aug 10, 2003, 4:54:28 PM8/10/03
to Sean O'Rourke, perl6-i...@perl.org
On Sat, 9 Aug 2003, Sean O'Rourke wrote:

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

0 new messages