Re: C as a "junction" operator
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 () { 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 C 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
--- 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, █ &follow) { > # ... er, how do you write "if"? Hmm... > $test ?? block() :: follow() > } > > sub elsunless ($test, █ &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
> 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, █ &follow) { > > # ... er, how do you write "if"? Hmm... > > $test ?? block() :: follow() > > } > > > > sub elsunless ($test, █ &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, █ &follow) { !$test ?? block() :: follow() } Or something like that. Darn. Luke
Re: L2R/R2L syntax
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: Yeah, a three-argument form would easily allow chaining. But of course it still doesn't do the appropriate syntax checking (C outside of C, 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
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, █ &follow) { !$test ?? block() :: follow() } Right, but it's acceptable magic (magic that would be used for any subs, not just the , C, etc.) Not grammar-level magic special to conditionals. MikeL
Re: L2R/R2L syntax
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: Yeah, a three-argument form would easily allow chaining. But of course it still doesn't do the appropriate syntax checking (C outside of C, 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
--- 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: > > > Yeah, a three-argument form would easily allow chaining. But of > course > it still doesn't do the appropriate syntax checking (C outside > of > C, 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 C versus C 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
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
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
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
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 C 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
Joseph F. Ryan wrote in perl.perl6.language : > > I think the point of having C 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 strain on the lexer were a design criterion, I blew it long ago. -- Larry Wall
Re: A proposal on if and else
Rafael Garcia-Suarez wrote: Joseph F. Ryan wrote in perl.perl6.language : I think the point of having C 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 C as special syntax, which is the real issue at hand.. I question whether treating C 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
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 C as special syntax, which is the real issue > at hand.. > > I question whether treating C 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)
--- "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 ((elsif | elsunless )*) (else )?/ 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)
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)
--- 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)
[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 C needs work (was Re: L2R/R2L syntax)
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 C, etc., we could drop the inferred-comma rule as well (unless we're really successful in making C 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 C syntax. I'd dislike C, 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... Over the years, I've seen quite a few newbies struggle with the C syntax; the most frequent mistake is to reverse the order of the arguments, saying map @a, {...} (Another common one is to not understand what C 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 to it". In other words, when newcomers verbalize the statement, they tend to think of the C as operating on @a. Which is true. You might also say "it does 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. C, C, 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. So is there fix for C 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 C, 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 C 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 C 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 C 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 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 -- C 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 C, C, C, 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 C-like chaining in Perl5. I can't begin to justify why one should be superior to the other, and would certainly use them both. So t
Re: L2R/R2L syntax
> 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