Re: A6: argument initializations via //=, ||=, ::=
On Tuesday, March 25, 2003, at 12:59 PM, Smylers wrote: Michael Lazzaro writes: Larry Wall wrote: We don't have a word for START right now. It's somewhat equivalent to state $foo //= 0 unless $foo gets undefined, I suppose. Assuming we have a static-like scope called Cstate, one can definitely see the use of having an assignment variant for not yet initialized or doesn't yet exist, the proposed spelling of which was C::=. I'm unconvinced by the need for a cryptic way to distinguish undefined from uninitialized. snip Or, at least, if we want to make such a distinction here it should be because we come up with good examples where the distinction is useful, doing something that couldn't easily be achieved in some other way -- and that that usefulness is thought to outway the additional complexity of having another assignment operator in the language and having to distinguish it when teaching or learning Perl. I suppose my own most common example is a hash representing a cache... it's entirely possible for Cundef to be calculated and cached, but that doesn't mean the cache entry is invalid and should be recalculated every time -- a nonextant key would mean the cache entry is invalid. { $cache.{ $key } = $cache.load($key) if not exists $cache.{ $key }; $cache.{ $key }; } In my own experiences, code similar to the above is awfully common. An assign-if-not-present form (at least for hashes, but in a magical fairy world, for arrays/params/whatever, too) such as: $cache.{ $key } __= $cache.load($key); would be a lot cleaner, and maybe a little faster, since it's testing C$cache.{ $key } once instead of -- what, 2.5 or 3 times, I guess, depending on how you count it? Your mileage may vary, of course -- I must confess I need the undefined vs. noexists distinction all the time, but it's quite possible I code weirdly compared to other people. :-/ MikeL
Re: A6: argument initializations via //=, ||=, ::=
Michael Lazzaro writes: On Wednesday, March 19, 2003, at 08:30 AM, Larry Wall wrote: We don't have a word for START right now. It's somewhat equivalent to state $foo //= 0 unless $foo gets undefined, I suppose. Assuming we have a static-like scope called Cstate, one can definitely see the use of having an assignment variant for not yet initialized or doesn't yet exist, the proposed spelling of which was C::=. I'm unconvinced by the need for a cryptic way to distinguish undefined from uninitialized. Damian argued in favour of not being able to store Cundef in arrays that have some some other, explicit, default value. I think his argument was that Cundef is the value to indicate the lack of a meaningful value, and that we shouldn't be encouraging people to overload Cundef with other meanings by making it easy to distinguish it from a lack of their being a value. If that applies there, I think it should apply here too. Or, at least, if we want to make such a distinction here it should be because we come up with good examples where the distinction is useful, doing something that couldn't easily be achieved in some other way -- and that that usefulness is thought to outway the additional complexity of having another assignment operator in the language and having to distinguish it when teaching or learning Perl. Smylers
Re: A6: argument initializations via //=, ||=, ::=
On Tuesday, March 25, 2003, at 06:17 PM, Damian Conway wrote: Likewise, I read sub foo($x //= 1) {...} as saying the value stored in $x is a constant, but if the caller passed an undefined value (or didn't pass anything at all), we're going to instead pretend they passed us a (still-constant) 1. I'm not sure why that violates any rules.(?) //= means assign to lvalue unless lvalue is defined. So I read that as: $x is a constant variable. Bind the corresponding argument to $x and then assign 1 to it if its value is undef. But the container bound to $x is bound as a constant, so it *can't* be assigned to. OK, I buy that, I think. But does that mean that fixing edge cases in your arguments doesn't work at all, i.e. you can't even do this? sub foo(?$x) { $x //= 1; # if they passed an undef, init it to 1 ... } or that you have to say it like this? sub foo(?$x) { my $x = $x // 1; # hide $x param using a non-const Cmy? ... } MikeL
Re: A6: argument initializations via //=, ||=, ::=
Michael Lazzaro wrote: OK, I buy that, I think. But does that mean that fixing edge cases in your arguments doesn't work at all, i.e. you can't even do this? sub foo(?$x) { $x //= 1; # if they passed an undef, init it to 1 ... } That's right. It's an error. You need: sub foo(?$x is copy) { $x //= 1; # if they passed an undef, init it to 1 ... } or that you have to say it like this? sub foo(?$x) { my $x = $x // 1; # hide $x param using a non-const Cmy? ... } That won't work either, since the name of the lexical variable C$x is introduced immediately in Perl 6, so the C$x on the lhs is the lexical one from the rhs, not the parameter. Damian
Re: A6: argument initializations via //=, ||=, ::=
On Tue, Mar 25, 2003 at 10:42:39AM -0800, Michael Lazzaro wrote: But it is certainly possible to extend the initialization capabilities to be more robust: sub foo($x = 'blah') {...} # wrong: use one of the below sub foo($x ::= 'blah') {...} # same as C$x is default('blah') sub foo($x //= 'blah') {...} # sets $x whenever $x is undefined sub foo($x ||= 'blah') {...} # sets $x whenever $x is false While this looks pretty in email, it makes me wonder what the :: operator does outside of regular expressions and how that operator interacts with ??:: And don't forget these other argument initializations: sub foo($x = 'blah') {...}# sets $x whenever $x is true sub foo($x += 1) {...} # add 1 to whatever $x given sub foo($x -= 1) {...} # subtract 1 to whatever $x given sub foo($x *= 2) {...} # multiply by 2 whatever $x given sub foo($x /= 2) {...} # divide by 2 whatever $x given sub foo($x ~= foo) {...} # Append foo to whatever $x given Depending on how you're bent, the default() property starts to look pretty good at this point. :-) (with the others relegated to be the body of the sub) -Scott -- Jonathan Scott Duff [EMAIL PROTECTED]
Re: A6: argument initializations via //=, ||=, ::= [OT]
(Note forwarded to the list as penance for my silliness. :) sub foo($x .= foo) {...} # Append foo to whatever $x given sub foo($x ~= foo) {...} # smart-test $x against foo Well, last time I looked (granted, it could've changed numerous times since then) ~ was the string concatenator and ~~ was the smart match op, so those should be: sub foo($x ~= foo) {...}# Append foo to whatever $x given sub foo($x ~~= foo) {...} # smart-test $x against foo lol -- flashbacks. Was off on both! I'm obviously behind the curve on ~ and ~~ ... but .= is P5, so TOTALLY wrong. Sorry! So _ isn't going to be the string catenation operator any more? Ok, I need an op reference, lol Is there a page up anywhere that summarizes the latest prognostications? Thanks for straightening me out. ;o] __ Do you Yahoo!? Yahoo! Platinum - Watch CBS' NCAA March Madness, live on your desktop! http://platinum.yahoo.com
Re: A6: argument initializations via //=, ||=, ::= [OT]
On Tue, Mar 25, 2003 at 12:19:30PM -0800, Paul wrote: Is there a page up anywhere that summarizes the latest prognostications? Mike Lazzaro had compiled the state-of-the-ops for perl6, but I don't know if it's anywhere other than in the archives for this list. Just go to google groups and search for Perl Operator List. -Scott -- Jonathan Scott Duff [EMAIL PROTECTED]
Re: A6: argument initializations via //=, ||=, ::=
On Tue, Mar 25, 2003 at 01:47:32PM -0800, Michael Lazzaro wrote: On Tuesday, March 25, 2003, at 11:08 AM, Jonathan Scott Duff wrote: On Tue, Mar 25, 2003 at 10:42:39AM -0800, Michael Lazzaro wrote: But it is certainly possible to extend the initialization capabilities to be more robust: sub foo($x = 'blah') {...} # wrong: use one of the below sub foo($x ::= 'blah') {...} # same as C$x is default('blah') sub foo($x //= 'blah') {...} # sets $x whenever $x is undefined sub foo($x ||= 'blah') {...} # sets $x whenever $x is false While this looks pretty in email, it makes me wonder what the :: operator does outside of regular expressions and how that operator interacts with ??:: Well, := is the binding operator, and ::= is the compile-time binding operator. Interesting. When juxtaposed against //= and ||= it looks more like bind unless already bound to me. I'm arguing for these three defaulting options in particular, but my more encompassing argument is the wrapper-like notion that signatures should be able to specify assertions, invariants, and initializations that may then be inherited by all implementations of that function/method. Don't we already have the pre() trait and PRE block for this? Placing such extensive capabilities in the sig is especially useful if we can 'typecast' subs, as others have pointed out. class mysub is sub(...big long signature...) returns int {...} sub foo is mysub { ... } sub bar is mysub { ... } If ...big long signature... contains initializations and assertions that are required to be shared by all sub implementations, than it makes the sig a quite powerful thing. Sure, a complex sig could be pretty big. But it's one big thing, as opposed to repeating the same assertions in N implementations. From A6: sub Num foo (int $one, Str [EMAIL PROTECTED]) { return [EMAIL PROTECTED] } is short for saying something like: sub foo is signature( sig(int $one, Str [EMAIL PROTECTED]) ) is returns( sig(Num) ) will do { return [EMAIL PROTECTED] } So, it seems to me that we might be able to do something like this: $sig = sig(...big long signature...); presub = { ...initializations, etc. ... }; sub foo is signature($sig) is pre(presub) { ... } sub bar is signature($sig) is pre(presub) { ... } Resisting assignment in signatures (for now), -Scott -- Jonathan Scott Duff [EMAIL PROTECTED]
Re: A6: argument initializations via //=, ||=, ::=
I don't see how ::= (compile-time-bind) can be used as the initialize-if-non-existent operator. I mean, it happens in the wrong phase (compile-time, not run-time) and it does the wrong thing (binding, not assignment). For example: sub foo { state $count ::= 0;# $count bound to constant zero $count++; # Error, can't modify constant ... } Or: sub bar ($start, ?$end ::= $start+1) {...} # $end bound to 1. # ($start is undef # at compile-time) I think that all we need to do is to mentally distinguish assignment from initialization: my $x = 1;# initialization $x = 1;# assignment and say that initialization happens only on declarations and only once, at the very beginning of the lifetime of a variable. Thus: state $count = 0;# initialization: happens only once $count = 1;# assignment: happens every time We then simply define the = in: sub foo ( ?$bar = $baz ) {...} to be an initialization (since it's on the declaration of the parameter). If the parameter has already be bound to some other container, then that other container isn't at the start of its lifetime, so the initialization doesn't occur. If it hasn't been bound during the call, then it's just starting its existence and the initialization does occur. And I don't think that allowing 20 different types of assignment in the parameter list of a subroutine actually helps at all. Especially since the vast majority of parameters in Perl 6 will be constant. Damian
Re: A6: argument initializations via //=, ||=, ::=
On Wed, Mar 26, 2003 at 09:19:42AM +1100, Damian Conway wrote: my $x = 1;# initialization $x = 1;# assignment Woo, C++ :-) Considering 'our' merely declares a lexical alias to a package var, how do we initialize package vars? -- Matthijs van Duin -- May the Forth be with you!
Re: A6: argument initializations via //=, ||=, ::=
On Wed, Mar 26, 2003 at 09:19:42AM +1100, Damian Conway wrote: We then simply define the = in: sub foo ( ?$bar = $baz ) {...} to be an initialization (since it's on the declaration of the parameter). If the parameter has already be bound to some other container, then that other container isn't at the start of its lifetime, so the initialization doesn't occur. If it hasn't been bound during the call, then it's just starting its existence and the initialization does occur. And I don't think that allowing 20 different types of assignment in the parameter list of a subroutine actually helps at all. Especially since the vast majority of parameters in Perl 6 will be constant. But does allowing even one type of assignment help? I'm thinking that something like sub foo (?$bar is init($baz)) { ... } is better than an assignment with slightly different semantics than usual. Of course, I also think that instead of state we should do something like this too: sub CallMe { my $count is kept is init(1); print you've called me $($count++) times\n; } Boy am I glad Larry is the language designer. :-) -Scott -- Jonathan Scott Duff [EMAIL PROTECTED]
Re: A6: argument initializations via //=, ||=, ::=
On Tue, Mar 25, 2003 at 11:27:55PM +0100, Matthijs van Duin wrote: On Wed, Mar 26, 2003 at 09:19:42AM +1100, Damian Conway wrote: my $x = 1;# initialization $x = 1;# assignment Woo, C++ :-) Considering 'our' merely declares a lexical alias to a package var, how do we initialize package vars? The first time they are assigned to, it's an initialization :-) -Scott -- Jonathan Scott Duff [EMAIL PROTECTED]
Re: A6: argument initializations via //=, ||=, ::=
Damian Conway wrote: I don't see how ::= (compile-time-bind) can be used as the initialize-if-non-existent operator. I mean, it happens in the wrong phase (compile-time, not run-time) and it does the wrong thing (binding, not assignment). The only case I can think of where is might be useful is with a optional parameter with an is rw trait, so you could provide an default binding. Possible example: sub myprint(+$file is IO:File is rw ::= IO:STDOUT, [EMAIL PROTECTED]) {...} open f /a/d/v/f/r; myprint file = f, Hello World!\n; # goes to f myprint Differnet World!\n;# goes to IO:STDOUT although maybe what I really want is := instead. -- Mark Biggar [EMAIL PROTECTED] [EMAIL PROTECTED]
Re: A6: argument initializations via //=, ||=, ::=
On Tuesday, March 25, 2003, at 03:35 PM, Mark Biggar wrote: sub myprint(+$file is IO:File is rw ::= IO:STDOUT, [EMAIL PROTECTED]) {...} open f /a/d/v/f/r; myprint file = f, Hello World!\n; # goes to f myprint Differnet World!\n;# goes to IO:STDOUT As a side note... that sig will not do the behavior you've described. You instead want this: sub myprint([EMAIL PROTECTED], +$file is IO:File is rw ::= IO:STDOUT) {...} The named parameter +$file has to go behind the positional [EMAIL PROTECTED] in the signature, but still goes _before_ [EMAIL PROTECTED] in the actual call. (Insert image of a five-year-old me jumping up and down on a chair, pointing my finger, saying see! see! I told you people would do that!) MikeL
Re: A6: argument initializations via //=, ||=, ::=
On Tuesday, March 25, 2003, at 02:19 PM, Damian Conway wrote: And I don't think that allowing 20 different types of assignment in the parameter list of a subroutine actually helps at all. Especially since the vast majority of parameters in Perl 6 will be constant. Twenty types of _initialization_. :-D Seriously, tho, I'm not sure I understand the constantness part. sub foo($x = 1) {...} # A6 syntax I read the above as saying $x is indeed constant, but if it's not explicitly placed by the caller, we're going to pretend the caller passed us a 1. Likewise, I read sub foo($x //= 1) {...} as saying the value stored in $x is a constant, but if the caller passed an undefined value (or didn't pass anything at all), we're going to instead pretend they passed us a (still-constant) 1. I'm not sure why that violates any rules.(?) As a marginal bonus, perhaps an assertion-style sub foo($x //= 1) {...} optimizes to be faster, runtime, than sub foo($x) { $x //= 1; ... } when passing a constant in $x, e.g Cfoo(5) or Cfoo('BLAH'), since it can optimize out the assertion at compile-time? MikeL
Re: A6: argument initializations via //=, ||=, ::=
sub myprint(+$file is IO:File is rw ::= IO:STDOUT, [EMAIL PROTECTED]) {...} As a side note... that sig will not do the behavior you've described. You instead want this: sub myprint([EMAIL PROTECTED], +$file is IO:File is rw ::= IO:STDOUT) {...} The named parameter +$file has to go behind the positional [EMAIL PROTECTED] in the signature, but still goes _before_ [EMAIL PROTECTED] in the actual call. *sigh* I haven't been the sharpest tool in the shed today, and I know that the usual cases will be simpler, and that I'll get used to it with use until it makes sense and comes naturally. But in the meantime, I kinda hafta agree. It's burning my brain. __ Do you Yahoo!? Yahoo! Platinum - Watch CBS' NCAA March Madness, live on your desktop! http://platinum.yahoo.com
Re: A6: argument initializations via //=, ||=, ::=
--- Damian Conway [EMAIL PROTECTED] wrote: However I still think we're probably multiplying entities unnecessarily. A beautiful if somewhat understated reference to Occam's Razor. While the synoptic synthesis of the writing of William of Occam is often translated into English as One should not multiply entities needlessly, it's more colloquially stated as the simplest answer is usually best. So why am I multiplying words? :) Ok. I agree with Damian (which is usually a safe thing to say anyway, lol...) __ Do you Yahoo!? Yahoo! Platinum - Watch CBS' NCAA March Madness, live on your desktop! http://platinum.yahoo.com