Re: Container method calls

2004-12-06 Thread Larry Wall
On Sat, Dec 04, 2004 at 03:28:12PM -0800, Ashley Winters wrote:
: On Sat, 4 Dec 2004 11:15:14 -0800, Larry Wall [EMAIL PROTECTED] wrote:
:  On Sat, Dec 04, 2004 at 10:25:49AM -0700, Luke Palmer wrote:
:  : But this convention provides much more accuracy than memorizing a list
:  : of methods that don't automatically thread, or memorizing a list of
:  : iterator methods that act on the iterator and not its current value.
:  
:  Except that you don't actually have to memorize a list.  Methods thread
:  on their invocant only if their invocant isn't a Junction.  Its
:  mnemonic value is no better or worse than any other MMD distinction.
: 
: Is this behavior exclusive to methods? Or does something like this:
: 
: 3.14159 + 1|2;
: 
: try to MMD-dispatch to:
: 
: multi sub *infix:+ (Num $foo, Str|Int $bar)
: 
: instead of (or before) threading?

That would be an instead of, I suspect.

Larry


Container method calls

2004-12-04 Thread Ashley Winters
Howdy,

While browsing the updated synopses, I noticed a problem with how
scalar container methods are called. Currently, both value methods and
container methods are shown in the synopses as being called with
C$foo.bar().

For several reasons, that doesn't work for me. The method conflict
between container methods and value methods should be obvious. What
should ((1|2)|(34)).values return?

The answer is simple enough: for scalar container method calls, use
$foo.\bar(), which would be syntactic sugar for (\$foo).bar, and would
be the Perl6 equivalent to the Perl5 idiom tied($foo)-bar()

That way, we get:

((1|2)|(34)).values ~~ (1|3,2|4)   # (1,2)|(3,4) I presume
((1|2)|(34)).\values ~~ (1|2, 34)

@foo.\elems would work the same as @foo.elems, since @foo in scalar
context *is* the container object in the first place.

Comments?

Ashley Winters


Re: Container method calls

2004-12-04 Thread Larry Wall
On Sat, Dec 04, 2004 at 10:25:49AM -0700, Luke Palmer wrote:
: Ashley Winters writes:
:  For several reasons, that doesn't work for me. The method conflict
:  between container methods and value methods should be obvious. What
:  should ((1|2)|(34)).values return?
: 
: Well, there is an answer, and it's one I've never been extremely happy
: with.  That is, Junctions delegate everything to their junctands
: *except* a small set of methods.  .values is one of those.  So:
: 
: ((1|2)|(34)).values  returns  (1|2), (34)
: 
: And you can call values on each of those to get the others out.
: 
: In my proposal The Object Sigil, I attempted to get around this
: problem for both Junctions and iterators, using a syntactic convention.
: I later realized that you could do this with just one method.
: Presumably this method would be called the same thing for everything,
: let's say .val.
: 
: Then:
: 
: ((1|2)|(34)).values   returns
: ((1|2).values | (34).values)  which returns
: (1.values | 2.values) | (3.values  4.values)  which is an error
: 
: So instead you'd use:
: 
: ((1|2)|(34)).val.values
: 
: You can see why I wanted syntactic support.
: 
: But this convention provides much more accuracy than memorizing a list
: of methods that don't automatically thread, or memorizing a list of
: iterator methods that act on the iterator and not its current value.

Except that you don't actually have to memorize a list.  Methods thread
on their invocant only if their invocant isn't a Junction.  Its
mnemonic value is no better or worse than any other MMD distinction.

: That is:
: 
: for @foo - $i {
: $i.next; # call .next on the current value in @foo
: $i.val.next; # call .next on the iterator
: 
: # let's say @foo is a list of iterators!
: $i.next; # call .next on the value pointed to by the iterator in 
@foo
: $i.val.next; # call .next on the iterator $i
: $i.val.deref.val.next;  # call .next on the iterator in @foo
: }
: 
: Yeah, the last one is a mouthfull, but let's see you do that *at all*
: with the other semantics.

We can't have semantics where an object keeps track of what container
it's in.  What if it's in more than one container?

The only reason a tied()-like operator works is that it's not really
a run-time operator at all.

: Anyway, there's something to think about.  Moving on...
: 
:  The answer is simple enough: for scalar container method calls, use
:  $foo.\bar(), which would be syntactic sugar for (\$foo).bar, and would
:  be the Perl6 equivalent to the Perl5 idiom tied($foo)-bar()
: 
: Er, hmm.  See, that doesn't solve your junction problem.  Junction is a
: value, and it's different from the scalar container it goes in.
: 
: Differentiating method calls on arrays and hashes and on their values is
: easy:
: 
: @array.sort;
: @array[0].sort;
: 
: It's scalars which are the problem.  /A1?2/ said that you actually do
: use:
: 
: tied($foo).bar;
: 
: So, well, there you go.  

Except that S12 currently has that as var() instead of tied().

: It'd be nice to have some nicer way than tied($foo).bar, though.  I
: think we should see how often it comes up in the real world (or the
: theoretical world) before we jump to adding a new operator on it.

Agreed.

Larry


Re: Container method calls

2004-12-04 Thread Ashley Winters
On Sat, 4 Dec 2004 11:15:14 -0800, Larry Wall [EMAIL PROTECTED] wrote:
 On Sat, Dec 04, 2004 at 10:25:49AM -0700, Luke Palmer wrote:
 : But this convention provides much more accuracy than memorizing a list
 : of methods that don't automatically thread, or memorizing a list of
 : iterator methods that act on the iterator and not its current value.
 
 Except that you don't actually have to memorize a list.  Methods thread
 on their invocant only if their invocant isn't a Junction.  Its
 mnemonic value is no better or worse than any other MMD distinction.

Is this behavior exclusive to methods? Or does something like this:

3.14159 + 1|2;

try to MMD-dispatch to:

multi sub *infix:+ (Num $foo, Str|Int $bar)

instead of (or before) threading?

Ashley Winters


Re: Container method calls

2004-12-04 Thread Luke Palmer
Larry Wall writes:
 : But this convention provides much more accuracy than memorizing a list
 : of methods that don't automatically thread, or memorizing a list of
 : iterator methods that act on the iterator and not its current value.
 
 Except that you don't actually have to memorize a list.  Methods thread
 on their invocant only if their invocant isn't a Junction.  Its
 mnemonic value is no better or worse than any other MMD distinction.

Well, except that you do have to memorize a list.  But, yeah, you
basically do have to memorize a list of all MMD functions that take
junctions...  so, I guess, sortof 

 : That is:
 : 
 : for @foo - $i {
 : $i.next; # call .next on the current value in @foo
 : $i.val.next; # call .next on the iterator
 : 
 : # let's say @foo is a list of iterators!
 : $i.next; # call .next on the value pointed to by the iterator 
 in @foo
 : $i.val.next; # call .next on the iterator $i
 : $i.val.deref.val.next;  # call .next on the iterator in @foo
 : }
 : 
 : Yeah, the last one is a mouthfull, but let's see you do that *at all*
 : with the other semantics.
 
 We can't have semantics where an object keeps track of what container
 it's in.  What if it's in more than one container?

That's not what I'm talking about.  I'm just saying that .val is the one
method that doesn't delegate when you're an iterator:

$i   ==  the iterator
$i.val   ==  the iterator without delegation ability
$i.val.deref ==  what the iterator points to without the .val method

It's just a way of making things concrete in delegates so that they
delegate in all but one simple case (for when you need to talk to the
delegate itself).

What I'm really worried about is:

my $meth = get_method();   # say it returns values
my $rets = (1|2).::($meth);

And instead of getting a junction in $rets like you would for *any other
method*, you get a list.  It's a spooky, inconsistent,
hard-to-work-around special case. 

And come to think of it, .val doesn't really solve that either.

You can see why I wanted syntactic support :-)

I don't really care how ugly it is though, I just want it.  If we can
make it into a method or routine or something, that's fine, as long as
we can get it consistent.  No, not consistent, *predictable*.

Note that with  delegate-style iterator semantics, it is *not possible*
to manipulate an iterator through another iterator.  There's some famous
Perl quote about things being possible...

 Except that S12 currently has that as var() instead of tied().

Cool.