Re: When scoping
On 5/4/05, Larry Wall [EMAIL PROTECTED] wrote: To get the other behavior, you have to say one of: given hello { when /hello/ { say One; when /hello/ { say Two; continue; } when /hello/ { say Three; continue; } continue; } say Four; } given hello { when /hello/ { say One; say Two when /hello/; say Three when /hello/; continue; } say Four; } given hello { when /hello/ { say One; if /hello/ { say Two; } if /hello/ { say Three; } continue; } say Four; } That seems like enough WTDI. Not quite. There's also the way that I have it in the pugs IRC bot: given hello { when /hello/ { given $_ { say One; when /hello/ { say Two } when /hello/ { say Three } } } say Four; } Which I actually like the best. If only it weren't so heavily indented. Hmmm, maybe I should go implement Acme::Whiven: given hello { whiven /hello/ { when /hello/ {...} ... } } Luke
Re: reduce metaoperator
Luke Palmer wrote: On 5/4/05, Larry Wall [EMAIL PROTECTED] wrote: [] could mean monotonically increasing. Not unless we make boolean operators magic. There are arguments for doing that, but I don't really want to think about how that would be done at the moment. Reduce over a straight-up (or left) boolean operator doesn't make much sense... But the comparators *are* magic in Perl 6. They're not binary, they're n-ary. So, since: [] @vals actually means: @vals[0] @vals[1] @vals[2] @vals[3] we get the n-ary behaviour, which is true if those values *are* in that order. Perhaps you're forgetting the difference between what reduce means mathematically, and how its semantics are approximated in Perl 5 (in List::Util). Reduce means bung this operator in between each of the elements of this list. But there's no way[*] to do that directly in Perl 5, so we currently have to live with a pairwise binary approximation. That's perhaps the nicest feature of Larry's proposed reduction operator: that it will finally allow us to implement the real semantics of reduce and so get all the handy metaoperators (sum, product, sum-of-squares, monotonicity, first-true, first-defined) we've been missing to date. Damian [*] Okay, that's not strictly true. Evil Damian is already contemplating how to implement n-ary reduction in Perl 5. Bwah-ha-ha-ha!
Re: stdio
On Thu, May 05, 2005 at 08:39:52AM +0300, Gaal Yahas wrote: : How do I open a file named -? Um, depending on what you mean, and whether we continue to support the '=' pseudofile, maybe: $fh = io(-); or $fh = open -; or $fh = $name eq '-' ?? $*IN :: open $name; : How do I open stdout (and the other standard handles)? Maybe something like: $fh = open file, :w:c:usefd(1); or $*OUT.reopen(file,:w:c); or reopen $*OUT: file, :w:c; give or take a few options. Larry
Re: stdio
On Wed, May 04, 2005 at 11:44:58PM -0700, Larry Wall wrote: : How do I open a file named -? Um, depending on what you mean, and whether we continue to support the '=' pseudofile, maybe: $fh = io(-); $fh = open -; $fh = $name eq '-' ?? $*IN :: open $name; My concern is again with magic control. I've no gripes with the first or last of those, but I think the second should not be allowed by default. There has to be a safe mode for opening a file and knowing that's what you're opening: not a pipe, not stdio (hence there are places I can't permit myself to use #1). But as your third example suggests, never allowing open - will make unixish tools tedious to write, so maybe we need something like getopt(...); $fh = open $in, :allowstdio; (only named more eloquently). : How do I open stdout (and the other standard handles)? Maybe something like: $fh = open file, :w:c:usefd(1); $*OUT.reopen(file,:w:c); reopen $*OUT: file, :w:c; give or take a few options. What does 'file' do in these examples? If we take your trailing-args suggestion from the Open and pipe thread, the filename could be optional. How to make this --friendly? If my earlier suggestion is okay, then by symmetry: $logfile = -; open $log, :a:allowstdio; -- Gaal Yahas [EMAIL PROTECTED] http://gaal.livejournal.com/
Re: Open and pipe
On May 4, 2005, at 8:13 AM, Uri Guttman wrote: AS Why? Because IO::Socket.new takes parameters that are built out of its AS entire inheritance tree, so a change to IO::Handle might radically AS modify the signature of the constructor. makes sense. we should look at the p5 IO:: tree and see what we want to salvage/savage from it as well as io::all. each has its good and bad points and hopefully we can figure out which is which. :) Yes. p5 IO:: has evolved a bit over time and some things have turned out to be bad choices in hindsight. For example, one thing I am still not convinced was the right thing was to create a hierarchy such that a given class only had methods that were valid for it. For example the recent issue on p5p with seek etc not being in IO::Handle but IO::Seekable and the core using IO::Handle. Also the way IO::Socket::* was done instead of all sockets created by IO::Socket-new these are all things that should be reconsidered and I am sure in all cases there will be people on both sides of the fence Graham.
Re: When scoping
On Wed, May 04, 2005 at 11:00:46PM -0700, David Wheeler wrote: : On May 4, 2005, at 22:31 , Larry Wall wrote: : : given hello { : when /hello/ { : say One; : if /hello/ { say Two; } : if /hello/ { say Three; } : continue; : } : say Four; : } : : Is there no more : : say Two if /hello/; : : ? You must have missed the implied ... at the end of my list of other WTDI. You can also do any of: say Two if /hello/; /hello/ say Two; /hello/ and say Two; /hello/ ?? say Two :: leave; infix:and(/hello/, { say Two }) continue unless /hello/; say Two; /hello { say Two }/; s/hello/{ say Two }$0/; ({}, { say Two })[?/hello/](); and probably a few more I can't think of off the top of my head. Larry
Re: reduce metaoperator
On Wed, May 04, 2005 at 11:58:59PM -0600, Luke Palmer wrote: : On 5/4/05, Larry Wall [EMAIL PROTECTED] wrote: : [] could mean monotonically increasing. : : Not unless we make boolean operators magic. There are arguments for : doing that, but I don't really want to think about how that would be : done at the moment. Reduce over a straight-up (or left) boolean : operator doesn't make much sense... It could be admitted under the rewrite rule as applied to chaining comparison operators, such that if [](1,2,3) {...} is the same as if 1 2 3 {...} Likewise, one could write [|] to mean any and [] to mean all, but that'd be kind of silly. On the other hand, I freely admit that those don't work under a recursive binary view that artificially forces left-associativity. Larry
Re: Cmmposition binop
On Thu, 5 May 2005, Stuart Cook wrote: What I refer to now is something that takes two {coderefs,anonymous subs,closures} and returns (an object that behaves like) another anonymous sub, precisely the one that acts like the former followed by the latter (or vice versa!). Do you mean like the mathematical 'f o g'? Indeed. Michele -- Have you noticed that people whose parents did not have children, also tend not to have children. - Robert J. Kolker in sci.math, Re: Genetics and Math-Ability
Re: stdio
On Thu, May 05, 2005 at 01:32:56AM -0600, Luke Palmer wrote: On 5/5/05, Gaal Yahas [EMAIL PROTECTED] wrote: getopt(...); $fh = open $in, :allowstdio; Maybe the opposite: $fh = open $in, :literal; One of the nice things about the magical - behavior is that people are writing more versatile, accepting scripts without realizing it. That was one of the things that made me really like Perl when I first started learning it. A few of the little utility / filter scripts that I wrote already accepted - on the command line, and I didn't even know it (and they still worked perfectly when you used -). Yeah, you and me both. And I don't think arguing in the name of security for the default case is going to buy us anything. Security doesn't come in scripts in any language for free; you have to walk through every line that sees the outside world and ask is there any way somebody could exploit this?. And a - handler would be one of the things you'd have to routinely write, just like making sure they're not opening ; rm -rf /. Why are you scare-quoting something I never said? I wasn't talking about security, I was talking about basic least-surprise. Opening ; rm -rf / with my perl5 does not do anything bad. Opening - potentially causes a script to hang. But I don't think a :literal flag or whatever will be a problem. Yes, I like your proposal, though I don't know which way should be the default. I'm not looking for sysopen (I know where to find it), I'm looking for an easy way to control magic. You can also open a file named -, in the absence of a literal option, like this: my $fh = open ./-; I'd say fine, except that this isn't portable. I think he misunderstood you (and if not, then I misunderstood you :-). You're asking about how to get a filehandle to stdout, he's telling you how to redirect stdout to a file. I think - will do the trick. Ah, yes, then again the question is how to conveniently choose whether to do e.g. log-to-stdout or write to a file named -. -- Gaal Yahas [EMAIL PROTECTED] http://gaal.livejournal.com/
Re: stdio
On 5/5/05, Gaal Yahas [EMAIL PROTECTED] wrote: On Thu, May 05, 2005 at 01:32:56AM -0600, Luke Palmer wrote: And I don't think arguing in the name of security for the default case is going to buy us anything. Security doesn't come in scripts in any language for free; you have to walk through every line that sees the outside world and ask is there any way somebody could exploit this?. And a - handler would be one of the things you'd have to routinely write, just like making sure they're not opening ; rm -rf /. Why are you scare-quoting something I never said? I'm scare-quoting everything today for some reason. Sorry. The issue has come up before, and one of the main arguments was it's more secure that way, which made so little sense, I thought that I'd argue against it again. Or something. Luke
Re: reduce metaoperator
Larry Wall [EMAIL PROTECTED] wrote: It would be nice to have an easy-to-access What's this? interface that could be stitched into your favorite editor to identify what's under the cursor, or at least a command like: p6explain '[+]' s:p5/nice to have/absolutely necessary/ unless $self ~~ @larry; Could $EDITOR-p6explain use life information from the parser with the current context of the requested token? leo
Re: stdio
On Thu, May 05, 2005 at 10:14:34AM +0300, Gaal Yahas wrote: : On Wed, May 04, 2005 at 11:44:58PM -0700, Larry Wall wrote: : : How do I open a file named -? : : Um, depending on what you mean, and whether we continue to support : the '=' pseudofile, maybe: : : $fh = io(-); : $fh = open -; : $fh = $name eq '-' ?? $*IN :: open $name; : : My concern is again with magic control. I've no gripes with the first : or last of those, but I think the second should not be allowed by : default. There has to be a safe mode for opening a file and knowing : that's what you're opening: not a pipe, not stdio (hence there are places : I can't permit myself to use #1). But as your third example suggests, : never allowing open - will make unixish tools tedious to write, so : maybe we need something like : : getopt(...); : $fh = open $in, :allowstdio; : : (only named more eloquently). I think that, as with various other parts of Perl 6, we can try to sweep all the dwimmery into one spot so that it can be easily recognized and/or avoided. And the default open is not the place for dwimmery. It should just open an ordinary file by default. The place for all that dwimmery is probably io(). In contrast, open should be a multisub/method that gives you exact semantics depending on the invocant. In fact, io() might just be short for IO.open(), which specifically requests dwimmery, just as URI.open() specifically requests URI interpretation. And bare open() is probably short for File.open(). (Though for io(), it's probable that it actually does the open lazily depending on usage, since that's part of its dwimmery.) Larry
Re: When scoping
On May 4, 2005, at 23:19 , Larry Wall wrote: You must have missed the implied ... at the end of my list of other WTDI. You can also do any of: say Two if /hello/; /hello/ say Two; /hello/ and say Two; /hello/ ?? say Two :: leave; infix:and(/hello/, { say Two }) continue unless /hello/; say Two; /hello { say Two }/; s/hello/{ say Two }$0/; ({}, { say Two })[?/hello/](); and probably a few more I can't think of off the top of my head. Okay then, pay no attention to my piddling contribution of a single example. :-) Best, David smime.p7s Description: S/MIME cryptographic signature
Declaration and definition of state() vars
Hi, sub gen() { state $svar = 42; # Only initialized once, as it is (per S04) equivalent to # state $svar will first{ 42 }; return { $svar++ }; } my $a = gen();# $svar == 42 $a(); $a(); # $svar == 44 my $b = gen();# $svar == 44 say $b(); # 44 # $svar == 45 I presume that's correct. Is the following correct, too? sub gen() { (state $svar) = 42; # Initialized on each invocation of gen, as it is equivalent to # (state $svar will first{ undef }) = 42; # I.e. $svar is only set to undef once (as $svar is a state # variable), but it is set to 42 each time gen is called. Correct? return { $svar++ }; } my $a = gen();# $svar == 42 $a(); $a(); # $svar == 44 my $b = gen();# $svar == 42 say $b(); # 42 # $svar == 43 --Ingo -- Linux, the choice of a GNU | Mathematicians practice absolute freedom. generation on a dual AMD | -- Henry Adams Athlon!|
Re: Declaration and definition of state() vars
On Thu, May 05, 2005 at 07:50:31PM +0200, Ingo Blechschmidt wrote: : Hi, : : sub gen() { : state $svar = 42; : # Only initialized once, as it is (per S04) equivalent to : # state $svar will first{ 42 }; : return { $svar++ }; : } : : my $a = gen();# $svar == 42 : $a(); $a(); # $svar == 44 : my $b = gen();# $svar == 44 : say $b(); # 44 : # $svar == 45 : : I presume that's correct. Yes. Though I'm not quite sure if we've nailed down whether the will form will auto-assign or would instead have to be written state $svar will first { $_ = 42 } I think the latter is probably correct. However, you should be able to write the non-closure form to auto-assign in any event: state $svar is first(42) : Is the following correct, too? : : sub gen() { : (state $svar) = 42; : # Initialized on each invocation of gen, as it is equivalent to : # (state $svar will first{ undef }) = 42; : # I.e. $svar is only set to undef once (as $svar is a state : # variable), but it is set to 42 each time gen is called. Correct? : return { $svar++ }; : } : : my $a = gen();# $svar == 42 : $a(); $a(); # $svar == 44 : my $b = gen();# $svar == 42 : say $b(); # 42 : # $svar == 43 Depends on whether assignment to a state variable is recognized in syntactic analysis (where parens count) or semantic analysis (where they don't). You're taking the syntactic approach. It can be argued that the semantic approach is more robust, insofar as it makes all of these equivalent: state $a = 1; state $b = 2; state ($a,$b) = (1,2); (state $a, state $b) = (1,2); just as my $a = 1; my $b = 2; my ($a,$b) = (1,2); (my $a, my $b) = (1,2); should all be equivalent. On the other hand, don't ask me when (my $a, state $b) = (1,2); should evaluate its RHS. The semantic analyzer should probably throw up its hands in disgust if it sees conflicting requirements for =. Or we could make assignment policy depend on the outside of the parens as you're doing. In that case my ($a, state $b) = (1,2); might initialize $b every time, while state ($a, my $b) = (1,2); would only initialize $b the first time. Hmm, then you could write state (my $first) = 1; and $first would be true only the first time though. Not sure if that's terribly useful. On the other hand, state (our $x) = 1; would have the same effect as our $x is first(1); That isn't terribly useful, but I think, for simplicity of analysis, let's go ahead with your approach and just make the assignment timing depend only on the declarator outside the parens. So, yes. Larry
Re: reduce metaoperator
On Wed, 4 May 2005, Larry Wall wrote: It would be nice to have an easy-to-access What's this? interface that could be stitched into your favorite editor to identify what's under the cursor, or at least a command like: p6explain '[+]' That would make me extremely happy. :$sum = [+] @array; # meta operator Another random thought which came to me (right after \\+ could be mnemonic for return a function ref for this operator) was this: How does [+] know you mean reduce infix:+, @array; instead of reduce prefix:+, @array; which is nonsense, but the [+] is in a prefix position. With the hyper metaoperator, the real operator is always in the place where it would normally be parsed. But this metaoperator pulls the real operator out of its usual pre/in/post position. I suppose users will need to know the answer when they start trying to write their own metaoperators. Maybe the metaoperator's function signature resolves that somehow? But I haven't been following the function signature thread closely. I can see how to ask for a binary (hence infix) operator, but how do I ask for a prefix or postfix operator specifically, which + and + do? Maybe there are Operator::Prefix, etc, roles defined so you can ask for them? ~ John Williams A06 typo: infix:+( prefix:-($a), $b) [Update: That's now infix:+( prefix:-($a), $b) .] The correction only corrected one of the errors: infix:+( prefix:-($a), $b)
Re: reduce metaoperator
On May 5, 2005, at 11:28 , John Williams wrote: How does [+] know you mean reduce infix:+, @array; instead of reduce prefix:+, @array; which is nonsense, but the [+] is in a prefix position. Because [] applies only to infix operators, as I understand it. With the hyper metaoperator, the real operator is always in the place where it would normally be parsed. But this metaoperator pulls the real operator out of its usual pre/in/post position. Well, if it was in its place, you wouldn't need to reduce it, would you? I suppose users will need to know the answer when they start trying to write their own metaoperators. They should write them only for infix operators. I can see how to ask for a binary (hence infix) operator, but how do I ask for a prefix or postfix operator specifically, which + and + do? Maybe there are Operator::Prefix, etc, roles defined so you can ask for them? Ask for them for what? Regards, David smime.p7s Description: S/MIME cryptographic signature
Re: reduce metaoperator
On Thu, 5 May 2005, David Wheeler wrote: I can see how to ask for a binary (hence infix) operator, but how do I ask for a prefix or postfix operator specifically, which + and + do? Maybe there are Operator::Prefix, etc, roles defined so you can ask for them? Ask for them for what? For negating all elements of an array: @negatives = -« @positives; They should write them [metaoperators] only for infix operators. The above example is in S03, so that is not an option. Because [] applies only to infix operators, as I understand it. You understand it. I understand it. But how does the parser know the difference between @x = - @y; and @x = [+] @y; or even @x -= @y; which shows that the position of metaoperator is not the distinguishing factor.
Semi-related question: reduce metaoperator
Can I put an operator in a variable and then use it in the [] reduce meta-operator? Something like: $op = '+'; $x = [$op] @x; Rob
Re: stdio
On Thu, 2005-05-05 at 12:31, Larry Wall wrote: On Thu, May 05, 2005 at 10:14:34AM +0300, Gaal Yahas wrote: : On Wed, May 04, 2005 at 11:44:58PM -0700, Larry Wall wrote: : : How do I open a file named -? [...] : $fh = io(-); : $fh = open -; : My concern is again with magic control. I've no gripes with the first : or last of those, but I think the second should not be allowed by : default. I think that, as with various other parts of Perl 6, we can try to sweep all the dwimmery into one spot so that it can be easily recognized and/or avoided. And the default open is not the place for dwimmery. I've been thinking about this particular thing ever since I wrote File::Copy, and wanted it to accept filenames, magical file-like strings or filehandles. Of course, that problem is easy in P6, but as I've been thinking about my dream IO type system in Perl for so long, I have a few opinions on it ;-) Dash this all on the rocks if you want, but understand that this is not an off-the-cuff reply, but something that I've spent a lot of time mulling over, and I really think Perl 6 programmers everywhere would enjoy such functionality. I'll even go so far as to offer to write it once Pugs is in a state that allows for such. First off, IMHO, open should be an alias for a closure-wrapped constructor, like so: sub open := IO.new; Pardon me if sub isn't the right tool there, I'm really not sure. The point there is to make open have the same signature(s) as the constructor(s) for IO. This allows you to instantly introduce every variant of open you'll ever want. This makes open the maximally dwimish operator. You can always introduce a sysopen and stdiopen and sockopen, etc. if you want domain-specific behavior exclusively (e.g. treat everything as a filename only, or as a host:port only, etc). Next, we need IO to be capable of understanding not only polymorphism: sub File::Copy::copy(IO $file1, IO $file2) {...} File::Copy::copy(IO::File.new($path1,:moderead), IO::File.new($path2,:modewrite)); but we also wish to be able to say: File::Copy::copy(IO.new(-),IO.new(-)); and perhaps even File::Copy::copy(-,-); and have the right thing happen (right thing not always being a universal for every program). How can we do this? Well, first IO has to accept a string for the constructor: class IO is ParrotIO { # ParrotIO? not sure ... method new(Str $string) {...} } I will assume that we upgrade types based on constructor signatures by constructing a temporary, though I honestly don't recall that being said explicitly in A12. That's all well and good, but how does IO know about its children? They might not even be loaded yet. You could just assume that any string constructor is either an IO::Handle (if it's -), an IO::Pipe (if it's |), or an IO::File otherwise, but that's a bit restrictive. What if we decide we want URIs to be readable things? It would be nice to be able to mix that in. Sure enough, there's an easy way: class IO is ParrotIO does RegisteredStringConstructor {...} role RegisteredStringConstructor { has %:registry; sub register(Any $pattern, Type $type) { %:registry{$pattern} = $type; } multi method new(Str $string,*%rest) { for %:registry.keys - $pat { if $string ~~ $pat { return %:registry{$pat}.bless(:string($string),*%rest); } } } } Now, IO::URI can say: class IO::URI is IO { use URI; IO.register(rx{^ URI::ProtocolScheme :}, ::IO::URI); ... } and then you can: my $fh = open(gnomevfs:spreadsheet:/home/me/sheet.gnumeric,:r); while =$fh - $row { say $row[0]; } Of course, my example URI brings up a host of questions, and probably is incorrect gnomevfs syntax, but you get the idea. Optional export features of IO::* could allow: * pipeline command execution * thread and/or process coupling * handle duping * much more Thus, you would control these features like so: use IO; use IO::Funky :register_string_open_funkiness; open(funk,:w); Now, if someone can just figure out how to re-write the string registration so that it behaves itself (that is, unregisters when the use goes out of scope), I think it would be perfect. -- Aaron Sherman [EMAIL PROTECTED] Senior Systems Engineer and Toolsmith It's the sound of a satellite saying, 'get me down!' -Shriekback
Re: reduce metaoperator
On Thu, 5 May 2005, John Williams wrote: or even @x -= @y; Doh! That should be C $x -= $y; of course.
adverbial blocks: description and examples requested
I was looking at a line in the hangman program: @letters == @solution.grep:{ $_ ne '' }; and was told that I was looking at an adverbial block. But I don't understand what that is and could not find a description and examples in a reverse search on dev and nntp.perl.org. I would appreciate any information on this topic. Thanks
Re: adverbial blocks: description and examples requested
Ugh, hit a in gmail when replying! On 5/5/05, Terrence Brannon [EMAIL PROTECTED] wrote: I was looking at a line in the hangman program: @letters == @solution.grep:{ $_ ne '' }; and was told that I was looking at an adverbial block. The adverbial block is what you're giving to `if` when you say: if $foo { ... } On the statement level, it looks like a block in operator position. However, on the expression level, it is preceded by a colon, and goes into the * argument of the sub. sub grep (*block, [EMAIL PROTECTED]) {...} (I don't know about the ordering of those arguments) It was invented to avert the annoying ({ }) construct, especially when used in a series: @result = @input.grep:{...}.map:{...} Did that answer your question? Luke
Re: adverbial blocks: description and examples requested
Luke Palmer [EMAIL PROTECTED] writes: Ugh, hit a in gmail when replying! On 5/5/05, Terrence Brannon [EMAIL PROTECTED] wrote: I was looking at a line in the hangman program: @letters == @solution.grep:{ $_ ne '' }; and was told that I was looking at an adverbial block. The adverbial block is what you're giving to `if` when you say: if $foo { ... } It is? An adverb describes a verb. What is the verb here? On the statement level, it looks like a block in operator position. On statement level... hmmm. Statement I think I understand: a complete sentence made up of expressions. operator position - how am I to know where operator position is? I'm really just asking these two questions about statement level and operator position so that you will be aware that not everyone will understand what you mean by these terms and you might want to explain them fully before using them when you write a Perl 6 tutorial/book/ etc. Don't bother explaining them to me. I can figure out what I need without knowing what you meant here. However, on the expression level, it is preceded by a colon, and goes into the * argument of the sub. sub grep (*block, [EMAIL PROTECTED]) {...} why must block be slurpy? can't it be specified as a required parameter like so: sub grep (block, [EMAIL PROTECTED]) {...} (I don't know about the ordering of those arguments) It was invented to avert the annoying ({ }) construct, especially when used in a series: @result = @input.grep:{...}.map:{...} So the annoying way to write this would be this? @result = map { } (grep { } @input) ; where the parentheses are required? So what are the colon-free ways to write this, which is not in series: sub has_won returns Bool { @letters == @solution.grep:{ $_ ne '' }; } Did that answer your question? yes, to a large extent and way way faster than anticipated! Luke -- Carter's Compass: I know I'm on the right track when, by deleting something, I'm adding functionality.
Re: reduce metaoperator
If I understand correctly, so far we have the following meta-operators: [ ] circumfix meta-operator on infix operator which produces a prefix operator circumfix meta-operator on infix operator which produces an infix operator = postfix meta-operator on infix operator which produces an infix operator prefix meta-operator on postfix operator which produces a postfix operator postfix meta-operator on prefix operator which produces a prefix operator In other words: +-+---+-++ | Meta-op | is| operates on | to produce | +-+---+-++ | [ ] | circumfix | infix | prefix | +-+---+-++ | | circumfix | infix | infix | +-+---+-++ | = | postfix | infix | infix | +-+---+-++ | | prefix| postfix | postfix| +-+---+-++ | | postfix | prefix | prefix | +-+---+-++ From this table, we can see that [ ] is the only meta-operator that produces a different 'type' of operator from that which it accepts, which might be where the confusion lies. As long as each meta-operator explicitly knows what type of regular operator it accepts (and produces), there shouldn't be any problems with ambiguity.
Re: reduce metaoperator
On 5/5/05, Stuart Cook [EMAIL PROTECTED] wrote: +-+---+-++ | Meta-op | is| operates on | to produce | +-+---+-++ | [ ] | circumfix | infix | prefix | +-+---+-++ | | circumfix | infix | infix | +-+---+-++ | = | postfix | infix | infix | +-+---+-++ | | prefix| postfix | postfix| +-+---+-++ | | postfix | prefix | prefix | +-+---+-++ I find this table very interesting, in that it shows the fundamental difference between reduce and the existing meta-ops. The existing meta-operators alter the semantics of the opoerator, but don't really change its syntax; a unary operator is still unary, a binary operator is still binary, and so on. Reduce is irreducibly (pardon the pun) different, in that it alters the syntax as well as the semantics. My suggestion is simple: multi *reduce(block, [EMAIL PROTECTED] is copy) { my [EMAIL PROTECTED]; while(@list) { $r = block($r, [EMAIL PROTECTED]( :elems(block.arity - 1) ); } return $r; } macro *reduce ($op, $expr) is parsed( / \[ (infix_operator) \] (expr)/ ) { # Would be reworked to produce a parse tree return reduce(infix:$op, $expr); } That would result in the following syntaxes: reduce { $^a / $^b } @foo; reduce [/] @foo; $sum = reduce[+] @array; $fact = reduce[*] 1..$num; $firsttrue = reduce[||] @args; $firstdef = reduce[//] @args; @sumrows := reduce[+«] @rows; @foo[0..9; reduce[;](@dims); 0..9] Clearly we could squabble about the exact bracketing operators to use (I chose square brackets because I thought they'd be less ambiguous than parentheses or curlies), but I trust you get the idea. I agree that reduce is very useful, and I even agree that it should be in core, but it's not *so* useful that it needs to be invokable without a keyword. Summing a list--which, let's face it, is likely to be the most common use for this--isn't common enough an operation to need such a compact syntax; I can think of more useful meta-ops, like one that tags each result with the operands that created it, allowing junctions to be used for the stuff people currently complain they can't be. multi sub *infixmetaop:[ ] ( $lhs, $rhs ) { return call but operands($lhs, $rhs); } -- Brent 'Dax' Royal-Gordon [EMAIL PROTECTED] Perl and Parrot hacker
Re: reduce metaoperator
On 5/6/05, Brent 'Dax' Royal-Gordon [EMAIL PROTECTED] wrote: I find this table very interesting, in that it shows the fundamental difference between reduce and the existing meta-ops. Yep, that was basically the whole point of the table. The existing meta-operators alter the semantics of the opoerator, but don't really change its syntax; a unary operator is still unary, a binary operator is still binary, and so on. Reduce is irreducibly (pardon the pun) different, in that it alters the syntax as well as the semantics. I was thinking of restricting the ways in which meta-ops can alter the syntax of an op, but now I think we're better off not letting it happen at all. Meta-ops that redefine syntax would be very hairy for the compiler (as I pointed out), and probably wouldn't buy us much that you couldn't achieve with a macro anyway. That would result in the following syntaxes: reduce { $^a / $^b } @foo; reduce [/] @foo; $sum = reduce[+] @array; $fact = reduce[*] 1..$num; $firsttrue = reduce[||] @args; $firstdef = reduce[//] @args; @sumrows := reduce[+«] @rows; @foo[0..9; reduce[;](@dims); 0..9] I personally like that, and it has the additional property of avoiding the [+] @foo vs. [+1, -2] ambiguity I pointed out. Furthermore, it makes it /much/ easier for newbies to figure out what that code actually does (since they can just grep for 'reduce' in the docs). Stuart
Re: adverbial blocks: description and examples requested
On 5/5/05, Terrence Brannon [EMAIL PROTECTED] wrote: I was looking at a line in the hangman program: @letters == @solution.grep:{ $_ ne '' }; and was told that I was looking at an adverbial block. But I don't understand what that is and could not find a description and examples in a reverse search on dev and nntp.perl.org. Methods with arguments require parens. However, the block to grep isn't Ireally an argument. It's describing the manner in which the array will be grepped... that's an adverb to grep. So, why are the parens required on methods? Take the following if statements: if @foo.shift { ... } if @foo.grep { ... } # grep doesn't get the block To make things clear, methods without parens are assumed to take no arguments. In order to pass a block to the above grep, you either need to use @foo.grep({ $^a = $^b}) or the adverbial colon: if @foo.grep:{$^a = $^b} { ... } Ashley Winters