Re: No Cpow op with PMC arguments?
Sam Ruby wrote: This omission seems odd. Was this intentional? A single pow_p_p_p op backed by a (non-MMD) vtable entry would make it easier to support code like the following: Well, Python has a pow vtable slot. And it should be MMD. Patches welcome, leo
Re: Closures and subs
Klaas-Jan Stol [EMAIL PROTECTED] 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
Re: [PATCH] [resend] support of uniline yield/return
Stéphane Payrard wrote: My previous mail to [EMAIL PROTECTED] did not seem to make it. So the resend with many recipients. This is the patch to support the uniline yield/return we talked 2 weeks ago. I know that Leo advocate to separate the implementation of PASM and PIR. By retailoring the grammar and the code such patches paves the way for such a separation. Thanks, applied. leo
Re: Solicitation of Ideas for Performance Statistics and Graphs
Joshua Gatcomb [EMAIL PROTECTED] wrote: If you would like to see any of these ideas implemented, or you have some of your own - please respond to this on the list. I've amother one. Parrot has some internal settings and tweakable magic constants, mainly all inside the garbage collector. It would be great, if some of these settings could be compared. E.g. # bench.config [ Default ] # label for config section / graph [ IMS GC ]# incremental MS GC # file # subst to turn config on include/parrot/settings.h s/(PARROT_GC_MS)\s+1/$1 0/ # next setting, either based on previous or on default Now instead of an overlay graph of unoptimized/optimized/non-JIT/JIT (which isn't utterly useful) I'd like to see a comparison of the given configurations, optimized build only. WRT parrot run-options: there is a -Ot switch, which should enable the fastest runtime options available on that machine. Cheers Joshua Gatcomb leo
Re: [PATCH] dynclass build
Sam Ruby [EMAIL PROTECTED] wrote: Attached patch makes building in the dynclass ghetto a bit less inhospitable... Thanks, applied. leo
Re: No Cpow op with PMC arguments?
On Nov 3, 2004, at 8:09 AM, Dan Sugalski wrote: At 11:04 AM -0500 11/3/04, Sam Ruby wrote: A single pow_p_p_p op backed by a (non-MMD) vtable entry would make it easier to support code like the following: def f(x): return x**3 print f(3), f(2.5) Yeah, it would. I know I'm going to regret asking, but... any reason *not* to make it MMD? (Though I have no idea what happens if you square a matrix) I feel like we have op-itis and vtable-itis. I would think that rather than a pow_p_p_p, you'd compile x**y as something like: set N0, P0 set N1, P1 pow N2, N0, N1 new P2, .PythonNumber assign P2, N2 I.e., PMCs don't inherently exponentiate--numbers do, and you can exponentiate PMCs by numberizing them, exponentiating, and creating a PMC with the result. Or, if we must have an op, implement it something like this (without needing a new vtable entry, or MMD): inline op pow(out PMC, in PMC, in PMC) :base_core { $1 = pmc_new(interpreter, $2-vtable-type(interpreter, $2)); $1-vtable-set_number_native(interpreter, $1, pow( $2-vtable-get_number(interpreter, $2), $3-vtable-get_number(interpreter, $3))) goto NEXT(); } Those would probably JIT to about the same thing, given register mapping. This is the viewpoint that pow() isn't a fundamental operation that makes sense for all types; it's a numeric operation, which can be extended in a straighforward manner to types which know how to represent themselves as numbers. (e.g., it's gibberish to raise a ManagedStruct to a ParrotIO power, except that you can stretch and interpret such a thing as just implicit num-ification of the arguments.) JEff
Re: Closures and subs
Leopold Toetsch wrote: Klaas-Jan Stol [EMAIL PROTECTED] 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 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
Re: Closures and subs
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
Re: Closures and subs
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
Please, Help on I/O
I have the folowing program : print Give me an integer number : ¥n getstdinP0 readline S1,P0 Its execution gives : 10 Give me an integer number : How is it possible to flush stdout before reading the number. It means the equivalent of the $| in Perl. __ \|||/ (o o) +--ooO-( )-Ooo--+ | Christian Aperghis-Tramoni | | | | Case Postale 901 Tel : (33) 04 91 82 92 49 | | 163 Avenue de Luminy SFR : (33) 06 18 93 10 70 | | 13288 Marseille Cedex 09 Fax : (33) 04 91 82 92 75 | | FranceMel : [EMAIL PROTECTED] | /) [EMAIL PROTECTED](\ / ) WEB : http://www.dil.univ-mrs.fr/~chris ( \ ( (+---+) ) ((\ \) / ) / ) (/ //) (\\\ \_/ /\ \_/ ///) \ /\ / ___\___/__\___/ print join('',map({$i=1-$i;$a=$i?10*$_.\b\b:packc,$a+$_+0x16}split (//,5110789279758710838810587992861093898779948387799310)),...\n); ___
Re: Please, Help on I/O
On Thu Nov 4 11:53:45 2004, Christian Aperghis-Tramoni wrote: It means the equivalent of the $| in Perl. You can switch off buffering on stdout by doing: getstdout P1 pioctl I0, P1, 3, 0 To switch back to line buffering, do: getstdout P1 pioctl I0, P1, 3, 1 -- Marty
Re: No Cpow op with PMC arguments?
Jeff Clites wrote: On Nov 3, 2004, at 8:09 AM, Dan Sugalski wrote: At 11:04 AM -0500 11/3/04, Sam Ruby wrote: A single pow_p_p_p op backed by a (non-MMD) vtable entry would make it easier to support code like the following: def f(x): return x**3 print f(3), f(2.5) Yeah, it would. I know I'm going to regret asking, but... any reason *not* to make it MMD? (Though I have no idea what happens if you square a matrix) I feel like we have op-itis and vtable-itis. I would think that rather than a pow_p_p_p, you'd compile x**y as something like: set N0, P0 set N1, P1 pow N2, N0, N1 new P2, .PythonNumber assign P2, N2 I.e., PMCs don't inherently exponentiate--numbers do, and you can exponentiate PMCs by numberizing them, exponentiating, and creating a PMC with the result. Or, if we must have an op, implement it something like this (without needing a new vtable entry, or MMD): inline op pow(out PMC, in PMC, in PMC) :base_core { $1 = pmc_new(interpreter, $2-vtable-type(interpreter, $2)); $1-vtable-set_number_native(interpreter, $1, pow( $2-vtable-get_number(interpreter, $2), $3-vtable-get_number(interpreter, $3))) goto NEXT(); } Those would probably JIT to about the same thing, given register mapping. This is the viewpoint that pow() isn't a fundamental operation that makes sense for all types; it's a numeric operation, which can be extended in a straighforward manner to types which know how to represent themselves as numbers. (e.g., it's gibberish to raise a ManagedStruct to a ParrotIO power, except that you can stretch and interpret such a thing as just implicit num-ification of the arguments.) From a Python or Ruby language perspective, infix operators are not fundamental operations associated with specific types, they are syntactic sugar for method calls. A the moment, I'm compiling x=y**z into: x = y.__pow__(z) There is nothing reserved about the name __pow__. Any class can define a method by this name, and such methods can accept arguments of any type, and return objects of any type. They can be called explicitly, or via the infix syntax. What's the downside of compiling this code in this way? If you are a Python programmer and all the objects that you are dealing with were created by Python code, then not much. However, if somebody wanted to create a language independent complex number implementation, then it wouldn't exactly be obvious to a Python programmer how one would raise such a complex number to a given power. Either the authors of the complex PMC would have to research and mimic the signatures of all the popular languages, or they would have to provide a fallback method that is accessible to all and educate people to use it. Ultimately, Parrot will need something akin to .Net's concept of a Common Language Specification which defines a set of rules for designing code to interoperate. A description of .Net's CLS rules can be found in sections 7 and 11 (a total of six pages) in the CLI Partition I - Architecture document[1]. - Sam Ruby [1] http://msdn.microsoft.com/net/ecma/
Re: [PATCH] dynclass build
At 10:07 AM +0100 11/4/04, Leopold Toetsch wrote: Sam Ruby [EMAIL PROTECTED] wrote: Attached patch makes building in the dynclass ghetto a bit less inhospitable... Thanks, applied. Are we comfortable adding the dynclasses to the default build target? I want to at some point, if only to make really sure that we don't break them. (As stuff that gets built and tested by default stays up to date, while the rest... tends not to) -- Dan --it's like this--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: [PATCH] dynclass build
Dan Sugalski wrote: At 10:07 AM +0100 11/4/04, Leopold Toetsch wrote: Sam Ruby [EMAIL PROTECTED] wrote: Attached patch makes building in the dynclass ghetto a bit less inhospitable... Thanks, applied. Are we comfortable adding the dynclasses to the default build target? I want to at some point, if only to make really sure that we don't break them. (As stuff that gets built and tested by default stays up to date, while the rest... tends not to) The best way to find out is to add it. I would prefer that this be added sooner rather than later, and now is as good a time as any. Within a day or so, I should have an initial set of python PMCs that I would like to see committed, as well as the beginnings of a test suite. - Sam Ruby
Re: No Cpow op with PMC arguments?
At 1:19 AM -0800 11/4/04, Jeff Clites wrote: On Nov 3, 2004, at 8:09 AM, Dan Sugalski wrote: At 11:04 AM -0500 11/3/04, Sam Ruby wrote: A single pow_p_p_p op backed by a (non-MMD) vtable entry would make it easier to support code like the following: def f(x): return x**3 print f(3), f(2.5) Yeah, it would. I know I'm going to regret asking, but... any reason *not* to make it MMD? (Though I have no idea what happens if you square a matrix) I feel like we have op-itis and vtable-itis. I would think that rather than a pow_p_p_p, you'd compile x**y as something like: Or, in this case, MMD-itis, since that's the right thing to do here. If it can be overridden, and in this case it certainly can, then we must allow for it. We only get to scam for speed *after* we meet the basic language requirements. -- Dan --it's like this--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: Quality from the Beginning: Better Estimates
Thanks for all the feedback and suggestions for improving estimation. Based on this and other research, I expect to make a sort of best practices documentation for use at my small professional services firm. I'm thinking of including these key parts in it: 1. A checklist of things to consider when estimating. This is especially for the non programming parts. While not meant to be comprehensive, it may help to jar the memory about factors that come into play. 2. Have all significant estimates peer reviewed. Perhaps reality-checked is more what I have in mind. Did I leave out some part of the process that takes time? Does anything seem really off? 3. A spreadsheet to document past estimates, with columns for estimated time, actual time, scope, and risk factors 4. Reward good estimates. :) Comments? Mark -- . . . . . . . . . . . . . . . . . . . . . . . . . . . Mark StosbergPrincipal Developer [EMAIL PROTECTED] Summersault, LLC 765-939-9301 ext 202 database driven websites . . . . . http://www.summersault.com/ . . . . . . . .
estimating other people's work (was Re: Quality from the Beginning: Better Estimates)
I also have a follow-up question: Another real world constraint is that sometimes by the time the client approves the quote, I'm involved in another project and it works better logistically to have another programmer complete the task (or help with it). Since programmers are not plug and play units, we have different levels of efficiency. What, if anything, do you to do address this in estimates? Perhaps you feel there's generally programmer parity and don't worry so much about this. I, for one, know I can feel uneasy if I have to work on a budget for programming work that I didn't contribute to myself. Mark -- . . . . . . . . . . . . . . . . . . . . . . . . . . . Mark StosbergPrincipal Developer [EMAIL PROTECTED] Summersault, LLC 765-939-9301 ext 202 database driven websites . . . . . http://www.summersault.com/ . . . . . . . .
Does Parrot have True coroutines?
Hello, I spoke (through email) with Roberto Ierusalimschy, one of the creators of the Lua programming language, and I said that Parrot has good support for implementing coroutines and closures (heck, they are explicitly there). However, in a reply, Roberto asked: Are you sure Parrot support true coroutines? Does it integrate coroutines and closures correctly? (For instance, a single closure may refer to variables in several different coroutines.) M, I wouldn't know. In Lua, one can create a coroutine explicitly (through a kind of package coroutine, an example is included: co = coroutine.create(function () for i=1,10 do print(co, i) coroutine.yield() end end) Anybody got a clue on whether Parrot has true coroutines? thanks, Klaas-Jan
Re: No Cpow op with PMC arguments?
Jeff Clites [EMAIL PROTECTED] wrote: I feel like we have op-itis and vtable-itis. I'm for sure the last one that would add an opcode or a vtable, if it's not needed. But in that case it has to be one. The PMC can be any kind of plain scalar and also *complex*. We have different operations with different results. So your example set N0, P0 set N1, P1 pow N2, N0, N1 doesn't work for complex numbers. $1-vtable-set_number_native(interpreter, $1, Same problem. JEff leo
Re: Closures and subs
Klaas-Jan Stol [EMAIL PROTECTED] 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
Re: [PATCH] dynclass build
At 3:51 PM +0100 11/4/04, Leopold Toetsch wrote: Dan Sugalski [EMAIL PROTECTED] wrote: Are we comfortable adding the dynclasses to the default build target? I think it can go in. Lets do that then. I want to at some point, if only to make really sure that we don't break them. (As stuff that gets built and tested by default stays up to date, while the rest... tends not to) Good point. We need tests: 1) basic operation: is dynclass loading working (current samples, modified not to use absolute type numbers) 2) Where should dynamic {tcl, perl, python, ...}_classes tests go? t/xt/$lang # xt for extension and test sorting? If the individual dynclasses have pir or pasm that can test them, then it can go in t/dynclass/pmcname.t. If it needs anything fancier... we can punt for now. Language specific PMCs can be tested in the language's test suite, I expect. -- Dan --it's like this--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: [PATCH] dynclass build
Dan Sugalski [EMAIL PROTECTED] wrote: Are we comfortable adding the dynclasses to the default build target? I think it can go in. I want to at some point, if only to make really sure that we don't break them. (As stuff that gets built and tested by default stays up to date, while the rest... tends not to) Good point. We need tests: 1) basic operation: is dynclass loading working (current samples, modified not to use absolute type numbers) 2) Where should dynamic {tcl, perl, python, ...}_classes tests go? t/xt/$lang # xt for extension and test sorting? leo
Intermittently Failing Benchmarks
All: In collecting the historical data for the benchmark statistics and graphs, I discovered that there were a few days where I had to play the CVS time game to get a working parrot for that day. I expected this. What I have found interesting though is when individual benchmarks don't work. For instance, from 10/20 to 10/22, gc_generations and gc_header_reuse would just hange (still running after 10 minutes). Last night (11/3 at 23:59) addit2.imc is doing the same thing. I checked a up to the minute checkout and it is finishing now - but there is no printed output. So I have 2 questions: 1. Would people prefer missing data for benchmarks where they won't work or a manually entered high number to draw attention to them? 2. Should we be checking that the output of the benchmarks (right or wrong) is consistent? Cheers Joshua Gatcomb a.k.a. Limbic~Region __ Do you Yahoo!? Check out the new Yahoo! Front Page. www.yahoo.com
Re: estimating other people's work (was Re: Quality from the Beginning: Better Estimates)
Mark, This can be an issue, however I think it is easily solved. 1) Use a mean between the most efficient and least efficient programmers times, since it could be either one (and probably both) who work on it. In many situations, your more efficient programmer is managing your less efficient programmers, so the more efficient one will have an idea of what that 'mean' time will be, and maybe even give that to you from the start knowing full well that he/she might not do all the work on it. 2) Keep good programmers around. This is not as simple as is sounds, since we all know programmers (me included) are moody beasts. But I know for me, if I am challanged and feel respected, I will stick around. Its only when I am bored and don't feel like I am contributing and respected that I will start surfing the job boards during my lunch hour. The basic idea is that you try to avoid having too much of a difference between the most efficient programmers and the least efficient, and therefore reduce this problem as a whole while also increasing the quality of your product (and you can see all the futher benefits I'm sure). Hope this helps. BTW - Interesting thread, it got me thinking more analytically about my own approach. Steve On Nov 4, 2004, at 10:18 AM, Mark Stosberg wrote: I also have a follow-up question: Another real world constraint is that sometimes by the time the client approves the quote, I'm involved in another project and it works better logistically to have another programmer complete the task (or help with it). Since programmers are not plug and play units, we have different levels of efficiency. What, if anything, do you to do address this in estimates? Perhaps you feel there's generally programmer parity and don't worry so much about this. I, for one, know I can feel uneasy if I have to work on a budget for programming work that I didn't contribute to myself. Mark -- . . . . . . . . . . . . . . . . . . . . . . . . . . . Mark StosbergPrincipal Developer [EMAIL PROTECTED] Summersault, LLC 765-939-9301 ext 202 database driven websites . . . . . http://www.summersault.com/ . . . . . . . .
Re: Intermittently Failing Benchmarks
On Thu, 4 Nov 2004 08:57:28 -0800 (PST), Joshua Gatcomb [EMAIL PROTECTED] wrote: What I have found interesting though is when individual benchmarks don't work. For instance, from 10/20 to 10/22, gc_generations and gc_header_reuse would just hange (still running after 10 minutes). Last night (11/3 at 23:59) addit2.imc is doing the same thing. I checked a up to the minute checkout and it is finishing now - but there is no printed output. Maybe the benchmarks should be part of the test suite? They're valid code, so they should work at all times: if they don't, something's broken. Seems like a good opportunity for testing to me. -- matt
Re: Intermittently Failing Benchmarks
Matt Diephouse [EMAIL PROTECTED] wrote: Maybe the benchmarks should be part of the test suite? They're valid code, so they should work at all times: if they don't, something's broken. Seems like a good opportunity for testing to me. Yep. Patches welcome. But please make sure that they don't run too long. Output of a few (gc_*.pasm comes to my mind) needs some tweaking WRT result. leo
Re: Does Parrot have True coroutines?
Klaas-Jan Stol [EMAIL PROTECTED] wrote: Hello, Are you sure Parrot support true coroutines? Does it integrate coroutines and closures correctly? (For instance, a single closure may refer to variables in several different coroutines.) Well, I don't know how true coroutines are defined, but Parrot, as it's CPS based, has no problems with coroutines and there are no restrictions to coroutines, AFAIK. How coroutines finally really behave WRT argument passing isn't really layed out. There is a good article in Dan's blog IIRC. co = coroutine.create(function () for i=1,10 do print(co, i) coroutine.yield() end end) In Parrot's enough to include a .yield() ... ,--[ simplest usage ]- | $ cat coro.imc | .sub main @MAIN | $I0 = coro() | print $I0 | $I0 = coro() | print $I0 | .end | .sub coro | .yield(4) | .yield(2) | .end | | $ ./parrot coro.imc | 42 `- to get a static coroutine. Above Lua snippet would use the Cnewsub opcode to create a Coroutine function object. Such objects act as closures too (modulo untested, unimplemented features ;) thanks, Klaas-Jan leo
Branching off the tree
Since I'm about to start in on some of the Irrevocable Changes (or something like that) to the string system with the new encoding/charset stuff, I tagged CVS and will be working in a branch (I hope). If you feel like watching or playing along at home, the branch is pluggable_encodings, assuming I did this all right. -- Dan --it's like this--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: special blocks tests fail on 5.8.0
On Thu, Oct 28, 2004 at 01:31:40PM +1000, [EMAIL PROTECTED] wrote: I dont know if the code under test is wrong or the expected output. I run RH9, which uses Perl 5.8.0. I was getting a failure for t/aspecial_blocks, indicating a difference in the expected output for a CHECK {} block. If I remember correctly, RH9 shipped with a 5.8.0 which was really 5.8.0 plus a bunch of patches. I suspect that one of those patches is causing this behaviour, enabling Devel::Cover to check the coverage of your CHECK blocks. You'll notice that your patch effectively brings test_output/cover/special_blocks.5.008 up to test_output/cover/special_blocks.5.008001. IF the expected output is wrong, I have provided a patch of the test_output/cover/special_blocks.5.008 golden file. So, I won't apply this patch, since it would break every standard 5.8.0 installation, but thanks very much for taking the trouble to create it. And the good news is that you can safely use Devel::Cover, with the added bonus of getting your CHECK blocks covered. I dont have a patch if the code under test is wrong, wouldnt even have a clue where to start - I ran t/aspecial_blocks under Devel::ptkdb, and realised I'd need to dig a lot deeper to find out where the code goes... Can anyone give me a hint to track the code for a CHECK block? Do I have to trace the dynamically generated command maually ? If you are still interested, the code in question is in Cover::report(), the section that starts if (exists B::check_av). In a standard 5.8.0 that would be false. In 5.8.1 and, it would seem, RH9 5.8.0 it is true. -- Paul Johnson - [EMAIL PROTECTED] http://www.pjcj.net
Search paths and library routines
Okay, this has been an ongoing source of annoyance, and I think it's time to address it. We need to get search paths for loading of stuff into parrot, both at the pir/pasm assembly level and at runtime for dynamic library loading. Now, bizarrely enough, I *don't* want to build this into parrot. (Yeah, I know. Yes, I am feeling OK :) At least not the runtime library loading, and if we can skip it for the assembly level that'd be fine too. What I'd like to do is pass off the job of finding generally-unqualified names to a library routine and have it look for the thing for me. That means we need a method of registering search paths (which ought be a library routine itself) too. So I'd like that stuff in the library. To make this actually work we need some standards, and the ability to embed bytecode segments into an executable (like, say, parrot :) so they're always at hand. Hard to load in your library if your library finding code's in the library, after all. I'm also not averse to some sort of special accommodation for low-level library code so it can be found relatively quickly without a full namespace search if it seems necessary, though I'm not so sure about that one. We'll see. Note here that I'm not talking about perl/python/ruby/tcl's standard library here -- this is parrot's low-level library, stuff that we need but isn't time-critical enough to warrant opcodes. So. Anyone want to champion parrot's standard library? And anyone want to take a shot at getting fully functioning embeddable bytecode, along with spec'ing out whatever (hopefully minimal) APIs might be needed to make 'em work? -- Dan --it's like this--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Shared library question
Background: Pmc2c.pm emits code which references Parrot_PMC_typenum. This code is present in libparrot.so, which currently is not referenced as a library by the link step for dynclasses. Options include: 1) eliminating this dependency, as it is the only one 2) directly including extend.o into each shared library 3) linking to libparrot.so As an added complication, the link step for dynclasses is by default run from a different directory than the main build. Preferences? - Sam Ruby
Re: Shared library question
At 3:49 PM -0500 11/4/04, Sam Ruby wrote: Background: Pmc2c.pm emits code which references Parrot_PMC_typenum. This code is present in libparrot.so, which currently is not referenced as a library by the link step for dynclasses. Options include: 1) eliminating this dependency, as it is the only one 2) directly including extend.o into each shared library 3) linking to libparrot.so #3's the right thing here. PMC classes have access to enough of the internals that linking to libparrot's fine. If we're feeling paranoid we can define a PMC API and link against a shared library that exposes it, but that's a bit much for now. As an added complication, the link step for dynclasses is by default run from a different directory than the main build. Pfui. Probably ought to be fixed. -- Dan --it's like this--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: Does Parrot have True coroutines?
Well, I don't know how true coroutines are defined, but Parrot, as it's CPS based, has no problems with coroutines and there are no restrictions to coroutines, AFAIK. To be honest, I hadn't thought of this, either (this true-ness of coroutines), but then again, I'm no expert on these things. How coroutines finally really behave WRT argument passing isn't really layed out. There is a good article in Dan's blog IIRC. I'll read it again. co = coroutine.create(function () for i=1,10 do print(co, i) coroutine.yield() end end) In Parrot's enough to include a .yield() ... ,--[ simplest usage ]- | $ cat coro.imc | .sub main @MAIN | $I0 = coro() | print $I0 | $I0 = coro() | print $I0 | .end | .sub coro | .yield(4) | .yield(2) | .end | | $ ./parrot coro.imc | 42 `- I hadn't seen .yield(x) Is .yield(x) the same as: .pcc_begin_yield .return x .pcc_end_yield ? to get a static coroutine. Above Lua snippet would use the Cnewsub opcode to create a Coroutine function object. Such objects act as closures too (modulo untested, unimplemented features ;) So, correct me if I'm wrong, a Coroutine is also a closure? In that case, anytime you would create a closure, you could also create a coroutine? I've also included the reply I got from Roberto: quote Untested code: function f(x) A = function () x=x+1 end B = coroutine.wrap( function (y) C = coroutine.wrap( function (z) while true do coroutine.yield(x+y+z) end end) while true do y=y+1 coroutine.yield() end end) end X = f() -- Now we have: - function A: each call increments x (in the main thread) - coroutine B: each call increments y (in that coroutine) - coroutine C: each call returns x+y+z (each in a different coroutine) Of course, all this wold be more fun with recursion :) -- Roberto /quote Do you think the above code snippet could work? That is, without much special code, can this be done in PIR? (Of course, why would one ever want to write /such/ code :-P, but that's another issue) Thanks, Klaas-Jan
Re: Are we done with big changes?
On Tue, 2 Nov 2004 13:35:09 -0500, Dan Sugalski [EMAIL PROTECTED] wrote: What, think this warrants a 0.1.2 release? I'm not so sure about that. It's not that big a deal... In the past week, Parrot has seen a dramatic speedup. We're in about the best shape we've been in in the past 4 months: http://www.sidhe.org/~timeparrot/graphs/A/sum.png Seems like a pretty big deal. -- matt
Re: Are we done with big changes?
At 4:38 PM -0500 11/4/04, Matt Diephouse wrote: On Tue, 2 Nov 2004 13:35:09 -0500, Dan Sugalski [EMAIL PROTECTED] wrote: What, think this warrants a 0.1.2 release? I'm not so sure about that. It's not that big a deal... In the past week, Parrot has seen a dramatic speedup. We're in about the best shape we've been in in the past 4 months: http://www.sidhe.org/~timeparrot/graphs/A/sum.png Seems like a pretty big deal. Hrm. Okay, then, if I've not managed to make a mess of things with the stuff I've been doing, why don't we do a 0.1.2 performance release? Between the speedups and the gentler effects of -t it seems likely to be worth it for people who're working with parrot to do stuff. (Better -t definitely makes debugging a *lot* less painful...) -- Dan --it's like this--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: Does Parrot have True coroutines?
I sense confusion between closure, continuation and coroutine. http://c2.com/cgi/wiki?ContinuationExplanation http://c2.com/cgi/wiki?ContinuationsAndCoroutines http://c2.com/cgi/wiki?CoRoutine http://c2.com/cgi/wiki?LexicalClosure Cheers, Michael On Thu, 04 Nov 2004 22:11:07 +0100, Klaas-Jan Stol [EMAIL PROTECTED] wrote: Well, I don't know how true coroutines are defined, but Parrot, as it's CPS based, has no problems with coroutines and there are no restrictions to coroutines, AFAIK. To be honest, I hadn't thought of this, either (this true-ness of coroutines), but then again, I'm no expert on these things. How coroutines finally really behave WRT argument passing isn't really layed out. There is a good article in Dan's blog IIRC. I'll read it again. co = coroutine.create(function () for i=1,10 do print(co, i) coroutine.yield() end end) In Parrot's enough to include a .yield() ... ,--[ simplest usage ]- | $ cat coro.imc | .sub main @MAIN | $I0 = coro() | print $I0 | $I0 = coro() | print $I0 | .end | .sub coro | .yield(4) | .yield(2) | .end | | $ ./parrot coro.imc | 42 `- I hadn't seen .yield(x) Is .yield(x) the same as: .pcc_begin_yield .return x .pcc_end_yield ? to get a static coroutine. Above Lua snippet would use the Cnewsub opcode to create a Coroutine function object. Such objects act as closures too (modulo untested, unimplemented features ;) So, correct me if I'm wrong, a Coroutine is also a closure? In that case, anytime you would create a closure, you could also create a coroutine? I've also included the reply I got from Roberto: quote Untested code: function f(x) A = function () x=x+1 end B = coroutine.wrap( function (y) C = coroutine.wrap( function (z) while true do coroutine.yield(x+y+z) end end) while true do y=y+1 coroutine.yield() end end) end X = f() -- Now we have: - function A: each call increments x (in the main thread) - coroutine B: each call increments y (in that coroutine) - coroutine C: each call returns x+y+z (each in a different coroutine) Of course, all this wold be more fun with recursion :) -- Roberto /quote Do you think the above code snippet could work? That is, without much special code, can this be done in PIR? (Of course, why would one ever want to write /such/ code :-P, but that's another issue) Thanks, Klaas-Jan
Re: Closures and subs
Leopold Toetsch [EMAIL PROTECTED] writes: Klaas-Jan Stol [EMAIL PROTECTED] 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? If it does, this is slightly more broken than a very broken thing.
Re: Does Parrot have True coroutines?
On Thu, Nov 04, 2004 at 10:11:07PM +0100, Klaas-Jan Stol wrote: I hadn't seen .yield(x) Is .yield(x) the same as: .pcc_begin_yield .return x .pcc_end_yield ? Yes. This alternative syntax has been checked in yesterday and is documented in the updated calling_conventions.pod. The parentheses are mandatory. Similarly you have: .return(x) which is equivalent to: .pcc_begin_return .return x .pcc_end_return -- stef
Re: Search paths and library routines
Dan Sugalski [EMAIL PROTECTED] wrote: To make this actually work we need some standards, and the ability to embed bytecode segments into an executable (like, say, parrot :) so they're always at hand. The attached patch implements one (evil) way to do this. (Even if we don't end up using the pbc2cc utility I've written, the patches to embed.[ch] might be useful; they implement a new embedding interface function for loading a packfile that's already in memory.) -- Brent 'Dax' Royal-Gordon [EMAIL PROTECTED] Perl and Parrot hacker There is no cabal. --- /dev/null Wed Jan 7 17:19:56 2004 +++ pbc2cc.pl Thu Nov 4 19:09:45 2004 @@ -0,0 +1,86 @@ +#!/usr/bin/perl -w + +=head1 TITLE + +pbc2cc.pl - Convert a Parrot bytecode file to a C constant + +=head1 SYNOPSIS + +pbc2cc.pl foo foo.pbc foo.c +#Generates a foo.c with a Parrot_pbc2cc_read_foo function +# containing foo.pbc's contents. + +=head1 DESCRIPTION + +Fpbc2cc.pl converts an input file into a C constant, then outputs some code +to load that file as a Parrot packfile. The program takes a C identifier and +an input file on the command line (the input file defaults to STDIN if not +specified) and writes its output to STDOUT. It also takes a C identifier to +be used as part of the function name to retrieve the packfile. + +The function generated has the signature: + +Parrot_PackFile Parrot_pbc2cc_read_name(Parrot_Interp interpreter); + +Where name is the C identifier given on the command line. + +=cut + +use strict; +use File::Temp qw(tempfile); + +my($name, $in)[EMAIL PROTECTED]; +$in ||= '-'; +my $size=0; + +open(IN, $in) or die Can't open input file $in: $!; +my $temp=tempfile() or die Can't create temporary file: $!; + +binmode(IN); +binmode($temp); + +{ +local $/=\1024; +while(IN) { +$size += length; +print $temp $_; +} +} + +seek $temp, 0, 0; + +print END; +/* + * DO NOT EDIT THIS FILE + * This file has been automatically generated by $0 in the Parrot distribution. + */ +#ifndef PARROT_PBC2CC_${name}_GUARD +#define PARROT_PBC2CC_${name}_GUARD + +#include stdlib.h +#include string.h +#include parrot/embed.h + +static const Parrot_Int Parrot_pbc2cc_size_$name=$size; +/* gcc gives a warning about variable-size objects if we try to use that constant here */ +static const unsigned char Parrot_pbc2cc_bits_${name}[$size]={ +END + +{ +local $/=\16; +while($temp) { +print \t0x, join(, 0x, map { sprintf %2.2x, $_ } unpack C*, $_), ,\n; +} +} + +print END; +}; + +Parrot_PackFile Parrot_pbc2cc_read_$name(Parrot_Interp interpreter) { +\tunsigned char * rawfile=malloc(Parrot_pbc2cc_size_$name); +\tmemcpy(rawfile, Parrot_pbc2cc_bits_$name, Parrot_pbc2cc_size_$name); +\treturn Parrot_readbc_ptr(interpreter, $name (embedded), rawfile, Parrot_pbc2cc_size_$name, 0); +} + +#endif +END Index: include/parrot/embed.h === RCS file: /cvs/public/parrot/include/parrot/embed.h,v retrieving revision 1.25 diff -u -r1.25 embed.h --- include/parrot/embed.h 2 May 2004 10:47:51 - 1.25 +++ include/parrot/embed.h 5 Nov 2004 03:25:33 - @@ -36,6 +36,8 @@ Parrot_PackFile Parrot_readbc(Parrot_Interp, const char *); +Parrot_PackFile Parrot_readbc_ptr(Parrot_Interp, const char *, unsigned char *, size_t, Parrot_Int); + void Parrot_loadbc(Parrot_Interp, Parrot_PackFile); void Parrot_setup_argv(Parrot_Interp, int argc, char ** argv); Index: src/embed.c === RCS file: /cvs/public/parrot/src/embed.c,v retrieving revision 1.119 diff -u -r1.119 embed.c --- src/embed.c 22 Oct 2004 13:29:36 - 1.119 +++ src/embed.c 5 Nov 2004 03:25:33 - @@ -201,7 +201,7 @@ Parrot_readbc(Interp *interpreter, const char *filename) { INTVAL program_size, wanted; -char *program_code; +unsigned char *program_code; struct PackFile *pf; FILE * io = NULL; INTVAL is_mapped = 0; @@ -325,14 +325,7 @@ /* Now that we have the bytecode, let's unpack it. */ -pf = PackFile_new(is_mapped); - -if (!PackFile_unpack -(interpreter, pf, (opcode_t *)program_code, program_size)) { -PIO_eprintf(interpreter, Parrot VM: Can't unpack packfile %s.\n, -filename); -return NULL; -} +pf = Parrot_readbc_ptr(interpreter, filename, program_code, program_size, is_mapped); #ifdef PARROT_HAS_HEADER_SYSMMAN @@ -347,6 +340,20 @@ return pf; } +struct PackFile * +Parrot_readbc_ptr(Interp *interpreter, const char *name, unsigned char *ptr, size_t size, Intval is_mapped) { +struct PackFile *pf = PackFile_new(is_mapped); + +if (!PackFile_unpack +(interpreter, pf, (opcode_t *)ptr, size)) { +PIO_eprintf(interpreter, Parrot VM: Can't unpack packfile %s.\n, +name); +return NULL; +} + +return pf; +} + /* =item Cvoid
Re: No Cpow op with PMC arguments?
Jeff Clites [EMAIL PROTECTED] wrote: I.e., PMCs don't inherently exponentiate--numbers do, and you can exponentiate PMCs by numberizing them, exponentiating, and creating a PMC with the result. This is true. But how do you define a number? Do you include floating-point? Fixed-point? Bignum? Bigrat? Complex? Surreal? Matrix? N registers don't even begin to encompass all the numbers out there. -- Brent 'Dax' Royal-Gordon [EMAIL PROTECTED] Perl and Parrot hacker There is no cabal.
Re: No Cpow op with PMC arguments?
On Nov 4, 2004, at 8:29 PM, Brent 'Dax' Royal-Gordon wrote: Jeff Clites [EMAIL PROTECTED] wrote: I.e., PMCs don't inherently exponentiate--numbers do, and you can exponentiate PMCs by numberizing them, exponentiating, and creating a PMC with the result. This is true. But how do you define a number? Do you include floating-point? Fixed-point? Bignum? Bigrat? Complex? Surreal? Matrix? N registers don't even begin to encompass all the numbers out there. Floating point, and possibly integer. Those are the numeric primitives of processors. Other aggregate mathematical types are always defined in terms of those (in a computing context), one way or another. JEff
Re: No Cpow op with PMC arguments?
On Thu, 4 Nov 2004 21:46:19 -0800, Jeff Clites [EMAIL PROTECTED] wrote: On Nov 4, 2004, at 8:29 PM, Brent 'Dax' Royal-Gordon wrote: This is true. But how do you define a number? Do you include floating-point? Fixed-point? Bignum? Bigrat? Complex? Surreal? Matrix? N registers don't even begin to encompass all the numbers out there. Floating point, and possibly integer. Those are the numeric primitives of processors. Other aggregate mathematical types are always defined in terms of those (in a computing context), one way or another. Yes, but your decomposition (N2=P2; N3=P3; N1=N2+N3; P1=N1) doesn't take anything but the primitives into account. It would destroy the meaningfulness of performing a pow() on a complex number, or even just a bignum (which the language isn't necessarily even aware will be involved in a particular operation--many will convert smoothly between integer and bignum). Dynamic languages generally try to hide the reality of the machines they run on from the programmer; things like pow only works on numeric primitives smack the programmer in the face with that reality. (Sure, languages can work around it, but their various hacks will probably be mutually incompatible and less efficient than just doing it ourselves.) Operations that only work with primitives makes sense for hardware, but out here in the realm of software we can do better. -- Brent 'Dax' Royal-Gordon [EMAIL PROTECTED] Perl and Parrot hacker There is no cabal.