Re: RFC 222 (v1) Interpolation of method calls
On Fri, Sep 15, 2000 at 10:58:26AM +0200, Bart Lateur wrote: MJD has a "silly module" which can tie a hash to a function: Interpolation.pm. I think I would like a special case, a specific hash that is *always* tied to a function that returns the arguments. Make it, for example, %$, %@ or %?. These are not in use now, are they? print "You have to pay $?{money($amount)} dollars."; I always thought MJD's module was neat, but never had a real desire for interpolated function calls. If it was part of the core library I may be inclined to use it more, but I doubt it. Or maybe an alternative, using : "foo foo(arg, arg, arg) bar" "foo { foo(arg, arg, arg) } bar" I suspect this has already been discussed and discarded at some point; I sincerely doubt I'm the only one who came up with it. Or maybe we need a more generic solution (as someone else suggested, I forget who). Something that allows the arbitrary execution of code, much like @{[ ]}, but cleaner. Unfortunately, I can't think of anything suitable. Whatever direction this discussion takes, I don't think it should impact the interpolation of method calls. It'd be nice to find a clean and simple syntax for calling functions within double-quoted strings, but it's already clean and simple to call methods. Michael -- Administrator www.shoebox.net Programmer, System Administrator www.gallanttech.com --
Re: RFC - Interpolation of method calls
On Fri, Sep 15, 2000 at 07:24:39PM -0500, David L. Nicol wrote: The only decision, then, is to decide which context to use; if it deparses to concatenation then it seems logical to use scalar context. This also makes sense in that you can force list context with @{[ $weather-temp ]} if you really wanted it. $ perl -le 'sub w{wantarray?"WA":"WS"};print " attempt: ${\scalar(w)}"' attempt: WS Maybe we just need a shorter synonym for Cscalar? Or DWIM "${\foo()}" to force scalar context. Everytime I come across that construct I have to wonder why it's not called in scalar context. The '$' would seem to imply it should. Or cause the foo() method in "foo $foo-bar bar" to be called in scalar context by default, obviating the need for a specific scalar call. I'd actually like both solutions to be implemented. What's even more confusing: sub foo { wantarray ? "list" : "scalar" } print scalar("${\foo()}") -- "list" print scalar(${\foo()}) -- "list" $foo = ${\foo()}; print $foo-- "list" And yet: sub foo { wantarray ? \"list" : \"scalar" } print ${foo()} -- "scalar" print ${ ("bar", foo()) } -- "scalar" (These were all tested using 5.6.0.) I have to assume \foo() is actually \(foo()) or some such. IMHO, this is entirely non-intuitive. Can anyone enlighten me as to why this is as it is? I believe there was a p5p discussion about this, but I dread delving into the archives again.. Michael -- Administrator www.shoebox.net Programmer, System Administrator www.gallanttech.com --
Re: RFC - Interpolation of method calls
This topic is actually covered, albeit far less in-depth and lumped with an unrelated change, by Nathan Wiger's RFC 103, just in case you weren't aware. On Thu, Sep 14, 2000 at 03:57:41AM -0400, Michael G Schwern wrote: Methods will be run in scalar context. A method which returns a single scalar is treated normally. If a list is returned, it should be treated same as array interpolation. The list seperator will be applied. In effect, the deparsing will really work out as follows: print 'Today\'s weather will be '.join($", $weather-temp()). ' degrees and sunny.'; However if temp() calls wantarray(), the result will be FALSE (scalar). Ok, this is very confusing. You're saying the method is called in scalar context, but then proceed to call it in list context, meanwhile tricking it into thinking it's scalar context. Interpolated method calls should behave the same as every other method call, without extra magic. The only decision, then, is to decide which context to use; if it deparses to concatenation then it seems logical to use scalar context. This also makes sense in that you can force list context with @{[ $weather-temp ]} if you really wanted it. =head2 Argument passing Interpolation should also handle passing arguments to methods in a string: print "Today's weather will be $weather-temp("F") degrees and sunny."; This should deparse to: print 'Today\'s weather will be '.$weather-temp("F"). ' degrees and sunny.'; The arguments to the method are considered as normal expressions, thus: print "There is $obj-foo(this = $yar, that = 2 + 2) in my head."; deparses as: print 'There is '.$obj-foo(this = $yar, that = 2 + 2). ' in my head."; Now perl is parsing full statements within strings. I -really- don't like this, not only because perl is now reaching into strings to parse yet more, but also because it's already beginning to look very difficult for me, personally, to parse. Not only that, it gives me the heeby-geebies (which of course means you should all immediately agree with me :). I'd say keep it simple, allow only simple, non-parenthetical method calls. "foo $foo-bar bar" -- "foo " . $foo-bar . " bar" "foo $foo-bar() bar" -- "foo " . $foo-bar . "() bar" Granted, it may confuse the newbies, but I think it makes things much easier on everyone. Normally, whitespace is allowed between tokens of a method call. $obj - bar ("this"); and $obj-bar("this"); are equivalent. Whitespace between the object, '-', method name and opening paren should be disallowed when interpolated. This will avoid many ambiguous cases. This is a good idea, and has precedence (as I just discovered answering someone's question about it in #Perl as I was writing this email, weird..): "$hash - {'foo'}" -- "HASH(0x8bbf0b8) - {k1}" Michael -- Administrator www.shoebox.net Programmer, System Administrator www.gallanttech.com --
Re: RFC - Interpolation of method calls
On Thu, Sep 14, 2000 at 07:49:32AM -0700, Nathan Wiger wrote: print 'Today\'s weather will be '.join($", $weather-temp()). ' degrees and sunny.'; However if temp() calls wantarray(), the result will be FALSE (scalar). I think what he's trying to get at is that these should all work the same: print "Here's some @stuff"; print "Here's some $h-{stuff}"; print "Here's some $r-stuff"; That may be, but I don't think calling it in one context, accepting another, and lying about it all is the right way to go. I think I'll let the author try to explain what he had intended. print 'There is '.$obj-foo(this = $yar, that = 2 + 2). ' in my head."; Now perl is parsing full statements within strings. This already happens with: print "Here's some $h-{$stuff}"; print "Here's some $a-[$stuff + $MIN]"; So it's not that confusing, and quite consistent. Well, I still find it confusing (most probably because of the length of the examples), but it is indeed consistent. Stupid mistake on my part. Michael -- Administrator www.shoebox.net Programmer, System Administrator www.gallanttech.com --
Re: RFC 222 (v1) Interpolation of method calls
On Thu, Sep 14, 2000 at 06:37:22PM -0500, David L. Nicol wrote: A possibility that does not appear in RFC222.1 is to put tho whole accessor expression inside curlies: print "Today's weather will be ${weather-temp} degrees and sunny."; which would follow the "You want something funny in your interpolated scalar's name or reference, you put it in curlies" rule. Since the contents of that expression is not strictly \w+ it does not get interpreted as the symbol table lookup ${'weather-temp'}, so that is not a problem, nor are the whitespace situations listed in the CAVEATS section. Currently, ${weather-temp} means dereference the return value of the method 'temp' in the 'weather' class as a scalar reference (or a symbolic reference, if it's not a scalar reference and you're not using strict). Do you intend for this meaning to be taken away entirely, or to be special-cased within interpolated strings? If either I would have to heartily disagree with you; it's inconsistent, and while special cases can be a good thing when it comes to DWIM, I think we should DWIM on the side of interpolating method calls, rather than taking away existing syntax. Michael -- Administrator www.shoebox.net Programmer, System Administrator www.gallanttech.com --
Re: RFC 200 (v1) Objects: Revamp tie to support extensibility (Massive tie changes)
On Fri, Sep 08, 2000 at 04:57:46AM -, Perl6 RFC Librarian wrote: =head3 Merge CTIESCALAR, CTIEHASH, and CTIEARRAY into CTIE In practice, people rarely make a class that Cties multiple data types through the same interface. The reason is that CSTORE, CFETCH, CDESTROY, and other methods overlap. As such, it is more feasible to create several different modules; witness CTie::Array, CTie::Scalar, CApache::Session, and other modules. I'm not so sure about this. As Schwern mentioned, it'd be nice to know what exactly is being tied, and he suggested a first argument of the type. But isn't this just moving the information from the subroutine name into @_? I'd much rather Perl say "oh, you can't tie a hash, there's no TIEHASH" than be forced to switch on the first argument and raise a fatal exception if I can't support what's being tied. Instead, this RFC proposes that Ctie's operation become much more fundamental, simply translating functions via the existing indirect object syntax: tie Transaction %trans;# indirect object constructor $trans{$var} = $value ;# $obj-STORE($var, $value); lock $trans{$var}; # $obj-lock($var); Ignoring for a moment the ambiguities inherent in indirect object syntax (which we should all be aware of), what says $trans{$var} is not an object in itself, on which we want to call the lock method? =head3 Cuntie should take all references out of scope When called, Cuntie currently suffers the somewhat nasty problem of not being able to automatically destroy inner references. This means if you've mixed OO and Ctied calls, you may not be able to destroy your tied object as easily as you like. Cuntie should forceably destroy hanging references. [2] I would argue that this should be handled with weak references, and not enforced by untie(). I don't necessarily want Perl deleting my object behind my back because I untied a variable. Michael -- Administrator www.shoebox.net Programmer, System Administrator www.gallanttech.com --
Re: RFC 171 (v2) my Dog $spot should call a constructor implicitly
On Mon, Sep 04, 2000 at 10:25:37AM +0100, Piers Cawley wrote: Maybe a compromise along the lines of: my Dog $spot = LIST; # $spot = Dog-new(LIST) my Dog $patches; # $patches is undefined but we assert that # it'll be a Dog. (Whether you can do # $patches-new is left as an exercise) Where the first element of LIST is not a Dog. If you want to autocreate a null object then you can do Cmy Dog $spot = () I was trying to keep away from the $scalar = (LIST) construct calling a constructor with a list of arguments. It's very unintiutive for me. As for the latter, having on create an object and the other not seems inconsistent. It also precludes simple usage, as mentioned in the examples section: my int ($x, $y, $z); my array_ref @matrix; my int %counters; That's not polymorphism, that's inheritance. Ahh, of course, duh. Well, I don't know how you think this proposal breaks polymorphism, and at this point I don't particularly care. Given several different objects, if they all have the same method, calling the method on each will work just fine. I'm proposing an implicit constructor, not the breaking of OO. Michael -- Administrator www.shoebox.net Programmer, System Administrator www.gallanttech.com --
Re: RFC 171 (v2) my Dog $spot should call a constructor implicitly
On Sun, Sep 03, 2000 at 12:42:52PM +0200, Bart Lateur wrote: But now you're throwing away the kid with the bathwater. my Dog $spot; initially was syntax invented so that $spot was marked as only been ably to reference a Dog, with as a result that code internally could be optimized, by doing things at compile time why otherwise would need to be dealt with at runtime. (use fields, as the most notable example). Don't throw that away. Just to be clear, I'm not throwing it away. Nothing's preventing the compiler from still doing that optimization. I'm simply tacking on additional meaning, that it creates a Dog object out of $spot. It's been something of a struggle to word the RFC correctly so that it properly conveys that the old usage of my Dog $spot won't work as used currently, but the optimization can still be done. Does that make any sense? Your proposed isa(Dog) syntax is supposed to replace that syntax, while the old syntax would get new functionality. It doesn't look nice, for a start. The idea breaks the "if it does something else, give it a new name" rule. How about: my new Dog $spot; That's definitely an alternative. I don't particularly like it, but it's an alternative. That is, assuming we all (or at least, most of us) want an implicit construction mechanism. From the discussion, that doesn't seem to be the case. Michael -- Administrator www.shoebox.net Programmer, System Administrator www.gallanttech.com --
Re: RFC 171 (v2) my Dog $spot should call a constructor implicitly
On Fri, Sep 01, 2000 at 10:58:36AM -0800, Michael Fowler wrote: my $spot isa(Dog); This should be my $spot : isa(Dog); Michael -- Administrator www.shoebox.net Programmer, System Administrator www.gallanttech.com --
Re: RFC 171 (v2) my Dog $spot should call a constructor implicitly
On Fri, Sep 01, 2000 at 12:35:24PM -0700, David E. Wheeler wrote: Well then, that makes this example rather wasteful, doesn't it? It wasn't an example of how my Dog $spot should be used. I was explaining to Nate what his code was doing. my Dog $spot; if ($input eq 'Collie') { $spot = Collie-new; } elsif ($input eq 'Dalmation') { $spot = Dalmation-new; } Becuase we're creating two objects when we really only want one. Yes. That my Dog $spot should be either my $spot or my $spot : isa(Foo) (which I just recently made up) in this case. Michael -- Administrator www.shoebox.net Programmer, System Administrator www.gallanttech.com --
Re: RFC 171 (v1) my Dog $spot should call a constructor implicitly
On Tue, Aug 29, 2000 at 12:57:07PM -0700, Matt Youell wrote: So perhaps sometimes in Perl we could say: my Dog $spot = undef;# Automagically knows to be a Dog ref instead of a Dog object because of the undef. if ($age 12) { $spot = new Doberman(); } else { $spot = new Corgi(); } That's a little too special-case and magical for my tastes. What if the programmer really wants to call the constructor with an undef argument? Or what if the programmer calls my Dog $spot = $foo, expecting $foo to be defined, but it isn't? That would end up being a difficult to trace bug. Michael -- Administrator www.shoebox.net Programmer, System Administrator www.gallanttech.com --
Re: RFC 171 (v1) my Dog $spot should call a constructor implicitly
On Tue, Aug 29, 2000 at 11:04:26PM -0400, Michael Maraist wrote: First greatly stylistic compatibilty. An inexperienced programmer would see: my Dog $spot = "Spot"; And become confused. It's totally unintuitive (at least so far as other mainstream OO languages go). It looks like Dog could be a type of String subclass. Granted, the my Dog $spot = "Spot" example is a little confusing. In this specific example it doesn't make much sense to assign a value in this way. Consider, however, types: my int $i = 4; my float $f = 8.5e10; possibly even (and I'm making syntax up here): my int ($x, $y, $z) = (4, 5, 6); This general syntax is not entirely unseen, consider C: int x = 4; int x = 4, y = 5, z = 6; or C++: string foo = "bar"; The latter being an overload of the assignment operator; any arbitrary value could be there, provided you have an overload that matches it. It's up to the author of the library (or module) to make it make sense. The next most important point is that, up until this point, there has been no enforcement of the constructor name (nor for the $self name). This obviously requires it. Now there have been numerous discussions about RFCs that required such standardization. Some stronger than others. I don't think that this alone is a strong enough case to break backward compatibility (with things like DBI-connect). The constructor name is only forced (if it's not author-controlled) when using the my Dog $spot syntax. my $spot = Dog-new() isn't going anywhere. As with the above, the problem you are trying to solve is long type-names (which is a bazzar thing to find in perl anyway). I just think that there are better ways of skinning that cat. Well, if it were only long type names I'm trying to solve, Doug MacEachern submitted a patch that provides for: my __PACKAGE__ $spot = Animal::Mammal::Canine-new(); to be the equivalent long version. (At least, that's what I think it's supposed to do.) I was going for more elegance and simplicity, especially in the case of specifying types. Perhaps you can suggest some alternatives? :) Michael -- Administrator www.shoebox.net Programmer, System Administrator www.gallanttech.com --