Re: Fun with junctions (was Sets vs Junctions)

2005-02-12 Thread Jonathan Scott Duff
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

2005-02-12 Thread Adrian Howard
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

2005-02-12 Thread Timothy S. Nelson
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?

2005-02-12 Thread Timothy S. Nelson
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?

2005-02-12 Thread Timothy S. Nelson
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

2005-02-12 Thread Bernhard Schmalhofer
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

2005-02-12 Thread Joe Gottman
   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?

2005-02-12 Thread Autrijus Tang
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?

2005-02-12 Thread Autrijus Tang
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)

2005-02-12 Thread Patrick R. Michaud
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?

2005-02-12 Thread Patrick R. Michaud
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?

2005-02-12 Thread Patrick R. Michaud
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)

2005-02-12 Thread Patrick R. Michaud
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)

2005-02-12 Thread Patrick R. Michaud
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

2005-02-12 Thread via RT
# 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?

2005-02-12 Thread Autrijus Tang
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

2005-02-12 Thread Uri Guttman
 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

2005-02-12 Thread David A. Golden
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)

2005-02-12 Thread Rod Adams
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)

2005-02-12 Thread Rod Adams
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

2005-02-12 Thread Larry Wall
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?

2005-02-12 Thread Larry Wall
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)

2005-02-12 Thread Patrick R. Michaud
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

2005-02-12 Thread Uri Guttman
 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

2005-02-12 Thread Larry Wall
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)

2005-02-12 Thread Larry Wall
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)

2005-02-12 Thread Rod Adams
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)

2005-02-12 Thread Damian Conway
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)

2005-02-12 Thread Damian Conway
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)

2005-02-12 Thread Jonathan Scott Duff
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)

2005-02-12 Thread Damian Conway
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)

2005-02-12 Thread Jonathan Scott Duff
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?

2005-02-12 Thread Eirik Berg Hanssen
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)

2005-02-12 Thread Rod Adams
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

2005-02-12 Thread Michael G Schwern
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

2005-02-12 Thread via RT
# 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

2005-02-12 Thread via RT
# 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

2005-02-12 Thread David A. Golden
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