Re: Clarification of S04 closure traits

2009-07-28 Thread Ben Morrow

Moritz Lenz wrote:

Ben Morrow wrote:


- Presumably when an exception is thrown through a block, the LEAVE and
  POST queues are called (in that order).


POST was inspired from the Design By Contract department, and are meant
to execute assertions on the result. If you leave a block through an
exception you don't have a result, so I don't think running a POST block
makes sense.


OK, if POST is only for asserting on the return value that would make 
sense. But I thought POST was also supposed to be able to assert that 
global state had been left as it should, in which case it should be run 
even on exceptional exit? I'm not sure how any given POST block is 
supposed to distinguish between an ordinary undef return and an 
exception, though, to avoid checking the return value. Some sort of 
guarantee that $! is undef in a POST block unless an exception is 
currently being thrown might be helpful, but I'm not sure how that 
interacts with the Perl 6 exception model as a whole.



I'm not sure about running LEAVE blocks either, because that's what
CATCH blocks are for.


LEAVE blocks I am certain *should* be run, no matter how the block is 
exitted (well, unless a PRE fails: see below). They are equivalent to 
'finally' blocks in other languages, and AIUI they are for cleanup: 
closing files, tearing down database connections and the like.



What if a PRE block fails: is
  the POST queue on the same block called? (Do you have to satisfy your
  post-conditions even if your pre-conditions failed?)


I'd say that if a PRE block fails, nothing else is run (neither LEAVE
nor POST nor ...)


I agree that none of ENTER, LEAVE or the main body of the block should 
be run. However, if a POST block is asserting, say, that a global holds 
a valid value, shouldn't that still be checked even if your 
preconditions failed? I admit I haven't read much about DBC.



- If a POST block is called as a result of a thrown exception, and it
  fails, which exception 'wins'?


Question obsoleted by previous answer ;-)


...maybe :).


- Can a try block catch an exception thrown from its own ENTER or LEAVE
  queue? 


Yes.


OK. What about PRE/POST? It seems wrong somehow to be able to catch 
failure of your own pre-/post-conditions: they are meant for the caller 
to catch. Does that seem right?


Ben



confusing list assignment tests

2009-07-28 Thread Moritz Lenz
I'm in the mood to question my sanity, so I'm seeking feedback for some
test mangling:

In t/spec/S03-operators/assign.t there are some tests that cause me a
headache. I'm trying to re-write them to not use the now-gone want()
function, but I'd have to understand them first ;-)

A good example is this one:

sub W () { substr(eval('want'), 0, 1) }
...

# line 560:
{
my @a;
my @z = (@a[0] = W, W);
#?rakudo 2 todo 'want function'
is(@a, 'L','lhs treats @a[0] as list');
is(@z[0], 'L', 'lhs treats @a[0] as list');
ok(!defined(@z[1]), 'lhs treats @a[0] as list');
}


This tests that
1) both calls to want() are in list context
2) @a[0] gets only the return value of the first call to W()
3) @z[0] gets the same thing
4) There's no item for @z[1]

Somehow I think this test (and many similar tests) are dead wrong.
Here's why:

Either it's parsed as '@a[0] = (W, W)' (list assignment), then @a should
get both elements, and so should @z.
Or it's parsed as '(@a[0] = W), W' (item assignment), then the first
call should be in item context, and the second one in list context, and
@z should still get both items.
Right? Or am I completely missing something important here?

My current plan is to write such tests as

sub l { 1, 2 } # return a short list
{
my @a;
my @z = (@a[0] = l(), l());
is @a[0].elems, 4, '@a[0] =  treats LHS as list'
is @z.elems,4, '... and passes all elements on the right';
}

Does this look sane, and match your understanding of assignment?

Cheers,
Moritz


r27784 - docs/Perl6/Spec

2009-07-28 Thread pugs-commits
Author: pmichaud
Date: 2009-07-28 21:45:55 +0200 (Tue, 28 Jul 2009)
New Revision: 27784

Modified:
   docs/Perl6/Spec/S04-control.pod
Log:
Fix incorrect specification of implicit $_ in blocks.


Modified: docs/Perl6/Spec/S04-control.pod
===
--- docs/Perl6/Spec/S04-control.pod 2009-07-28 19:37:57 UTC (rev 27783)
+++ docs/Perl6/Spec/S04-control.pod 2009-07-28 19:45:55 UTC (rev 27784)
@@ -44,7 +44,7 @@
 (either explicitly or implicitly) is treated as though C<$_> were a
 formal parameter:
 
-$func = { .print if $_ };   # Same as: $func = -> $_ { .print if $_ };
+$func = { .print if $_ };   # Same as: $func = <-> $_ { .print if $_ };
 $func("printme");
 
 In any case, all formal parameters are the equivalent of C variables



Re: confusing list assignment tests

2009-07-28 Thread Larry Wall
On Tue, Jul 28, 2009 at 09:24:40PM +0200, Moritz Lenz wrote:
: sub W () { substr(eval('want'), 0, 1) }
: ...
: 
: # line 560:
: {
: my @a;
: my @z = (@a[0] = W, W);
: #?rakudo 2 todo 'want function'
: is(@a, 'L','lhs treats @a[0] as list');
: is(@z[0], 'L', 'lhs treats @a[0] as list');
: ok(!defined(@z[1]), 'lhs treats @a[0] as list');
: }
: 
: 
: This tests that
: 1) both calls to want() are in list context
: 2) @a[0] gets only the return value of the first call to W()
: 3) @z[0] gets the same thing
: 4) There's no item for @z[1]
: 
: Somehow I think this test (and many similar tests) are dead wrong.
: Here's why:
: 
: Either it's parsed as '@a[0] = (W, W)' (list assignment), then @a should
: get both elements, and so should @z.

Not according to S03, at least by one reading.  @a[0] as a scalar
container only wants one item, so it only takes the first item off
the list, and the list assignment produces a warning on the second
because it's discarded.  Since an assignment returns its left side,
only one element is available to @z from @a[0].

: Or it's parsed as '(@a[0] = W), W' (item assignment), then the first
: call should be in item context, and the second one in list context, and
: @z should still get both items.

It's not parsed like that, because only $x, $$xref, $($xref) and such
are allowed targets for item assignment.  Basically, it has to start
with a $ sigil and not do anything fancy like subscripting.   However,
if you say

@z = $x = $a, $b;

it parses as @z = ($x = $a), $b and $b ends up in @z[1] but not
in $x, which only gets $a.

: Right? Or am I completely missing something important here?

To get all the elements into $x you'd have to say

@z = $x = ($a, $b);

and @z[0] would be ($a,$b) with some type or other, whatever was
returned by the parens, quite possibly Parcel (that is, List of Thunk
or some such).

: My current plan is to write such tests as
: 
: sub l { 1, 2 } # return a short list
: {
: my @a;
: my @z = (@a[0] = l(), l());
: is @a[0].elems, 4, '@a[0] =  treats LHS as list'
: is @z.elems,4, '... and passes all elements on the right';
: }
: 
: Does this look sane, and match your understanding of assignment?

Yes, but no.  @z.elems and @a[0].elems should both be 1, I suspect.
I wish we had a way of trapping and testing warnings too so we could
see that 3 elements were discarded by the inner list assignment..

Larry


Re: confusing list assignment tests

2009-07-28 Thread Jon Lang
Larry Wall wrote:
> Moritz Lenz wrote:
> : Either it's parsed as '@a[0] = (W, W)' (list assignment), then @a should
> : get both elements, and so should @z.
>
> Not according to S03, at least by one reading. �...@a[0] as a scalar
> container only wants one item, so it only takes the first item off
> the list, and the list assignment produces a warning on the second
> because it's discarded.  Since an assignment returns its left side,
> only one element is available to @z from @a[0].

So, do we still have p5's 'want_array' (or whatever it was called)?
That is, the predicate that tells the you whether the function is
being called in item or list context?  I know that the generalized
'want' function proved to be unworkable; but I'd expect p6 to at least
be able to do everything that p5 can do; and that includes functions
that are aware of whether they're being used as singular or plural.

-- 
Jonathan "Dataweaver" Lang


Re: confusing list assignment tests

2009-07-28 Thread Moritz Lenz
Thanks for the quick reply.

Larry Wall wrote:
> On Tue, Jul 28, 2009 at 09:24:40PM +0200, Moritz Lenz wrote:
> : sub W () { substr(eval('want'), 0, 1) }
> : ...
> : 
> : # line 560:
> : {
> : my @a;
> : my @z = (@a[0] = W, W);
> : #?rakudo 2 todo 'want function'
> : is(@a, 'L','lhs treats @a[0] as list');
> : is(@z[0], 'L', 'lhs treats @a[0] as list');
> : ok(!defined(@z[1]), 'lhs treats @a[0] as list');
> : }
> : 
> : 
> : This tests that
> : 1) both calls to want() are in list context
> : 2) @a[0] gets only the return value of the first call to W()
> : 3) @z[0] gets the same thing
> : 4) There's no item for @z[1]
> : 
> : Somehow I think this test (and many similar tests) are dead wrong.
> : Here's why:
> : 
> : Either it's parsed as '@a[0] = (W, W)' (list assignment), then @a should
> : get both elements, and so should @z.
> 
> Not according to S03, at least by one reading.  @a[0] as a scalar
> container only wants one item, so it only takes the first item off
> the list, and the list assignment produces a warning on the second
> because it's discarded.  Since an assignment returns its left side,
> only one element is available to @z from @a[0].

So it's parsed like a list assignment, but list-assigning to a scalar
container doesn't promote the whole RHS to a Capture (or whatever it
ends up being) as it would do in the case of item assignment, but takes
one item off. OK.

I guess when I initialize @a[0] = [] it's the same, because then @a[0]
is still a scalar, right?
Only when I wrote @a[0] := [] I'd get all items in @a[0].

> : Or it's parsed as '(@a[0] = W), W' (item assignment), then the first
> : call should be in item context, and the second one in list context, and
> : @z should still get both items.
> 
> It's not parsed like that, because only $x, $$xref, $($xref) and such
> are allowed targets for item assignment.  Basically, it has to start
> with a $ sigil and not do anything fancy like subscripting.   However,
> if you say
> 
> @z = $x = $a, $b;
> 
> it parses as @z = ($x = $a), $b and $b ends up in @z[1] but not
> in $x, which only gets $a.
> 
> : Right? Or am I completely missing something important here?
> 
> To get all the elements into $x you'd have to say
> 
> @z = $x = ($a, $b);
> 
> and @z[0] would be ($a,$b) with some type or other, whatever was
> returned by the parens, quite possibly Parcel (that is, List of Thunk
> or some such).

Ok, that makes sense to me.

> : My current plan is to write such tests as
> : 
> : sub l { 1, 2 } # return a short list
> : {
> : my @a;
> : my @z = (@a[0] = l(), l());
> : is @a[0].elems, 4, '@a[0] =  treats LHS as list'
> : is @z.elems,4, '... and passes all elements on the right';
> : }
> : 
> : Does this look sane, and match your understanding of assignment?
> 
> Yes, but no.  @z.elems and @a[0].elems should both be 1, I suspect.
> I wish we had a way of trapping and testing warnings too so we could
> see that 3 elements were discarded by the inner list assignment..
> 
> Larry

Cheers,
Moritz


Re: confusing list assignment tests

2009-07-28 Thread Mark J. Reed
My understanding is that the P6 way to do that is to return a Capture
containing the desired return values (which can lazily do things only
when accessed) in the appropriate slots.

On 7/28/09, Jon Lang  wrote:
> Larry Wall wrote:
>> Moritz Lenz wrote:
>> : Either it's parsed as '@a[0] = (W, W)' (list assignment), then @a should
>> : get both elements, and so should @z.
>>
>> Not according to S03, at least by one reading. �...@a[0] as a scalar
>> container only wants one item, so it only takes the first item off
>> the list, and the list assignment produces a warning on the second
>> because it's discarded.  Since an assignment returns its left side,
>> only one element is available to @z from @a[0].
>
> So, do we still have p5's 'want_array' (or whatever it was called)?
> That is, the predicate that tells the you whether the function is
> being called in item or list context?  I know that the generalized
> 'want' function proved to be unworkable; but I'd expect p6 to at least
> be able to do everything that p5 can do; and that includes functions
> that are aware of whether they're being used as singular or plural.
>
> --
> Jonathan "Dataweaver" Lang
>

-- 
Sent from my mobile device

Mark J. Reed 


Re: confusing list assignment tests

2009-07-28 Thread Moritz Lenz
Jon Lang wrote:
> Larry Wall wrote:
>> Moritz Lenz wrote:
>> : Either it's parsed as '@a[0] = (W, W)' (list assignment), then @a should
>> : get both elements, and so should @z.
>>
>> Not according to S03, at least by one reading.  @a[0] as a scalar
>> container only wants one item, so it only takes the first item off
>> the list, and the list assignment produces a warning on the second
>> because it's discarded.  Since an assignment returns its left side,
>> only one element is available to @z from @a[0].
> 
> So, do we still have p5's 'want_array' (or whatever it was called)?

No.

> That is, the predicate that tells the you whether the function is
> being called in item or list context?  I know that the generalized
> 'want' function proved to be unworkable; but I'd expect p6 to at least
> be able to do everything that p5 can do; and that includes functions
> that are aware of whether they're being used as singular or plural.

The problem is that it's impossible in Perl 6, because we have multi
dispatch.

Consider this simple case:

multi a(@a*){  } # provides list context onto the arguments
multi a(Str $x) {  } # provides Str context or at least some sort of
 # item context on the argument
sub b() { }
a(b());  # you can't know which context b() is called in

since the multi dispatch to a() depends on the return value of b(), we
only know b()'s context after we know its return value - which is too late.

So the "active" context propagation that Perl 5 does is not possible in
Perl 6.

Cheers,
Moritz


Re: confusing list assignment tests

2009-07-28 Thread Damian Conway
Mark J. Reed wrote:

> My understanding is that the P6 way to do that is to return a Capture
> containing the desired return values (which can lazily do things only
> when accessed) in the appropriate slots.

Return a Capture or a more heavily overloaded object, depending on how
fine a degree of context discrimination you need.

Further to that idea, I'm actually planning to attempt to port
Contextual::Return to Perl 6 in the next few weeks.

Damian


Re: confusing list assignment tests

2009-07-28 Thread Larry Wall
On Tue, Jul 28, 2009 at 01:22:28PM -0700, Jon Lang wrote:
: Larry Wall wrote:
: > Moritz Lenz wrote:
: > : Either it's parsed as '@a[0] = (W, W)' (list assignment), then @a should
: > : get both elements, and so should @z.
: >
: > Not according to S03, at least by one reading. �...@a[0] as a scalar
: > container only wants one item, so it only takes the first item off
: > the list, and the list assignment produces a warning on the second
: > because it's discarded.  Since an assignment returns its left side,
: > only one element is available to @z from @a[0].
: 
: So, do we still have p5's 'want_array' (or whatever it was called)?
: That is, the predicate that tells the you whether the function is
: being called in item or list context?  I know that the generalized
: 'want' function proved to be unworkable; but I'd expect p6 to at least
: be able to do everything that p5 can do; and that includes functions
: that are aware of whether they're being used as singular or plural.

Perl 6 is not about doing everything that Perl 5 can do.  It's about
breaking everything that needs breaking.  This is one of those things.

We *may* have something like want someday, but if so, it can only
work by time travel (read: return a type profile with lazy values,
and let the eventual binding of the type profile call back for the
actual values).  But I doubt will require such for 6.0.0 in any case.

But Perl 6 is based on knowing the types to do MMD, and we have to know
at least those types, even if we don't know the values.  That makes
it very difficult for a function that wants to return *different*
types based on the eventual dispatch, since the eventual dispatch
depends on those types in a circular sort of way.  Sanity dictates
that we make time flow forward rather than backward for most of what
Perl 6 programmers will want to do most of the time.

Larry


Re: confusing list assignment tests

2009-07-28 Thread Jon Lang
Damian Conway wrote:
> Mark J. Reed wrote:
>> My understanding is that the P6 way to do that is to return a Capture
>> containing the desired return values (which can lazily do things only
>> when accessed) in the appropriate slots.
>
> Return a Capture or a more heavily overloaded object, depending on how
> fine a degree of context discrimination you need.
>
> Further to that idea, I'm actually planning to attempt to port
> Contextual::Return to Perl 6 in the next few weeks.

Right.  I don't think that a Capture has sufficiently fine context
discrimination to handle even those cases that Perl 5 was able to
handle.  For instance, consider a function that's intended to return a
list of items in list context, or a count of the items in item
context: since imposing item context on a Capture object extracts the
first positional parameter, a Capture object wouldn't be able to be
loaded properly to do this.  So something along the lines of
Contextual::Return is probably a good idea.

Hmm... it might be nice to be able to use something akin to a "given
... when" construct:

sub foo() {
return context {
when Item { 5 }
when List { a, b, c, d, e }
}
}

The idea here is that the 'context' keyword means that the block is to
be called as soon as the desired context is known, with said context
being passed to the block as its topic ('$_').

-- 
Jonathan "Dataweaver" Lang


Re: confusing list assignment tests

2009-07-28 Thread Larry Wall
On Tue, Jul 28, 2009 at 10:42:01PM +0200, Moritz Lenz wrote:
: I guess when I initialize @a[0] = [] it's the same, because then @a[0]
: is still a scalar, right?

No, as in Perl 5 [] still produces a scalar object that hides the arrayness
from list context, so it's like:

$b = [];
@a[0] = $b;

It doesn't unwrap the scalar object to see what's in it.

: Only when I wrote @a[0] := [] I'd get all items in @a[0].

That binds the Array in place of the current @a[0] container, just as

$b = [];
@a[0] := $b;

would.

Just as $obj and @$obj default differently in list context, so do
[] and ().  To put it another way, Array and Hash objects don't
naturally interpolate into list context without some help from @ or %
syntax (or equivalent method call).  If I say:

@a = 42, [1,2,3], { foo => 1, bar => 2, baz => 3 };

then @a will always end up with exactly 3 elements, just as if I'd
said:


$a = 42;
$b = [1,2,3];
$c = { foo => 1, bar => 2, baz => 3 };
@a = $a, $b, $c;

Larry