Re: RFC 222 (v1) Interpolation of method calls

2000-09-15 Thread Michael Fowler

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

2000-09-15 Thread Michael Fowler

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

2000-09-14 Thread Michael Fowler

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

2000-09-14 Thread Michael Fowler

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

2000-09-14 Thread Michael Fowler

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)

2000-09-08 Thread Michael Fowler

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

2000-09-04 Thread Michael Fowler

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

2000-09-03 Thread Michael Fowler

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

2000-09-01 Thread Michael Fowler

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

2000-09-01 Thread Michael Fowler

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

2000-08-30 Thread Michael Fowler

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

2000-08-29 Thread Michael Fowler

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
--