Re: Cfor as a junction operator

2003-01-20 Thread Dave Whipp
Damian Conway wrote:

 Yes, but will it junctify them con-, dis-, ab-, or in-junctively???

Probably most similar to injunctively. But sequentially. I had been 
thinking of something like this:

while (DATA)
{
  print matched $_ if $_ == for(1,2,3,4,5);
}
__DATA__
1
2
9
3
4
5

Like the old bistable operator, each instance of the loop would
maintain the current state of the sequence.

 There's still the issue of implicit serialization.
 Junctions...err...don't.

Perhaps you're right that this isn't really a junction; but its
not completely dissimilar, either. I used the term junction as
a frame of reference for the type of behavior I was thinking of.


 Besides, I don't think we need to sacrifice Cfor to achieve this
 behaviour. If ordered junctions are a useful concept (and I can see
 that they might well be), we can have them like so: [...]

I wasn't thinking of a sacrifice: just an adjustment of perception to 
integrate with pipelining.


Dave.



Re: L2R/R2L syntax

2003-01-20 Thread Austin Hastings

--- Luke Palmer [EMAIL PROTECTED] wrote:
  Mailing-List: contact [EMAIL PROTECTED]; run by ezmlm
  Date: Sat, 18 Jan 2003 15:07:56 -0800 (PST)
  From: Sean O'Rourke [EMAIL PROTECTED]
  Cc: Damian Conway [EMAIL PROTECTED],
  [EMAIL PROTECTED] [EMAIL PROTECTED]
  X-SMTPD: qpsmtpd/0.20, http://develooper.com/code/qpsmtpd/
  
  On Sat, 18 Jan 2003, Michael Lazzaro wrote:
   So 'if' and friends are just (native) subroutines with prototypes
 like:
  
  sub if (bool $c, Code $if_block) {...};
  
  IIRC it's not that pretty, unfortunately, if you want to support
 this:
  
  if $test1 {
  # blah
  } elsunless $test2 {
  # ...
  }
 
 Ahh, you used the unmentionable _correctly_, unlike so many who
 misunderstood some six months ago.
 
  since that gets parsed as
  
  if($test1, { ... }) # aiee: too many arguments to if
 
 That is not a problem:
 
   # We'll just pretend that dereferencing the undef sub does
 nothing
 
   sub if ($test, block; follow) {
 # ... er, how do you write if? Hmm...
 $test ?? block() :: follow()
   }
 
   sub elsunless ($test, block; follow) {
 !$test ?? block() :: follow() 
   }
 
 So:
 
   if $test1 { 
 # stuff
   }
   elsunless $test2 {
 # stuff 2
   }
 
 Becomes (semantically):
 
   if($test1, {
 # stuff
   }, elsunless($test2, {
 # stuff 2
   }));

Is this magic, or do coderef args construct closures, or what? How do
you avoid evaluating the argument to elsunless() when feeding it to the
if() sub?

=Austin




Re: L2R/R2L syntax

2003-01-20 Thread Luke Palmer
 Date: Mon, 20 Jan 2003 09:20:45 -0800 (PST)
 From: Austin Hastings [EMAIL PROTECTED]
 Reply-To: [EMAIL PROTECTED]
 Cc: [EMAIL PROTECTED]
 
 
 --- Luke Palmer [EMAIL PROTECTED] wrote:
   Mailing-List: contact [EMAIL PROTECTED]; run by ezmlm
   Date: Sat, 18 Jan 2003 15:07:56 -0800 (PST)
   From: Sean O'Rourke [EMAIL PROTECTED]
   Cc: Damian Conway [EMAIL PROTECTED],
 [EMAIL PROTECTED] [EMAIL PROTECTED]
   X-SMTPD: qpsmtpd/0.20, http://develooper.com/code/qpsmtpd/
   
   On Sat, 18 Jan 2003, Michael Lazzaro wrote:
So 'if' and friends are just (native) subroutines with prototypes
  like:
   
   sub if (bool $c, Code $if_block) {...};
   
   IIRC it's not that pretty, unfortunately, if you want to support
  this:
   
   if $test1 {
 # blah
   } elsunless $test2 {
 # ...
   }
  
  Ahh, you used the unmentionable _correctly_, unlike so many who
  misunderstood some six months ago.
  
   since that gets parsed as
   
   if($test1, { ... }) # aiee: too many arguments to if
  
  That is not a problem:
  
# We'll just pretend that dereferencing the undef sub does
  nothing
  
sub if ($test, block; follow) {
  # ... er, how do you write if? Hmm...
  $test ?? block() :: follow()
}
  
sub elsunless ($test, block; follow) {
  !$test ?? block() :: follow() 
}
  
  So:
  
if $test1 { 
  # stuff
}
elsunless $test2 {
  # stuff 2
}
  
  Becomes (semantically):
  
if($test1, {
  # stuff
}, elsunless($test2, {
  # stuff 2
}));
 
 Is this magic, or do coderef args construct closures, or what? How do
 you avoid evaluating the argument to elsunless() when feeding it to the
 if() sub?

Oops.  Good point.  In this case I see no way of doing it except for
specifying magic:

  sub elsunless ($test is lazy, block; follow) {
!$test ?? block() :: follow() 
  }

Or something like that.  Darn.

Luke



Re: L2R/R2L syntax

2003-01-20 Thread Michael Lazzaro

On Sunday, January 19, 2003, at 09:51  PM, Luke Palmer wrote:

From: Sean O'Rourke [EMAIL PROTECTED]
On Sat, 18 Jan 2003, Michael Lazzaro wrote:

So 'if' and friends are just (native) subroutines with prototypes 
like:
IIRC it's not that pretty, unfortunately, if you want to support this:

That is not a problem:

snipped

Yeah, a three-argument form would easily allow chaining.  But of course 
it still doesn't do the appropriate syntax checking (Celse outside of 
Cif, etc.).  (It's only speculation on our part, of course, but 
Damian's response was quite intriguing -- he seemed to imply they had a 
solution that would work.)

And it still suffers from the semicolon problem, as Sean pointed out.  
A *big* semicolon problem (sigh).

MikeL



Re: L2R/R2L syntax

2003-01-20 Thread Michael Lazzaro

On Monday, January 20, 2003, at 09:37  AM, Luke Palmer wrote:

Is this magic, or do coderef args construct closures, or what? How do
you avoid evaluating the argument to elsunless() when feeding it to 
the
if() sub?

Oops.  Good point.  In this case I see no way of doing it except for
specifying magic:

  sub elsunless ($test is lazy, block; follow) {
!$test ?? block() :: follow()
  }


Right, but it's acceptable magic (magic that would be used for any 
subs, not just the if, Celse, etc.)  Not grammar-level magic 
special to conditionals.

MikeL



Re: L2R/R2L syntax

2003-01-20 Thread Buddha Buck
Michael Lazzaro wrote:


On Sunday, January 19, 2003, at 09:51  PM, Luke Palmer wrote:


From: Sean O'Rourke [EMAIL PROTECTED]
On Sat, 18 Jan 2003, Michael Lazzaro wrote:


So 'if' and friends are just (native) subroutines with prototypes like:


IIRC it's not that pretty, unfortunately, if you want to support this:


That is not a problem:


snipped

Yeah, a three-argument form would easily allow chaining.  But of course 
it still doesn't do the appropriate syntax checking (Celse outside of 
Cif, etc.).  (It's only speculation on our part, of course, but 
Damian's response was quite intriguing -- he seemed to imply they had a 
solution that would work.)

Would this work?

class True is Bool is singleton {
  method isTrue(block) { block.apply(); };
  method isFalse(block) { };
}

class False is Bool is singleton {
  method isTrue(block) { };
  method isFalse(block) { block.apply(); };
}

class ElseCode is Code {};

our True true is builtin;
our False false is builtin;

sub if (Bool $test, Code $block) { $test.isTrue($block); };
sub if (Bool $test, Code $ifblock, ElseCode $elseblock)
  { $test.ifTrue($ifblock); $test.ifFalse($elseblock); };
sub unless (Bool $test, Code $block) {$test.isFalse($block);};
sub unless (Bool $test, Code $ifblock, ElseCode $elseblock)
  { $test.ifFalse($ifblock); $test.ifTrue($elseblock); };

sub else (Code $block) returns ElseBlock { $block };
sub elseif (Bool $test is lazy, Code $block)
  { if $test, $block; };
sub elseif (Bool $test is lazy, Code $block, ElseCode $elseblock)
  {if $test, $block, $elseblock;};

etc...







Re: L2R/R2L syntax

2003-01-20 Thread Austin Hastings

--- Michael Lazzaro [EMAIL PROTECTED] wrote:
 
 On Sunday, January 19, 2003, at 09:51  PM, Luke Palmer wrote:
  From: Sean O'Rourke [EMAIL PROTECTED]
  On Sat, 18 Jan 2003, Michael Lazzaro wrote:
  So 'if' and friends are just (native) subroutines with prototypes
 
  like:
  IIRC it's not that pretty, unfortunately, if you want to support
 this:
  That is not a problem:
 snipped
 
 Yeah, a three-argument form would easily allow chaining.  But of
 course 
 it still doesn't do the appropriate syntax checking (Celse outside
 of 
 Cif, etc.).  (It's only speculation on our part, of course, but 
 Damian's response was quite intriguing -- he seemed to imply they had
 a 
 solution that would work.)

I'm not sure that there *IS* much appropriate syntax checking, but you
could (and, I suspect, MUST) easily implement this by constructing
reference objects. (There has to be some kind of stack...)

But consider:

print foo if ($bar);
print baz else;

*What about THAT, Mr. Fong?*

This looks to me like an infix operator, or a postfix one for else.


Also, the case of Cif versus Cif-els... is generally a
separable-verb problem:

log $user onto $system.

log $message to $stderr.

l2x = log 2 * log $x;   # Don't check my math, please. :-)


Is it worth handling this?

sub log($n) { ... }
sub log _ onto($user; _ ; $machine) { ... }
sub log _ to($message; _ ; $stream) { ... }

=Austin






A proposal on if and else

2003-01-20 Thread Brent Dax
Many people have pointed out the 'semicolon problem' with if and
else--that is, if Perl intuits a semicolon after every codeblock that
ends a blank line, you would have to cuddle all your elses:

if $cond {
...
}   -- Virtual semicolon here
else {
...
}

My proposed solution to this is to make ALL codeblocks take an optional
'else', accessed by the $code.else attribute.  Depending on what sort of
builtin was being used, the else would mean different things:

sub if($cond, code) {
$cond ?? code() :: code.else();
}

sub while(cond, code) {
if(cond()) {
#There's probably a way to do an
# else without a goto, but...
TOP:
code();
return unless cond();
goto TOP;
}
else {
code.else();
}
}

sub for(@list is lazy, code) {
while(@list) {
code(@list.unshift);
}
else {
code.else();
}
}

The else on a subroutine declaration might be called if preconditions
(PRE and POST) didn't match, or it might just be ignored.

else would be able to take a single subroutine call instead of a block:

if $cond {
...
}
else if $cond2 {
...
}

Yes, I know this means that we have 'else if' instead of 'elsif', but
it's only two more characters and it makes the grammar cleaner.

--Brent Dax [EMAIL PROTECTED]
@roles=map {Parrot $_} qw(embedding regexen Configure)

How do you test this 'God' to prove it is who it says it is?
If you're God, you know exactly what it would take to convince me. Do
that.
--Marc Fleury on alt.atheism




Re: L2R/R2L syntax

2003-01-20 Thread Smylers
Michael Lazzaro wrote:

 Damian Conway wrote:
 
  you can leave a comma out either side of a block/closure, no matter
  where it appears in the argument list
 
 Hmm.  I had been figuring the all conditional/loop stuff would be
 special cases within the grammar, because of their associated cruft...
 but if comma-optional is allowed on *either* side of any block, it
 means that their grammar becomes quite trivial.
 
 That wins the less-special-cases war by a mile, so I emphatically
 withdraw my objection.

Ah.  It was only on reading that (and discovering that you hadn't
previously known about the 'optional comma with closure argument' rule)
that I understood why you had previously been so in favour of proposed
new syntaxes: through a desire to banish the Perl 5 syntax.

Mike, now you've come to terms with the Perl 5 syntax, do you still find
right-left pipelines as compelling as you've previously argued?

It seems that when chaining together functions, omitting C ~ 
operators gives the same result in the familiar Perl 5 standard
function-call syntax:

  @foo = sort { ... } ~ map { ... } ~ grep { ... } ~ @bar;
  @foo = sort { ... } map { ... } grep { ... } @bar;

Left-right pipelines make sense to me.  I'm not yet sure how much I'd
use them, but there are times when I find it a little odd to have data
flowing 'upstream' in code, and reversing this could be nifty.

However right-left pipelines don't seem to add much to the language,
while becoming something else to have to learn and/or explain.
(Damian's explanation of what C ~  does to code seemed
significantly more involved than that of C ~ .)  And an alternative
spelling for the assignment operator[*0] doesn't strike me as something
Perl is really missing:

  $msg ~ 'Hello there';
  $msg = 'Hello there';

I realize that there's a symmetry between the two operators, but that
isn't a convincing reason for having them both.  People are used to data
flow in one direction; it seems reasonable only to have an operator when
wanting to change this, to make it go in the opposite direction.

What benefit does C ~  bring to the language?

Smylers



Re: A proposal on if and else

2003-01-20 Thread Rafael Garcia-Suarez
Brent Dax wrote in perl.perl6.language :
 Yes, I know this means that we have 'else if' instead of 'elsif', but
 it's only two more characters and it makes the grammar cleaner.

The tokeniser could send two tokens else and if whenever it
recognizes the keyword elsif -- so this isn't a problem.



Re: A proposal on if and else

2003-01-20 Thread Joseph F. Ryan
Rafael Garcia-Suarez wrote:


Brent Dax wrote in perl.perl6.language :
 

Yes, I know this means that we have 'else if' instead of 'elsif', but
it's only two more characters and it makes the grammar cleaner.
   


The tokeniser could send two tokens else and if whenever it
recognizes the keyword elsif -- so this isn't a problem.



I think the point of having Cif as a sub rather than as a separate
syntax is so the parser doesn't have to do anything special for
special keywords.

I think the goal was to simplify the compiler, but with the
discussion of recent weeks, it certainly doesn't look like that
happened. :)


Joseph F. Ryan
[EMAIL PROTECTED]




Re: A proposal on if and else

2003-01-20 Thread Joseph F. Ryan
Rafael Garcia-Suarez wrote:


Joseph F. Ryan wrote in perl.perl6.language :
 

I think the point of having Cif as a sub rather than as a separate
syntax is so the parser doesn't have to do anything special for
special keywords.

I think the goal was to simplify the compiler, but with the
discussion of recent weeks, it certainly doesn't look like that
happened. :)
   


Simplify the compiler, yes; but (with my limited knowledge of Perl 6) I
don't expect the tokenizer to be simple. And the hack I just proposed to
the tokenizer is mostly stateless.




If the final design stays the way it is now, there really won't be
a lexer.  Instead, a perl6 grammar parses the data, and builds up
a huge match-object as it, well, matches.  This match object is then
munged into the optree.

This means the grammar probably won't be anything resembling simple,
since it has to act as both a lexer and a parser at the same time.
However, that's not to say your hack couldn't work; in fact, it would
be easy to implement during the match-object-munging phase.
However, it still treats Cif as special syntax, which is the real issue
at hand..

I question whether treating Cif as a function rather than as built-in
syntax will make the parser any simpler if special block rules keep
getting added to simply make it work.  I'm in favor of keeping a few
special blocks if it makes things easier to implement/design in the
long run.


Joseph F. Ryan
[EMAIL PROTECTED]




Re: A proposal on if and else

2003-01-20 Thread Rafael Garcia-Suarez
Joseph F. Ryan wrote in perl.perl6.language :
 
 If the final design stays the way it is now, there really won't be
 a lexer.  Instead, a perl6 grammar parses the data, and builds up
 a huge match-object as it, well, matches.  This match object is then
 munged into the optree.

Oh, yes, I remember now. Thanks.

 This means the grammar probably won't be anything resembling simple,
 since it has to act as both a lexer and a parser at the same time.
 However, that's not to say your hack couldn't work; in fact, it would
 be easy to implement during the match-object-munging phase.

Indeed.

 However, it still treats Cif as special syntax, which is the real issue
 at hand..
 
 I question whether treating Cif as a function rather than as built-in
 syntax will make the parser any simpler if special block rules keep
 getting added to simply make it work.  I'm in favor of keeping a few
 special blocks if it makes things easier to implement/design in the
 long run.

Makes sense. Note that I'm not advocating elsif, quite an horrible
keyword, that I still mispell as elseif sometimes. But I like hacking
on grammars ;-)



A proposal for separable verbs. (Was: Re: A proposal on if and else)

2003-01-20 Thread Austin Hastings

--- Joseph F. Ryan [EMAIL PROTECTED] wrote:
 If the final design stays the way it is now, there really won't be
 a lexer.  Instead, a perl6 grammar parses the data, and builds up
 a huge match-object as it, well, matches.  This match object is then
 munged into the optree.
 

With this in mind, I'll say it again:

Let's support separable verbs. 

Here's how:

# Note my arbitrary selection of _ as separation indicator. Feel free
to replace this with something more appropriate:

sub if($test, block) 
  _ elsif ($test, block) is optional is floating is multi
  _ elsunless ($test, block) is optional is floating is multi
  _ else (block) is optional is fixed
{
  while (!$args[0].test) shift;
  args[0].block();
}

Where:

1: I'm hacking real hard on the implementation. Better Ideas Welcome.
2: space-underscore-space means separable bit. Negotiable. BIW.
3: is optional/[dflt: required] means doesn't have to appear.
4: is floating/[dflt: fixed] means can appear in any order.
5: is multi/[dflt: single] means can appear more than once.

The last three (3, 4, 5) are really just match-hints to the rexer for
here's how to look for me:

/if arg-bits 
  ((elsif arg-bits | elsunless arg-bits)*)
  (else arg-bits)?/

Instead of, say, requiring all the elsif in front of all the elsunless,
or whatever.

I think this is one of those p6-ish generalizations:

try/catch/finally
do/while
if/elsif/elsunless/else
repeat/until
(arguably: switch/case/default)

are all just separable verbs:

sub try (block)
  _ catch ($e, block) is optional is multi is fixed
  _ finally (block) is optional is fixed;

sub do (block)
  _ while ($cond); # is single is fixed is required

sub repeat (block)
  _ until ($cond); # is single is fixed is required

sub switch ($cond)
  _ case ($val, block) is multi is required
  _ default (block) is optional;

(Note: This leaves switch statements looking like crap, so I'd really
rather sugar them up. But the point is, you *could* to it that way.)

switch ($x)
case (10) { print 10; }
case (11) { print 11; }
default   { print Something else; }

=Austin







RE: A proposal for separable verbs. (Was: Re: A proposal on if and else)

2003-01-20 Thread Brent Dax
Austin Hastings:
# Let's support separable verbs. 
# 
# Here's how:
# 
# # Note my arbitrary selection of _ as separation indicator. 
# Feel free to replace this with something more appropriate:
# 
# sub if($test, block) 
#   _ elsif ($test, block) is optional is floating is multi
#   _ elsunless ($test, block) is optional is floating is multi
#   _ else (block) is optional is fixed

How do you name one of these suckers?

%::{'if'}   #Incomplete, and is there an %::{'elsif'}?
%::{'if_elsif_elsunless_else'}  #Could conflict with other symbols
%::{'if _ elsif _ elsunless _ else'}#Depends on ordering

Remember, this also has bearing on importing them from a module.

# {
#   while (!$args[0].test) shift;

1. Where did this $args come from?
2. The while syntax is way wrong.
3. How does else's test default to 1?

#   args[0].block();

From this, it's obvious you forgot about sigil invariance.

# }
# 
# Where:
# 
# 1: I'm hacking real hard on the implementation. Better Ideas Welcome.
# 2: space-underscore-space means separable bit. Negotiable. BIW.
# 3: is optional/[dflt: required] means doesn't have to appear.
# 4: is floating/[dflt: fixed] means can appear in any order.
# 5: is multi/[dflt: single] means can appear more than once.

5 conflicts with multimethods.

# I think this is one of those p6-ish generalizations:
# 
# try/catch/finally
# do/while
# if/elsif/elsunless/else
# repeat/until
# (arguably: switch/case/default)

Except that none of the other ones exist in Perl 6.  :^)

try {
...
CATCH {
...
}
}

loop {
...
last unless cond;
}

loop {
...
last if cond;
}

given(topic) {
when cond {
...
}

default {

}
}

IMHO, separable keywords are in general a bad design, so perhaps they
should be grammar-munge hard.  We really don't need anything but else
(and possibly its friends) for our purposes, but we want them
everywhere, so I don't see why we shouldn't do it this way.

--Brent Dax [EMAIL PROTECTED]
@roles=map {Parrot $_} qw(embedding regexen Configure)

How do you test this 'God' to prove it is who it says it is?
If you're God, you know exactly what it would take to convince me. Do
that.
--Marc Fleury on alt.atheism




RE: A proposal for separable verbs. (Was: Re: A proposal on if and else)

2003-01-20 Thread Austin Hastings
--- Brent Dax [EMAIL PROTECTED] wrote:
 Austin Hastings:
 # Let's support separable verbs. 
 # 
 # Here's how:
 # 
 # # Note my arbitrary selection of _ as separation indicator. 
 # Feel free to replace this with something more appropriate:
 # 
 # sub if($test, block) 
 #   _ elsif ($test, block) is optional is floating is multi
 #   _ elsunless ($test, block) is optional is floating is multi
 #   _ else (block) is optional is fixed
 
 How do you name one of these suckers?
 
 %::{'if'} #Incomplete, and is there an %::{'elsif'}?
 %::{'if_elsif_elsunless_else'}#Could conflict with other symbols
 %::{'if _ elsif _ elsunless _ else'}  #Depends on ordering
 
 Remember, this also has bearing on importing them from a module.
 

Full name, with full signature. if_elsif_elsunless_else($c,b,$c,b,
$c, b, b);

Maybe a special widget in the arglist to denote separability? This
could be important for varargs multimethods.

 # {
 #   while (!$args[0].test) shift;
 
 1. Where did this $args come from?
 2. The while syntax is way wrong.
 3. How does else's test default to 1?
 
 #   args[0].block();
 
 From this, it's obvious you forgot about sigil invariance.

I can't even spell sigil invariance. And I'm nowhere close to sure that
it would be valid to use while when in the middle of trying to define
if. 

I was backfilling the innards after writing the 'outards'. Just a
competence fault on my part.

 
 # }
 # 
 # Where:
 # 
 # 1: I'm hacking real hard on the implementation. Better Ideas
 Welcome.
 # 2: space-underscore-space means separable bit. Negotiable. BIW.
 # 3: is optional/[dflt: required] means doesn't have to appear.
 # 4: is floating/[dflt: fixed] means can appear in any order.
 # 5: is multi/[dflt: single] means can appear more than once.
 
 5 conflicts with multimethods.

s/multi/repeatable/ or whatever. BIW.

 
 # I think this is one of those p6-ish generalizations:
 # 
 # try/catch/finally
 # do/while
 # if/elsif/elsunless/else
 # repeat/until
 # (arguably: switch/case/default)
 
 Except that none of the other ones exist in Perl 6.  :^)

Because we have not heretofore had a cool syntax for separable verbs.
Now we do. Now it can be possible to say use pascal; and get extra
syntax overhead. Rejoice. :-/

 
   try {
   ...
   CATCH {
   ...
   }
   }
 
   loop {
   ...
   last unless cond;
   }
 
   loop {
   ...
   last if cond;
   }
 
   given(topic) {
   when cond {
   ...
   }
   
   default {
   
   }
   }
 
 IMHO, separable keywords are in general a bad design, so perhaps they
 should be grammar-munge hard.  We really don't need anything but else
 (and possibly its friends) for our purposes, but we want them
 everywhere, so I don't see why we shouldn't do it this way.

Go us. One step closer to total world domination.

=Austin




Re: A proposal for separable verbs. (Was: Re: A proposal on if and else)

2003-01-20 Thread Simon Cozens
[EMAIL PROTECTED] (Austin Hastings) writes:
 Let's support separable verbs. 

That (http://dev.perl.org/perl6/rfc/309.html) is a really good idea.

-- 
Writing software is more fun than working.



Why Cmap needs work (was Re: L2R/R2L syntax)

2003-01-20 Thread Michael Lazzaro
On Monday, January 20, 2003, at 12:30  PM, Smylers wrote:

Ah.  It was only on reading that (and discovering that you hadn't
previously known about the 'optional comma with closure argument' rule)
that I understood why you had previously been so in favour of proposed
new syntaxes: through a desire to banish the Perl 5 syntax.


Yes.  Again, it's not that I never knew about the perl5 rule, it's that 
I _dislike_ the perl5 rule, as I dislike most special-case grammar 
rules.  If we dropped Cmap, etc., we could drop the inferred-comma 
rule as well (unless we're really successful in making Cif a simple 
function, in which case we need the rule anyway, so who cares?)

But the inferred-comma rule is tangential to my dislike of the current 
Cmap syntax.  I'd dislike Cmap, and like pipelines, even if the 
inferred-comma rule wasn't there.

Mike, now you've come to terms with the Perl 5 syntax, do you still 
find
right-left pipelines as compelling as you've previously argued?

Yes, very much so.  Here's why...

The Problem

Over the years, I've seen quite a few newbies struggle with the Cmap 
syntax; the most frequent mistake is to reverse the order of the 
arguments, saying

   map @a, {...}

(Another common one is to not understand what Cmap {...} @a, @b would 
do.)  There's a couple of reasons for that, IMO, but the wording I 
often get when I'm trying to get people to verbalize what this 
statement does is that it takes @a, and does blah to it.

In other words, when newcomers verbalize the statement, they tend to 
think of the Cmap as operating on @a.  Which is true.  You might also 
say it does blah to @a, which is also true.  For many people, the 
brain seems to lock around the C@a as the most important part of the 
statement, not the blah part.

Logically, that makes sense.  Cmap, Cgrep, etc., is an operation on 
@a.  It's not an operation on the {...} part -- the {...} is just an 
adverb describing the how, which is of lesser importance.

Is there an OO solution?

So is there fix for Cmap that wouldn't trip newbies up quite so much? 
 The simple fix would seem to be to emphasis the it operates on @a 
part, so that people more easily remember it from the way they 
verbalize it.  Obviously, an OO style fixes that easily:

   @a.map {...};

That's very intuitive to people, esp. new converts from other 
languages.  And, happily, it's very easy to implement and extend.  But 
it works only in one direction, L2R.  (And, as Damian stated, chaining:

   @a.map {...} .sort {...};

probably wouldn't work at all, unless you tossed some parens around all 
your curlies.  Yuck.)

So fine, we convert Cmap, etc., to be methods of collections, as is 
typical programming practice these days.  And, in fact, we _are_ doing 
that elsewhere in the language.  Things like Clength @a will become 
C@a.length or similar.  Even subscripts C[$n] can have dotted 
syntax, e.g. C.[$n].  And, presumably, there will be a C.map, 
C.grep, etc.

But in doing that, we lose a lot of functionality -- mainly, the simple 
L2R and R2L chaining that we have now.  So people want to keep Cmap 
as functions, not methods, and use the old syntax.  Well, that's OK, 
but we're back to the beginning.

 Is there a pipelike solution? 

People like the current Cmap syntax because it allows R2L chaining.  
Saying C @a.map {...}  isn't so onerous that it should send people 
reeling, since it's the exact same syntax as the entire rest of the 
language.  But losing the chaining would hurt, because it's a very 
useful feature.

Here's where the pipeline suggestions come in.  Looking at a strawman 
syntax using '-', JUST FOR THE SAKE OF IMPARTIAL EXAMPLE:

   @out = map {...} - @a;

That's two (OK, three) characters longer than the old syntax.  It could 
be described to newcomers as using @a, do blah with it.

Essentially, it's a post-invocant, a reversed way of saying C @a.map 
{...} .  Note that it doesn't rely on the existence of universal 
functions -- Cmap is just a method of @a.

Here's the important part:  This same syntax will work on ANY object, 
and ANY method of that object.  So you're removing the specific global 
functions Cmap, Cgrep, Csort, etc., and replacing them with a 
generic syntax for right-to-left chaining for any operations object.  
You don't have to _build_ functions that can support chaining, because 
_any_ method can be chained.

And it provides a very visual way to define any pipe-like algorithm, in 
either direction:

   $in - lex - parse - codify - optimize - $out;   # L2R

   $out - optimize - codify - parse - lex - $in;   # R2L

It's clear, from looking at either of those, that they represent data 
pipes.  Both are even clearer than the equiv:

   $out = $in.lex.parse.codify.optimize;

Whether you would code a pipeline as L2R or R2L depends on the specific 
algorithm you're representing, and is purely a matter of taste...  
you'd probably use R2L in the same places as you use Cmap-like 
chaining in Perl5.  I can't begin to justify 

Re: L2R/R2L syntax

2003-01-20 Thread Luke Palmer
 Date: 20 Jan 2003 20:30:07 -
 From: Smylers [EMAIL PROTECTED]
 
 It seems that when chaining together functions, omitting C ~ 
 operators gives the same result in the familiar Perl 5 standard
 function-call syntax:
 
   @foo = sort { ... } ~ map { ... } ~ grep { ... } ~ @bar;
   @foo = sort { ... } map { ... } grep { ... } @bar;
 
 Left-right pipelines make sense to me.  I'm not yet sure how much I'd
 use them, but there are times when I find it a little odd to have data
 flowing 'upstream' in code, and reversing this could be nifty.

Agreed.

 However right-left pipelines don't seem to add much to the language,
 while becoming something else to have to learn and/or explain.
 (Damian's explanation of what C ~  does to code seemed
 significantly more involved than that of C ~ .) 

It's simple:  it's a backwards dot.  The invocant goes on the right
and the method and arguments go on the left.

  $foo.bar($baz);
-or-
  bar $foo: $baz;

is the same as:

  bar $baz ~ $foo;

And you see now what this gives us.  It gives us the ability to place
the invocant (almost) anywhere we want:  On the left, in between, or
on the right.  I think it's fortunate that we can't put it between
arguments...

 And an alternative spelling for the assignment operator[*0] doesn't
 strike me as something Perl is really missing:
 
   $msg ~ 'Hello there';
   $msg = 'Hello there';

Yeah, I didn't see much gain in this bit.  But it's an expectable
generalization from ~.

 I realize that there's a symmetry between the two operators, but that
 isn't a convincing reason for having them both.  People are used to data
 flow in one direction; it seems reasonable only to have an operator when
 wanting to change this, to make it go in the opposite direction.
 
 What benefit does C ~  bring to the language?

Again, it provides not just a null operator between to calls, but
rather a rewrite of method call syntax.  So:

  map {...} ~ grep {...} ~ @boing;

is not:

  map {...} grep {...} @boing;

But rather:

  @boing.map({...}).grep({...});

Which will be defined to mean the same thing, but in many cases this
won't be true.  Another example:

  print Starting server\n~ open  $logfile;

The important thing is that it's starting the server, not that it's
writing that to the logfile.  

I personally think that this could add something to readability at
times.  Maybe not as much as ~, but every once in a while.

Luke