Re: Fun with junctions (was Sets vs Junctions)
On Sat, Feb 12, 2005 at 01:03:26AM -0600, Rod Adams wrote: I also find the following incredibly disturbing: perl6 -e $x = 'cat'|'dog'; say $x; dog cat Would that happen though? What's the signature of Csay? I think it's something like multi sub *say ($stream = $*OUT: *$data) { ... } so autothreading wouldn't happen anyway as S9 says the slurpy array/hash aren't autothreaded. Also, for user-defined subs I'd imagine that you could give perl a hint not to autothread it with perhaps a is nonthreading trait. Getting iterated executions of a statement without explicitly iterating it bothers me greatly. It's funny how one man's feature is another man's bother :-) So, if we are not having Sets, how exactly does one tell if what they are holding is a single value scalar, or a multi-value junction? Using the same introspection capabilities that let's you tell if that scalar you have is an object of some sort I'd imagine. Can a junction hold values of completely different types, or just different values of the same type? Given perl's tendency towards permission rather than restriction, I'd guess that you could have a junction composed of almost anything. Consider: any(3,fred,@foo, { $^x*$^x}) Now, what that *means* is another story :-) If evaluation of one value of a junction causes an error, is $! now a junction as well? How do you evaluate one value of a junction? I would think that the junctive disposition of $! would depend on whether that one value were a junction or not. If not, then you just get $! when that one particular value is evaluated (like 3/any(2,0,3) would generate a junction of any(3/2,3/0,3/3) with that 3/0 waiting to be realized (evaluated) and once it is, then $! would hold the divide by zero) In my current sleep-deprived state I think that you're more likely to get a junction of various $! valus than have $! be a junction of values (unless you're setting it explicitly) -Scott -- Jonathan Scott Duff [EMAIL PROTECTED]
Re: Testing What Was Printed
On 11 Feb 2005, at 19:52, Shawn Sorichetti wrote: [snip] I've started working on Test::Output that is based on Schwern's TieOut module that comes with Test::More. I'm hoping to have it released on CPAN later tonight. Test::Output is a self contained so that it can be included with other modules, and no prereqs. Right now it provides output_is() (combined STDERR, STDOUT), stderr_is(), and stdout_is(), but I plan to add _like, and _found shortly. Excellent! I love it when other people do things that I'm too lazy to get around to doing myself (see http://www.nntp.perl.org/group/perl.qa/1828 http://www.nntp.perl.org/group/perl.module-authors/1939) :-) Much better implemented than mine too. Thank you! Adrian
Re: Control Structures II: loop
On Thu, 14 Nov 2002, Luke Palmer wrote: nest: Nest is the power loop thingy documented in Raphael Finkel's top notch book Advanced Programming Language Design, near the end of the Control Structures chapter -- this book is in PDF format: http://www.nondot.org/sabre/Mirrored/AdvProgLangDesign/ The only thing it doesn't cover is Cnest, which, in practical situations, isn't all that useful anyway. It's cleaner just to nest manually. In 2002, I said: As the Finkel book points out, that only works if you know ahead of time how many layers deep you're going to be nesting. Personally, I don't expect to need nest more than once or twice in my life, but it'd be useful for the times it's needed. Now I add: I knew there was a situation where these are useful, and I've found it, and it'll probably be more frequent in Perl6 than Perl5: recursing through multidimensional arrays where you don't know how many dimensions there are. For example, nest would be great for implementing some of the APL operators. Just fors the record: PerlAPL Operators Functions Hyper-operators Operators http://www.info.univ-angers.fr/pub/gh/wAides/sax6_userdoc.pdf Look under Language Guide/Operators. :) - | Name: Tim Nelson | Because the Creator is,| | E-mail: [EMAIL PROTECTED] | I am | - BEGIN GEEK CODE BLOCK Version 3.12 GCS d+ s:- a- C++$ U++ P++ L++ E- W+++ N+ w--- V- Y+++ PGP-++ R !tv b++ DI D+ G e++ h! y- -END GEEK CODE BLOCK-
Extra Operator bits?
More hyper-operators Incidentally, is there any chance we'll have more than one official hyper-operator in Perl6? According to the S3, there's only one, the hyper-operator, . If I understand, hyper-operators are just operators which operate on functions (including operators). We effectively already have three more hyper-operators, sort, map and grep, all of which are operators which take one function and one array. But I can also see uses for some of the other ones from APL (where they call hyper-operators operators). Maybe if we could work out some way to take the current perl hyper-operator, and have it optionally f-Reduce (see APL) rather than expanding arrays. Then we could do something better than: @array = qw(1 2 3 4 5 6 7 8); foreach(@array) { $total += @array; } eg. $total += @array; For f-Reduce: http://www.info.univ-angers.fr/pub/gh/wAides/sax6_userdoc.pdf Look under Language Guide/Operators. Yes, I suspect we really can't use ; maybe we could use some unicode thing. New comparison operator --- It'd be nice to have a subset operator. If one operand is an array, it says whether the other operand is a subset of it. If both operands are scalar, it returns the position of one as a substring in the other. Override comparison function We have two set of operators for comparison, one for numeric, and one for string. There are a variety of other comparisons possible, for example case insensitive, soundex, Wagner-Fischer (cf. Text::WagnerFischer, agrep, etc). I know that the first two can be simulated by running both operands through a conversion function first, but this is a pain in eg. sort. I was thinking that this also could be resolved with hyper-operators. Imagine two hyper-operators, which I will call s (string), and o (other) (these are not suggested syntax, but placeholders in this discussion). Then we could do: $a == $b $a ==s $b $a ==o $b The first would be a numeric comparison, as always. The second would be a string comparison. The third would be another comparison, and could be redefined with eg. use Text::WagnerFischer or use Text::Soundex. It'd also be cool if we could do: @a = sort=s @b (sort would default to sort =, but the above would do a string comparison). Or, as an alternate syntax (I don't mind the syntax, I just want the functionality), we could have an internal function called eg. scalar_compare, which points to scalar_compare_string. We'd keep all the current operators, but when someone did use Text::WagnerFischer qw(override_compare), it would repoint scalar_compare at scalar_compare_WagnerFischer, and all string comparison functions (eg. eq, ne, sort) would automatically use the new function. Note both ways achieve what I want, but the first would have overrides on a per-operator basis, whereas the second would make it the default for all comparison functions. There are various middle ways, but I think the whole thing could be easier this way. Array operators (functions?) --- It'd be nice to have awway union and intersection operators. I'm assuming that all arrays in the following example have unique elements (speaking of which, I'd like a uniq function to be part of perlfunc). Union: Easily simulated with (@a, @b) == uniq == @c Intersection: this one's harder: foreach $avar (@a) { push @c, grep { /$avar/ } @b; } -or- @c = map { $avar = $_; grep { /$avar/ } @b } @a; -or- @a == map { $avar = $_; @b == grep { /$avar/ } } == @c; ...none of which are neat. Assuming we don't get an extra magic variable (ie. $_ = this, $!!! = $that), it'd be nice to have something that does this. getfiledir function --- I don't see anything that talks about a perlfunc rewrite, so I thought I'd comment on the one function I use in nearly *every* perl program I write. Here it is: sub getfiledir { my($file) = @_; my(@lines); if(-d $file) { return(glob($file)) } else { open(FILE, $file) or die Error: Can't open file '$file': $!; @lines = FILE; close(FILE) or die Error: Can't close file '$file': $!; } } That also lets me pass in command pipes ending in |. --- Anyway, hopefully someone will point out an easy way to do one or two of the above with existing features, and the other(s) will be useful to the community. :) - | Name: Tim Nelson | Because the Creator is,| | E-mail: [EMAIL PROTECTED] | I am |
Re: Extra Operator bits?
Ok, having just seen Damien's post about built-in methods, I can answer part of my own post: Re: more hyper-operators: reduce, thank-you! :) Of course, it'd still be better as a hyper-operator instead of a function (so that it works on operators too). I wrote: (speaking of which, I'd like a uniq function to be part of perlfunc). Damian wrote: uniq - remove duplicates without reordering I now write Sorry! Btw, even a complete list of built-in functions would be nice as a synopsis; it would prevent ill-informed posts like most of my previous one; Damian's one is a great start :). :) - | Name: Tim Nelson | Because the Creator is,| | E-mail: [EMAIL PROTECTED] | I am | - BEGIN GEEK CODE BLOCK Version 3.12 GCS d+ s:- a- C++$ U++ P++ L++ E- W+++ N+ w--- V- Y+++ PGP-++ R !tv b++ DI D+ G e++ h! y- -END GEEK CODE BLOCK-
CVS commit access
Hi, I'm currently working on some Parrot bits, including some more cleanup of the test suite. For that it would be convenient to have commit right in CVS and rights in the RequestTracker. Could a kind soul set that up? My user ID on auth.perl.org is 'bernhard'. CU, Bernhard -- /* [EMAIL PROTECTED] */ DSL Komplett von GMX +++ Supergünstig und stressfrei einsteigen! AKTION Kein Einrichtungspreis nutzen: http://www.gmx.net/de/go/dsl
Closure trait for loop entry
Often when I write a loop I want to run some code at loop entry time. It would be nice to have a closure trait for this, similar to NEXT for loop continuation or LAST for loop termination, but there isn't one. I don't think either FIRST or ENTER do quite what I want. FIRST runs only once, which is too few times, and ENTER runs every time the loop block is entered, which is too many. To demonstrate what I want, consider the following examples: sub use_first() { for 1..2 { FIRST {say 'entering loop';} say $_; LAST{say 'leaving loop';} } } sub use_enter() { for 1..2 { ENTER {say 'entering loop';} say $_; LAST{say 'leaving loop';} } } The first time use_first is called it will print entering loop 1 2 leaving loop but subsequently it will print 1 2 leaving loop and leave out the 'entering loop'. When use_enter is called it will print entering loop 1 entering loop 2 leaving loop I want to output entering loop 1 2 leaving loop every time I run my loop. I suggest we create a new closure trait called SETUP for this. Then the code could read for 1..2 { SETUP {say 'entering loop';} say $_; LAST{say 'leaving loop';} } Since SETUP can be used for initialization, it should probably be allowed within an expression: state $first_iteration = SETUP {true} will next {$_ = false}; Lower case 'setup' could probably also be used as a trait on a variable state $first_iteration will setup {$_ = true} will next {$_ = false}; Joe Gottman
Re: Junctive collapsing?
On Sat, Feb 12, 2005 at 10:55:05AM -0600, Patrick R. Michaud wrote: On Sat, Feb 12, 2005 at 12:09:37PM +0800, Autrijus Tang wrote: [...] - one() checks its operands for duplicates; if found, it collapses itself into an empty one() junction, thus failing all tests. Is this somewhat saner? :-) Depends on when it's checking its operands for duplicates, and the type of checking being performed. For example, $x = one(0, 0, 1); Right. What I mean is that one($a, $a, $b) should collapse into one($b) That is, it should delete all duplicate elements from its set. Does it look like correct? Thanks, /Autrijus/ pgpKovsC2oVkK.pgp Description: PGP signature
Re: Junctive collapsing?
On Sat, Feb 12, 2005 at 11:10:13AM -0600, Patrick R. Michaud wrote: No, consider $a = 1; $b = 2; one($a, $a, $b) # false one($b) # true Right. Evidently I need to sleep real soon. :-) However, is there a way to remove the $a from the equation? I'd like to keep implementation decision of using Sets without duplicate elements, unless it is unavoidable, in which case I'll switch back to a List... Thanks, /Autrijus/ pgpcYbNbtT8vH.pgp Description: PGP signature
Re: Fun with junctions (was Sets vs Junctions)
On Sat, Feb 12, 2005 at 01:02:45PM +0800, Autrijus Tang wrote: On Fri, Feb 11, 2005 at 02:12:51PM -0600, Patrick R. Michaud wrote: I briefly grepped through the apocalypses/synopses and couldn't find the answer -- how do I tell a scalar context to expect a junction of values? In particular, is there a way for me to pass a junction to a routine without it autothreading and without having to bury the junction in an array or some other structure? If you have control over that routine, argument prototypes is probably the way to go. I just hadn't seen a CJunction data type listed anywhere in the synopses/apocalypses. Damian has since given me the same answer you provided. Pm
Re: Junctive collapsing?
On Sat, Feb 12, 2005 at 12:09:37PM +0800, Autrijus Tang wrote: [...] - one() checks its operands for duplicates; if found, it collapses itself into an empty one() junction, thus failing all tests. Is this somewhat saner? :-) Depends on when it's checking its operands for duplicates, and the type of checking being performed. For example, $x = one(0, 0, 1); has duplicate elements (the zeroes) but is still true. Similarly, with $x = one(2, 3, 2); $x = $x % 2; if $x { say Exactly one odd value; } collapsing the one(2, 3, 2) to be one() in the first statement would be incorrect. Pm
Re: Junctive collapsing?
On Sun, Feb 13, 2005 at 01:01:15AM +0800, Autrijus Tang wrote: On Sat, Feb 12, 2005 at 10:55:05AM -0600, Patrick R. Michaud wrote: On Sat, Feb 12, 2005 at 12:09:37PM +0800, Autrijus Tang wrote: [...] - one() checks its operands for duplicates; if found, it collapses itself into an empty one() junction, thus failing all tests. Is this somewhat saner? :-) Depends on when it's checking its operands for duplicates, and the type of checking being performed. For example, $x = one(0, 0, 1); Right. What I mean is that one($a, $a, $b) should collapse into one($b) That is, it should delete all duplicate elements from its set. Does it look like correct? No, consider $a = 1; $b = 2; one($a, $a, $b) # false one($b) # true Pm
Re: Fun with junctions (was Sets vs Junctions)
On Sat, Feb 12, 2005 at 12:41:19AM -0600, Rod Adams wrote: I've given here. For example, a junction can have a value like: $x = ($a $b) ^ ($c $d) which is true only if $a and $b are true or $c and $d are true but not both. That's why I allowed for virtual sets, defined by a closure. Oops, I missed that part. Sorry. Of course we'll always have Cgrep. But this is Perl, and I want YAWTDI. After all, another way to test membership was just added, whereas before you pretty much just had Cgrep. ...another way to test membership was added...? My issue is less that lists and sets are radically different. It is much more a matter of Junctions and Scalars are radically different. Getting me to accept that a Scalar holds several different values at once is a hard sell. Especially when you consider duplicated side effects. Since Scalars can be objects that are fairly complex aggregations that simultaneously hold (or appear to hold) multiple different values at once, this doesn't seem like a strong argument. And what happens if you attempt to evaluate a junction in a non-boolean context? I dunno, which context are you concerned about? $a = any(2,3,4); $b = ? $a; # boolean context, $b == true $n = $a + 3; # numeric context, $n == any(5,6,7) $s = $a ~ 'x'; # string context, $s == any('2s', '3s', '4s') @l = ($a); # list context, @l == (any(2,3,4)) Pm
Re: Fun with junctions (was Sets vs Junctions)
On Sat, Feb 12, 2005 at 03:49:02AM -0600, Jonathan Scott Duff wrote: On Sat, Feb 12, 2005 at 01:03:26AM -0600, Rod Adams wrote: I also find the following incredibly disturbing: perl6 -e $x = 'cat'|'dog'; say $x; dog cat Would that happen though? What's the signature of Csay? I think it's something like multi sub *say ($stream = $*OUT: *$data) { ... } so autothreading wouldn't happen anyway as S9 says the slurpy array/hash aren't autothreaded. True, but it's always possible to find or create functions that would have the disturbing effect that Rod was pointing out. sub mysay { say $^x; } $x = 'cat' | 'dog'; mysay $x; Pm
[perl #34117] [PATCH] fix make html
# New Ticket Created by Markus Amslser # Please include the string: [perl #34117] # in the subject line of all future correspondence about this issue. # URL: https://rt.perl.org/rt3/Ticket/Display.html?id=34117 make html failes currently, because the src/test_main.c file was moved to examples/c/text_main.c. Markus ChangeLog: - update search path to find the file test_main.c. - warn if a file is not found Index: lib/Parrot/Distribution.pm === RCS file: /cvs/public/parrot/lib/Parrot/Distribution.pm,v retrieving revision 1.3 diff -u -w -r1.3 Distribution.pm --- lib/Parrot/Distribution.pm 27 Mar 2004 22:22:36 - 1.3 +++ lib/Parrot/Distribution.pm 12 Feb 2005 16:46:34 - @@ -91,7 +91,8 @@ $self-directory_with_name('encodings'), $self-directory_with_name('io'), $self-directory_with_name('pf'), - $self-directory_with_name('types'),; + $self-directory_with_name('types'), + $self-directory_with_name('examples')-directory_with_name('c'),; } =item Cc_source_file_with_name($name) @@ -113,6 +114,7 @@ if $dir-file_exists_with_name($name); } + print 'WARNING: ' . __FILE__ . ':' . __LINE__ . ' File not found:' . $name .\n; return undef; }
Re: Junctive collapsing?
On Sat, Feb 12, 2005 at 06:34:05PM +0100, Eirik Berg Hanssen wrote: I think one([EMAIL PROTECTED], [EMAIL PROTECTED], [EMAIL PROTECTED]) is equivalent to all(none([EMAIL PROTECTED]),one([EMAIL PROTECTED])), which should permit an implementation using Sets without duplicate elements. Whether it is worth it is another matter ... Indeed. Perhaps I can refactor one() to store it with two subsets: the none set and the one set; new elements are checked against the one set; if duplicates are found, it gets moved into the none set. That way the type of the junction is still one(); the .values() method will then return two items for each element in the none() subset, and one for each in the one() subset. Does it make sense? Thanks, /Autrijus/ pgp3jMaOkbqJb.pgp Description: PGP signature
Re: Closure trait for loop entry
JG == Joe Gottman [EMAIL PROTECTED] writes: JGsub use_first() JG{ JG for 1..2 { JG FIRST {say 'entering loop';} JG say $_; JG LAST{say 'leaving loop';} JG } JG } JG The first time use_first is called it will print JG entering loop JG 1 JG 2 JG leaving loop JG but subsequently it will print JG 1 JG 2 JG leaving loop that seems to imply that FIRST is a program level first time action. i think it does what you want and is executed on the first iteration of a loop, each time the loop is started up. it is symmetrical to LAST in that way. it should print the former text each time the sub is called. but i could be wrong. :) uri -- Uri Guttman -- [EMAIL PROTECTED] http://www.stemsystems.com --Perl Consulting, Stem Development, Systems Architecture, Design and Coding- Search or Offer Perl Jobs http://jobs.perl.org
Re: Testing What Was Printed
Michael G Schwern wrote: On Fri, Feb 11, 2005 at 07:30:24AM -0500, David Golden wrote: stdout_is { fcn() } $string, comment; # exact stdout_like{ fcn() } qr/regex/, comment; # regex match stdout_count { fcn() } qr/regex/, $count, comment; # number of matches stdout_found { fcn() } qr/regex/, [EMAIL PROTECTED], comment; # list of matches The trouble with this interface is sometimes you want to collect a bunch of output from a bunch of different functions together. That's why I suggested that it be prototyped to take a code block: stdout_is { fcn1(); # more processing fcn2(); } $expected, comment; David
Re: Fun with junctions (was Sets vs Junctions)
Patrick R. Michaud wrote: On Sat, Feb 12, 2005 at 03:49:02AM -0600, Jonathan Scott Duff wrote: On Sat, Feb 12, 2005 at 01:03:26AM -0600, Rod Adams wrote: I also find the following incredibly disturbing: perl6 -e $x = 'cat'|'dog'; say $x; dog cat Would that happen though? What's the signature of Csay? I think it's something like multi sub *say ($stream = $*OUT: *$data) { ... } so autothreading wouldn't happen anyway as S9 says the slurpy array/hash aren't autothreaded. I reread S09, and I believe autothreading is the wrong term for the iteration that a junction incurs (Even though it appears in the section immediately after Junctions. Autothreading is something far weirder, dealing with partial dimensional slices, I believe. And in that case, it makes sense to turn off autothreading for slurpys, since in flattening, you get rid of the messy dimensions. Therefore I suspect that the above is wrong, and the behavior of Csay 'cat'|'dog' is still to duplicate. -- Rod Adams
Re: Fun with junctions (was Sets vs Junctions)
Patrick R. Michaud wrote: On Sat, Feb 12, 2005 at 12:41:19AM -0600, Rod Adams wrote: Of course we'll always have Cgrep. But this is Perl, and I want YAWTDI. After all, another way to test membership was just added, whereas before you pretty much just had Cgrep. ...another way to test membership was added...? $x == any(@y); My issue is less that lists and sets are radically different. It is much more a matter of Junctions and Scalars are radically different. Getting me to accept that a Scalar holds several different values at once is a hard sell. Especially when you consider duplicated side effects. Since Scalars can be objects that are fairly complex aggregations that simultaneously hold (or appear to hold) multiple different values at once, this doesn't seem like a strong argument. But, to extract those alternative values from an object, you do something special to it, like call a method. Whenever you evaluate the object as a scalar, you get a single value back. Quite probably a reference to something much more elaborate, but a single value none the less. When you do a Csay $obj, Csay is only called once. And what happens if you attempt to evaluate a junction in a non-boolean context? I dunno, which context are you concerned about? $a = any(2,3,4); $b = ? $a; # boolean context, $b == true $n = $a + 3; # numeric context, $n == any(5,6,7) $s = $a ~ 'x'; # string context, $s == any('2s', '3s', '4s') @l = ($a); # list context, @l == (any(2,3,4)) It was basically a reiteration of my iterated side effect argument, which gets worse if you do: @l = (any(1,2,3),any(4,5,6),any(7,8,9),any(10,11,12),any(13,14,15)); say @l.join(' '); I believe this generates 243 lines of text. IMO, this is not desirable. However, if the majority of people out there are fine with this behavior, I'll let it rest. I also have not seen any good way to avoid the situation. It's now been established that one can do a C.isa(Junction) to determine that what we have is, indeed, a junction. However, once that happens, your options are basically to either live with it, or throw an exception. If you're given 'cat'|'dog', there's no way to extract 'cat' and or 'dog', unless you happened to be expecting 'cat' and 'dog', and test for them explicitly. For clarification, is the type of 3|'four' == Junction|int|str? And I've yet to receive a good answer for what C3/any(0,1) does to $!. -- Rod Adams
Re: Closure trait for loop entry
On Sat, Feb 12, 2005 at 12:44:05PM -0500, Uri Guttman wrote: : JG == Joe Gottman [EMAIL PROTECTED] writes: : : JGsub use_first() : JG{ : JG for 1..2 { : JG FIRST {say 'entering loop';} : JG say $_; : JG LAST{say 'leaving loop';} : JG } : JG } : : JG The first time use_first is called it will print : JG entering loop : JG 1 : JG 2 : JG leaving loop : : JG but subsequently it will print : JG 1 : JG 2 : JG leaving loop : : that seems to imply that FIRST is a program level first time action. i : think it does what you want and is executed on the first iteration of a : loop, each time the loop is started up. it is symmetrical to LAST in : that way. it should print the former text each time the sub is called. : : but i could be wrong. :) What's going on here is that the loop body is a closure that is cloned upon entry to the loop (you're logically passing a closure to the for() function that implements the loop), so if there's a FIRST inside, it runs each time the loop is initialized. Likewise state variables are logically regenerated for closure clones, so if use_first() above wants to have a state variable that is maintained from call to call, it must put it *outside* the loop. Also, note that a LAST block, if any, has to be called from within the implementation of for(), since only for() knows when it's done with the loop as a whole. It will be an interesting problem for the optimizer to figure out how to avoid cloning closures that are passed only to synchronous loop-controller functions such as for() and not otherwise used asynchronously. Perhaps the signature of for() can make some guarantees about not squirreling away the closure pointer in some weird place. This is perhaps related to the issue of timely GC on pointers you know haven't been copied into outside storage. Larry
Re: Extra Operator bits?
On Sat, Feb 12, 2005 at 05:55:48PM +1100, Timothy S. Nelson wrote: : More hyper-operators : : : Incidentally, is there any chance we'll have more than one official : hyper-operator in Perl6? According to the S3, there's only one, the : hyper-operator, . If I understand, hyper-operators are just operators : which operate on functions (including operators). Just to straighten around our terminology here, we're reserving the term hyper operator to refer only to explicitly parallelized operators. (We tried briefly to call them vector operators, but that confused the mathmaticians.) Anyway, I think the term you're looking for here is higher-order function, if you're referring to the semantics, or meta-operator, if you're referring to the syntax. Of course, these terms are all arbitrary, but that's how we're using them currently. : We effectively already have : three more hyper-operators, sort, map and grep, all of which are : operators which take one function and one array. But I can also see uses for : some of the other ones from APL (where they call hyper-operators operators). Well, in Perl 6 any operator that takes a closure as an argument is essentially a higher-order function, which leads me to suspecty you're mostly just asking for syntactic relief in the form of a meta-operator that happens to implement a higher-order function. : Maybe if we could work out some way to take the current perl : hyper-operator, and have it optionally f-Reduce (see APL) rather than : expanding arrays. Then we could do something better than: : : @array = qw(1 2 3 4 5 6 7 8); : foreach(@array) { $total += @array; } : : eg. : : $total += @array; : : : For f-Reduce: : http://www.info.univ-angers.fr/pub/gh/wAides/sax6_userdoc.pdf : Look under Language Guide/Operators. : : Yes, I suspect we really can't use ; maybe we could use some : unicode thing. I've explicitly made Unicode available for such purposes--though, to be sure, you'll have to justify your use of esoteric operators to your own audience. For Perl 6 itself we're intentionally restricting ourselves to Latin-1. : New comparison operator : --- : It'd be nice to have a subset operator. If one operand is an array, : it says whether the other operand is a subset of it. If both operands are : scalar, it returns the position of one as a substring in the other. This seems like a confusing spec. You don't seem to care about the ordering of the array, but you do care about the ordering of the string. That's not terribly consistent, especially to people who view a string as essentially an array of characters. Or were you thinking of the array's subset as a subsequence? (To me, subsets aren't ordered because sets aren't ordered.) : Override comparison function : : : We have two set of operators for comparison, one for numeric, and one : for string. There are a variety of other comparisons possible, for example : case insensitive, soundex, Wagner-Fischer (cf. Text::WagnerFischer, agrep, : etc). I know that the first two can be simulated by running both operands : through a conversion function first, but this is a pain in eg. sort. : : I was thinking that this also could be resolved with hyper-operators. : Imagine two hyper-operators, which I will call s (string), and o (other) : (these are not suggested syntax, but placeholders in this discussion). Then : we could do: : : $a == $b : $a ==s $b : $a ==o $b : : The first would be a numeric comparison, as always. The second would : be a string comparison. The third would be another comparison, and could be : redefined with eg. use Text::WagnerFischer or use Text::Soundex. : : It'd also be cool if we could do: : @a = sort=s @b : : (sort would default to sort =, but the above would do a string : comparison). We have room in the grammar engine for defining various metasyntaxes surrounding operators, so that + and += are just specific examples of more generic operator transformations. However, we'll try to discourage profligate use of such metasyntax as leading to gobbledygook. Basically, you shouldn't be coining new verb forms too frequently if there's another way to modify an existing verb. And natural language provides just such a way with adverbs. So instead, we're trying to encourage people to modify their operators using an adverbial syntax. The prototypical example is the range operator: for 1..100 :by(2) {...} This is not exactly a higher-order function, though. There has to be at least one range operator that understands the by option. We'll eventually be relying on multiple dispatch to find that operator. Using a higher-order function for this would be overkill. : Or, as an alternate syntax (I don't mind the syntax, I just want the
Re: Fun with junctions (was Sets vs Junctions)
On Sat, Feb 12, 2005 at 01:18:53PM -0600, Rod Adams wrote: My issue is less that lists and sets are radically different. It is much more a matter of Junctions and Scalars are radically different. Getting me to accept that a Scalar holds several different values at once is a hard sell. Especially when you consider duplicated side effects. Since Scalars can be objects that are fairly complex aggregations that simultaneously hold (or appear to hold) multiple different values at once, this doesn't seem like a strong argument. But, to extract those alternative values from an object, you do something special to it, like call a method. Whenever you evaluate the object as a scalar, you get a single value back. Quite probably a reference to something much more elaborate, but a single value none the less. When you do a Csay $obj, Csay is only called once. s/object/Junction/g above doesn't give me much grief. Extracting values from a Junction is also done by calling methods or functions. And what happens if you attempt to evaluate a junction in a non-boolean context? I dunno, which context are you concerned about? [...] It was basically a reiteration of my iterated side effect argument, which gets worse if you do: @l = (any(1,2,3),any(4,5,6),any(7,8,9),any(10,11,12),any(13,14,15)); say @l.join(' '); I'm not so sure it gets worse here -- @l.join(' ') gets evaluated first, and Cjoin is called only once because none of its parameters are a junction. In this case Cjoin is going to return a junction of strings. Similarly, as Scott Duff pointed out, Csay will be called only once, since the arguments to Csay are passed as part of a slurpy array and as such do not autothread. (No, I'm not entirely sure what would be output as a result. However, whatever it is, it should all be on one line, not 243 lines.) I also have not seen any good way to avoid the situation. It's now been established that one can do a C.isa(Junction) to determine that what we have is, indeed, a junction. However, once that happens, your options are basically to either live with it, or throw an exception. If you're given 'cat'|'dog', there's no way to extract 'cat' and or 'dog', unless you happened to be expecting 'cat' and 'dog', and test for them explicitly. Umm, what's wrong with...? $l = 'cat'|'dog'|'mouse'; @extract = $l.values(); # ('cat', 'dog', 'mouse') For clarification, is the type of 3|'four' == Junction|int|str? I would guess the type of 3|'four' to be int|str, which is also a Junction, but don't hold me to that. And I've yet to receive a good answer for what C3/any(0,1) does to $!. I'm sure that 3/any(0,1) throws some sort of divide by zero exception; same as 3/0 would, and places the exception into $!. I don't know that $! must necessarily then be a junction of exceptions, or that the exceptions would have to be processed in parallel (i.e., as with many things, processing of the value/list/object/junction stops at the first exception encountered). But someone more expert than I would need to provide an answer to that one. :-) Pm
Re: Closure trait for loop entry
LW == Larry Wall [EMAIL PROTECTED] writes: LW : JG The first time use_first is called it will print LW : JG entering loop LW : JG 1 LW : JG 2 LW : JG leaving loop LW : LW : JG but subsequently it will print LW : JG 1 LW : JG 2 LW : JG leaving loop LW : LW : that seems to imply that FIRST is a program level first time action. i LW : think it does what you want and is executed on the first iteration of a LW : loop, each time the loop is started up. it is symmetrical to LAST in LW : that way. it should print the former text each time the sub is called. LW What's going on here is that the loop body is a closure that is LW cloned upon entry to the loop (you're logically passing a closure LW to the for() function that implements the loop), so if there's a LW FIRST inside, it runs each time the loop is initialized. Likewise LW state variables are logically regenerated for closure clones, so if LW use_first() above wants to have a state variable that is maintained LW from call to call, it must put it *outside* the loop. i am not clear on the actual answer. my take on what you said is that i was right, FIRST will execute at the beginning of each time the loop is entered which is what joe wants. am i correct? LW Also, note that a LAST block, if any, has to be called from within LW the implementation of for(), since only for() knows when it's done LW with the loop as a whole. similarly for FIRST as only for() knows when it starts up the loop again and reinitializes the counter. LW It will be an interesting problem for the optimizer to figure out LW how to avoid cloning closures that are passed only to synchronous LW loop-controller functions such as for() and not otherwise used LW asynchronously. Perhaps the signature of for() can make some LW guarantees about not squirreling away the closure pointer in LW some weird place. This is perhaps related to the issue of timely LW GC on pointers you know haven't been copied into outside storage. i see the problem. if the loop body refers to lexicals declared outside it, it looks like a classic perl5 closure and would need to be cloned. what about the fact that for() will be called in effectively a void context? a classic closure makes sense only when the code ref is saved or possible called immediately via (p5) -. for() is called immediately but with a different signature as you said. the void context would help the optimizer since you don't save the code block for later reuse, no cloning should be done. uri -- Uri Guttman -- [EMAIL PROTECTED] http://www.stemsystems.com --Perl Consulting, Stem Development, Systems Architecture, Design and Coding- Search or Offer Perl Jobs http://jobs.perl.org
Re: Closure trait for loop entry
On Sat, Feb 12, 2005 at 03:55:40PM -0500, Uri Guttman wrote: : LW What's going on here is that the loop body is a closure that is : LW cloned upon entry to the loop (you're logically passing a closure : LW to the for() function that implements the loop), so if there's a : LW FIRST inside, it runs each time the loop is initialized. Likewise : LW state variables are logically regenerated for closure clones, so if : LW use_first() above wants to have a state variable that is maintained : LW from call to call, it must put it *outside* the loop. : : i am not clear on the actual answer. my take on what you said is that i : was right, FIRST will execute at the beginning of each time the loop is : entered which is what joe wants. am i correct? Yes. : LW Also, note that a LAST block, if any, has to be called from within : LW the implementation of for(), since only for() knows when it's done : LW with the loop as a whole. : : similarly for FIRST as only for() knows when it starts up the loop again : and reinitializes the counter. I think FIRST initialization happens automatically based on the cloning mechanism, and the fact that FIRST knows when it's first already. The code of a FIRST can actually be called inline, I think. Could be wrong about that. : LW It will be an interesting problem for the optimizer to figure out : LW how to avoid cloning closures that are passed only to synchronous : LW loop-controller functions such as for() and not otherwise used : LW asynchronously. Perhaps the signature of for() can make some : LW guarantees about not squirreling away the closure pointer in : LW some weird place. This is perhaps related to the issue of timely : LW GC on pointers you know haven't been copied into outside storage. : : i see the problem. if the loop body refers to lexicals declared outside : it, it looks like a classic perl5 closure and would need to be : cloned. what about the fact that for() will be called in effectively a : void context? a classic closure makes sense only when the code ref is : saved or possible called immediately via (p5) -. for() is called : immediately but with a different signature as you said. the void context : would help the optimizer since you don't save the code block for later : reuse, no cloning should be done. Doesn't really help--when you think about it, the block you pass to map or grep is also a loop block, and those generally aren't used in void context. It would have to be a marker on the actual block argument in the signature. Maybe based on type: sub mygrep (Block block, [EMAIL PROTECTED]) {...} # don't clone sub mysched (Closure block, [EMAIL PROTECTED]) {...} # clone Since the Block declaration would mostly be an optimizer hint, I suspect the default should be to clone, so the latter can just be written: sub mysched (block, [EMAIL PROTECTED]) {...} # clone Actual type names are negotiable, of course. Maybe typename is the wrong place for that info, and it should just be sub mygrep (block is uncloned, [EMAIL PROTECTED]) {...}# don't clone Or maybe it's just spelled with existing props: sub mygrep (block is ref, [EMAIL PROTECTED]) {...} # don't clone sub mygrep (block is copy, [EMAIL PROTECTED]) {...}# clone (default) Larry
Re: Fun with junctions (was Sets vs Junctions)
On Sat, Feb 12, 2005 at 02:20:45PM -0600, Patrick R. Michaud wrote: : And I've yet to receive a good answer for what C3/any(0,1) does to $!. : : I'm sure that 3/any(0,1) throws some sort of divide by zero exception; : same as 3/0 would, and places the exception into $!. I don't know : that $! must necessarily then be a junction of exceptions, or that the : exceptions would have to be processed in parallel (i.e., as with many : things, processing of the value/list/object/junction stops at the : first exception encountered). But someone more expert than I would : need to provide an answer to that one. :-) I think this is a really good argument for unthrown exceptions, AKA interesting values of undef. In Perl 6 you don't really get in trouble for producing undefined values--you're not really in bad trouble till you start trying to *use* an undefined value to do something defined. Being undefined is just a funny kind of tainting, as it were. As long as the undef remembers that it was undefined because you tried to divide by 0 back at line 42, that's probably good enough for the user to trace back and find the error. Or think of each individual undef as containing a little cockpit recorder telling how it got there. But if you say 3 / any(@foo) == 1 it shouldn't really care if any of the values are undefined, I think. (All subject to pragmatic control, I suspect.) Larry
Re: Fun with junctions (was Sets vs Junctions)
Patrick R. Michaud wrote: On Sat, Feb 12, 2005 at 01:18:53PM -0600, Rod Adams wrote: My issue is less that lists and sets are radically different. It is much more a matter of Junctions and Scalars are radically different. Getting me to accept that a Scalar holds several different values at once is a hard sell. Especially when you consider duplicated side effects. Since Scalars can be objects that are fairly complex aggregations that simultaneously hold (or appear to hold) multiple different values at once, this doesn't seem like a strong argument. But, to extract those alternative values from an object, you do something special to it, like call a method. Whenever you evaluate the object as a scalar, you get a single value back. Quite probably a reference to something much more elaborate, but a single value none the less. When you do a Csay $obj, Csay is only called once. s/object/Junction/g above doesn't give me much grief. Extracting values from a Junction is also done by calling methods or functions. None of which has been mentioned or defined, so I was forced to assume they didn't exist. Of course, if we go this route, we are now saying that the return type signature of a sub is defined by an instance of class Junction. And what happens if you attempt to evaluate a junction in a non-boolean context? I dunno, which context are you concerned about? [...] It was basically a reiteration of my iterated side effect argument, which gets worse if you do: @l = (any(1,2,3),any(4,5,6),any(7,8,9),any(10,11,12),any(13,14,15)); say @l.join(' '); I'm not so sure it gets worse here -- @l.join(' ') gets evaluated first, and Cjoin is called only once because none of its parameters are a junction. In this case Cjoin is going to return a junction of strings. Similarly, as Scott Duff pointed out, Csay will be called only once, since the arguments to Csay are passed as part of a slurpy array and as such do not autothread. (No, I'm not entirely sure what would be output as a result. However, whatever it is, it should all be on one line, not 243 lines.) As I stated in a different message, my latest, fairly careful, interpretation of S09 rendered that autothreading and junctions were not directly related topics, even if I wrongly implied they were several posts ago. Thus the reference that slurpy lists cancel autothreading is not relevant to this issue. But if it makes the rest of the discussion go smoother, assume I've overwritten Csay with a non-slurpy version that otherwise does the same thing. I would still think that the above would print 243 times. Consider it this way: P5's Cprint returns true upon success. Thus, Csay would could also be considered a boolean function for Is this printable with a linefeed after it?. So I could then write: @l = (any(1,2,3),any(4,5,6),any(7,8,9),any(10,11,12),any(13,14,15)); $x = say @l.join(' ')); Given the rest of Junction logic defined thus far, I would expect $x be a junction of 243 true/false values. I also have not seen any good way to avoid the situation. It's now been established that one can do a C.isa(Junction) to determine that what we have is, indeed, a junction. However, once that happens, your options are basically to either live with it, or throw an exception. If you're given 'cat'|'dog', there's no way to extract 'cat' and or 'dog', unless you happened to be expecting 'cat' and 'dog', and test for them explicitly. Umm, what's wrong with...? $l = 'cat'|'dog'|'mouse'; @extract = $l.values(); # ('cat', 'dog', 'mouse') The fact that it didn't exist until now. Does this mean we can do: @l = (any(qw/a b c d/) eq any(qw/c d e f/)).values(); and get @l == ('c','d')? For clarification, is the type of 3|'four' == Junction|int|str? I would guess the type of 3|'four' to be int|str, which is also a Junction, but don't hold me to that. But if you go with the Junction is a Class argument from above, I would expect the type would have to be Junction, and then one could query the Junction object as to what types it can mimic. Of course, we could have Junction do some magic, and have each instance create an anonymous subclass that is also ISA whatever types of values happen to be in it at the time. Which seems fairly heavyweight for something so integrated into the language. Will I be able to create variables that can hold ints, but _not_ junctions of ints? In other words, is: my int $x = 3|4; legal? How do I make it illegal, so as to protect myself from duplicated side effects which may be disastrous in application X? If the above is illegal, how do a declare a variable that can hold junctions, but only of type int? Using my set notation, we get a simple: my int #x = 3|4; I'm not certain my creation of a new Set container is the Right Way to be doing things, but it does seem to be resolving or eliminating the issues I see with Junctions. At least in my head. I
Re: Fun with junctions (was Sets vs Junctions)
Rod Adams wrote: I also find the following incredibly disturbing: perl6 -e $x = 'cat'|'dog'; say $x; dog cat That would be disturbing if that's what happened. Csay @what is just a shorthand for Cprint @what, \n. So saying a junction is the same as printing it, which is a run-time error. Can a junction hold values of completely different types, or just different values of the same type? Junctions are values. They don't hold anything. Can a junction have values of different types? Yes. If evaluation of one value of a junction causes an error, is $! now a junction as well? See Larry's response. My response it that, by default, if: foo(2) and foo(3) each throw an exception, then: foo(1|2|3); throws an (single, non-junctive) exception. Which exception gets thrown is indeterminate, since the ordering of a junction, and hence of the autothreading of a junction, is indeterminate. Damian
Re: Fun with junctions (was Sets vs Junctions)
Autrijus wrote: FWIW, I also find it incredibly disturbing. Although I don't have to deal with it yet in the side-effect-free FP6, I think one way to solve this is for the say to return a junction of IO actions. No. It just throws an exception: Can't output a raw junction (did you mean $x.values(), or $x.perl(), or $x.pick() ???) Damian
Re: Fun with junctions (was Sets vs Junctions)
On Sat, Feb 12, 2005 at 12:19:46PM -0600, Rod Adams wrote: I reread S09, and I believe autothreading is the wrong term for the iteration that a junction incurs (Even though it appears in the section immediately after Junctions. Autothreading is something far weirder, dealing with partial dimensional slices, I believe. And in that case, it makes sense to turn off autothreading for slurpys, since in flattening, you get rid of the messy dimensions. Therefore I suspect that the above is wrong, and the behavior of Csay 'cat'|'dog' is still to duplicate. The first large paragraph in the section on Junctions says: Some contexts, such as boolean contexts, have special rules for dealing with junctions. In any scalar context not expecting a junction of values, a junction produces automatic parallelization of the algorithm. In particular, if a junction is used as an argument to any routine (operator, closure, method, etc.), and the scalar parameter you are attempting to bind the argument to is inconsistent with the Junction type, that routine is autothreaded, meaning the routine will be called automatically as many times as necessary to process the individual scalar elements of the junction in parallel. That last sentence says that autothreading is exactly this implicit multiple call behavior that worries you. Let's set aside for the moment the fact that slurpy arrays/hashes aren't autothreaded and talk about a user-defined routine: sub foo ($alpha) { ... } It doesn't take much imagination to come up with a mechanism for Perl6 programmers to stop the autothreading: sub foo is nonthreaded ($alpha) { ... } which would cause an execption of some sort on attempted junctification The down side is that programmers need to be more aware of subroutine/method side effects and write their programs accordingly. Because of this, I'd suggest that autothreading of user-defined routines not be the default, but rather enabled via a pragma of some sort (or, of course, via an autothreaded trait). For the built-in routines this isn't a worry as we get to design them appropriately. -Scott -- Jonathan Scott Duff [EMAIL PROTECTED]
Re: Fun with junctions (was Sets vs Junctions)
Jonathan Scott Duff wrote: Let's set aside for the moment the fact that slurpy arrays/hashes aren't autothreaded and talk about a user-defined routine: sub foo ($alpha) { ... } It doesn't take much imagination to come up with a mechanism for Perl6 programmers to stop the autothreading: sub foo is nonthreaded ($alpha) { ... } Ironically, the way you do that in Perl 6 is with a junction: sub foo ($alpha is none(Junction)) { ... } which would cause an execption of some sort on attempted junctification The down side is that programmers need to be more aware of subroutine/method side effects and write their programs accordingly. This is a *down*-side??? ;-) Because of this, I'd suggest that autothreading of user-defined routines not be the default, but rather enabled via a pragma of some sort (or, of course, via an autothreaded trait). For the built-in routines this isn't a worry as we get to design them appropriately. This seems to be needlessly optimizing for the rare case. And needlessly restrictive. I'd suggest that it would suffice to have a(n optional) warning emitted when a subroutine with side-effects is autothreaded: use warnings 'autothreading'; Damian
Re: Fun with junctions (was Sets vs Junctions)
On Sun, Feb 13, 2005 at 09:53:36AM +1100, Damian Conway wrote: Jonathan Scott Duff wrote: The down side is that programmers need to be more aware of subroutine/method side effects and write their programs accordingly. This is a *down*-side??? ;-) Indeed ;-) I'm using programmer in the broadest possible sense here. Joe the dairy-farmer who wrote his first program ever (and it happened to be in perl) yesterday is still a programmer. Because of this, I'd suggest that autothreading of user-defined routines not be the default, but rather enabled via a pragma of some sort (or, of course, via an autothreaded trait). For the built-in routines this isn't a worry as we get to design them appropriately. This seems to be needlessly optimizing for the rare case. And needlessly restrictive. Perhaps. I'm not so sure it's the rare case that programmers aren't prepared to deal with implicit parallelization. :-) Part of the appeal of perl is that people of all skill/knowledge levels can jump in and start doing useful work. Autothreading by default has the potential to force people to be aware of junctions before they are ready to understand them. I'd suggest that it would suffice to have a(n optional) warning emitted when a subroutine with side-effects is autothreaded: use warnings 'autothreading'; This works for me but I'd make it one of the default set of enabled warnings from a plain use warnings; though. -Scott -- Jonathan Scott Duff [EMAIL PROTECTED]
Re: Junctive collapsing?
Autrijus Tang [EMAIL PROTECTED] writes: On Sat, Feb 12, 2005 at 11:10:13AM -0600, Patrick R. Michaud wrote: No, consider $a = 1; $b = 2; one($a, $a, $b) # false one($b) # true Right. Evidently I need to sleep real soon. :-) However, is there a way to remove the $a from the equation? I'd like to keep implementation decision of using Sets without duplicate elements, unless it is unavoidable, in which case I'll switch back to a List... I think one([EMAIL PROTECTED], [EMAIL PROTECTED], [EMAIL PROTECTED]) is equivalent to all(none([EMAIL PROTECTED]),one([EMAIL PROTECTED])), which should permit an implementation using Sets without duplicate elements. Whether it is worth it is another matter ... Eirik -- Skill without imagination is craftsmanship and gives us many useful objects such as wickerwork picnic baskets. Imagination without skill gives us modern art. -- Tom Stoppard
Re: Fun with junctions (was Sets vs Junctions)
Damian Conway wrote: Rod Adams wrote: I also find the following incredibly disturbing: perl6 -e $x = 'cat'|'dog'; say $x; dog cat That would be disturbing if that's what happened. Csay @what is just a shorthand for Cprint @what, \n. So saying a junction is the same as printing it, which is a run-time error. So we have a restriction that Junctions cannot be outputted. What qualifies as output? Clearly Cprint and its derivatives are output. What about a DBI call? Hmm. I guess it does ultimately resolve into a socket write, so it would be trapped there. However, what if what you're calling a non-Perl Parrot based function? Do we disable junctions from playing with non-PurePerl functions? Or do we autothread over them? How do we tell if a non-Perl function outputs to determine if we should be able to autothread into them or not? Out of curiosity, was the Junctions can't be outputted error documented somewhere prior to now? -- Rod Adams
Re: Testing What Was Printed
On Sat, Feb 12, 2005 at 12:47:56PM -0500, David A. Golden wrote: The trouble with this interface is sometimes you want to collect a bunch of output from a bunch of different functions together. That's why I suggested that it be prototyped to take a code block: stdout_is { fcn1(); # more processing fcn2(); } $expected, comment; Be very careful you do not alter the output with your code block. For example: stdout_is { print scalar caller; } scalar caller;
[perl #34120] [PATCH] win32 bind, listen, accept
# New Ticket Created by Markus Amslser # Please include the string: [perl #34120] # in the subject line of all future correspondence about this issue. # URL: https://rt.perl.org/rt3/Ticket/Display.html?id=34120 This patch extends the io NET_DEVEL with the 'server' functions bind, listen and accept. I only tested it on win32, so no idea what happens on unix. I'm not sure wether i did it right with the ops numbering, but it worked for me (See the next patch). Markus Changelog: - implement bind, listen, accept on win32 - some casting cleanup Index: include/parrot/io.h === RCS file: /cvs/public/parrot/include/parrot/io.h,v retrieving revision 1.61 diff -w -u -r1.61 io.h --- include/parrot/io.h 1 Feb 2005 09:43:18 - 1.61 +++ include/parrot/io.h 12 Feb 2005 23:52:19 - @@ -184,6 +184,9 @@ extern INTVAL PIO_recv(theINTERP, PMC *pmc, STRING **buf); extern INTVAL PIO_send(theINTERP, PMC *pmc, STRING *buf); extern INTVAL PIO_connect(theINTERP, PMC *pmc, STRING *address); +extern INTVAL PIO_bind(theINTERP, PMC *pmc, STRING *address); +extern INTVAL PIO_listen(theINTERP, PMC *pmc, INTVAL backlog); +extern PMC *PIO_accept(theINTERP, PMC *pmc); extern INTVAL PIO_putps(theINTERP, PMC *io, STRING *s); Index: io/io.c === RCS file: /cvs/public/parrot/io/io.c,v retrieving revision 1.108 diff -w -u -r1.108 io.c --- io/io.c 27 Jan 2005 14:11:37 - 1.108 +++ io/io.c 12 Feb 2005 23:52:21 - @@ -1391,6 +1391,73 @@ /* =item CINTVAL +PIO_bind(theINTERP, PMC *pmc, STRING *address) + +Binds C*pmc's socket to the local address and port specified by C*address. + +=cut + +*/ + +INTVAL +PIO_bind(theINTERP, PMC *pmc, STRING *address) +{ +ParrotIOLayer *l = PMC_struct_val(pmc); +ParrotIO *io = PMC_data(pmc); +if(!io) +return -1; + +return PIO_bind_down(interpreter, l, io, address); +} + +/* + +=item CINTVAL +PIO_listen(theINTERP, PMC *pmc, INTVAL backlog) + +Listen for new connections on socket C*pmc. + +=cut + +*/ + +INTVAL +PIO_listen(theINTERP, PMC *pmc, INTVAL backlog) +{ +ParrotIOLayer *l = PMC_struct_val(pmc); +ParrotIO *io = PMC_data(pmc); +if(!io) +return -1; + +return PIO_listen_down(interpreter, l, io, backlog); +} + +/* + +=item CINTVAL +PIO_accept(theINTERP, PMC *pmc) + +Accept a new connection and return a newly created CParrotIO socket. +=cut + +*/ + +PMC * +PIO_accept(theINTERP, PMC *pmc) +{ +ParrotIO *io2; +ParrotIOLayer *l = PMC_struct_val(pmc); +ParrotIO *io = PMC_data(pmc); +if(!io) +return NULL; + +io2 = PIO_accept_down(interpreter, l, io); +return new_io_pmc(interpreter, io2); +} + +/* + +=item CINTVAL PIO_isatty(theINTERP, PMC *pmc) Returns a boolean value indicating whether C*pmc is a console/tty. Index: io/io_passdown.c === RCS file: /cvs/public/parrot/io/io_passdown.c,v retrieving revision 1.9 diff -w -u -r1.9 io_passdown.c --- io/io_passdown.c1 Oct 2004 08:46:50 - 1.9 +++ io/io_passdown.c12 Feb 2005 23:52:21 - @@ -568,6 +568,88 @@ /* +=item CINTVAL +PIO_bind_down(theINTERP, ParrotIOLayer *layer, ParrotIO *io, STRING *address) + +Looks for the implementation of CBind and calls it if found, +returning its return value. + +Returns C-1 if no implementation is found. + + +=cut + +*/ + +INTVAL +PIO_bind_down(theINTERP, ParrotIOLayer *layer, ParrotIO *io, STRING *address) +{ +while (layer) { +if (layer-api-Bind) { +return layer-api-Bind(interpreter, layer, io, address); +} +layer = PIO_DOWNLAYER(layer); +} +return -1; +} + +/* + +=item CINTVAL +PIO_listen_down(theINTERP, ParrotIOLayer *layer, ParrotIO *io, INTVAL backlog) + +Looks for the implementation of Clisten and calls it if found, +returning its return value. + +Returns C-1 if no implementation is found. + + +=cut + +*/ + +INTVAL +PIO_listen_down(theINTERP, ParrotIOLayer *layer, ParrotIO *io, INTVAL backlog) +{ +while (layer) { +if (layer-api-Listen) { +return layer-api-Listen(interpreter, layer, io, backlog); +} +layer = PIO_DOWNLAYER(layer); +} +return -1; +} + +/* + +=item CParrotIO * +PIO_accept_down(theINTERP, ParrotIOLayer *layer, ParrotIO *io, STRING *address)Y + + +Looks for the implementation of CAccept and calls it if found, +returning its return value. + +Returns C-1 if no implementation is found. + + +=cut + +*/ + +ParrotIO * +PIO_accept_down(theINTERP, ParrotIOLayer *layer, ParrotIO *io) +{ +while (layer) { +if (layer-api-Accept) { +return layer-api-Accept(interpreter, layer, io); +} +layer = PIO_DOWNLAYER(layer); +} +return -1; +} + +/* + =back =head1 SEE ALSO Index: io/io_private.h
[perl #34121] [NEW] imc http server
# New Ticket Created by Markus Amslser # Please include the string: [perl #34121] # in the subject line of all future correspondence about this issue. # URL: https://rt.perl.org/rt3/Ticket/Display.html?id=34121 Now it's getting funny. I have written a tiny webserver in imc, that can serve the parrot html documentation. That's also a pretty good test for the NET_DEVEL and file readings functions. I tested it on win32, so no idea what happens on unix. The attached file should be placed in examples/io (no idea how to create a /dev/null patch on win32!). This patch depends of course on #34120. have fun Markus =head1 NAME examples/io/httpd.imc - HTTP server =head1 SYNOPSIS % ./parrot examples/io/httpd.imc =head1 DESCRIPTION A very tiny HTTP-Server. Currently only understands GET method. It's a nice way of testing pretty all io funtions. By default it binds to localhost:1234, and serves the HTML Documentation in ./docs/html. Make sure you have built them with % make html After that you can browse the documenation with http://localhost:1234/html/index.html Currently the URL isn't decoded, so the docs get served only partially Be sure to set CPARROT_NET_DEVEL to 1 in Fio/io_private.h and rebuild Parrot or the network layer won't exist. TODO make it work on W32/IE =cut .sub _main .local pmc sock .local pmc work .local pmc fp .local string address .local string buf .local string req .local string rep .local string temp .local int ret .local int len .local int pos .local int occ1 .local int occ2 .local string meth .local string url .local string doc_root .local string file_con .local string tst .local string tst2 doc_root = docs socket sock, 2, 1, 0 unless sock goto ERR # Pack a sockaddr_in structure with IP and port sockaddr address, 1234, localhost print Binding to port 1234\n bind ret, sock, address NEXT: listen ret, sock, 5 accept work, sock req = MORE: recv ret, work, buf if ret = 0 goto SERVE_REQ concat req, buf index pos, req, \r\n\r\n if pos = 0 goto SERVE_REQ index pos, req, \n\n if pos = 0 goto SERVE_REQ index pos, req, \r\r if pos = 0 goto SERVE_REQ goto MORE SERVE_REQ: #print Request:\n #print req # split is not implemented, so parse it the old way # GET the method and file index occ1, req, add occ1, occ1, 1 index occ2, req, , occ1 sub len, occ1, 1 substr meth, req, 0, len sub len, occ2, occ1 substr url, req, occ1, len if meth == GET goto SERVE_GET print unknown method:' print meth print '\n goto NEXT SERVE_GET: # decode the url url = urldecode (url) # open the file in url if url !=/ goto GET2 url = /index.html GET2: concat url, doc_root, url open fp, url, unless fp goto SERVE_404 read file_con, fp, 65535 rep = HTTP/1.x 200 OK\n concat rep, Server: Parrot-httpd/0.1\n # concat rep, Content-type: text/html\n concat rep, Content-Length: length len, file_con temp = to_string (len) concat rep, temp concat rep, \n\n concat rep, file_con send ret, work, rep print served file ' print url print '\n goto NEXT SERVE_404: rep = HTTP1/1 404 Not Found\nContent-Length: 3\n\n404\n print File not found: ' print url print '\n send ret, work, rep goto NEXT ERR: print Socket error\n end END: close sock end .end .sub to_string .param int n .local string ret .local string char .local int rest ret = NEXT_CHAR: mod rest, n, 10 sub n, n, rest div n, n, 10 add rest, 48, rest chr char, rest concat ret, char, ret if n0 goto NEXT_CHAR .pcc_begin_return .return ret .pcc_end_return .end .sub urldecode .param string in .local string out .local string char_in .local string char_out .local int c_out .local int pos_in .local int len .local string hex length len, in pos_in = 0 out = START: if pos_in = len goto END substr char_in, in, pos_in, 1 char_out = char_in if char_in != % goto INC_IN # OK this was a escape character, next two are hexadecimal add pos_in, 1, pos_in substr hex, in, pos_in, 2 c_out = hex_to_int (hex) chr char_out, c_out add pos_in, 1, pos_in INC_IN: concat out, char_out add pos_in, 1, pos_in goto START END:
Re: Testing What Was Printed
Michael G Schwern wrote: On Sat, Feb 12, 2005 at 12:47:56PM -0500, David A. Golden wrote: The trouble with this interface is sometimes you want to collect a bunch of output from a bunch of different functions together. That's why I suggested that it be prototyped to take a code block: stdout_is { fcn1(); # more processing fcn2(); } $expected, comment; Be very careful you do not alter the output with your code block. For example: stdout_is { print scalar caller; } scalar caller; That's a good warning on code blocks, and worth documenting for a module like this, but I'm not sure it's going to be a big issue in writing test scripts. Unless you're testing the print built-in function, that test is more easily written as is(scalar caller, scalar caller) or maybe even just as ok(1) :-) David