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

Closures and subs

6 views
Skip to first unread message

Klaas-Jan Stol

unread,
Nov 3, 2004, 7:55:58 PM11/3/04
to perl6-i...@perl.org
Hello,


I've been playing with closures and subs but I have a little bit of
trouble with those.
I'm a bit confused by all different flavours of syntax, I've been trying
to read and understand all documents concerning this subject, the most
useful was reading the test scripts. However, that is PASM, and I like
PIR better :-).

A general question is: what syntax should one use in what context?
(I understand that PCC should be used whenever one wants to interact
with other languages. Also, calling functions can be done in many ways)

A more specific question is this:
I'm trying to create a closure, and I think I've implemented this code
(it's lua code, but I'm not sure if it's 100% correct,
anyway, I'm trying to get a feeling for how one should translate this).
So, actually I have 2 questions;

(1): did I translate the function below correctly (I think the Lua
syntax won't be a problem, it's quite straightforward).
(2): what is causing my strange result (see below).

function main()

local p = 123;
local q = 345;

foo(q);
foo(q);

function foo(a) # nested function, it does have access to p in "main"
print(p);
p = p + p;

print(typeof(a));
print(a);
end
end

I would translate this to this PIR code:

.sub _main
new_pad 0

# local p = 123
.local pmc p
p = new .PerlInt
p = 123
store_lex 0, "p", p

# local q = 345
.local pmc q
q = new .PerlInt
q = 345
store_lex 0, "q", q

newsub $P0, .Closure, _foo

# foo(q)
.arg q
$P0()

# foo(q)
.arg q
$P0()

end
.end

.sub _foo
.param pmc a

# print(p);
find_lex $P0, "p"
print $P0

# p = p + p;
$P0 = $P0 + $P0
store_lex "p", $P0

# print(typeof(a));
$S0 = typeof a
print $S0 # ????

# print(a);
print a # ERROR!
.end

My problem with the last 2 statements is:
- the statement print(typeof(a)); print "SArray", which I don't understand.

- "print a" causes an error: "get_string() not implemented in SArray" (
I know that is because of a being an SArray)


I know there are more important issues at the moment, but if someone
could spare a moment, that'd be great. I'm trying to get a grip on
function syntax.

Regards,

Klaas-Jan Stol


Sam Ruby

unread,
Nov 3, 2004, 8:16:17 PM11/3/04
to Klaas-Jan Stol, perl6-i...@perl.org
Klaas-Jan Stol wrote:

> Hello,
>
>
> I've been playing with closures and subs but I have a little bit of
> trouble with those.
> I'm a bit confused by all different flavours of syntax, I've been trying
> to read and understand all documents concerning this subject, the most
> useful was reading the test scripts. However, that is PASM, and I like
> PIR better :-).
>
> A general question is: what syntax should one use in what context?
> (I understand that PCC should be used whenever one wants to interact
> with other languages. Also, calling functions can be done in many ways)
>
> A more specific question is this:
> I'm trying to create a closure, and I think I've implemented this code
> (it's lua code, but I'm not sure if it's 100% correct,
> anyway, I'm trying to get a feeling for how one should translate this).
> So, actually I have 2 questions;
>
> (1): did I translate the function below correctly (I think the Lua
> syntax won't be a problem, it's quite straightforward).
> (2): what is causing my strange result (see below).
>

[snip]


>
> # foo(q)
> .arg q
> $P0()

Try this instead:

$P0(q)

- Sam Ruby

Leopold Toetsch

unread,
Nov 4, 2004, 1:50:36 AM11/4/04
to Klaas-Jan Stol, perl6-i...@perl.org
Klaas-Jan Stol <vand...@home.nl> wrote:
> Hello,

> I've been playing with closures and subs but I have a little bit of
> trouble with those.

newsub $P0, .Closure, _foo
$P0(q)
newsub $P0, .Closure, _foo
$P0(q)

Closures have to be distinct.


leo

Klaas-Jan Stol

unread,
Nov 4, 2004, 4:42:50 AM11/4/04
to l...@toetsch.at, perl6-i...@perl.org
Leopold Toetsch wrote:

Thanks for your quick reactions.
Indeed, doing

$P0(q)

works ok. I'm a bit confused by syntax then (but I think it makes sense
now, if IMCC sees the "(", it is expecting args I guess)

In the mean time, I wrote another example for closures (maybe I should
collect these in a HOWTO document :-)
(This one *is* working, however, again I don't understand why some
things have to be done in a particular way)

First, I show the Lua code:

function newCounter ()
local i = 0
return function () -- anonymous function
i = i + 1
return i
end
end

c1 = newCounter()
print(c1()) --> 1
print(c1()) --> 2

This is the translation (and it works! :-)

.sub _newcounter
new_pad 0
# local i = 0
.local pmc i
i = new .PerlInt
i = 0
store_lex -1, "i", i

# create closure of "function" to return
.local pmc clos
newsub clos, .Closure, _function
# why should I do this? (should I?) ".return clos" does not work
(then it's whining about "SArray" again)
P5 = clos

.end

.sub _function
# i = i + 1
.local pmc j
find_lex j, "i"
j = j + 1
print j
store_lex -1, "j", j
# return i
.return j
.end

.sub _main @MAIN
# c1 = newcounter()
.local pmc c1
c1 = _newcounter()

# print(c1()) Prints 1
.local pmc i
i = c1()
print i
print "\n"

# print(c1()) Prints 2
i = c1()
print i
print "\n"

# print(c1()) Prints 3
i = c1()
print i
print "\n"
end
.end

So, this one works. I guess my question concerns syntax: why doesn't
".return clos" in newclosure() work?

Klaas-Jan

Klaas-Jan Stol

unread,
Nov 4, 2004, 5:45:19 AM11/4/04
to Klaas-Jan Stol, l...@toetsch.at, perl6-i...@perl.org

>
>
I now see I made some errors (I explain below)

> First, I show the Lua code:
>
> function newCounter ()
> local i = 0
> return function () -- anonymous function
> i = i + 1
> return i
> end
> end
> c1 = newCounter()
> print(c1()) --> 1
> print(c1()) --> 2
>
> This is the translation (and it works! :-)
>
> .sub _newcounter
> new_pad 0
> # local i = 0
> .local pmc i
> i = new .PerlInt
> i = 0
> store_lex -1, "i", i
>
> # create closure of "function" to return
> .local pmc clos
> newsub clos, .Closure, _function
> # why should I do this? (should I?) ".return clos" does not work
> (then it's whining about "SArray" again)

THIS should be done with a .pcc_begin/end_return pair, and with use of a
.return statement:

> P5 = clos
>
> .end
>
> .sub _function
> # i = i + 1
> .local pmc j
> find_lex j, "i"
> j = j + 1

THIS print should not be here:

> print j
> store_lex -1, "j", j
> # return i

THIS should be enclosed in .pcc_begin/end_return pair:

>
> .return j

> .end
>
> .sub _main @MAIN
> # c1 = newcounter()
> .local pmc c1
> c1 = _newcounter()
> # print(c1()) Prints 1
> .local pmc i i = c1()
> print i
> print "\n"
>
> # print(c1()) Prints 2
> i = c1()
> print i
> print "\n"
>
> # print(c1()) Prints 3
> i = c1()
> print i
> print "\n"
> end
> .end
>
> So, this one works. I guess my question concerns syntax: why doesn't
> ".return clos" in newclosure() work?
>
> Klaas-Jan
>
>
>

WHoops, I see I made a mistake:

1. it didn't work, like I thought. There was some print statement which
shouldn't be there, which caused me thinking it worked.
2. "P5 = clos" can be replaced by a .pcc_begin/end_return pair.

So, I think I 've got my answer there !

thanks anyway,
klaas-jan


Luke Palmer

unread,
Nov 3, 2004, 8:24:41 PM11/3/04
to Klaas-Jan Stol, perl6-i...@perl.org
I haven't written PIR in a while, and I'm not terribly familiar with the
new changes, but I'll make some guesses.

Klaas-Jan Stol writes:
> function main()
>
> local p = 123;
> local q = 345;
>
> foo(q);
> foo(q);
>
> function foo(a) # nested function, it does have access to p in "main"
> print(p);
> p = p + p;
>
> print(typeof(a));
> print(a);
> end
> end
>
> I would translate this to this PIR code:
>
> .sub _main
> new_pad 0
>
> # local p = 123
> .local pmc p
> p = new .PerlInt
> p = 123
> store_lex 0, "p", p

If I recall, store_lex 0 is meaningless, and you ought to be using
either store_lex 1 or store_lex -1. Not too sure about this one though.

>
> # local q = 345
> .local pmc q
> q = new .PerlInt
> q = 345
> store_lex 0, "q", q
>
> newsub $P0, .Closure, _foo
>
> # foo(q)
> .arg q
> $P0()

Shouldn't this be:

$P0(q)

? And likewise below?

>
> # foo(q)
> .arg q
> $P0()
>
> end
> .end
>
> .sub _foo
> .param pmc a
>
> # print(p);
> find_lex $P0, "p"
> print $P0
>
> # p = p + p;
> $P0 = $P0 + $P0

I feel a little uneasy about this line. I'm not sure how PIR interprets
this.

> store_lex "p", $P0
>
> # print(typeof(a));
> $S0 = typeof a
> print $S0 # ????
>
> # print(a);
> print a # ERROR!
> .end
>
> My problem with the last 2 statements is:
> - the statement print(typeof(a)); print "SArray", which I don't understand.

I'm going to guess that that's due to your use of .arg above.

Luke

Leopold Toetsch

unread,
Nov 4, 2004, 5:20:12 AM11/4/04
to Klaas-Jan Stol, perl6-i...@perl.org
Klaas-Jan Stol <vand...@home.nl> wrote:

> Thanks for your quick reactions.

You are welcome.

> Indeed, doing

> $P0(q)

> works ok. I'm a bit confused by syntax then (but I think it makes sense
> now, if IMCC sees the "(", it is expecting args I guess)

Yep. Function and method calls as well as *returns* have their arguments
in parenthesis.

> In the mean time, I wrote another example for closures (maybe I should
> collect these in a HOWTO document :-)

Yes please.

> (This one *is* working, however, again I don't understand why some
> things have to be done in a particular way)

> newsub clos, .Closure, _function


> # why should I do this? (should I?) ".return clos" does not work
> (then it's whining about "SArray" again)
> P5 = clos

.return(clos)

> find_lex j, "i"
> j = j + 1
> print j
> store_lex -1, "j", j

The store_lex isn't really necessary, as you are modifying "j" in place-

> .return j

.return(j)

> Klaas-Jan

leo

Piers Cawley

unread,
Nov 4, 2004, 5:59:18 PM11/4/04
to l...@toetsch.at, Klaas-Jan Stol, perl6-i...@perl.org
Leopold Toetsch <l...@toetsch.at> writes:

Does this *really* mean that, if I create a closure in a function and
return it to my caller, that closure can only be invoked once?

If it does, this is slightly more broken than a very broken thing.

Leopold Toetsch

unread,
Nov 5, 2004, 2:43:12 AM11/5/04
to Piers Cawley, perl6-i...@perl.org
Piers Cawley <pdca...@bofh.org.uk> wrote:
> Leopold Toetsch <l...@toetsch.at> writes:

>> Klaas-Jan Stol <vand...@home.nl> wrote:
>>> Hello,
>>
>>> I've been playing with closures and subs but I have a little bit of
>>> trouble with those.
>>
>> newsub $P0, .Closure, _foo
>> $P0(q)
>> newsub $P0, .Closure, _foo
>> $P0(q)
>>
>> Closures have to be distinct.

> Does this *really* mean that, if I create a closure in a function and
> return it to my caller, that closure can only be invoked once?

No, it can be invoked as often you like.

But above case seems to be different and very similar to what I already
asked:

(define (choose . all-choices)
(let ((old-fail fail))
(call-with-current-continuation

You remember that snippet, it's now a test in t/op/gc.t. I had to insert
the line below XXX and use a second closure, which has the "arr2" in it's
context.

newsub choose, .Closure, _choose
x = choose(arr1)

# XXX need this these closures have different state
newsub choose, .Closure, _choose
y = choose(arr2)

The question was, if that's technically correct.

leo

Piers Cawley

unread,
Nov 5, 2004, 1:19:03 PM11/5/04
to l...@toetsch.at, perl6-i...@perl.org
Leopold Toetsch <l...@toetsch.at> writes:

Ah... of course, I was asking a stupid question. Always the most
plausible hypothesis I think.

--
Piers
Oh, predicting the future's easy, you just make a continuation at the
point you're asked, say anything and head off into the future to find what
happens, then take the continuation back to the question and give a more
accurate answer. -- me in #parrot

0 new messages