Does a string remember all Unicode levels?

2009-08-08 Thread Moritz Lenz
t/spec/S02-builtin_data_types/unicode.t has tests like this:

# LATIN CAPITAL LETTER A, COMBINING GRAVE ACCENT
my Str $u = \x[0041,0300];
is $u.bytes, 3, 'combining À is three bytes as utf8';
is $u.codes, 2, 'combining À is two codes';
is $u.graphs, 1, 'combining À is one graph';

Which seems to imply that a Str remembers its codepoints, even if it is
in grapheme mode (because that's the default).

Is this correct? I don't really think that's sensible. I'd expect  a
compiler to store strings in composed normalization (+ NFG), so $u.codes
would be 1.

Cheers,
Moritz


[perl #68274] Script runs for ~18,000 iterations then seg faults

2009-08-08 Thread via RT
# New Ticket Created by  Solomon Foster 
# Please include the string:  [perl #68274]
# in the subject line of all future correspondence about this issue. 
# URL: http://rt.perl.org/rt3/Ticket/Display.html?id=68274 


use v6;

loop (my $n = 2; $n = 354294; $n++)
{
my @digits = $n.comb(/\d/);
my $sum = [+] (@digits ** 5);
say $n, $sum if ($n % 1234 == 0);
say $n = sum of its digits to the 5th power!!! if ($sum == $n);
}

This simple Project Euler script dies with Segmentation fault after
18,000 iterations or so.

Platform: Mac OS X 10.5.6.
Chicago release of Rakudo.

-- 
Solomon Foster: colo...@gmail.com
HarmonyWare, Inc: http://www.harmonyware.com


[perl #68292] [PATCH] splice (and tests) fixed

2009-08-08 Thread via RT
# New Ticket Created by  dakkar 
# Please include the string:  [perl #68292]
# in the subject line of all future correspondence about this issue. 
# URL: http://rt.perl.org/rt3/Ticket/Display.html?id=68292 


here is the first patch that I wrote in Lisbon: splice works.

I already committed the splice.t spectest into the pugs repository.
From 888786de06a14b7616999a6e84a4f3e79f0941d6 Mon Sep 17 00:00:00 2001
From: dakkar dak...@sardina.(none)
Date: Thu, 6 Aug 2009 19:50:44 +0200
Subject: [PATCH] splice now works

---
 src/setting/Array.pm |   19 ++-
 t/spectest.data  |1 +
 2 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/src/setting/Array.pm b/src/setting/Array.pm
index 2a8fb28..0c27786 100644
--- a/src/setting/Array.pm
+++ b/src/setting/Array.pm
@@ -1,12 +1,17 @@
+# is export on Array does not work (it's Perl6Array internally)
+
 class Array is also {
-multi method splice(@array is rw: $offset = 0, $size = @array.elems - $offset, *...@values) is export {
+multi method splice(@array is rw: $offset is copy = 0, $size? is copy, *...@values) {
 my @spliced;
 my @deleted;
 
-my $off = ($offset  @array.end) ?? @array.end !! $offset;
-my $len = $size;
-@spliced.push(@array.shift) while ($off--  0  @array);
-@deleted.push(@array.shift) while ($len--  0  @array);
+$offset += @array.elems if $offset  0;
+$offset = @array.elems min floor($offset);
+$size += @array.end if $size  0;
+$size = floor( $size // (@array.elems - $offset) );
+
+@spliced.push(@array.shift) while (--$offset = 0  @array);
+@deleted.push(@array.shift) while (--$size = 0  @array);
 @spliced.push(@values) if @values;
 @spliced.push(@array) if @array;
 
@@ -15,4 +20,8 @@ class Array is also {
 }
 }
 
+multi splice(@array is rw, $offset?, $size?, *...@values) {
+@array.splice($offset,$size,@values);
+}
+
 # vim: ft=perl6
diff --git a/t/spectest.data b/t/spectest.data
index b202c01..dad03c1 100644
--- a/t/spectest.data
+++ b/t/spectest.data
@@ -379,6 +379,7 @@ S32-array/pop.t
 S32-array/push.t
 S32-array/rotate.t
 S32-array/shift.t
+S32-array/splice.t
 S32-array/unshift.t
 S32-container/zip.t
 S32-hash/exists.t
-- 
1.5.6.3



signature.asc
Description: PGP signature


[perl #68290] [BUG] Rakudo should also warn about redefinition of regex/token/rule and methods

2009-08-08 Thread via RT
# New Ticket Created by  Hanno Hecker 
# Please include the string:  [perl #68290]
# in the subject line of all future correspondence about this issue. 
# URL: http://rt.perl.org/rt3/Ticket/Display.html?id=68290 



$ cat test.p6
use v6;
class A { sub a { say a }; sub a { say a } }
grammar B { token b { 'b' }; token b { 'b' } };
class C { method c { say c }; method c { say c } }
### vim: ft=perl6 ts=4 sw=4 expandtab
$ ./perl6 test.p6 
Redefinition of routine a
$


[perl #68306] Rakudo 2009-07

2009-08-08 Thread via RT
# New Ticket Created by  Aaron Sherman 
# Please include the string:  [perl #68306]
# in the subject line of all future correspondence about this issue. 
# URL: http://rt.perl.org/rt3/Ticket/Display.html?id=68306 


I'm working in a firewalled environment today where I can't get access to
git, so here's what I see in 2009-07 downloaded from
http://github.com/rakudo/rakudo/downloads

S12 says:

The .^methods method returns method-descriptors containing:

namethe name of the method
signature   the parameters of the method
as  the coercion type of the method
multi   whether duplicate names are allowed
do  the method body



That doesn't tell me exactly what I'm looking for, but I tried:

 say Str.^methods[0]
sprintf

Which looks suspiciously like a single string, but just in case, I tried:

 say Str.^methods[0]signature
get_pmc_keyed() not implemented in class 'Sub'
in Main (unknown:1)
 say Str.^methods[0].^signature
Method 'signature' not found for invocant of class 'P6metaclass'
 say Str.^methods[0].signature
No signature found

That last one looks more promising, but still not quite as advertised. Oddly
enough if I try another one of the descriptors listed, it gets stranger:

 say Str.^methods[0].name
pred

eh? The rest of the names (as, multi, do) don't seem to exist at all. I
expect that this is because I'm not actually looking at a descriptor at
all, but rather a Sub object that stringifies itself to sprintf. Is that a
bug in Rakudo or S12?


[perl #68296] [PATCH] pick in the setting

2009-08-08 Thread via RT
# New Ticket Created by  dakkar 
# Please include the string:  [perl #68296]
# in the subject line of all future correspondence about this issue. 
# URL: http://rt.perl.org/rt3/Ticket/Display.html?id=68296 


third patch from Lisbon: pick in the setting
From 884a1799328f2bccaf7ec06d1910c4360227c625 Mon Sep 17 00:00:00 2001
From: dakkar dak...@sardina.(none)
Date: Thu, 6 Aug 2009 18:43:09 +0200
Subject: [PATCH] moved pick to setting

---
 src/builtins/any-list.pir |   90 -
 src/setting/Any-list.pm   |   39 +++
 2 files changed, 39 insertions(+), 90 deletions(-)

diff --git a/src/builtins/any-list.pir b/src/builtins/any-list.pir
index cd78d87..6cbefd6 100644
--- a/src/builtins/any-list.pir
+++ b/src/builtins/any-list.pir
@@ -94,96 +94,6 @@ Return a List with the keys of the invocant.
 signature.!add_implicit_self($P0)
 .end
 
-=item pick($num, :$repl)
-
-=cut
-
-.namespace []
-.sub 'pick' :multi(_)
-.param int p_num
-.param pmc values  :slurpy
-.param pmc p_repl  :optional :named('repl')
-.param int has_repl:opt_flag
-if has_repl goto have_repl
-p_repl = get_hll_global ['Bool'], 'False'
-  have_repl:
-.tailcall values.'pick'(p_num, 'repl'=p_repl)
-.end
-
-.sub 'pick' :multi('Whatever')
-.param pmc whatever
-.param pmc values  :slurpy
-.param pmc p_repl  :optional :named('repl')
-.param int has_repl:opt_flag
-unless has_repl goto no_repl
-unless p_repl goto no_repl
-die Infinite lazy pick not implemented
-  no_repl:
-.tailcall values.'pick'(whatever)
-.end
-
-.namespace ['Any']
-.sub 'pick' :method :multi()
-.param int p_num   :optional
-.param int has_num :opt_flag
-.param pmc p_repl  :optional :named('repl')
-.param int has_repl:opt_flag
-
-.local pmc list, result, rand
-.local int elems
-list = self.'list'()
-elems = list.'elems'()
-result = 'list'()
-rand = get_hll_global ['Any'], '$!random'
-
-if has_num goto have_num
-p_num = 1
-  have_num:
-
-.local int repl
-repl = 0
-unless has_repl goto have_repl
-repl = istrue p_repl
-  have_repl:
-if repl goto skip_clone
-list = clone list
-  skip_clone:
-
-  loop:
-unless p_num  0 goto done
-unless elems  0 goto done
-$N0 = rand
-$N0 *= elems
-$I0 = $N0
-$P0 = list[$I0]
-push result, $P0
-dec p_num
-if repl goto loop
-delete list[$I0]
-elems = list.'elems'()
-goto loop
-  done:
-$I0 = result.'elems'()
-dec $I0
-unless $I0 goto single_item
-.return (result)
-  single_item:
- $P0 = result[0]
-.return ($P0)
-.end
-
-.sub 'pick' :method :multi(_, 'Whatever')
-.param pmc whatever
-.param pmc p_repl  :optional :named('repl')
-.param int has_repl:opt_flag
-unless has_repl goto no_repl
-unless p_repl goto no_repl
-die Infinite lazy pick not implemented
-  no_repl:
-$I0 = self.'elems'()
-.tailcall self.'pick'($I0)
-.end
-
 =item sort()
 
 Sort list.  In this case we copy into an FPA to make use of the
diff --git a/src/setting/Any-list.pm b/src/setting/Any-list.pm
index 9a9431a..18a31e2 100644
--- a/src/setting/Any-list.pm
+++ b/src/setting/Any-list.pm
@@ -36,6 +36,37 @@ class Any is also {
 }
 }
 
+multi method pick(Int $num is copy = 1, :$repl) {
+
+$num=floor($num);
+
+if ($num == 1) {
+return @.list[floor(@.list.elems.rand)];
+}
+
+my @l;
+if ($repl) {
+@l := @.list;
+}
+else {
+@l = @.list;
+}
+
+gather {
+while ($num  0 and @l.elems  0) {
+my $idx = floor(@l.elems.rand());
+take @l[$idx];
+@l.splice($idx,1) unless $repl;
+--$num;
+}
+}
+}
+
+multi method pick(Whatever $, :$repl) {
+die Infinite lazy pick not implemented if $repl;
+@.pick(@.elems);
+}
+
 # RT #63700 - parse failed on infix:cmp
 multi method max( $values: Code $by = sub { $^a cmp $^b } ) {
  my @list = $values.list;
@@ -152,6 +183,14 @@ our List multi map(Code $expr, *...@values) {
 @values.map($expr)
 }
 
+multi pick(Int $num, :$repl, *...@values) {
+@values.pick($num,:repl($repl));
+}
+
+multi pick(Whatever $, :$repl, *...@values) {
+@values.pick(*,:repl($repl));
+}
+
 multi max(Code $by, *...@values) {
 @values.max($by);
 }
-- 
1.5.6.3



signature.asc
Description: PGP signature


[perl #62178] gather/take does not work with loop, either

2009-08-08 Thread Solomon Foster
rakudo: my @a = gather loop (my $i = 1; $i  10; $i++) { take $i }; @a.perl.say;
p6eval: rakudo 7717c4: OUTPUT«[10, 10, 10, 10, 10, 10, 10, 10, 10]␤»

-- 
Solomon Foster: colo...@gmail.com
HarmonyWare, Inc: http://www.harmonyware.com


[perl #68320] [BUG] TODO: $!.pending not implemented (yet)

2009-08-08 Thread via RT
# New Ticket Created by  Ben Petering 
# Please include the string:  [perl #68320]
# in the subject line of all future correspondence about this issue. 
# URL: http://rt.perl.org/rt3/Ticket/Display.html?id=68320 


eval 'widdle()';
eval 'waddle()';

say pending:  ~ $!.pending.perl;

... gives ...

Method 'pending' not found for invocant of class 'Exception'



[perl #68298] Null PMC bug when code confused as hash

2009-08-08 Thread via RT
# New Ticket Created by  Solomon Foster 
# Please include the string:  [perl #68298]
# in the subject line of all future correspondence about this issue. 
# URL: http://rt.perl.org/rt3/Ticket/Display.html?id=68298 


colomon: rakudo: (1..3).map({$_ = $_*$_}).perl.say
p6eval: rakudo e5a63d: OUTPUT«Use of uninitialized value␤Use of
uninitialized value␤Use of uninitialized value␤Null PMC access in
invoke()␤in Main (/tmp/xCUuiEBOsh:2)␤»

I understand that this code should not work, but it shouldn't Null PMC
access either.

On the other hand, not sure if this one should work or not:

colomon: rakudo: (1..3).map({$_ = $_*$_;}).perl.say
p6eval: rakudo e5a63d: OUTPUT«Use of uninitialized value␤Use of
uninitialized value␤Use of uninitialized value␤Null PMC access in
invoke()␤in Main (/tmp/8McBNVU08o:2)␤»

-- 
Solomon Foster: colo...@gmail.com
HarmonyWare, Inc: http://www.harmonyware.com


[perl #68318] [BUG] use exceptions not handled correctly within try block

2009-08-08 Thread via RT
# New Ticket Created by  Ben Petering 
# Please include the string:  [perl #68318]
# in the subject line of all future correspondence about this issue. 
# URL: http://rt.perl.org/rt3/Ticket/Display.html?id=68318 


# Normal exception in try {} is caught
BEGIN {
 try {
 widdle;
 CATCH {
 say caught: $!;
 }
 }
}

# But use is not.
BEGIN {
 try {
 use NonExistent; # dies, not caught.
 CATCH {
 say caught: $!;
 }
 }
}

Output (with Rakudo pulled 2009-08-08 06:40 UTC, how on earth do you  
specify revisions with git?)

 caught: Could not find non-existent sub widdle
 Can't find ./NonExistent in @*INC
 in Main (src\gen_setting.pm:445)

(I'm not sure if this is correct, but I'm struggling to imagine why  
this would be useful behavior.)



Re: [perl #68306] Rakudo 2009-07

2009-08-08 Thread Moritz Lenz


Aaron Sherman (via RT) wrote:
 # New Ticket Created by  Aaron Sherman 
 # Please include the string:  [perl #68306]
 # in the subject line of all future correspondence about this issue. 
 # URL: http://rt.perl.org/rt3/Ticket/Display.html?id=68306 
 
 
 I'm working in a firewalled environment today where I can't get access to
 git, so here's what I see in 2009-07 downloaded from
 http://github.com/rakudo/rakudo/downloads
 
 S12 says:
 
 The .^methods method returns method-descriptors containing:
 
 namethe name of the method
 signature   the parameters of the method
 as  the coercion type of the method
 multi   whether duplicate names are allowed
 do  the method body
 
 
 
 That doesn't tell me exactly what I'm looking for, but I tried:
 
 say Str.^methods[0]
 sprintf
 
 Which looks suspiciously like a single string,

It's not, it's just an object that returns the method name in string
context.


 but just in case, I tried:
 
 say Str.^methods[0]signature
 get_pmc_keyed() not implemented in class 'Sub'

You're trying to use a hash key, not calling a method.

$ perl6 -e 'say Str.^methods[0].signature'
Signature()0x7fff2799f5b0
$ perl6 -e 'say Str.^methods[0].signature.perl'
:(Object self, Any $encoding?, Any $nf?, Object *%_)

(Note that the order of the returned methods is not fixed, so you might
see something different).

 say Str.^methods[0].name
 pred

Yes, there's a method 'pred'. So what?

 eh? The rest of the names (as, multi, do) don't seem to exist at all. I
 expect that this is because I'm not actually looking at a descriptor at
 all, but rather a Sub object that stringifies itself to sprintf. Is that a
 bug in Rakudo or S12?

I think it's just not yet implemented.

Cheers,
Moritz


[perl #68294] [PATCH] kv in the setting

2009-08-08 Thread via RT
# New Ticket Created by  dakkar 
# Please include the string:  [perl #68294]
# in the subject line of all future correspondence about this issue. 
# URL: http://rt.perl.org/rt3/Ticket/Display.html?id=68294 


second patch from Lisbon: kv in the setting
From db44fb60bde4009d148ac699c0a9b8383ac2206d Mon Sep 17 00:00:00 2001
From: dakkar dak...@sardina.(none)
Date: Thu, 6 Aug 2009 16:18:15 +0200
Subject: [PATCH] moved kv to setting

---
 src/builtins/any-list.pir |   40 
 src/setting/Any-list.pm   |   15 +++
 2 files changed, 15 insertions(+), 40 deletions(-)

diff --git a/src/builtins/any-list.pir b/src/builtins/any-list.pir
index e963092..cd78d87 100644
--- a/src/builtins/any-list.pir
+++ b/src/builtins/any-list.pir
@@ -94,46 +94,6 @@ Return a List with the keys of the invocant.
 signature.!add_implicit_self($P0)
 .end
 
-
-=item kv
-
-=cut
-
-.namespace []
-.sub 'kv' :multi() :subid('_kv')
-.param pmc values  :slurpy
-values.'!flatten'()
-.tailcall values.'kv'()
-.end
-.sub '' :init :load
-.local pmc block, signature
-.const 'Sub' $P0 = _kv
-block = $P0
-signature = new [Signature]
-setprop block, $!signature, signature
-signature.'!add_param'('@values', 1 :named('slurpy'))
-'!TOPERL6MULTISUB'(block)
-.end
-
-.namespace ['Any']
-.sub 'kv' :method
-.local pmc result, it
-result = new ['List']
-it = self.'iterator'()
-.local int i
-i = 0
-  loop:
-unless it goto done
-$P0 = shift it
-push result, i
-push result, $P0
-inc i
-goto loop
-  done:
-.return (result)
-.end
-
-
 =item pick($num, :$repl)
 
 =cut
diff --git a/src/setting/Any-list.pm b/src/setting/Any-list.pm
index 32d1ecf..9a9431a 100644
--- a/src/setting/Any-list.pm
+++ b/src/setting/Any-list.pm
@@ -85,6 +85,17 @@ class Any is also {
 }
 }
 
+our List multi method kv() {
+my $i=0;
+gather {
+for @.list - $value {
+take 0+$i;
+take $value;
+++$i
+}
+}
+}
+
 multi method reduce(Code $expression is rw) {
 my Int $arity = $expression.count;
 fail('Cannot reduce() using a unary or nullary function.')
@@ -133,6 +144,10 @@ our Str multi join(Str $separator = '', *...@values) {
 @values.join($separator)
 }
 
+our List multi sub kv(*...@values) is export {
+@values.kv();
+}
+
 our List multi map(Code $expr, *...@values) {
 @values.map($expr)
 }
-- 
1.5.6.3



signature.asc
Description: PGP signature


Re: [perl #68306] Rakudo 2009-07

2009-08-08 Thread Carl Mäsak
Moritz Lenz (), Aaron Sherman (via RT) ():
 say Str.^methods[0]
 sprintf
 [...]
 say Str.^methods[0].name
 pred

 Yes, there's a method 'pred'. So what?

I, for one, find that pair of results... surprising. If the method
object stringifies to its name, shouldn't the above two print the
same?

// Carl


S05 (regex) Q: after

2009-08-08 Thread Austin Hastings
S05 mentions the magic after pattern in two locations, but I cannot 
find a specification of the interaction between after and the 
ratcheting {rule/token} status.


Specifically, is

token {
  ... ?after x 
}

going to match the same pattern as

rule {
  ... ?after x 
}

??

I ask because (I just did it, and) with rules encouraging the liberal 
use of whitespace, and implicitly generating .ws matches, something like:


rule {
   X ?after X
}

will insert a .ws before the ?after, which the after-block should 
then be aware of.




So, I suppose the question is, does ?after always behave a certain 
way, ratchet-wise, and if so what is it? Or does it take its mode from 
the surrounding context, or something else?


=Austin



Re: Testing Perl 6 analog to Perl 5's tie.

2009-08-08 Thread Jonathan Worthington

Aaron Sherman wrote:

On Sun, Aug 2, 2009 at 1:10 PM, Moritz Lenz mor...@faui2k3.org wrote:

  

Let's pick up this old mail before it gets completely warnocked ;-)

For the record, this discussion only applies to scalar implementation
types. For example for Arrays I expect things to work by overriding the
method postcircumfix:[ ].




Really? What about:

  my ImplementationType @foo;
  @foo = 1..Inf;

  
That would mean that you want an Array in which you could only store 
things of ImplementationType, rather than setting the implementation 
type of the array. Use 'is' for that (and the thing that you implement 
as an implementation type should do the Positional role and implement 
postcircumfix:[ ] unless you inherited one).


Jonathan



Re: [perl #68306] Rakudo 2009-07

2009-08-08 Thread Jonathan Worthington

Aaron Sherman (via RT) wrote:

I'm working in a firewalled environment today where I can't get access to
git, so here's what I see in 2009-07 downloaded from
http://github.com/rakudo/rakudo/downloads

S12 says:

The .^methods method returns method-descriptors containing:

namethe name of the method
signature   the parameters of the method
as  the coercion type of the method
multi   whether duplicate names are allowed
do  the method body



That doesn't tell me exactly what I'm looking for, but I tried:

  

say Str.^methods[0]


sprintf

Which looks suspiciously like a single string, but just in case, I tried:

  
It's a Method object, or at least should be. (The S12 wording is maybe a 
little misleading in its use of descriptor which suggests you get 
something other than the Method object itself. Would be good to clarify 
S12 there.)



say Str.^methods[0]signature


get_pmc_keyed() not implemented in class 'Sub'
in Main (unknown:1)
  
Pretty much correct - subs don't do associative indexing (fine, better 
error message would be good, but it's not so wrong). You should call 
.signature to get the signature.



say Str.^methods[0].^signature


Method 'signature' not found for invocant of class 'P6metaclass'
  

Correct. .signature is a method on the Method object, not it's metaclass.


say Str.^methods[0].signature


No signature found

That last one looks more promising, but still not quite as advertised. 
This is a Rakudo issue. Basically, subs written in the Perl 6 setting 
get a signature object set up for them. Those written in PIR don't. We 
can fix that and have in some cases already, but it's easier to wait on 
that than do it now, as more and more stuff gets moved into the Perl 6 
setting. ;-)



Oddly enough if I try another one of the descriptors listed, it gets stranger:

  

say Str.^methods[0].name


pred

eh? The rest of the names (as, multi, do) don't seem to exist at all. I
expect that this is because I'm not actually looking at a descriptor at
all, but rather a Sub object that stringifies itself to sprintf. Is that a
bug in Rakudo or S12?
  
As mentioned earlier in this message, the descriptor and the Sub object 
are the same thing. .multi should work though was only recently 
implemented; .as doesn't because Rakudo doesn't implement coercion yet; 
.do I don't really grok, and I suspect should be removed from S12 unless 
somebody can actually provide an implementable spec that distinguishes 
it from the object itself.


So anyway, my feelings from this are mostly that S12 needs patching a 
little to be clearer that the descriptor and the Method object itself 
are not different things and - depending on feedback - the removal of 
.do, and Rakudo needs to make the difference between things in PIR and 
things in the setting be invisible to people using Perl 6, plus 
implement coercion and then make .as work Ah, and the spec had better 
mention the (implemented!) .of and .returns...


Visiting friends and being sick at the moment...will try and chase up 
both sides of this once I'm back home and healthy. :-)


Thanks,

Jonathan



Re: [perl #68306] Rakudo 2009-07

2009-08-08 Thread Aaron Sherman
On Sat, Aug 8, 2009 at 5:13 PM, Carl Mäsak cma...@gmail.com wrote:

 Moritz Lenz (), Aaron Sherman (via RT) ():
  say Str.^methods[0]
  sprintf
  [...]
  say Str.^methods[0].name
  pred
 
  Yes, there's a method 'pred'. So what?

 I, for one, find that pair of results... surprising. If the method
 object stringifies to its name, shouldn't the above two print the
 same?



Yes, that was the one that had me scratching my head the most. I was trying
to figure out which usage was correct, and was getting different, but
seemingly correct answers. Is the name of this method sprintf or pred
or am I getting both in some sort of odd quantum super-positioning?


Re: S05 (regex) Q: after

2009-08-08 Thread Patrick R. Michaud
On Sat, Aug 08, 2009 at 05:45:40PM -0400, Austin Hastings wrote:
 [...]
 Specifically, is
 token { ... ?after x  }
 going to match the same pattern as
 rule { ... ?after x  }
 ??

 I ask because (I just did it, and) with rules encouraging the liberal  
 use of whitespace, and implicitly generating .ws matches, something 
 like:
 rule { X ?after X }
 will insert a .ws before the ?after, which the after-block should  
 then be aware of.

Why should the after-block be (automatically?) aware of the .ws?

Put another way, afaik ?after ... is just a subrule like any 
other -- it doesn't get any special syntactic significance
that enables it to be aware of its surroundings.  I would say that
the rule should be either

rule { X?after X }

or if checking the whitespace is desired, it should be

rule { X ?after [X ]  }   # note whitespace after the X

 So, I suppose the question is, does ?after always behave a certain  
 way, ratchet-wise, and if so what is it? Or does it take its mode from  
 the surrounding context, or something else?

Ultimately I think that ?after ...  behaves the same as any other
subrule, and its pattern takes its ratchet/sigspace mode from the 
surrounding pattern scope.

Pm