I'll show you mine...
Okay, this is the beginnings of Scheme in Perl6. I'm sure there's stuff I'm getting wrong. I've not written the parser yet for instance and I'm toying with waiting for A5 before I do. Also, I've not yet implemented such important stuff as proper closures/lambda or the environment chain, but the underpinning structure is there. I'm also deeply uncertain about the workings of overloading and of operator declaration so those bits are probably wrong. ---SNIP--- module SchemeInterpreter; class SchemeExpr { use overload '' = 'raw_string', '0+' = 'to_number', fallback = 1 ; my SchemeExpr $.value; method new($proto: $val) { my $s = $proto.SUPER::new but true; $s.set_value( $val ); $s; } method value { $.value } method set_value($s: SchemeExpr $val) { $.value = $val; $s } method raw_string { $.value } method display_string { .raw_string } method evaluate($s: $context) { $s } method AUTOLOAD { my($method) = ($AUTOLOAD =~ m/.*::(.*)/); my $self = shift; $self.NEXT::$method(*@_) unless $method =~ /^is_/; return; } } class SchemeBoolean is SchemeExpr { my($t, $f); method new($proto: $val) { given $val { when '#t' { $t //= $proto.SUPER::new($val) } when '#f' { $f //= $proto.SUPER::new($val) but false } default { $proto.new( $val ?? '#t' :: '#f' ) } } } method is_boolean { 1 } } class SchemeNumber is SchemeExpr { my sub apply($self: $target, $rhs, block) { if $is_rhs { $self.new(+ block( $target, $self.value )) } else { $self.new(+ block( $self.value, $target )) } } method operator:+ { apply(*@_, {$^a + $^b}) } method operator:* { apply(*@_, {$^a * $^b}) } method operator:- { apply(*@_, {$^a * $^b}) } method operator:/ { apply(*@_, {$^a * $^b}) } method is_number { 1 } } class SchemePair is SchemeExpr { my $nil //= class is SchemeExpr { method is_nil {1} method car { fail Exception: msg = car: expects argument of type pair, given () } method cdr { fail Exception: msg = cdr: expects argument of type pair, given () } }.new('()'); method new($proto: PAIR $val) { $proto.SUPER::new($val) } method cons($proto: SchemeExpr $car, SchemeExpr $cdr) { $proto.new( $car = $cdr ) } method car { .value.key } method cdr { .value.value } method is_pair { 1 } method as_array($s:) { my ary; my $l = .cons($nil, $s); while ($.is_pair) { push ary, $l.car; $l = $l.cdr; } push ary, $l; return ary; } method raw_string { my ary = .as_array; if ary[-1].is_nil { ary.pop; (ary) } else { my $last = ary.pop; (ary . $last) } } method evaluate($self: $context) { $context.eval_list($self) } method length($self:) { my ary = $self.as_array; unless ary[-1].is_nil { fail Exception: msg = length: expects argument of type proper list; given $self; ary.length - 1; } method AUTOLOAD { .NEXT::AUTOLOAD unless $AUTOLOAD =~ /:?c([ad]+)r$/; my ops = reverse split '', $1; my $val = $_[0]; for ops - $type { $val = $val.c${type}r; } return $val; } } class SchemeSymbol is SchemeExpr { my %symcache; method new($name) { %symcache{$name} //= .SUPER::new($name); } method is_symbol { 1 }; method evaluate($self: $context) { $context.eval_symbol($self); } } class SchemePrimitive is SchemeExpr { method new($proto: PAIR $val) { $proto.SUPER::new($val) } method is_primitive { 1 }; method raw_string { #primitive: _ .value.key _ } method apply($self: SchemeExpr $expr, $context) { $self.value.value($expr, $context) } } class SchemeEnvironment is HASH { my $the_null_envt = class { method exists { } method bind { fail You can't bind anything in the null environment } method set { fail You can't set anything in the null environment } method get($symbol) { fail reference to undefined identifier: $symbol } }.new; method init { .{__parent__} //= $the_null_envt; method new_scope($self:) { ref($self).new(__parent__ = $self) } method bind_primitive($name, func) { .bind(SchemeSymbol.new($name), SchemePrimitive.new( $name = func )); } my method parent { .{__parent__} } method set($self: SchemeSymbol $key, SchemeExpr $value) { given .exists($key) { when defined { .value($value) } default { fail cannot set undefined identifier: $key } } return $self; } method bind($self: SchemeSymbol $key, SchemeExpr $val) { .{$key} = $value; return $self; } } class MathEvaluator { method evaluate($self: SchemeExpr $expr) { $expr.evaluate($self); } method eval_list($self: SchemePair $list) { my($op, $a, $b, rem) = $list.as_array; fail Exception: msg = Malformed expression $list. Expect (op arg arg) if rem.length; $a.evaluate($self); $b.evaluate($self); given $op {
Re: I'll show you mine...
In message [EMAIL PROTECTED], I wrote: [ A huge wodge of possible perl 6 code ] I'm getting that Warnock's Dilemma feeling here... Did I stun you all into silence? -- Piers It is a truth universally acknowledged that a language in possession of a rich syntax must be in need of a rewrite. -- Jane Austen?
Re: I'll show you mine...
At 3:03 PM +0100 4/10/02, Piers Cawley wrote: In message [EMAIL PROTECTED], I wrote: [ A huge wodge of possible perl 6 code ] I'm getting that Warnock's Dilemma feeling here... Did I stun you all into silence? Nah. You just can't hear the people running away screaming from there. ;-P -- Dan --it's like this--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: I'll show you mine...
On Wed, 2002-04-10 at 10:03, Piers Cawley wrote: In message [EMAIL PROTECTED], I wrote: [ A huge wodge of possible perl 6 code ] I'm getting that Warnock's Dilemma feeling here... Did I stun you all into silence? On my clock, your original message arrived at 04:23, and your followup at 10:03. On the west coast of the US, that would be 01:23 to 07:03. That's probably the time you're least likely to get responses. Personally, I'm a little stunned. I wish I could load it into a debuggger ;-) Your idea at the end of regugitating the code back out as Parrot or Perl is just slightly stunning on its own. Still digesting
Re: I'll show you mine...
At 3:49 PM +0100 4/10/02, Piers Cawley wrote: Aaron Sherman [EMAIL PROTECTED] writes: Your idea at the end of regugitating the code back out as Parrot or Perl is just slightly stunning on its own. I thought that was the easy bit. The compiler just (for appropriate values of 'just' of course) walks the syntax tree and uses an appropriate code generator to output appropriate source, which is what compilers have been doing since the year dot surely. We're going to have to put the asm keyword in for you, aren't we? :) (Or maybe attributed string eval, like: $foo = eval.Parrot EOP set I0, 12 sub I0, I0, 5 EOP Now that'd be interesting. Any parser module could be used. Hmmm) -- Dan --it's like this--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: Unary dot
On Tue, Apr 09, 2002 at 09:56:02PM +0100, Piers Cawley wrote: Larry Wall [EMAIL PROTECTED] writes: We're talking about how to make .foo mean self.foo regardless of the current topic. Are we? I was looking for a way to unambgiously access the current object in such a way that topicalizers would still work... I think we were talking about both. Okay, now that thith hath had a chanth to thteep in my brain for a day or tho... Here's a twist to another perspective: The thing with this invocant is, you're essentially creating another $_. It's an accessible named thing that acts as a noun and automatically receives a value in a particular context. It may be implemented as a macro, but will be perceived as a variable, another named alias to the value, since it can be used in all the same contexts as a full variable. Because of this, I'd like to see it keep the sigil, not by choice, but by requirement: use invocant self; ... method ical { $self.method_call(); ... } It's similar to the old concept of topic, before topic and $_ were unified. Maybe we now have invocantalizers? ;) Some of the issues: - The .method_call() syntax is not nearly as appealing if you can't use it consistently, but, - It is desirable, from a language learning/use perspective, for .some_call() to always act the same within a Cgiven when the topic is an object, whether the construct is within a method or not (or at least default to acting the same). - The natural question, once you realize Perl is holding this automatically generated value for you (which seems almost, but not quiet, identical to $_), is Why can't I default to it?, but, - One of the reasons for merging $_ and topic was to avoid the confusion of multiple defaults (and to avoid deprecating $_ to the default default). Invocants might add that complexity back. I see two directions the solution could go in. Direction 1 is if you don't like it, lump it. If you're going to need to access an outer topic within a nested topicalizer, you should define a named variable/parameter (method icial ($self:...). This is the path we've taken with other nested topicalizers. Direction 2 moves into the more exciting but scarier realm of alternate defaults. I would suggest that if we do add a) the ability to automatically populate variables (or macro accessed values) other than $_ and b) the ability to default to these variables (or macro accessed values), that we separate the two concepts, either by using two separate pragmas, or by making the invocant as default an option on the invocant pragma. I don't think defining a blank invocant name, or leaving off the name is ostentatious enough to do justice to the drastic change of altering the topic structure within the scope of all methods in the class (this is related to the linguistic principle of given vs. new information, new information is typically marked, more prominent). Here are a few possibilities: use invocant self; use method_default self; use invocant self is method_default; my $self is invocant is method_default; None of these is quite satisfying. All have associated problems: the first because the method_default pragma couldn't quite stand alone, the second because of the non-standard use of Cis, the third because you don't quite want to declare a variable, just specify a default. Hmm... possibly: use invocant $self is method_default; Which solves the first problem, by being a single statement, the second problem by making the is method_default a property of the variable (or more literally, a property that is pre-defined to be associated to the variable when it is instantiated in a method), and totally bypasses the third problem. The choice of method_default is intended to specify that the unique behaviour only affects .method_call() defaults, not the hoi polloi, garden-variety defaulting constructs, but a better name could be found. Allison
Re: I'll show you mine...
At 09:23 AM 4/10/2002 +0100, Piers Cawley wrote: Okay, this is the beginnings of Scheme in Perl6. I'm sure there's stuff I'm getting wrong. I've not written the parser yet for instance Very nice! Quite a sample, maybe Larry/Damian can use this in one of the next $(A,E)'s my SchemeExpr $.value; I haven't been keeping up in the back, I've a wedding bearing down on me. What is the significance of the . in the declaration? I think I paid attention enough to know a little about the unary dot but I'm still confused. We are able to use .foo to mean self.foo, but I would assume foo would be declared with my Foo $foo, not my Foo $.foo ? method car { .value.key } method cdr { .value.value } Maybe its the C++ in me but why the use of the unary . inside methods of the current class who's scope includes Cvalue already? Isn't this like using Cthis in C++ from inside a non-static method? I'll await your ruler on my knuckles, but overall; very impressed here. -Melvin
Re: Unary dot
Allison Randal wrote: On Tue, Apr 09, 2002 at 09:56:02PM +0100, Piers Cawley wrote: Larry Wall [EMAIL PROTECTED] writes: We're talking about how to make .foo mean self.foo regardless of the current topic. Are we? I was looking for a way to unambgiously access the current object in such a way that topicalizers would still work... I think we were talking about both. I see two directions the solution could go in. Direction 1 is if you don't like it, lump it. If you're going to need to access an outer topic within a nested topicalizer, you should define a named variable/parameter (method icial ($self:...). This is the path we've taken with other nested topicalizers. Yes, yes, be explicit. If the current topic is an object, its methods get invoked by unary dot, be it inside a method or outside a method. Direction 2 moves into the more exciting but scarier realm of alternate defaults. It could, but how about an alternative? Need there be a unary dot to specify invocation of an alternate method in the same class as the method being compiled? In other words, the following rules: 1) A method implicitly defines the default topic to be the object on which it was invoked. 2) Unary dot uses the default topic as the object on which to invoke methods. If the default topic is not an object, an exception results. 3) The function call name space within a method is first other methods of the same class, then other functions. (This is similar to C++, I believe) Hence, given a class containing two methods m1 and m2... method m1 { m2; # calls method m2 in the same class m2; # this should do the same, if the is still permitted .m2; # syntax error given ( $other_object ) { when m2 { ... } # invokes method m2 in the same class when .m2 { ... } # invokes $other_object.m2 when $_.m2 { ... } # invokes $other_object.m2 when $self.m2 { ... } # syntax error, unless some use invocant self # directive is included somewhere in the scope # If it is, then invokes method m2 in same class } } -- Glenn = Remember, 84.3% of all statistics are made up on the spot.
Re: Unary dot
On Wed, Apr 10, 2002 at 10:30:25AM -0700, Glenn Linderman wrote: method m1 { m2; # calls method m2 in the same class Yes, but does it call it as an instance method on the current invocant or as a class method with no invocant? If the former, how would you do the latter? .m2; # syntax error Doesn't that violate your stated rule thatthe default topic within a method be the invocant? Shouldn't .m2 be equivalent to $_.m2? -- Mark J. REED[EMAIL PROTECTED]
RE: Unary dot
Mark J. Reed wrote: On Wed, Apr 10, 2002 at 10:30:25AM -0700, Glenn Linderman wrote: method m1 { m2; # calls method m2 in the same class Yes, but does it call it as an instance method on the current invocant or as a class method with no invocant? If the former, how would you do the latter? I would expect the the m2() call would use the invocant of m1. If m1 is a called as a class method, then m2 would, also. If every object has a Cclass method (Cref?), then you could always call class-methods as class.m2(). Dave.
Re: Unary dot
Mark J. Reed wrote: On Wed, Apr 10, 2002 at 10:30:25AM -0700, Glenn Linderman wrote: method m1 { m2; # calls method m2 in the same class Yes, but does it call it as an instance method on the current invocant or as a class method with no invocant? If the former, how would you do the latter? Should both be allowed to exist? Do both exist? Why do both exist? (with the same name). If only one exists, then that would be the one that gets called. .m2; # syntax error Doesn't that violate your stated rule thatthe default topic within a method be the invocant? Shouldn't .m2 be equivalent to $_.m2? Oops. Yep, got me there. I should have wrapped a given $non_object around that one. Thanks. -- Glenn = Remember, 84.3% of all statistics are made up on the spot.
Re: Unary dot
On Wed, Apr 10, 2002 at 10:50:52AM -0700, Glenn Linderman wrote: Yes, but does it call it as an instance method on the current invocant or as a class method with no invocant? If the former, how would you do the latter? Should both be allowed to exist? Do both exist? Why do both exist? (with the same name). If only one exists, then that would be the one that gets called. Making the decision based on existence implies a requirement that Perl6 methods be explicitly declared as either class or instance. Not that there's anything wrong with that; I'm just not aware of that decision having been made. I guess we won't find out for sure until either Apoc6 or Apoc12? -- Mark J. REED[EMAIL PROTECTED]
Re: Unary dot
David Whipp wrote: Mark J. Reed wrote: On Wed, Apr 10, 2002 at 10:30:25AM -0700, Glenn Linderman wrote: method m1 { m2; # calls method m2 in the same class Yes, but does it call it as an instance method on the current invocant or as a class method with no invocant? If the former, how would you do the latter? I would expect the the m2() call would use the invocant of m1. If m1 is a called as a class method, then m2 would, also. If every object has a Cclass method (Cref?), then you could always call class-methods as class.m2(). Dave. Thanks, Dave, that's an excellant idea. -- Glenn = Remember, 84.3% of all statistics are made up on the spot.
Re: Unary dot
At 10:50 AM 4/10/2002 -0700, Glenn Linderman wrote: Mark J. Reed wrote: On Wed, Apr 10, 2002 at 10:30:25AM -0700, Glenn Linderman wrote: method m1 { m2; # calls method m2 in the same class Yes, but does it call it as an instance method on the current invocant or as a class method with no invocant? If the former, how would you do the latter? Should both be allowed to exist? Do both exist? Why do both exist? (with the same name). If only one exists, then that would be the one that gets called. I'd hope it would assume instance method until told otherwise, since static methods (class methods) are seldom used in OOP. Also there are issues when just assuming if m1() is a class method, I call m2() as a class method because m2() may access instance data that wouldn't exist if it were called staticly. -Melvin
Re: I'll show you mine...
Melvin Smith [EMAIL PROTECTED] writes: At 09:23 AM 4/10/2002 +0100, Piers Cawley wrote: Okay, this is the beginnings of Scheme in Perl6. I'm sure there's stuff I'm getting wrong. I've not written the parser yet for instance Very nice! Quite a sample, maybe Larry/Damian can use this in one of the next $(A,E)'s my SchemeExpr $.value; I haven't been keeping up in the back, I've a wedding bearing down on me. What is the significance of the . in the declaration? class Class { my $class_variable; my $.instance_variable; ... } Easy eh? I think I paid attention enough to know a little about the unary dot but I'm still confused. We are able to use .foo to mean self.foo, but I would assume foo would be declared with my Foo $foo, not my Foo $.foo ? method car { .value.key } method cdr { .value.value } Maybe its the C++ in me but why the use of the unary . inside methods of the current class who's scope includes Cvalue already? Consider class SpecializedPair is SchemePair { method value {...} } If you've written 'cdr' without the unary . it will attempt to dispatch to a *subroutine* in the same context, ie SchemePair::value. Even assuming that we play nice and allow confusion between methods and subroutines (which I'm personally not keen on), it's still apparent that, in the case of a SpecializedPair, car and cdr would use the wrong value. Isn't this like using Cthis in C++ from inside a non-static method? Don't ask me. I know nothing about C++ -- Objective C (Looong ago), Perl 5, Smalltalk and Ruby for me. I'll await your ruler on my knuckles, but overall; very impressed here. Thanks. Wait for the next version though, I'm busy implementing lexical scopes at the moment. -- Piers It is a truth universally acknowledged that a language in possession of a rich syntax must be in need of a rewrite. -- Jane Austen?
Re: Unary dot
Melvin Smith [EMAIL PROTECTED] writes: At 10:50 AM 4/10/2002 -0700, Glenn Linderman wrote: Mark J. Reed wrote: On Wed, Apr 10, 2002 at 10:30:25AM -0700, Glenn Linderman wrote: method m1 { m2; # calls method m2 in the same class Yes, but does it call it as an instance method on the current invocant or as a class method with no invocant? If the former, how would you do the latter? Should both be allowed to exist? Do both exist? Why do both exist? (with the same name). If only one exists, then that would be the one that gets called. I'd hope it would assume instance method until told otherwise, since static methods (class methods) are seldom used in OOP. Um... don't you use factory methods? I know I do. -- Piers It is a truth universally acknowledged that a language in possession of a rich syntax must be in need of a rewrite. -- Jane Austen?
Re: Unary dot
On Wed, Apr 10, 2002 at 01:35:22PM -0400, Mark J. Reed wrote: On Wed, Apr 10, 2002 at 10:30:25AM -0700, Glenn Linderman wrote: method m1 { m2; # calls method m2 in the same class Yes, but does it call it as an instance method on the current invocant or as a class method with no invocant? If the former, how would you do the latter? This may be a case of keep up at the back, but if that is a method call, how do I call a subroutine from within a method ? Graham.
Re: Unary dot
Graham Barr wrote: On Wed, Apr 10, 2002 at 01:35:22PM -0400, Mark J. Reed wrote: On Wed, Apr 10, 2002 at 10:30:25AM -0700, Glenn Linderman wrote: method m1 { m2; # calls method m2 in the same class Yes, but does it call it as an instance method on the current invocant or as a class method with no invocant? If the former, how would you do the latter? This may be a case of keep up at the back, but if that is a method call, how do I call a subroutine from within a method ? The same way. If there is a name conflict between subroutine and methods, then you qualify the subroutine name... ::m2; # calls global subroutine main::m2 main::m2; # calls global subroutine main::m2 -- Glenn = Remember, 84.3% of all statistics are made up on the spot.
Re: Unary dot
Graham Barr [EMAIL PROTECTED] writes: On Wed, Apr 10, 2002 at 01:35:22PM -0400, Mark J. Reed wrote: On Wed, Apr 10, 2002 at 10:30:25AM -0700, Glenn Linderman wrote: method m1 { m2; # calls method m2 in the same class Yes, but does it call it as an instance method on the current invocant or as a class method with no invocant? If the former, how would you do the latter? This may be a case of keep up at the back, but if that is a method call, how do I call a subroutine from within a method ? And anyone who says You don't will receive a good hard talking to from me. Being able to declare private subroutines within classes is really useful, witness: class SchemeNumber is SchemeExpr { my sub apply($self: $target, $rhs, block) { if $is_rhs { $self.new(+ block( $target, $self.value )) } else { $self.new(+ block( $self.value, $target )) } } method operator:+ { apply(*@_, {$^a + $^b}) } method operator:* { apply(*@_, {$^a * $^b}) } method operator:- { apply(*@_, {$^a * $^b}) } method operator:/ { apply(*@_, {$^a * $^b}) } method is_number { 1 } } Yes, I know there's several different ways I could do it, but this approach feels right. -- Piers It is a truth universally acknowledged that a language in possession of a rich syntax must be in need of a rewrite. -- Jane Austen?
Re: Unary dot
Glenn Linderman [EMAIL PROTECTED] writes: Graham Barr wrote: On Wed, Apr 10, 2002 at 01:35:22PM -0400, Mark J. Reed wrote: On Wed, Apr 10, 2002 at 10:30:25AM -0700, Glenn Linderman wrote: method m1 { m2; # calls method m2 in the same class Yes, but does it call it as an instance method on the current invocant or as a class method with no invocant? If the former, how would you do the latter? This may be a case of keep up at the back, but if that is a method call, how do I call a subroutine from within a method ? The same way. If there is a name conflict between subroutine and methods, then you qualify the subroutine name... ::m2; # calls global subroutine main::m2 main::m2; # calls global subroutine main::m2 This is looking more and more horrible Glenn. -- Piers It is a truth universally acknowledged that a language in possession of a rich syntax must be in need of a rewrite. -- Jane Austen?
Re: Unary dot
On Wed, Apr 10, 2002 at 07:57:01PM +0100, Piers Cawley wrote: ::m2; # calls global subroutine main::m2 main::m2; # calls global subroutine main::m2 This is looking more and more horrible Glenn. I think we need to back off of unmarked subroutines becoming a method call. That one extra '.' in front isn't too much, is it? I like the following, assumed to be within method m1: ..m2();# call m2 the same way m1 was called, instance or class $_.m2(); # same thing? Does the class become the topic in a static method? ..class.m2: # call static m2 within m1's class, regardless of how m1 was called m2() # call subroutine m2 with no arguments, implied or otherwise -- Mark J. REED[EMAIL PROTECTED]
Re: Unary dot
On Wed, Apr 10, 2002 at 10:30:25AM -0700, Glenn Linderman wrote: Allison Randal wrote: Direction 2 moves into the more exciting but scarier realm of alternate defaults. It could, but how about an alternative? Ah-ha, yet a third Direction! Need there be a unary dot to specify invocation of an alternate method in the same class as the method being compiled? In other words, the following rules: 1) A method implicitly defines the default topic to be the object on which it was invoked. As has been mentioned, this is already true. 2) Unary dot uses the default topic as the object on which to invoke methods. If the default topic is not an object, an exception results. Well, since all the variable types are now objects, which have methods, this wouldn't happen. But you would get some sort of exception if there was no method of that name for the current object. 3) The function call name space within a method is first other methods of the same class, then other functions. (This is similar to C++, I believe) Hence, given a class containing two methods m1 and m2... method m1 { m2; # calls method m2 in the same class m2; # this should do the same, if the is still permitted .m2; # syntax error given ( $other_object ) { when m2 { ... } # invokes method m2 in the same class when .m2 { ... } # invokes $other_object.m2 when $_.m2 { ... } # invokes $other_object.m2 when $self.m2 { ... } # syntax error, unless some use invocant self # directive is included somewhere in the scope # If it is, then invokes method m2 in same class } } I kind of like the idea of having both topic and invocant available at all times. But, I am concerned at having such a huge semantic difference (which object you're using) relying on the subtle visual distinction between m2() and .m2(). I can see a large opportunity for coder error and newbie misunderstanding. You also lose the visual cue that says this is a method call, not a subroutine or a built-in function. In the end I think that might be more confusing than it's worth. Allison
Re: Unary dot
On Wed, Apr 10, 2002 at 03:03:45PM -0400, Mark J. Reed wrote: ..class.m2: # call static m2 within m1's class, regardless of how m1 was called Typo. That should be just .class.m2, only one leading '.'. -- Mark J. REED[EMAIL PROTECTED]
RE: Unary dot
Mark J. Reed wrote On Wed, Apr 10, 2002 at 03:03:45PM -0400, Mark J. Reed wrote: ..class.m2: # call static m2 within m1's class, regardless of how m1 was called Typo. That should be just .class.m2, only one leading '.'. Wouldn't that be the current topic's class? Dave.
Re: Unary dot
On Wed, Apr 10, 2002 at 12:12:56PM -0700, David Whipp wrote: Mark J. Reed wrote On Wed, Apr 10, 2002 at 03:03:45PM -0400, Mark J. Reed wrote: ..class.m2: # call static m2 within m1's class, regardless of how m1 was called Typo. That should be just .class.m2, only one leading '.'. Wouldn't that be the current topic's class? .. . . and not necessarily the class in which m1 was declared. Good point. I was assuming a simpler, inheritance-free case. -- Mark J. REED[EMAIL PROTECTED]
Re: Unary dot
On Wed, Apr 10, 2002 at 03:03:45PM -0400, Mark J. Reed wrote: On Wed, Apr 10, 2002 at 07:57:01PM +0100, Piers Cawley wrote: ::m2; # calls global subroutine main::m2 main::m2; # calls global subroutine main::m2 This is looking more and more horrible Glenn. I think we need to back off of unmarked subroutines becoming a method call. Yeah. I like the following, assumed to be within method m1: ..m2(); # call m2 the same way m1 was called, instance or class This has already been semi-rejected. I agree with the reasoning. Not that it wouldn't be nice to have a way to code the concept, just that the .. symbology isn't right for the job. $_.m2(); # same thing? Does the class become the topic in a static method? If ..m2() were the same as $self.m2(), $_.m2() would only be the same until you entered the scope of another topicalizer. m2() # call subroutine m2 with no arguments, implied or otherwise Agreed. Allison
Re: none
Ashley Winters [EMAIL PROTECTED] writes: grin Patches welcome. Excellent... Forgive any formatting errors, I have mail issues. Thanks, applying. With a few caveats. @@ -62,6 +62,7 @@ class SchemePair is SchemeExpr { my $nil //= class is SchemeExpr { method is_nil {1} +method is_pair {0} method car { fail Exception: msg = car: expects argument of type pair, given () } method cdr { fail Exception: That change isn't necessary. If you look you'll see that the anonymous class of which $nil is the only instance is a subclass of SchemeExpr, not SchemePair. @@ -77,12 +78,13 @@ method car { .value.key } method cdr { .value.value } method is_pair { 1 } + method is_nil { 0 } SchemeExpr's AUTOLOAD handles that automagically. method AUTOLOAD { .NEXT::AUTOLOAD unless $AUTOLOAD =~ /:?c([ad]+)r$/; -my @ops = reverse split '', $1; -my $val = $_[0]; +my @ops = reverse split '', $1; # $1? Apocalypse 5... +my $val = @_[0]; YARGH! I thought I'd got rid of all those 5isms. method new_scope($self:) { ref($self).new(__parent__ = $self) } - method bind_primitive($name, func) { -.bind(SchemeSymbol.new($name), - SchemePrimitive.new( $name = func )); + method bind_primitive(PAIR @primitives) { +for @primitives - $primitive { + .bind(SchemeSymbol.new($primitive.key), +SchemePrimitive.new( $primitive )); Hmm... does that declaration syntax work? I really hope so 'cos it's lovely. } my method parent { .{__parent__} } method set($self: SchemeSymbol $key, SchemeExpr $value) { given .exists($key) { - when defined { .value($value) } + when defined { .{key} = $value } D'oh. Should be C.{$key} thought. - '+' = $expr, $context - { + '+' = - $expr, $context { Oops. Csub operator:lambda { - *@_ } anyone? -- Piers It is a truth universally acknowledged that a language in possession of a rich syntax must be in need of a rewrite. -- Jane Austen?
Re: Unary dot
On Wed, Apr 10, 2002 at 02:42:58PM -0500, Allison Randal wrote: I like the following, assumed to be within method m1: ..m2();# call m2 the same way m1 was called, instance or class This has already been semi-rejected. I agree with the reasoning. Not that it wouldn't be nice to have a way to code the concept, just that the .. symbology isn't right for the job. MUA/MTA quoting seems to be getting in the way here - someone's prepending a '.' to avoid sending the SMTP end-of-message sentinel and it's not getting stripped off properly. That was supposed to be a single '.' in front of the m2(). In other words, unary . is the same as binary . with $_ as the LHS, so .m2() would be the same as $_.m2(). Which would have the semantics in my comment above, assuming that the class becomes the topic in static methods. -- Mark J. REED[EMAIL PROTECTED]
Re: Unary dot
Mark J. Reed [EMAIL PROTECTED] writes: On Wed, Apr 10, 2002 at 07:57:01PM +0100, Piers Cawley wrote: ::m2; # calls global subroutine main::m2 main::m2; # calls global subroutine main::m2 This is looking more and more horrible Glenn. I think we need to back off of unmarked subroutines becoming a method call. That one extra '.' in front isn't too much, is it? I like the following, assumed to be within method m1: ..m2(); # call m2 the same way m1 was called, instance or class Can't say I'm keen on that at all. We already have a '..' operator (admittedly it's binary), and this new, unary .. doesn't really do anything remotely similar (cf unary dot, unary _ and unary +, which have behaviours which are obviously related to the binary forms.). And haven't we done this discussion already? -- Piers It is a truth universally acknowledged that a language in possession of a rich syntax must be in need of a rewrite. -- Jane Austen?
RE: Unary dot
Piers Cawley This may be a case of keep up at the back, but if that is a method call, how do I call a subroutine from within a method ? [...] Yes, I know there's several different ways I could do it, but this approach feels right. I think this comes does to huffmann encoding: which things are common, and which are less common. This probably depends on what you are doing (what paradigm you are following), so its really a question about the nature of perl. The things I've heard people wanting to do are: call method on current topic call method on current invocant call class method on invocant's class call private subroutine defined in current class call global subroutine The following syntaxes have been seen: foo() .foo() ..foo() ## rejected because .. is different binary op class.foo() FooClass.foo() ::foo() Package::foo() $foo() $_.foo() I see 2 partionings: * by scope: topic, self, named package, global * by invocant: instance, class, none My suggested resolutions: By Scope: global/ named package use the existing Foo::bar syntax; Topic uses unary . syntax; self uses nothing By invocant: infer from current invocant/topic; use foo() for no invocant Thus, the perl5 transalations would be: foo() = $self-foo() .foo() = $_-foo() foo() = foo() ::foo() = ::foo() Bar::bar() = Bar::bar() class.foo() = ref($self)-foo() .class.foo() = ref($_)-foo() foo(self) = foo($self-self) = $self-self-foo() This assumes that Cclass and Cself are defined in UNIVERSAL Dave.
Re: Unary dot
David Whipp [EMAIL PROTECTED] writes: Piers Cawley This may be a case of keep up at the back, but if that is a method call, how do I call a subroutine from within a method ? [...] Yes, I know there's several different ways I could do it, but this approach feels right. I think this comes does to huffmann encoding: which things are common, and which are less common. This probably depends on what you are doing (what paradigm you are following), so its really a question about the nature of perl. The things I've heard people wanting to do are: call method on current topic call method on current invocant call class method on invocant's class call private subroutine defined in current class call global subroutine The following syntaxes have been seen: foo() .foo() ..foo() ## rejected because .. is different binary op class.foo() FooClass.foo() ::foo() Package::foo() $foo() $_.foo() I see 2 partionings: * by scope: topic, self, named package, global * by invocant: instance, class, none My suggested resolutions: By Scope: global/ named package use the existing Foo::bar syntax; Topic uses unary . syntax; self uses nothing By invocant: infer from current invocant/topic; use foo() for no invocant Thus, the perl5 transalations would be: foo() = $self-foo() .foo() = $_-foo() foo() = foo() ::foo() = ::foo() Bar::bar() = Bar::bar() class.foo() = ref($self)-foo() .class.foo() = ref($_)-foo() foo(self) = foo($self-self) = $self-self-foo() This assumes that Cclass and Cself are defined in UNIVERSAL For reasons that I can't quite put my finger on at the moment, I really, really don't like that approach. One of the really nice things about perl 4 was that we didn't have to use any more. Making it essential seems like a horribly retrograde step. I suppose you could require the only when calling subroutines from within a method/class definitions, but I still don't like it. -- Piers It is a truth universally acknowledged that a language in possession of a rich syntax must be in need of a rewrite. -- Jane Austen?
Re: Unary dot
The following syntaxes have been seen: foo() .foo() ..foo() ## rejected because .. is different binary op class.foo() FooClass.foo() ::foo() Package::foo() $foo() $_.foo() With a nod to Piers, and with apologes if this is silly in the context of Perl 6 syntax, what about: $.foo -- ralph
Re: Unary dot
On Wed, Apr 10, 2002 at 03:49:44PM -0400, Mark J. Reed wrote: On Wed, Apr 10, 2002 at 02:42:58PM -0500, Allison Randal wrote: I like the following, assumed to be within method m1: ..m2(); # call m2 the same way m1 was called, instance or class This has already been semi-rejected. I agree with the reasoning. Not that it wouldn't be nice to have a way to code the concept, just that the .. symbology isn't right for the job. MUA/MTA quoting seems to be getting in the way here - someone's prepending a '.' to avoid sending the SMTP end-of-message sentinel and it's not getting stripped off properly. That was supposed to be a single '.' in front of the m2(). Then, Agreed. In other words, unary . is the same as binary . with $_ as the LHS, so .m2() would be the same as $_.m2(). Which would have the semantics in my comment above, Yes, until you used a Cgiven or a Cfor, etc. Then .m2() would be the same as $_.m2() (at least it would be if we don't make any of the changes we're talking about), but wouldn't be called the same way m1 was called, it would be called on the current topic. assuming that the class becomes the topic in static methods. Larry Wall wrote in A4: Any method definition is a topicalizer within the body of the method, and will assume a given of its $self object (or whatever you have named it). I would hope that static methods wouldn't be *too* different from instance methods. Allison
Re: I'll show you mine...
great idea :) I've just tried gnuCash program and think it is very cool (i've enjoyed to take first steps in double-entry accounting, i was always wondering what the hell is this :) )... http://www.ncsysadmin.org/july2001/ncsa-gnucash-talk.html#toc1 (very entertaining intro :) ) Meanwhile during browsing the docs i found that there was a way to extend the program but via Scheme (it had possiblity to be extended via perl at the begining but now not, for some their reason !!!). And so I wanted always to learn Prolog Lisp and so now I'm reading the Scheme online book : http://www.scheme.com/tspl2d/index.html It looks very cool, so go for it... i hope i will learn it :) = iVAN [EMAIL PROTECTED] PS. Before a couple of years I was using happily Windows and one my friend told me (arguing constantly ) do u know that Linux is very cool (no matter it used Win :)) .. so i got a book and started to learn Linux, i read about awk and started to write a report program (parsing IIS,proxy etc.. logs), meanwhile i constantly saw Perl examples in the same book, and also precaution that Perl is much more powerfull and hard to learn, so be prepared to spend alot of time. so one day i decided this awk is cute but what if i try Perl ? And on the third week my program much more featurefull was ready :) (up to this time i used only pascal basic) The good things always happen acidently .. So ... Thank you very much.
Re: Unary dot
On Wed, Apr 10, 2002 at 09:23:23PM +0100, Piers Cawley wrote: David Whipp [EMAIL PROTECTED] writes: Thus, the perl5 transalations would be: foo() = $self-foo() .foo() = $_-foo() foo() = foo() ... For reasons that I can't quite put my finger on at the moment, I really, really don't like that approach. One of the really nice things about perl 4 was that we didn't have to use any more. Making it essential seems like a horribly retrograde step. I suppose you could require the only when calling subroutines from within a method/class definitions, but I still don't like it. I agree. It makes an exception where none is needed (foo() required instead of foo()) just to re-use the syntax for a less common construction that could just as easily be represented any number of other ways. Allison
Re: Unary dot
David Whipp [EMAIL PROTECTED] writes: Thus, the perl5 transalations would be: foo() = $self-foo() .foo() = $_-foo() foo() = foo() ... Alternative: $self.foo() = $self-foo() # and can be .foo() when $self is $_ .foo() = $_-foo() # but might be altered by a pragma foo() = foo() Allison
Re: Unary dot
$.foo It's already defined as an instance variable. I don't think I like that. Instance variables are far more common that class variables, so why not just $foo, and you could use a compile-time property for class variables. Like Cis private as discussed. That or Cis static. I think the latter makes more sense. Or is there some reason this wouldn't work? Luke
Re: Unary dot
Allison wrote: David Whipp [EMAIL PROTECTED] writes: Thus, the perl5 transalations would be: foo() = $self-foo() .foo() = $_-foo() foo() = foo() ... Alternative: $self.foo() = $self-foo() # and can be .foo() when $self is $_ .foo() = $_-foo() # but might be altered by a pragma foo() = foo() And welcome back to where we started! ;-) However, having circumnavigated the alternatives, we now have a better perspective on the trade-offs and hidden costs. The original idea of topicalizing the invocant in methods was that it makes very simple methods even simpler: method name { .assigned_name // .std_name // ??? } For anything more complex than very simple (i.e. anything with internal topicalizers), one names the invocant explicitly: method rank ($self:) { given ($.status) { when covert { return Special operative } when detached { return Field operative } default { return $self.actual_rank } } } or, if the class has many such methods, implicitly: use invocant 'invocant'; method rank () { given ($.status) { when covert { return Special operative } when detached { return Field operative } default { return invocant.actual_rank } } } The problem that this discussion has highlighted is that using a bare .foo in a method means the reader/maintainer has to track what the current topic is in order to know who the current invocant is. That would seem to be a (potentially expensive) hidden cost of this idiom. Reflecting on this, it seems that it would be useful if methods implicitly did their default topicalization-of-invocant like so: - $self rather than just: - $_ That is, that as well as aliasing the invocant to $_, they also alias it to some standard variable name. Then one would be guaranteed an invariant name (across all OO Perl!) for the invocant, even under internal topicalizations. Of course, the problem is then: what should the name of this topicalizer variable be? The main options are: $self $me $I $this $invocant $object $obj And frankly, that's a very minor issue. Someone (i.e. Larry) should just pick one and then we can all move on. Damian
Re: Unary dot
On Thu, Apr 11, 2002 at 08:04:56AM +1000, Damian Conway wrote: Allison wrote: $self.foo() = $self-foo() # and can be .foo() when $self is $_ .foo() = $_-foo() # but might be altered by a pragma foo() = foo() And welcome back to where we started! ;-) Exactly! :) The problem that this discussion has highlighted is that using a bare .foo in a method means the reader/maintainer has to track what the current topic is in order to know who the current invocant is. That would seem to be a (potentially expensive) hidden cost of this idiom. But possibly less expensive than providing a means to default to something other than topic. That is, that as well as aliasing the invocant to $_, they also alias it to some standard variable name. Then one would be guaranteed an invariant name (across all OO Perl!) for the invocant, even under internal topicalizations. I'm in favor of the standardized variable name. It is a restriction, but not an onerous one. I've never used anything but $self, and I'm sure it would be easy to adapt to whatever else was chosen. Are there any statistics availble on current usage of $self vs. $this vs. whatever? It might be easiest to go with what the majority find most comfortable. Allison
Re: Unary dot
At 07:40 PM 4/10/2002 +0100, Piers Cawley wrote: Melvin Smith [EMAIL PROTECTED] writes: At 10:50 AM 4/10/2002 -0700, Glenn Linderman wrote: Mark J. Reed wrote: On Wed, Apr 10, 2002 at 10:30:25AM -0700, Glenn Linderman wrote: method m1 { m2; # calls method m2 in the same class Yes, but does it call it as an instance method on the current invocant or as a class method with no invocant? If the former, how would you do the latter? Should both be allowed to exist? Do both exist? Why do both exist? (with the same name). If only one exists, then that would be the one that gets called. I'd hope it would assume instance method until told otherwise, since static methods (class methods) are seldom used in OOP. Um... don't you use factory methods? I know I do. Sure I do, but it doesn't comprise more than 5% of the methods I call on objects. And in C++ or Java, when I need a class method, I specify it with the keyword 'static'. Along with it comes the restrictions of not accessing instance data, etc. etc. I will admit my applied usage of OOP is biased by the C++/Java lense. :) While I may be misunderstanding Perl6 syntax, I'm not misunderstanding OOP, these are basic concepts to C++ and Java and how many other languages; granted, I'll try to play catchup with reading the Apocs and Exegeses over, but it appears from the discussion thread that people are discussing class/instance method mixing as if this were a new concept to OOP. My feeling is you ask yourself: What makes sense and what does the compiler and runtime engine have to do based on the given rules that we choose. Its clear if invocant of foo() is the class, and not the instance, calling an instance method from class scope without creating an object to work with should either be disallowed, or analyzed to check whether it actually uses instance data. I'd choose former which is what C++ and Java does. -Melvin
Re: Unary dot
At 07:54 PM 4/10/2002 +0100, Piers Cawley wrote: Graham Barr [EMAIL PROTECTED] writes: On Wed, Apr 10, 2002 at 01:35:22PM -0400, Mark J. Reed wrote: On Wed, Apr 10, 2002 at 10:30:25AM -0700, Glenn Linderman wrote: method m1 { m2; # calls method m2 in the same class Yes, but does it call it as an instance method on the current invocant or as a class method with no invocant? If the former, how would you do the latter? This may be a case of keep up at the back, but if that is a method call, how do I call a subroutine from within a method ? And anyone who says You don't will receive a good hard talking to from me. Being able to declare private subroutines within classes is really useful, witness: class SchemeNumber is SchemeExpr { my sub apply($self: $target, $rhs, block) { if $is_rhs { $self.new(+ block( $target, $self.value )) } else { $self.new(+ block( $self.value, $target )) } } method operator:+ { apply(*@_, {$^a + $^b}) } method operator:* { apply(*@_, {$^a * $^b}) } method operator:- { apply(*@_, {$^a * $^b}) } method operator:/ { apply(*@_, {$^a * $^b}) } method is_number { 1 } } Yes, I know there's several different ways I could do it, but this approach feels right. I agree, however you passed in the invocant so there is no ambiguity in your case. Calling a class method off of an object, I've found use for. Calling an instance method from a class invocant scope doesn't make sense to me which is what I _think_ Graham's example was implying. I suppose this would be akin to: if(typeof(self) is 'class') { ... } else { # instance ... } I think that would be just plain bad design, but I'd be happy if someone showed me a use for it. :) -Melvin
Re: Unary dot
At 08:04 AM 4/11/2002 +1000, Damian Conway wrote: And welcome back to where we started! ;-) Wow there is a lot of blood on the ground here. Must have been messy... :) Of course, the problem is then: what should the name of this topicalizer variable be? The main options are: $self $me $I $this $invocant $object $obj And frankly, that's a very minor issue. Someone (i.e. Larry) should just pick one and then we can all move on. I'm waiting for Larry to say, We have decided to use $me, $myself and $i. -Melvin
RE: Unary dot
Melvin Smith wrote I think that would be just plain bad design, but I'd be happy if someone showed me a use for it. :) well, I've been known to do sub UNIVERSAL::debug { my $self = shift; my $msg = _; eval {$self=$self-name} if ref($self); my $timestamp = ...; my $caller = ...; print DEBUG [$timestamp] '$self' $caller: $msg\n; } sub UNIVERSAL::debugf { shift-debug(sprintf _) } which can then be called as: $class-debug(hello); or $self-debugf(world, %d, 42); or even hello-debug(world); You are right. This is just plain bad design. But it can be useful. Dave.
Defaulting params
The current plans indicate that a subroutine's params should be defaulted like this: sub load_data ($filename ; $version / /= 1) {...} (The space between / and / is on purpose, my emailer has problems if they are together.) If that's the technique, how does the caller indicate that the second param is *supposed* to be undef? If I were to call a sub like this: load_data ($filename, undef); then I would expect that means that I am explicitly saying the second argument is supposed to be undef. However, if I call it like this: load_data ($filename); then I'm not sending the second param and it can be whatever the default is. Ergo, I propose that / /= and simply = are both allowed and mean slightly different things: # $version is 1 if the second param isn't sent at all sub load_data ($filename ; $version = 1) {...} # $version is 1 if the second param is undef sub load_data ($filename ; $version / /= 1) {...} (Yes, this is a repeat of an earlier suggestion. It was suggested I might repost reworded.) -Miko
Re: Unary dot
On Thu, Apr 11, 2002 at 08:04:56AM +1000, Damian Conway wrote: Reflecting on this, it seems that it would be useful if methods implicitly did their default topicalization-of-invocant like so: - $self rather than just: - $_ That is, that as well as aliasing the invocant to $_, they also alias it to some standard variable name. Then one would be guaranteed an invariant name (across all OO Perl!) for the invocant, even under internal topicalizations. H... this being the case, is there any reason we should ever need to name the invocant explicitly? If Perl has already provided a named alias implicitly, why specify redundant information when other parameters follow? Leave the parameter lists for parameters that change from method to method, not for the one that will always be there. You get short parameter lists, and a truly invariant name for the invocant. method foo ($bar, $baz) { $self.boo; # $self always exists in a method } There's no conflict with Perl 5 since Cmethod is a new keyword. Also, the invocant pragma becomes unnecessary if you can always access the current object via $self (or $this, or $me, or whatever, as long as it's not $invocant ;). My, my, my, I *am* playing the devil's advocate today. :) Allison
Re: Unary dot
Allison Randal wrote: H... this being the case, is there any reason we should ever need to name the invocant explicitly? Yes. To make it read-writable. Perl makes that much easier than most other languages, because you can pass the invocant by (writable) reference, so you don't need to pass a separate $parent pointer: method Tree::delete(Tree $self is rw:) { if $.left_child { $.left_child.insert($.right_child) if $.right_child; $self = $.left_child } elsif $.right_child { $self = $.right_child } $.right_child = $.left_child = undef; } Damian
Re: Unary dot
On Thu, Apr 11, 2002 at 12:01:58PM +1000, Damian Conway wrote: Allison Randal wrote: H... this being the case, is there any reason we should ever need to name the invocant explicitly? Yes. To make it read-writable. Curses! Foiled again! :) Perl makes that much easier than most other languages, because you can pass the invocant by (writable) reference, so you don't need to pass a separate $parent pointer: Devil's advocate role aside, that is a very cool feature. Another thing you would lose is the ability to rename the parameter if you wanted (you could use assignment or binding, but it would be infinitely ugly). Allison
Re: Unary dot
At 04:01 PM 4/10/2002 -0600, Luke Palmer wrote: $.foo It's already defined as an instance variable. I don't think I like that. Instance variables are far more common that class variables, so why not just $foo, and you could use a compile-time property for class variables. Like Cis private as discussed. That or Cis static. I think the latter makes more sense. Or is there some reason this wouldn't work? I totally agree here. The common case is going to make code look ugly with $.foo everywhere. Please don't let this come into being. :( I think it is arguable that a closure is a class for a subroutine object, and in subs we will still use my $foo for lexicals. However we must remember in class scope to use $.foo for the default, instance variable, and a normal $foo for the less typical static or class variables. Yucky. Reserve the ugly syntax for the less common case. Plase. -Melvin
Re: Unary dot
Damian Conway [EMAIL PROTECTED] writes: [...] Reflecting on this, it seems that it would be useful if methods implicitly did their default topicalization-of-invocant like so: - $self rather than just: - $_ That is, that as well as aliasing the invocant to $_, they also alias it to some standard variable name. Then one would be guaranteed an invariant name (across all OO Perl!) for the invocant, even under internal topicalizations. Of course, the problem is then: what should the name of this topicalizer variable be? The main options are: $self $me $I $this $invocant $object $obj And frankly, that's a very minor issue. Someone (i.e. Larry) should just pick one and then we can all move on. Nailing my colours to the mast here, I choose '$self'. I will confess to suggesting the Cuse invocant '$whatever' syntax not because I thought it was a desperately good idea, but because I didn't want to get into arguing about what colour to paint the bikeshed before we'd actually decided whether or not to build the bikeshed in the first place. -- Piers It is a truth universally acknowledged that a language in possession of a rich syntax must be in need of a rewrite. -- Jane Austen?
Re: Unary dot
Luke Palmer [EMAIL PROTECTED] writes: $.foo It's already defined as an instance variable. I don't think I like that. Instance variables are far more common that class variables, so why not just $foo, and you could use a compile-time property for class variables. Like Cis private as discussed. That or Cis static. I think the latter makes more sense. Ah, but I think the mnemonic value of the '.' more than earns its keep here. Cour $foo is private is doing a slightly different job anyway. And instance variables are *not* the same as 'normal' variables, they hang off a different symbol table (or syte, to use Damian's oh so clever term from Perl 5+i) and I'm all for things that are different *looking* different. -- Piers It is a truth universally acknowledged that a language in possession of a rich syntax must be in need of a rewrite. -- Jane Austen?
Re: Defaulting params
Miko O'Sullivan [EMAIL PROTECTED] writes: The current plans indicate that a subroutine's params should be defaulted like this: sub load_data ($filename ; $version / /= 1) {...} (The space between / and / is on purpose, my emailer has problems if they are together.) If that's the technique, how does the caller indicate that the second param is *supposed* to be undef? If I were to call a sub like this: load_data ($filename, undef); then I would expect that means that I am explicitly saying the second argument is supposed to be undef. However, if I call it like this: load_data ($filename); then I'm not sending the second param and it can be whatever the default is. Ergo, I propose that / /= and simply = are both allowed and mean slightly different things: # $version is 1 if the second param isn't sent at all sub load_data ($filename ; $version = 1) {...} # $version is 1 if the second param is undef sub load_data ($filename ; $version / /= 1) {...} (Yes, this is a repeat of an earlier suggestion. It was suggested I might repost reworded.) I think you're right that this is a valid distinction, I'm just not sure if it's not a little too subtle and that the two different notations won't cause confusion. I *think* that the //= case is going to be the more common one, and one could always handle the first case more explicitly by doing: sub load_data ($filename; $version) { $version = 1 if @_.length 2; ... } Yes, it is undoubtedly uglier, but I don't think it's a common enough case that that worries me. -- Piers It is a truth universally acknowledged that a language in possession of a rich syntax must be in need of a rewrite. -- Jane Austen?
Re: Unary dot
Ah, but I think the mnemonic value of the '.' more than earns its keep here. Cour $foo is private is doing a slightly different job anyway. And instance variables are *not* the same as 'normal' variables, they hang off a different symbol table (or syte, to use Damian's oh so clever term from Perl 5+i) and I'm all for things that are different *looking* different. Well, I certainly don't like the aesthetic value of them. They are ugly as Perl 4. But, I have been caught in C++ making all my private variables _named _like _this, so I suppose it's analogous. But I don't like being forced to do it that way. What if you just want a simple struct-like thing? That's when it becomes really ugly and dislikable. Erm... wait a minute, how would you do that? $foo = new Foo; $foo..instancevar = 7; I doubt that's it. $foo.instancevar = 7; And that's unclear, if we refer to it as $.instancevar inside the function. Or, actually, I do think it's clear. Wow, I was arguing my point and I came to like the syntax. Hmm Ok, take your once-ugly syntax and run with it! I understand it now. Luke
Re: Defaulting params
On Thu, 11 Apr 2002, Piers Cawley wrote: Miko O'Sullivan [EMAIL PROTECTED] writes: The current plans indicate that a subroutine's params should be defaulted like this: sub load_data ($filename ; $version / /= 1) {...} (The space between / and / is on purpose, my emailer has problems if they are together.) If that's the technique, how does the caller indicate that the second param is *supposed* to be undef? If I were to call a sub like this: load_data ($filename, undef); then I would expect that means that I am explicitly saying the second argument is supposed to be undef. However, if I call it like this: load_data ($filename); then I'm not sending the second param and it can be whatever the default is. Ergo, I propose that / /= and simply = are both allowed and mean slightly different things: # $version is 1 if the second param isn't sent at all sub load_data ($filename ; $version = 1) {...} # $version is 1 if the second param is undef sub load_data ($filename ; $version / /= 1) {...} (Yes, this is a repeat of an earlier suggestion. It was suggested I might repost reworded.) I think you're right that this is a valid distinction, I'm just not sure if it's not a little too subtle and that the two different notations won't cause confusion. I *think* that the //= case is going to be the more common one, and one could always handle the first case more explicitly by doing: sub load_data ($filename; $version) { $version = 1 if @_.length 2; ... } Yes, it is undoubtedly uglier, but I don't think it's a common enough case that that worries me. Indeed, and with the //= thing, you can let parameters in the middle default. The only other language that lets you do that is VB, and I actually kinda liked it. (Not insinuating that VB is actually a language or anything...) Luke
Re: Defaulting params
Piers wrote: one could always handle the first case more explicitly by doing: sub load_data ($filename; $version) { $version = 1 if _.length 2; ... } Err...no. If you specify named parameters, you don't get _. It could be handled by overloading though: sub load_data ($filename) { load_data($filename, 1) } sub load_data ($filename, $version) {...} Damian
Re: Defaulting params
Damian Conway [EMAIL PROTECTED] writes: Piers wrote: one could always handle the first case more explicitly by doing: sub load_data ($filename; $version) { $version = 1 if @_.length 2; ... } Err...no. If you specify named parameters, you don't get @_. It could be handled by overloading though: sub load_data ($filename) { load_data($filename, 1) } sub load_data ($filename, $version) {...} Ooh. Multiple dispatch is definitely in then? Did I miss something? But *great*. -- Piers It is a truth universally acknowledged that a language in possession of a rich syntax must be in need of a rewrite. -- Jane Austen?