Re: receivers of pipes (the sharp end again)

2005-05-08 Thread Brad Bowman

 I guess the real question is whether == my $x is really assigning a
 list or binding an iterator to a Lazy slot somewhere.  It feels like
 the latter is more useful.  Which means that == @x can return as soon
 as it binds the iterator to @x.specs.  It doesn't have to wait for all
 the values to be produced, which an assignment implies (kinda sorta).

Iterators/streams would also help lazy pipelines play well with GC.
Using an array seems to require shifts to reclaim memory, an
iterator would do the right thing by default.

Brad

-- 
 Intelligence is nothing more than discussing things with others.
 Limitless wisdom comes of this. -- Hagakure



Re: receivers of pipes (the sharp end again)

2005-05-06 Thread Luke Palmer
On 5/6/05, Juerd [EMAIL PROTECTED] wrote:
 When piping to a scalar, I assume its reftype will determine what will
 happen. But what if the scalar is undef? Is it then assumed to want to
 behave like an array?

If you're piping into a scalar without parens, I think it should
always become an array ref.

 How do you pipe to an array returned by a sub? == @ foo()?

Well, you'd have to be piping into a returned array ref, because you
can't pipe into the list the sub returns.  So I think it's ==
@{foo()}

 Off topic, but I just thought of this again: is whitespace allowed or
 disallowed between sigil and name?

Disallowed.

Luke


Re: receivers of pipes (the sharp end again)

2005-05-06 Thread Juerd
Luke Palmer skribis 2005-05-06 10:45 (-0600):
  How do you pipe to an array returned by a sub? == @ foo()?
 Well, you'd have to be piping into a returned array ref, because you
 can't pipe into the list the sub returns.  So I think it's ==
 @{foo()}
  Off topic, but I just thought of this again: is whitespace allowed or
  disallowed between sigil and name?
 Disallowed.

Does this mean that @{foo()} can be written as @ foo()?


Juerd
-- 
http://convolution.nl/maak_juerd_blij.html
http://convolution.nl/make_juerd_happy.html 
http://convolution.nl/gajigu_juerd_n.html


Re: receivers of pipes (the sharp end again)

2005-05-06 Thread Larry Wall
On Fri, May 06, 2005 at 06:35:45PM +0200, Juerd wrote:
: Which things can receive?
: 
: If I recall things correctly, we already have these:
: 
: sub # slurpy list
: arrary  
: hash
: 
: Would it make sense to add, for example,
: 
: filehandle  # write
: 
: It may not, as it's not reversible like the others are: a filehandle in
: list context doesn't slurp. It's probably better to let this be done
: only with io().

That's one of the reasons io() is so Huffmanly short, I imagine.

: When piping to a scalar, I assume its reftype will determine what will
: happen. But what if the scalar is undef? Is it then assumed to want to
: behave like an array?

How does it autovivify, in other words?  Maybe it autovivifies to
an iterator:

do_stuff() == my $iter;

for =$iter {...}

If someone wants to use an array, I don't see why they wouldn't just use @.

: When is the pointy side evaluated?

Whenever it asks for more data, and more data is available.

: How do you pipe to an array returned by a sub? == @ foo()?

== foo()[]

That'd work for

== $foo[]

as well, presumably, and autovivify an array in $foo.

We probably ought to consider the parallel aspects of piping to a hash,
since there's no requirement that a hash be built in order.  With the
recent change to allow multiple input pipes, the pipes could probably
be run in parallel:

my %result == [==] @pairgenerators;
my %result{()} = 1 == [==] @keygenerators;

Actually that wouldn't work, since %result == @a == @b implies that
@b passes through @a on its way to %result.  Maybe I mean something
more like:

my %result »==« @pairgenerators;
my %result{()} = 1 »==« @keygenerators

But actually, %result == @a == @b doesn't imply passage through
@a unless == is right associative like assignment.  If it's left
associative, it means (%result == @a) == @b, which can probably be
parallelized, just like @b == %result == @a, and any other constructs
that can be borrowed from the B*f* class of languages.

I suppose == is left associative, which means that 

@a == foo() == %result

does go through foo().  But that probably means

%result == foo() == @a

really wants to be right associative, which means we can't reduce with
it.  However, we just got through saying that ; is basically equivalent
to ==.  But ; could be construed as left associative, so maybe we can
say it like this:

my %result == [;] @pairgenerators;
my %result{()} = 1 == [;] @keygenerators;

Interestingly, reduction with [;] works at the top level and can't
be confused with statement-final semicolon.

So if we want to parallize input pipes, we just bind to Lazy *array
and arrange to read whichever lazy list has something for us.  Probably
need some kind of internal support for that.  Maybe any(@array).shift can
do it.

: Off topic, but I just thought of this again: is whitespace allowed or
: disallowed between sigil and name?

Disallowed.

Larry


Re: receivers of pipes (the sharp end again)

2005-05-06 Thread Larry Wall
On Fri, May 06, 2005 at 06:55:47PM +0200, Juerd wrote:
: Luke Palmer skribis 2005-05-06 10:45 (-0600):
:   How do you pipe to an array returned by a sub? == @ foo()?
:  Well, you'd have to be piping into a returned array ref, because you
:  can't pipe into the list the sub returns.  So I think it's ==
:  @{foo()}
:   Off topic, but I just thought of this again: is whitespace allowed or
:   disallowed between sigil and name?
:  Disallowed.
: 
: Does this mean that @{foo()} can be written as @ foo()?

I would prefer not.  Use foo()[] instead.

Larry


Re: receivers of pipes (the sharp end again)

2005-05-06 Thread Juerd
Larry Wall skribis 2005-05-06 10:19 (-0700):
 If someone wants to use an array, I don't see why they wouldn't just use @.

Because it's an argument of a very generic function, and it could just
as well be a subref or hashref.

sub mypipe($receiver, [EMAIL PROTECTED]) { @list == $receiver }

 my %result == [;] @pairgenerators;
 my %result{()} = 1 == [;] @keygenerators;
 Interestingly, reduction with [;] works at the top level and can't
 be confused with statement-final semicolon.

Nice.


Juerd
-- 
http://convolution.nl/maak_juerd_blij.html
http://convolution.nl/make_juerd_happy.html 
http://convolution.nl/gajigu_juerd_n.html


Re: receivers of pipes (the sharp end again)

2005-05-06 Thread Rob Kinyon
 : Does this mean that @{foo()} can be written as @ foo()?
 
 I would prefer not.  Use foo()[] instead.

Does this mean that some constructs in Perl are parsed immediately
(such as foo() ...) and some are deferred (such as the [ in [+^]
...)? I would think this potentially makes a difference in how P6 code
is read ...

Rob


Re: receivers of pipes (the sharp end again)

2005-05-06 Thread Larry Wall
On Fri, May 06, 2005 at 10:45:57AM -0600, Luke Palmer wrote:
: On 5/6/05, Juerd [EMAIL PROTECTED] wrote:
:  When piping to a scalar, I assume its reftype will determine what will
:  happen. But what if the scalar is undef? Is it then assumed to want to
:  behave like an array?
: 
: If you're piping into a scalar without parens, I think it should
: always become an array ref.

I think it would be more general to return an iterator or some kind of
promise, insofar as it doesn't commit to storing the values, but merely
to returning them in the order produced.  You can always use $foo[] for
the other meaning.

Alternately, we could make =$foo an lvalue, but == =$foo is a bit strange,
and people will think it means to write to filehandle $foo.  Or we could
force people to say something evil like == my $foo is Iterator.

I guess the real question is whether == my $x is really assigning a
list or binding an iterator to a Lazy slot somewhere.  It feels like
the latter is more useful.  Which means that == @x can return as soon
as it binds the iterator to @x.specs.  It doesn't have to wait for all
the values to be produced, which an assignment implies (kinda sorta).

Which, if we continue with () as an explicit pipe target, == @x = ()
would force assignment semantics.  Alternately we could assume
assignment and force binding with == @x := ().  Just depends on
how lazy we want to be by default, I guess.  I don't have a good
feeling for how to answer that.  I guess you want to be as lazy
as possible without getting into trouble.

Larry


Re: receivers of pipes (the sharp end again)

2005-05-06 Thread Larry Wall
On Fri, May 06, 2005 at 01:26:10PM -0400, Rob Kinyon wrote:
:  : Does this mean that @{foo()} can be written as @ foo()?
:  
:  I would prefer not.  Use foo()[] instead.
: 
: Does this mean that some constructs in Perl are parsed immediately
: (such as foo() ...) and some are deferred (such as the [ in [+^]
: ...)? I would think this potentially makes a difference in how P6 code
: is read ...

I don't believe that [+^] does deferred parsing.  Reduction
operators are not a fancy form of eval.  Like symbolic refs, they're
a factoring out of something that would otherwise have to be done
by eval.  Basically, they're emulating what

@x.join( $op ).eval

*would* do, which is why [] and [|] can work.  But that's because the
list-associative operators actually have some kind of listy interface
for the general reduction code to call, or else they have special
code to bypass the left-associativity of the naïve solution.

Larry


Re: receivers of pipes (the sharp end again)

2005-05-06 Thread Larry Wall
On Fri, May 06, 2005 at 01:51:58PM -0400, Rob Kinyon wrote:
: I understand that the reduce [] operator will have its standard forms
: ([+], [], etc) which will be immediately recognizable just like all
: the other 3-char operators (==, etc) will be. I'm just concerned
: about the extended form and readability.

It's possible that we can allow both the reduce[*] and [*] forms, and
let local policy dictate matters cobolish vs mathish.  As a general
rule we've trying to eliminate synonyms in Perl 6, but this might be
a good place for one.

Or perhaps we should by default restrict short ones to simple
operators, since it's pretty obvious that [+] is doing *some* kind
of addition, while [EMAIL PROTECTED]$*#«=] is not quite so obvious.  In other
words, we apply some kind of Huffman amplification to the metaoperator,
where the rich stay rich, but the poor get poorer.  Or something
like that.  I always admired the Great Dalmutti as a game that has
the gall (or sense of reality) to prejudice itself in favor of the
overdogs rather than the underdogs.  If we we were more democratic,
we'd require reduce on the short ones instead of the long ones. :-)

Larry


Re: receivers of pipes (the sharp end again)

2005-05-06 Thread Larry Wall
On Fri, May 06, 2005 at 07:54:09PM +0200, Juerd wrote:
: Larry Wall skribis 2005-05-06 10:37 (-0700):
:  Alternately, we could make =$foo an lvalue, but == =$foo is a bit strange,
:  and people will think it means to write to filehandle $foo.  Or we could
:  force people to say something evil like == my $foo is Iterator.
: 
: I would personally not mind having an extra primary sigil for iterators.
: They're different enough, and used enough.

But then how do you know if you just want to pass one as a scalar and
not iterate it?

Larry


Re: receivers of pipes (the sharp end again)

2005-05-06 Thread Rob Kinyon
 Or perhaps we should by default restrict short ones to simple
 operators, since it's pretty obvious that [+] is doing *some* kind
 of addition, while [EMAIL PROTECTED]$*#«=] is not quite so obvious.  In other
 words, we apply some kind of Huffman amplification to the metaoperator,
 where the rich stay rich, but the poor get poorer.  Or something
 like that.  I always admired the Great Dalmutti as a game that has
 the gall (or sense of reality) to prejudice itself in favor of the
 overdogs rather than the underdogs.  If we we were more democratic,
 we'd require reduce on the short ones instead of the long ones. :-)

I like this idea. It provides more huffman-coding for readability.

Rob


Re: receivers of pipes (the sharp end again)

2005-05-06 Thread Juerd
Larry Wall skribis 2005-05-06 11:07 (-0700):
 But then how do you know if you just want to pass one as a scalar and
 not iterate it?

Assuming =:

 =iterator # the iterator itself, passable (autoreffing)
$=iterator # get one element
@=iterator # get remaining elements, lazily

This would mean we'd get

for @=$fh - $line { ... }

or

=it := =$fh;  # =it := $fh.it  # =it = $fh.it  # I dunno.
for @=it - $line { ... }

Ugly.

Another alternative would be

$fh.it   # the iterator itself, passable
=$fh # synonym for $fh.it.next, where a real iterator has .it
 # returning $self, so that =$iterator and =$handle both
 # work, without special magic.


Juerd
-- 
http://convolution.nl/maak_juerd_blij.html
http://convolution.nl/make_juerd_happy.html 
http://convolution.nl/gajigu_juerd_n.html