Re: Synopsis 2 draft 1 -- each and every
Dov Wasserman writes: > "Larry Wall" <[EMAIL PROTECTED]> wrote in message > news:[EMAIL PROTECTED] > > > next D next N all D all N > > == == = = > > $iter $iter.pull ?1 $iter.pull ?2 > > @array @array.pull @array.values @array.pull @array > > $array $array.pull $array.values $array.pull @$array > > %hash %hash.pull %hash.values@array.pull %hash.values > > $hash $hash.pull $hash.values@array.pull $hash.values > > > > After all, a pull is the other end of a push. > > True in real life, but why not pop as the destructive evil twin of push? > > I think 'pop' more clearly indicates a removing iteration than 'pull'. > And its 25% shorter! But mainly because it's an established term for > the exact concept we're going for here. Except that it's an established term for an operation at the _opposite_ end of the list. C is only the opposite of C if you're thinking about a stack; if you're thinking about a queue then C is the current named used. So C would work, but would yield values in the opposite order to that which many people are expecting. Smylers
Re: Synopsis 2 draft 1 -- each and every
"Larry Wall" <[EMAIL PROTECTED]> wrote in message news:[EMAIL PROTECTED] > [H]ow about a table that looks like this: > > next D next N all D all N > == == = = > $iter $iter.pull ?1 $iter.pull ?2 > @array @array.pull @array.values @array.pull @array > $array $array.pull $array.values $array.pull @$array > %hash %hash.pull %hash.values@array.pull %hash.values > $hash $hash.pull $hash.values@array.pull $hash.values > > After all, a pull is the other end of a push. > > Larry True in real life, but why not pop as the destructive evil twin of push? I think 'pop' more clearly indicates a removing iteration than 'pull'. And its 25% shorter! But mainly because it's an established term for the exact concept we're going for here. A different concern I have, though, is this distinction we're assuming in an iterator between destructive (DS) and non-destructive (ND). It seems to me that, generally speaking, that should be an implementation detail of the iterated-upon object. For example, I might be reading lines from an arbitrary input stream. If the stream is stdin, this is clearly a "destructive" operation, in the sense of being non-reversible. However, the stream could just as easily be backed by a file on disk, where reading lines does not destroy or remove them. I shouldn't have to think about which method to use since I don't care about the effect. Huffman-wise, I imagine that's actually the most likely iteration scenario. I think the general iteration API should therefore be a via a name that does not care whether its underlying object is being consumed or not (the Callous Iterator). The syntactic <> should behave exactly this way. Then, for those occasions you do care about how the sequence is being processed, you can call either $seq.pop or $seq.next (or whatever names) for the specific DS/ND behavior you need. -Dov Wasserman
Synopsis 4 draft 1
=head1 Title Synopsis 4: a Summary of Apocalypse 4 =head1 Author Larry Wall <[EMAIL PROTECTED]> =head1 Version Maintainer: Date: Last Modified: Number: 4 Version: 0 This document summarizes Apocalypse 4, which covers the block and statement syntax of Perl. =head1 The Relationship of Blocks and Declarations Every block is a closure. (That is, in the abstract, they're all anonymous subroutines that take a snapshot of their lexical scope.) How any block is invoked and how its results are used is a matter of context, but closures all work the same on the inside. Blocks are delimited by curlies, or by the beginning and end of the current compilation unit (either the current file or the current C string). Unlike in Perl 5, there are (by policy) no implicit blocks around standard control structures. (You could write a macro that violates this, but resist the urge.) Variables that mediate between an outer statement and an inner block (such as loop variables) should generally be declared as formal parameters to that block. There are three ways to declare formal parameters to a closure. $func = sub ($a, $b) { print if $a eq $b }; # standard sub declaration $func = -> $a, $b { print if $a eq $b }; # a "pointy" sub $func = { print if $^a eq $^b } # placeholder arguments A bare closure without placeholder arguments that uses C<$_> (either explicitly or implicitly) is treated as though C<$_> were a placeholder argument: $func = { print if $_ }; $func("printme"); In any case, all formal parameters are the equivalent of C variables within the block. See S6 for more on function parameters. Except for such formal parameter declarations, all lexically scoped declarations are visible from the point of declaration to the end of the enclosing block. Period. Lexicals may not "leak" from a block to any other external scope (at least, not without some explicit aliasing action on the part of the block, such as exportation of a symbol from a module). The "point of declaration" is the moment the compiler sees "my $foo", not the end of the statement as in Perl 5, so my $x = $x; will no longer see the value of the outer C<$x>; you'll need to say my $x = $OUTER::x; instead. (It's illegal to declare C<$x> twice in the same scope.) As in Perl 5, "C" introduces a lexically scoped alias for a variable in the current package. There is a new C declarator that introduces a lexically scoped variable like C does, but with a lifetime that persists for the life of the closure, so that it keeps its value from the end of one call to the beginning of the next. Separate clones of the closure get separate state variables. Perl 5's "C" function has been renamed to C to better reflect what it does. There is also a C function that sets a hypothetical value. It works exactly like C, except that the value will be restored only if the current block exits unsuccessfully. (See Definition of Success below for more.) =head1 Conditional statements The C and C statements work almost exactly as they do in Perl 5, except that you may omit the parentheses on the conditional: if $foo == 123 { ... } elsif $foo == 321 { ... } else { ... } Conditional statement modifiers also work as in Perl 5. So do the implicit conditionals implied by short-circuit operators. And there's a new C in Perl 6--except that it's spelled C. C<:-)> =head1 Loop statements The C and C statements work as in Perl 5, except that you may leave out the parentheses around the conditional: while $bar < 100 { ... } Looping statement modifiers are the same as in Perl 5, except that to avoid confusion applying one to a C block is specifically disallowed. Instead of do { ... } while $x; you must write loop { ... last unless $x; } Loop modifiers C, C, and C work as in Perl 5. There is no longer a C block. Instead, use a C block within the loop. See below. =head1 The general loop statement The C statement is the C-style C loop in disguise: loop $i = 0; $i < 10; $i++ { ... } As seen in the previous section, the 3-part loop spec may be entirely omitted to write an infinite loop. =head1 The C statement There is no C statement any more. It's always spelled C in Perl 6, so it always takes a list as an argument: for @foo { print } As mentioned earlier, the loop variable is named by passing a parameter to the closure: for @foo -> $item { print $item } Multiple parameters may be passed, in which case the list is traversed more than one element at a time: for %hash.kv -> $key, $value { print "$key => $value\n" } To process two arrays in parallel, use either the zip function: for zip(@a,@b) -> $a, $b { print "[$a, $b]\n" } or the "zipper" operator to interleave them: for @a ¥ @b ¥ @c -> $a, $b, $c { print "[$a, $b, $c]\n" } The list is evaluated laz
Re: Return with no expression
On Aug 19, 2004, at 11:07 AM, Aaron Sherman wrote: First off, in Perl 6, I *think* that that C<< => >> will enforce a scalar context (it's a tuple operator, last I recall). W00t! Second, in Perl 5 it should not be hard to identify such situations for warning purposes. C<< => >> may be a synonym for C<,>, but that doesn't mean that you can maintain some little smidge of state in the op that tells you that your right hand side should not be and expression that returns a list of more or less than one element. Yes, that would be very helpful. I get bit by this all the time myself. But even more helpful would be if C<< => >> enforced a scalar context in Perl 5, too. Regards, David smime.p7s Description: S/MIME cryptographic signature
Re: Return with no expression
On Aug 19, 2004, at 9:41 AM, Matt Diephouse wrote: If the parameter does not exist at all, then param() will return undef in a scalar context, and the empty list in a list context. Sure enough. And I've even read a large percentage of the (unwieldy) CGI.pm docs. But I was using C as an example. The behavior would exist with any subroutine that used C. It would be nice if Perl thought that => was scalar context for the expression that follows it. But then it wouldn't be just like a comma, would it? Regards, David smime.p7s Description: S/MIME cryptographic signature
Re: Synopsis 2 draft 1 -- each and every
On Thu, Aug 19, 2004 at 05:26:38PM -0400, John Macdonald wrote: : In scalar context a non-destructive read of an iterator might : be called $iter.peek and the next .read will get (and remove) : the same value that .peek returns. Implementation would be : fairly simple - the control info for an iterator would have a : field containing the next value and a flag to specify whether : that value had been determined yet. Indeed, the Perl 6 argument-passing/parameter-binding mechanism is based on the notion that a list is composed of the part it knows about already and the part it may have to generate on the fly. Arrays and iterators can share this characteristic. But arrays are inclined to remember their past values while iterators are inclined to forget. Larry
Re: Synopsis 2 draft 1 -- each and every
On Thu, Aug 19, 2004 at 01:54:39PM -0600, Luke Palmer wrote: : That is very tickley. But there's another kind of dissonance there. : @array.pull needs to take arguments[1] when called with list pull, : otherwise it's basically useless. It's not useless if you just want to interpolate an entire array destructively. But you can have an arguments to pull that say things like how many values to pull out. That's assuming Perl doesn't just up and figure out that ($a,$b,$c) = @array.pull; really means ($a,$b,$c) = @array.pull(3); : The same goes for %hash.pull, except I'm not sure what those : arguments would be. A pull of n arguments would be pretty useless if you don't know an ordering. So maybe there's an interaction with sorting somehow. But then you might as well sort it, put it into a temp array, and pull from the sorted array, unless you're willing to hide an array state somewhere in %foo.sort.pull(3). But I think the closest I want to get to that is the implicit list passed by a pipe operator. Suppose we named that @=. We might have %hash.sort ==> do { while @= { say @=.pull(5); } } : And I assume that %hash.pull would pull off values, to remain : consistent as sortof an array with nonnumeric keys (and no inherint : ordering?). If it's going to pull destructively, I'd say it wants to pull a pair, to avoid losing info. : Or would it pull off kv pairs, obsoleting the .kv method? But it wouldn't obsolete .kv anyway, since .kv is non-destructive. : It's tempting to do it this way due to the parallelism argument, but : it's also tempting to have different names for each, since they all have : their various quirks or shades. Yes, that's essentially the anti-perfect-language argument, which is a very good argument indeed. One must strike a balance on that subject, and other people will certainly disagree. Larry
Re: Synopsis 2 draft 1 -- each and every
On Thu, Aug 19, 2004 at 12:31:42PM -0700, Larry Wall wrote: > So let's rewrite the table (assuming that all the hash methods are just > variants of .values), where N and D are non-destructing and destructive: > > next D next N all D all N > == == = = > $iter $iter.read ?1 $iter.read ?2 > @array @array.shift@array.for @array.splice @array > $array $array.shift$array.for $array.splice @$array > %hash ?3 %hash.values?4 %hash.values > $hash ?3 $hash.values?4 $hash.values > > Hmm. Ignore ?1 and ?2, since it's not clear that iterators can be > read non-destructively. In scalar context a non-destructive read of an iterator might be called $iter.peek and the next .read will get (and remove) the same value that .peek returns. Implementation would be fairly simple - the control info for an iterator would have a field containing the next value and a flag to specify whether that value had been determined yet. sub peek { unless ($iter.flag) { $iter.nextval = $iter.getnext(); $iter.flag = true; } return $iter.nextval; } sub read { if ($iter.flag) { $iter.flag = false; return $iter.nextval; } return $iter.getnext(); } --
Re: Synopsis 2 draft 1 -- each and every
On Thursday 19 August 2004 02:14 pm, Paul Seamons wrote: > @array.push(3 => 'value'); # index 3 gets 'value' Hmm. Well that makes it hard to have an array of pairs - so never mind. Paul Seamons
Re: Synopsis 2 draft 1 -- each and every
> After all, a pull is the other end of a push. > > Larry So do we also get: %hash.push(key => 'value'); # harder than %hash<> = 'value'; %hash.unshift; # same as %hash.push %hash.shift; # same as %hash.pull %hash.pop; # same as %hash.pull Which then begs if you can do @array.push(3 => 'value'); # index 3 gets 'value' # which is harder han @array[3] = 'value' Paul Seamons
Re: Synopsis 2 draft 1 -- each and every
Larry Wall writes: > next D next N all D all N > == == = = > $iter $iter.read ?1 $iter.read ?2 > @array @array.shift@array.for @array.splice @array > $array $array.shift$array.for $array.splice @$array > %hash ?3 %hash.values?4 %hash.values > $hash ?3 $hash.values?4 $hash.values > > Hmm. Ignore ?1 and ?2, since it's not clear that iterators can be > read non-destructively. > > It looks like most of the problem is that we're not consistent in how > to destructively read something in a context sensitive manner. And I > don't really like .read anyway. Without necessarily deprecating > .shift or .splice, how about a table that looks like this: > > next D next N all D all N > == == = = > $iter $iter.pull ?1 $iter.pull ?2 > @array @array.pull @array.values @array.pull @array > $array $array.pull $array.values $array.pull @$array > %hash %hash.pull %hash.values@array.pull %hash.values > $hash $hash.pull $hash.values@array.pull $hash.values > > After all, a pull is the other end of a push. That is very tickley. But there's another kind of dissonance there. @array.pull needs to take arguments[1] when called with list pull, otherwise it's basically useless. The same goes for %hash.pull, except I'm not sure what those arguments would be. And I assume that %hash.pull would pull off values, to remain consistent as sortof an array with nonnumeric keys (and no inherint ordering?). Or would it pull off kv pairs, obsoleting the .kv method? It's tempting to do it this way due to the parallelism argument, but it's also tempting to have different names for each, since they all have their various quirks or shades. > Larry [1] And there's a-whole-nother beast in @array.pull arguments, dealing with the issue that I've been wanting to address of @array representing an ordered but not indexed list.
Re: Synopsis 2 draft 1 -- each and every
On Thu, Aug 19, 2004 at 10:53:06AM -0500, Jonathan Scott Duff wrote: : I like "each" best though. Why exactly can't it work? It could be made to work. The sources of cognitive interference are: 1. Perl 5's each(%hash) function, which is probably not a problem. 2. Ruby's array.each {|x| print x } construct, which probably ought to be spelled differently anyway. 3. English's "each", which doesn't work so well in "while each $IN". It's hard to come up with an English word that means "next" in scalar context but "all" in list context. So I lean toward punctuation, and since <> is historical, I like <$IN> and $IN.<> for that. But if I had to pick a good generic word that doesn't commit, I'd pick .read as a shortened form of Perl 5's .readline. (Leaving aside the conflict with the current read() function, which *might* be resolvable with MMD.) If we try to set up a table, we get something like: next as scalar all as list == === $iter $iter.read $iter.read @array @array.shift@array $array $array.shift@$array $array[] %hash %hash.each %hash .keys .values .pairs .kv $hash $hash.each %$hash .keys .values .pairs .kv This table shows us a number of bogusoidal facts. .read and .shift are destructive. Nothing else is. But .read and .shift are not synonymous in list context. %hash.each doesn't actually return a scalar if we follow Perl 5, which we probably aren't. %hash probably means %hash.pairs in list context. Arguably .keys, .values, .pairs, and .kv should all autoiterate in scalar context, which should replace .each entirely. @array should respond to .pairs and .kv, pretending the implicit array indexes are hash keys. There is no non-destructive scalar iterator for arrays except a C, which makes me wonder if there is a Rubyesque @array.for:{ dostuff }. So let's rewrite the table (assuming that all the hash methods are just variants of .values), where N and D are non-destructing and destructive: next D next N all D all N == == = = $iter $iter.read ?1 $iter.read ?2 @array @array.shift@array.for @array.splice @array $array $array.shift$array.for $array.splice @$array %hash ?3 %hash.values?4 %hash.values $hash ?3 $hash.values?4 $hash.values Hmm. Ignore ?1 and ?2, since it's not clear that iterators can be read non-destructively. It looks like most of the problem is that we're not consistent in how to destructively read something in a context sensitive manner. And I don't really like .read anyway. Without necessarily deprecating .shift or .splice, how about a table that looks like this: next D next N all D all N == == = = $iter $iter.pull ?1 $iter.pull ?2 @array @array.pull @array.values @array.pull @array $array $array.pull $array.values $array.pull @$array %hash %hash.pull %hash.values@array.pull %hash.values $hash $hash.pull $hash.values@array.pull $hash.values After all, a pull is the other end of a push. Larry
Re: Synopsis 2 draft 1 -- each and every
Matt Diephouse writes: >for $foo.records :sep"," { ... } > > The trouble is that using a for loop builds a list in memory, which > can be troublesome. I think that in Perl 6 C doesn't build a list in memory, so as to avoid the troublesome bits. Smylers
Re: Return with no expression
On Thu, 2004-08-19 at 10:03, Luke Palmer wrote: > Matt Diephouse writes: > > use CGI qw(:standard); > > > > my $foo = Bar->new( > > name => "Baz", > > value => param('baz'), > > something => 'else' > > ); > > > > See the problem? > > Yikes, yeah, that seems so innocent. Not to the compiler it shouldn't. First off, in Perl 6, I *think* that that C<< => >> will enforce a scalar context (it's a tuple operator, last I recall). Second, in Perl 5 it should not be hard to identify such situations for warning purposes. C<< => >> may be a synonym for C<,>, but that doesn't mean that you can maintain some little smidge of state in the op that tells you that your right hand side should not be and expression that returns a list of more or less than one element. In very high-level terms, and without having looked at the op(s) in question, I would assume the tree looks like: /---LHS->indentifier('value') op(,) < \---RHS->invoke('param',constant('baz')) So if C knows that it was originally C<< => >>, then it can issue a warning (perhaps only in -w mode) when discovering that its RHS yielded zero elements, and you're done. Of course if that really turns into (value => (param('baz'), (something => ('else then it gets harder, but it's still possible to warn correctly. -- â 781-324-3772 â [EMAIL PROTECTED] â http://www.ajs.com/~ajs
Re: Return with no expression
Matt Diephouse writes: > The point that it's documented for C and for C doesn't > remove the fact that while this DWIM the majority of the time, it can > be the cause of a subtle bug. I'm sure many people don't know about > the DWIM behavior. Or aren't actively aware of it. As is the case with many forms of DWIM. This is something we must always consider when adding a DWIMity. How could it subtly introduce bugs, or how could it be a pain? Some DWIMs become a major pain when you're dealing with generics, for instance, by requiring the user to duplicate the type switch used internally just go get consistent behavior. The one in Perl 5 that stands out most was the cause for the only patch I ever sent to p5p: the rand function. "rand $x" will give you a uniformly distributed random number in [0, $x) for any $x EXCEPT 0. If you say "rand 0", it gives you a random number between 0 and 1, which was supposed to be What I Meant. That led to code like this (Perl6ized as usual): my $num = $param == 0 ?? 0 : rand $param; Repeating the test that it did itself, just to get consistent behavior. We must be careful not to repeat mistakes like this in the design of Perl 6 [1]. Luke
Re: Return with no expression
On Thu, 19 Aug 2004 17:52:18 +0200, Juerd <[EMAIL PROTECTED]> wrote: > Ouch. You have foo-bar-baz code *at work*? :) Unfortunately, some of the code here is much worse than that. > In fact, this was anticipated and the doesn't-exist case is explicitly > documented as: > > If the parameter does not exist at all, then param() will return > undef in a scalar context, and the empty list in a list context. Sure enough. And I've even read a large percentage of the (unwieldy) CGI.pm docs. But I was using C as an example. The behavior would exist with any subroutine that used C. > > I can't imagine how much trouble this would have caused me if I didn't > > know about the C special case. > > There is no need to know about the special case, because you can read > exactly how it works in the documentation. The point that it's documented for C and for C doesn't remove the fact that while this DWIM the majority of the time, it can be the cause of a subtle bug. I'm sure many people don't know about the DWIM behavior. Or aren't actively aware of it. > > my $string = join "," => @array; > > my $string = join "," <== @array; > > It's a 180, but it'll workforme. I think I'm going to go with C< @array.join(",") >. :) -- matt > > Juerd
Re: Synopsis 2 draft 1 -- each and every
On Thu, 19 Aug 2004 10:38:48 -0500, Dan Hursh <[EMAIL PROTECTED]> wrote: > while another $foo {..} > > It's 5 characters too many, but it works. > > Dan At this point, you may as well use C<.records> (think C<$/> -- record separator): for $foo.records { ... } Then it'd be a small step to allow: for $foo.records :sep"," { ... } --or-- for $foo.records(",") { ... } to override C<$/>. Ideally, you'd have C<.lines> to use as well. It's not nearly general enough, but in many (most?) cases it would provide the wanted behavior. The trouble is that using a for loop builds a list in memory, which can be troublesome. But I suppose a singular version could be used to act as an iterator: while my $rec = $foo.record :sep"\n" { ... } while my $line = $foo.line { ... } Or maybe one method could be used both ways, depending on whether it's called in list or scalar context. But you wouldn't get the implicit assignment to C<$_>. -- matt
Re: Synopsis 2 draft 1 -- each and every
On Thu, Aug 19, 2004 at 05:08:55AM -0600, Luke Palmer wrote: : Well, C gives you a one-iteration loop. But perhaps list : flatten could work on iterators: : : for *$foo { ... } I dislike that purely on visual grounds in the case of for *$*IN { ... } But I expect most folks will end up writing $IN instead of $*IN anyway. [snip] : The array abstraction doesn't work well for iterators, so perhaps : that's not the best way to go. At the moment there seem to be two related punctuational forms: for <$iter> {...} for $iter.<> {...} : I'm personally a fan of "every" as well as renaming Ruby's "each" to : something else. We can settle on a word form later if necessary. Then if we make it a long enough word almost nobody will use it unless they really want to steal <> badly. :-) Of course a conniving thief might steal the angles from <$iter> without stealing them from $iter.<>. Larry
Re: Synopsis 2 draft 1 -- each and every
On Thu, Aug 19, 2004 at 10:38:48AM -0500, Dan Hursh wrote: > David Green wrote: > > >...but "print next $foo" is better than "print each $foo". ... > > print another $foo > > for another $foo {...} > > while another $foo {..} > > It's 5 characters too many, but it works. print more $foo; for more $foo { ... } # er ... while more $foo { ... } It sorta works. I like "each" best though. Why exactly can't it work? -Scott -- Jonathan Scott Duff [EMAIL PROTECTED]
Re: Return with no expression
Matt Diephouse skribis 2004-08-19 9:35 (-0400): > But I came across this code at work this week: > use CGI qw(:standard); > my $foo = Bar->new( > name => "Baz", > value => param('baz'), > something => 'else' > ); Ouch. You have foo-bar-baz code *at work*? :) > See the problem? Yes, you forgot "scalar". param() is *documented* to behave differently in list context. It's not an unfortunate side-effect, but the official, documented API. In fact, this was anticipated and the doesn't-exist case is explicitly documented as: If the parameter does not exist at all, then param() will return undef in a scalar context, and the empty list in a list context. > I can't imagine how much trouble this would have caused me if I didn't > know about the C special case. There is no need to know about the special case, because you can read exactly how it works in the documentation. The bare return is there only to avoid a warning. param's behaviour wouldn't be different with only the second return statement: return wantarray ? @{$self->{$name}} : $self->{$name}->[0]; > my $string = join "," => @array; my $string = join "," <== @array; It's a 180, but it'll workforme. Juerd
Re: Synopsis 2 draft 1 -- each and every
David Green wrote: ...but "print next $foo" is better than "print each $foo". ... print another $foo for another $foo {...} while another $foo {..} It's 5 characters too many, but it works. Dan
Re: Return with no expression
Matt Diephouse writes: > use CGI qw(:standard); > > my $foo = Bar->new( > name => "Baz", > value => param('baz'), > something => 'else' > ); > > See the problem? Yikes, yeah, that seems so innocent. > C uses C. In this example, it's called in list > context. So if there is no 'baz' parameter, the list will get shifted > like so: > > my $foo = Bar->new( > name => "Baz", > value => "something", > else => undef > ); > > I can't imagine how much trouble this would have caused me if I didn't > know about the C special case. Any chance this will work > differently in Perl 6? Yep. First of all, param('baz') would be called in scalar context, since it's on the right side of a pair constructor, as you're about to say. > I'd be tempted to suggest that C<<=>>>, in its new role as pair > constructor, put things in scalar context, but lately I've started to > write join's like so: > > my $string = join "," => @array; No such luck. I use => in all sorts of places where , usually goes. But I'm going to have to change my ways for Perl 6. All in all, I think the pair object gives us too many wins over the fat comma. On the other hand, you can now write your join in any of the following ways: join ",", @array; @array.join(","); join @array: ","; &*join(q{,}<[EMAIL PROTECTED]); :-) Luke
Re: Synopsis 2 draft 1
On 2004-08-18 at 22:37:31, Larry Wall wrote: > Actually, I've settled on .perl for now, on the assumption there could > also be a .python, a .ruby, a .cobol, a .intercal, etc. Perhaps there should be a special name visible only at the language level that automatically translates to .language_I_was_written_in by the time Parrot sees it? And I heartily volunteer anyone else but me to write .intercal for anything other than ints. :) -- Mark REED| CNN Internet Technology 1 CNN Center Rm SW0831G | [EMAIL PROTECTED] Atlanta, GA 30348 USA | +1 404 827 4754
Return with no expression
I recently got bit by C in Perl 5, which leads me to wonder about Perl 6. C, when called without an expression, tries to DWIM, returning an empty list in list context and undef in scalar context, which is generally a good thing. But I came across this code at work this week: use CGI qw(:standard); my $foo = Bar->new( name => "Baz", value => param('baz'), something => 'else' ); See the problem? C uses C. In this example, it's called in list context. So if there is no 'baz' parameter, the list will get shifted like so: my $foo = Bar->new( name => "Baz", value => "something", else => undef ); I can't imagine how much trouble this would have caused me if I didn't know about the C special case. Any chance this will work differently in Perl 6? I'd be tempted to suggest that C<<=>>>, in its new role as pair constructor, put things in scalar context, but lately I've started to write join's like so: my $string = join "," => @array; I want my cake. And I want to eat it to, dang it! -- matt
Re: Synopsis 2 draft 1 -- each and every
David Green writes: > On 8/19/04, [EMAIL PROTECTED] (David Green) wrote: > > >On Aug 14, 2004, at 5:52 PM, Larry Wall wrote: > > > > >>for all $*IN # all() is junction > > >>for each $*IN # each method wants closure if we follow Ruby > > >>for next $*IN # next $foo is a loop exit > [...] > >"Each" and "every" are the obvious choices, but I wouldn't want to > >follow Ruby exactly: "each" has a definite connotation of > >"separately", "one at a time" that works in "for each $foo"; "every" > >works better for the overall method. > > Hang on -- should we be saying "for each $foo" or "for $foo.each" > anyway? We don't say "for @foo.each"; the iteration is implicit. So > I'm thinking it should be "for $foo" or "while next $foo". Well, C gives you a one-iteration loop. But perhaps list flatten could work on iterators: for *$foo { ... } Which presumably is the same thing as: for @$foo { ... } Which implies that iterators can behave as arrays. Then you get to weird questions like what: $foo[-1] Does. Iterate to the end and return that? The array abstraction doesn't work well for iterators, so perhaps that's not the best way to go. I'm personally a fan of "every" as well as renaming Ruby's "each" to something else. Luke
Re: Synopsis 2 draft 1 -- each and every
On 8/19/04, [EMAIL PROTECTED] (David Green) wrote: > >On Aug 14, 2004, at 5:52 PM, Larry Wall wrote: > > >>for all $*IN # all() is junction > >>for each $*IN # each method wants closure if we follow Ruby > >>for next $*IN # next $foo is a loop exit [...] >"Each" and "every" are the obvious choices, but I wouldn't want to >follow Ruby exactly: "each" has a definite connotation of >"separately", "one at a time" that works in "for each $foo"; "every" >works better for the overall method. Hang on -- should we be saying "for each $foo" or "for $foo.each" anyway? We don't say "for @foo.each"; the iteration is implicit. So I'm thinking it should be "for $foo" or "while next $foo". (If we could call it "next", which is even more desirable now, seeing as the main place where "each" made sense was "for each", where it should be implicit anyway -- "while each $foo" doesn't sound as good, though I guess it's passable; "print each $foo" sounds like it's looping even though it isn't. "print following $foo"? "print subsequent $foo"? The latter could be abbreviated to $foo.seq ) Hm, we don't need a fixed name to be able to use the iterator implicitly, though. Why not method another is iterator { ... } using a trait to identify the iterating method(s?). That neatly passes the buck of what to call it to the individual programmer instead. =) - David "not sure whether the idea of overloading ++ as an iterator can be mentioned in polite company" Green
Re: Synopsis 2 draft 1 -- each and every
On 8/15/04, [EMAIL PROTECTED] (David Wheeler) wrote: >On Aug 14, 2004, at 5:52 PM, Larry Wall wrote: >>for all $*IN # all() is junction >>for each $*IN # each method wants closure if we follow Ruby >>for next $*IN # next $foo is a loop exit > >Hmm. Maybe the problem is that we shouldn't follow Ruby on .each's >signature. How about we have .apply or .filter do the Ruby implicit >iteration thing, and keep .each for iterating iterators. "Each" and "every" are the obvious choices, but I wouldn't want to follow Ruby exactly: "each" has a definite connotation of "separately", "one at a time" that works in "for each $foo"; "every" works better for the overall method. ("All" has an "all at once" sense that fits its junctive use; "next" certainly has the right meaning: "for next $foo" sounds funnier than "for each $foo", but "print next $foo" is better than "print each $foo". I suppose loop-next could be renamed "cont" except that we just renamed the continue block to NEXT -- perhaps there's some clever way to unify them and use "next" for both cases?) >>@bar = @foo.filter:{ $_ * 2 }; >>filter @foo: { $_ * 2 } ==> @bar; > >C is good for this; I like it. But if you decide you need to >keep it as C, >then I personally really don't mind using C for the iterator method. morph @foo: { $_ * 2 } ==> @bar; ? #less typing than "transmute" Personally, I like "apply", since the actual word "filter" means something more like 'grep' than 'map', but I guess in computer lingo, filters are often understood to map stuff. (FOLDOC tells me that Haskell's equivalent to "grep" is spelled "filter". (Though it might make more sense for the condition to be negated -- hm, if we have if/unless, while/until, why not grep/filter?)) -David "munge @foo: { $_ * 2 } ==> @bar; ??" Green
Re: Synopsis 2 draft 1 -- .as()
In article <[EMAIL PROTECTED]>, [EMAIL PROTECTED] (Larry Wall) wrote: >On Sat, Aug 14, 2004 at 09:56:34PM +, Smylers wrote: >: I like that exception; it means that if all your array elements end with >: line-breaks, you don't end up with all but the first one being indented [...] >That's the default behavior you can't write with .as(). Takes a .map or >some such. Can't .as sprintf its first arg if it's a string, but if you pass a code ref, use the return value? print @foo.as( { "*"~title_case($_) }, "\n"); And/or maybe passing undef as (either?) arg could mean "use the default". - David "as($you, $were)" Green