Re: Unwanted failure and FAILGOAL

2016-05-11 Thread Damian Conway
Hi Richard,

Not a complete answer to your question;
just an observation about your grammar:

>  rule TOP{ ^ + $ };
>
>  rule statement  {  '=' 
>  | { { self.panic($/, "Declaration syntax incorrect") } }
>  };
>
>  rule endvalue   {  '(' ~ ')' 
>  | { self.panic($/, "Invalid declaration.") }
>  }

That's more or less the equivalent of:

sub TOP   {
die if !at_start_of_input();
loop { last unless try statement() };
die if !at_end_of_input();
  }

sub statement {
try { id(); match_literal('='); endvalue() }
  or
die "Declaration syntax incorrect";
  }

sub endvalue  {
try { keyword(); match_literal('('); pairlist();
match_literal(')') }
  or
die "Invalid declaration."
  }

In which case, would you really have expected a call to TOP()
NOT to throw an exception from statement(), the first time statement()
couldn't match (as it inevitably won't if we're at the end of the input)???

If these were subroutines, I suspect you'd have written something
more like:

sub statement {
try { id(); match_literal('='); endvalue() }
  or

*!at_end_of_input()&& die
"Declaration syntax incorrect"*
  }

sub endvalue  {
try { keyword(); match_literal('('); pairlist();
match_literal(')' }
  or

*!at_end_of_input()&& die
"Invalid declaration.";*
  }

which, in a regex, would be something like:

   rule TOP{ ^ + $ };

   rule statement  {
  '=' 
   |
* \S  **# ...means we found something else, so...*
* { self.panic($/, "Declaration syntax incorrect") }*
   };

   rule endvalue   {
  '(' ~ ')' 
   |
* \S  **# ...means we found something else, so...*
* { self.panic($/, "Invalid declaration.") }*
   }

Though, personally, I'd have been inclined to write it like this:

rule TOP{ ^  +  *[ $ |  ]*  }

rule statement  { 'ID' '='  }

rule endvalue   { 'keyword' '(' ~ ')' 'pairlist' }



*rule unexpected { $ = (\N+)  {
self.panic($/,"Expected statement but found '$'")
}}*

In other words: after the statements, we're either at the end of the input,
or else we found something unexpected, so capture it and then report it.

HTH,

Damian


Perl 6 mentions on Wikipedia

2016-02-25 Thread Damian Conway
Dear fellow revellers in the dawning Golden Age of Perl 6,

I just had a colleague contact me, to express their surprise that Perl 6
does not rate a mention in:

https://en.wikipedia.org/wiki/Functional_programming.

The Perl 6 community (and Larry in particular) has already done an
incredible job raising Perl 6's profile on rosettacode.org, but the
language still seems under-represented on Wikipedia, especially on
the various pages describing different language paradigms.

As Perl 6 is now the pre-eminent example of the imperative,
declarative, functional, parallel, concurrent, pipelined, vector,
object-oriented, aspect-oriented, reactive, introspective, and
metaprogramming paradigms, surely it should be mentioned
on all those wiki pages?

Yeah, I know: "Thanks for volunteering!". I can't at present, but I
didn't want this important observation, or the opportunity it
represents, to be lost, just because it was initially directed at
someone who's currently drowning in other commitments.

So I thought I'd mention it here, in the hope that someone else
who is looking for a slightly unusual way to contribute to Perl 6
might find the suggestion worth considering.

Damian


Re: [perl6/specs] 89cc32: Spec Bag.kxxv

2014-04-22 Thread Damian Conway
Raiph Mellor wrote:

 The .kxxv method name is a placeholder.

Phew! Thanks for taking the time to respond and
explain, Raiph.


 The brief discussion that motivated introducing it is at:
 http://irclog.perlgeek.de/perl6/2014-04-13#i_8582049

 Larry has chimed in at:
 http://irclog.perlgeek.de/perl6/2014-04-14#i_8582684

As I said before, I like the idea, just not the too-clever name.


 Another discussion that's unfolding right now and could do with your
 attention imo is:
 https://github.com/perl6/specs/commit/9213b1382078fee890ab9d74223f3c7e95942837

Thanks for the pointer, though they seem to have resolved that question
reasonably well now. ;-)


 All of the above illustrates an issue that we ought to address, namely
 where we best discuss this stuff to make the best use of your time:

For the past few years I've been staying out of the discussion, quietly
watching every doc commit, and commenting (either directly to Larry,
or else on this list) whenever I was alarmed, confused, or worried by
something.


 1. For the last few years almost all discussion is entirely on #perl6.

Which seems to be working extremely well...just not for me. I can't
manage to track these discussions (even via the logs). I find the
interleaving of multiple threads utterly impossible to cope with.


 The above arrangement works for us and $Larry. But I'm thinking we might
 want to go back to @Larry with both you and him and figure out how we
 make that work for you.

You should first ask $Larry if he wants to go back to @Larry. ;-)

Meanwhile, I'm reasonably happy being just a sanity check on spec
commits. If there's greater need of me than that, perhaps I could
also be a kind of evil djinn, to be conjured by emailed pointers (such as you
so kindly provided) in cases of dire need. :-)


 Did you see that lizmat has taken a stab at implementing 'is cached' --
 because she saw that that's the one unimplemented thing in some code
 you recently published?

She said she was going to raise the issue. I'm delighted to see her take it
further than that. The lack of is cached was the sole point-of-failure in
my Perl 6 for CS talk.


 How confident are you that your all-in-one CS teaching platform concept
 will be taken up by some educational institutions? What timeframe are
 you thinking is involved here? Are you thinking P6 is already ready for it?

I suspect that Rakudo-on-MoarVM is now (or very soon will be) fast
enough and complete enough. It only needs to be sufficiently easy to
install (e.g. a standard part of Rakudo*), which I understand is very
close now. Of course, another 6-12 months of polishing...both of the
specs and of the implementation...wouldn't go amiss either. In particular,
the concurrency specs and implementation need to be a little more stable
and tested.

I have no confidence yet, however, that Perl 6 will be widely taken up
as a CS teaching language. I think the presentation I made was
compelling enough, but I've only given it at one institution, and my
experience is that language decisions rarely get made on the basis of
technical merit, or pedagogical merit... or even on the basis of mere
pedagogical convenience. Rather, the decision on a teaching language
usually reflects either the personal biases of the individual teacher,
or those of the curriculum committee, or else mirrors the market demand of the
local community. How else do we explain the awful languages that are so
often taught in our universities. :-(


 I don't think we're there yet but it seems like the perfect initial goal for
 P6-as-a-product.

I do think Perl 6 is an incredibly good fit for teaching both CS in general
and programming paradigms in particular. And, if we could get it into
schools, it would be a huge boost in its exposure and popularity.

I'm going to continue to refine my presentation, and offer it at any
educational institutions I can convince to host it in the various cities
I will be visiting over the next twelve months. We'll see if I get any
traction.

Damian


Re: [perl6/specs] 89cc32: Spec Bag.kxxv

2014-04-22 Thread Damian Conway
 It's an awesome language, which is exactly the problem. Inspiring
 awe is not far from inducing panic and terror, especially in people
 who aren't feeling too confident in the first place. We want to be
 accessible to the people who start looking nervous when the modulus
 operator is added to the basic four mathematical signs as operators.

This is an important point. And an area in which I believe Perl 6 can
excel. I do think it will be possible to specify (and even enforce) suitable
subsets of the language, to make it approachable by the easily over-awed.


 Sorry if I'm being boringly repetitive, but I do see complexity as a
 barrier to world domination.

No, it's an important point. I get very excited about the power and
sophistication of Perl 6. But I also get very excited about the
straightforwardness and simplicity it can offer. It's important that we
market both aspects...and to the right audiences.

For example, at OSCON this year I'm concentrating on the simplicity
of Perl 6:

http://www.oscon.com/oscon2014/public/schedule/detail/33839

Damian


Re: [perl6/specs] 89cc32: Spec Bag.kxxv

2014-04-13 Thread Damian Conway
   Spec Bag.kxxv

It's a clever name...but maybe too clever?

I find it unfortunate that a method that only returns keys has a 'v'
in its name.
Up to now, we've had a more predictable pattern to naming these accessors.

How about one of:

 .weighted-keys
 .distribution

instead???

And what is the use-case for this?
I can see that I might want:

$bag.kxxv.pick;

but:

$bag.pick

already does that.

I guess you might want to separate out the steps for some reason:

my $selection = median_value_from( $bag.kxxv );

but that would be far more readable/maintainable as:

my $selection = median_value_from( $bag.distribution );


Damian


Re: [perl #121454] Can't inline complex constraints in multisub signatures

2014-03-29 Thread Damian Conway
Moritz wrote:

 To spin the tale further, we need to think about what happens if
 somebody writes

 multi foo(1|2e0) { ... }

 so now we have Int|Num. We could explore the most-derived common
 ancestor (Cool), or look into role space (Real, Numeric come to mind),
 or simply error out.

Or maybe we need to reconsider the whole idea that it's appropriate to
infer type from a smartmatched constraint?

Because, having pondered it at some length, I think we could very
reasonably decide that, when providing a constraint, the coder is not
making any reliable implication regarding the associated parameter type.

Let's look at some examples...

1. Suppose we wanted a subroutine that classifies numbers according to a
   very simple scheme.  We might write:

multi classify($ where 0   ) { 'zero' }
multi classify($ where 1..9) { 'digit'}
multi classify($   ) { 'sequence' }

   It would be more convenient if we could just write:

multi classify( 0) { 'zero' }
multi classify( 1..9 ) { 'digit'}
multi classify( $) { 'sequence' }

But we can't, because the current inference rules would infer:

multi classify(Int   $ where 0   ) { 'zero' }
multi classify(List[Int] $ where 1..9) { 'digit'}
multi classify(Any   $ where *   ) { 'sequence' }

which is not helpful. It goes wrong because, except in the first
version of Cclassify, the type of the parameter constraint does
not imply the type of parameter.


2. Or suppose we wanted a subroutine that only ever accepts a given
   argument once. We might write:

sub unseen ($msg) { state %seen; %seen{$msg}++; }

multi ping($ where unseen ) { die 'One ping only!' }
multi ping($msg) { say PING! ($msg)   }

   It would be more convenient if we could write:

multi ping({.unseen}) { die 'One ping only!' }
multi ping($msg  ) { say PING! ($msg)   }

But we can't, because the current inference rules would make that:

multi ping(Block $ where {.unseen}) { die 'One ping only!' }

which is not helpful. Because, again, the type of the constraint
does not imply (nor is it even directly related to) the type of the
parameter.


3. Or suppose we wanted to detect special boundary conditions
   (a case similar to Moritz's example above). We might write:

multi check_value($ where 0|1e6) { fail 'edge case!' }
multi check_value($) { return True   }

   It would be more convenient if we could write:

multi check_value(0|1e6) { fail 'edge case!' }
multi check_value($) { return True   }

   But we can't, because the current inference rules would make that:

multi check_value(Junction $ where 0|1e6) { fail 'edge case!' }
multi check_value( $) { return True   }

which is not helpful. Because, as before, the type of the constraint
is not correlated with the type of the parameter.


In each case (and in the majority of other cases, I suspect) the type
and the constraint value are performing two entirely distinct tasks,
and are often unrelated. Or, at least, unrelated in the sense that the
constraint value is frequently not type-compatible with the type,
because the constraint is verified by smartmatching, which is most often
an operation between values of two unrelated types: integer matched
against block, string matched against list, number matched against
junction, etc. etc.

In other words specifying a constraint value is a way of applying a
smartmatched acceptance test to a parameter, but the type of the
acceptance test is typically totally unrelated to the type of the
parameter.

Which is why it now seems very odd to me that we are currently inferring
parameter types from constraint values.

The type of the constraint value tells us nothing reliable about the
type of the parameter it constrains. It only tells us that the value of
that parameter must be matchable against the value of that constraint.

And that appears to be true even for the very simplest example:

sub foo($ where 1) { say 'There can be only one!' }

foo(1);  # Okay
foo('1');# Okay
foo(True);   # Okay
foo([42]);   # Okay
 # et cetera...

I ought to be able to write that as:

sub foo(1) { say 'There can be only one!' }

but I cannot, because the current rules don't even infer a
coercive type.


TL;DR: In general, the type of a parameter's Cwhere constraint value
   has little to do with the type of the parameter,
   because constraints are smartmatched, not type-matched.


My proposal, therefore, is that any parameter specified only as a
constraint value simply does not attempt to infer its parameter type at
all, but just retains its default type of Any.

That is, in all cases:

sub foo( SOME_VALUE ) {...}

is just a shorthand for:

sub foo($ where SOME_VALUE ) 

Re: When do named subs bind to their variables? [perl #113930]

2012-07-08 Thread Damian Conway
Father Chrysostomos pointed out:

 I said when, not whether. :-)

Isn't that just typical of me: confusing ontology with chronology. ;-)

I'm afraid don't know the implementation details for Rakudo. It may be
bound as the surrounding block is entered, or perhaps just-in-time when
the Code object is first accessed in some way.


 Does Perl 6 have an equivalent to this?

 my $x;
 for $x(1..10) {}

In Perl 6 that's:

my $x;
for 1..10 - $x {}

And, as in Perl 5, they're two separate variables.

The iterator $x is a parameter of the loop block and acts as a readonly
alias to each successive iterated value, unless you write:

for 1..10 - $x {}

in which case it's a read-write alias to each iterated value.

Loop iterators are never package-scoped in Perl 6.


  is just a syntactic convenience for:

 my foo := sub { whatever() }

 Except that my sub foo happens upon block entry, right?

Quite so. So the equivalence is more precisely:

ENTER my foo := sub { whatever() };

except that the named code object is visible throughout its surrounding
block (even before its declaration point).

So I guess that equivalence I keep referring to is a little shakey. ;-)


 In Perl 5, $] in a piece of code is bound to *], not $], so it sees
 changes made by local($]) (which actually puts a completely new scalar
 in the *]{SCALAR} slot).  But ‘my $x; sub { $x }’ is bound, not to the
 $x slot in the outer block/sub/file, but to the actual scalar itself.

 It seems that Perl 6 closures close over the slot, not the
 scalar/array/etc.  Is that right?

That's right. This:

my $x   = 1;
my $x_prime = -1;

sub foo { say $x }

foo();

$x := $x_prime;

foo();

prints:

1
-1

...indicating that the $x in foo is bound to the slot, not to any var
implementation currently in the slot. The way I would have described it
is that binding is by name, not by reference.

Damian


Re: [perl #113930] Lexical subs

2012-07-08 Thread Damian Conway
 But by using the term ‘variable’, which is ambiguous, you are not
 answering my question! :-)

Sorry. I tend to think of *every* variable name as merely being
an alias for some underlying storage mechanism. ;-)

 Does

 my $x;
 for 1..10 - $x {}

 cause the existing name $x to refer temporarily to each of the numbers,
 or is a new $x name created?

A new one is created (each time through the loop).


 What does this do?

 my $x;
 my sub f { say $x }
 for 1..10 - $x { f(); }

It prints 'Any()' ten times (i.e. the equivalent of printing ten Perl 5 undefs).

The two $x's definitely exist at the same time during the loop.
For example, this:

my $x = 'outer x';
my sub f { say $x }

for 1..10 - $x {
print $x, : ;
f();
}

prints:

1: outer x
2: outer x
3: outer x
4: outer x
5: outer x
6: outer x
7: outer x
8: outer x
9: outer x
10: outer x


Damian


Re: When do named subs bind to their variables? (Re: Questionable scope of state variables ([perl #113930] Lexical subs))

2012-07-07 Thread Damian Conway
Father Chrysostomos asked:

 What I am really trying to find out is when the subroutine is actually
 cloned,

Yes. It is supposed to be (or at least must *appear* to be),
and currently is (or appears to be) in Rakudo.


 and whether there can be multiple clones within a single call of
 the enclosing sub.

Yes. For example, a lexical sub might be declared in a loop inside the
enclosing sub, in which case it should produce multiple instances, one
per iteration.

For example, this:

sub outer_sub () {
for (1..3) {
state $call_num = 1;
my sub inner_sub {
state $inner_state = (1..100).pick; # i.e. random number
say [call {$call_num++}] \$inner_state = $inner_state;
}

say \nsub id: , inner_sub.id;
inner_sub();
inner_sub();
}
}

outer_sub();

produces:

sub id: -4628941774842748435
[call 1] $inner_state = 89
[call 2] $inner_state = 89

sub id: -4628941774848253711
[call 3] $inner_state = 16
[call 4] $inner_state = 16

sub id: -4628941774839825925
[call 5] $inner_state = 26
[call 6] $inner_state = 26

under Rakudo


BTW, Both the above yes answers are consistent with (and can be
inferred from) the previous explanation that:

my sub foo { whatever() }

 is just a syntactic convenience for:

my foo := sub { whatever() }

HTH,

Damian


Re: [perl6/specs] 6ef69b: pod vars are now lowercase as seen in 3e1a9a5a576b...

2012-04-05 Thread Damian Conway
Herbert Breunung asked:

 what was you rational behind this decision.
 I like it visually but my brain refuses to find any logic why only there
 special vars should be different.

This change stems from another change that we made after discussions at
YAPC Riga last year. That change was to convert the =DATA and =END
markers to =data and =finish.

The rationale for that change was as follows...

In the original redesign for Pod6, every built-in directive (=begin,
=head1, =item, =table, etc.) was lower-case...except for =DATA and =END,
which retained their vestigal upper-casing, in analogy to Perl 5's
__DATA__ and __END__.

And in the original Pod6 design, every upper-case directive (=SYNOPSIS,
=AUTHOR, =COPYRIGHT, etc.) was a semantic blockexcept for =DATA
and =END, which were built-ins.

In other words, =DATA and =END were violating both the syntax for
built-ins (should be lower-case, but aren't) and the semantics
of upper-case (should be semantic blocks, but aren't).

So we changed them to what the syntax and semantics were telling us they
should be: lower-case.

But this change broke the one-to-one mapping between Pod sections and
Pod-access variables. Previously it was:

=pod-   $=pod
=UserDef-   $=UserDef
=SYNOPSIS   -   $=SYNOPSIS
=DATA   -   $=DATA

But, after the Riga discussions it became:

=pod-   $=pod
=UserDef-   $=UserDef
=SYNOPSIS   -   $=SYNOPSIS
=data   -   $=DATA   (oops!)

Now, this second change simply restores balance to the Force:

=pod-   $=pod
=UserDef-   $=UserDef
=SYNOPSIS   -   $=SYNOPSIS
=data   -   $=data


Note too that, under the current notion that *any* Pod block
(say: =foo or =BAR) is available under a variable of its own name
(i.e. $=foo and $=BAR), then $=DATA is still a valid variable. It does
not, however, access the built-in data block named =data. Instead, it
accesses the (potential) semantic block named =DATA...which is an
entirely different beastie.


BTW, S02 still has remnant mentions of $=POD and $=DATA, as well as some
other antiquities regarding Pod variables. I have attached a proposed
docpatch.


Damian


S02.patch
Description: Binary data


Re: [perl6/specs] 6ef69b: pod vars are now lowercase as seen in 3e1a9a5a576b...

2012-04-05 Thread Damian Conway
 Thank you damian, i will apply that patch,

Much appreciated, Herbert!

Damian


Re: How to make a new operator.

2012-03-25 Thread Damian Conway
 At least in #perl6 I've never seen anybody try to write an auto-deduced
 sequence, and fail because of floating-point errors.

Except for Martin's 1, sqrt(2), 2...8

But, yes, the widespread use of Rats rather than Nums
means only the edgiest of edge-cases fails. And as you get
an explicit Failure when it does happen, at least people will
know when the numerical computations don't work as hoped.

Damian


Re: Not-so-smart matching (was Re: How to make a new operator.)

2012-03-25 Thread Damian Conway
yary suggested:

 In a situation like this, I reach for a thesaurus

The standout from that list for me is: 'consonance'.
Second favorite is: 'gibe' or 'jibe'.

But the underlying operation is .ACCEPTS(),
so perhaps the operation should be referred to
as acceptance or acceptibility.

Damian


Re: How to make a new operator.

2012-03-24 Thread Damian Conway
 Actually, that one works fine in both niecza and rakudo, since those are Rats.

Oh, that's good to hear.

It doesn't change my underlying argument however. Any operations
performed on genuine floats are going to lose precision, and if we're
using such operations to infer relationships (such as equality or
sequence) then we ought to take the loss of precision we're causing
into account when deciding outcomes.

Which seems to mean either (a) making it a compiletime error to request
sequence inferences on floats , or (b) comparing the differences and
quotients within the sequence inference with a larger epsilon (or using
interval arithmetic).

Damian


Re: How to make a new operator.

2012-03-23 Thread Damian Conway
Patrick correctly observed:

 On Rakudo on my system, sqrt(2) indeed produces a Num,
 but since floating point arithmetic doesn't result in
 sqrt(2) / 1 == 2 / sqrt(2), no geometric sequence is deduced
 and the sequence fails with unable to deduce sequence.

Although, arguably, that might be considered a bug.

Not that sqrt(2) / 1 should == 2 / sqrt(2) of course, but that, when
deducing a sequence we know we're comparing quotients, so we ought to
allow for the inevitable loss of significant digits within the two
preliminary division ops, and therefore compare the results with an
suitably larger epsilon.

That would not only be computational more justifiable,
I suspect it might also produce more least surprise. ;-)

Damian


Re: How to make a new operator.

2012-03-23 Thread Damian Conway
 But unless we twist smartmatching semantics for that purpose,

No!

Please, no.

;-)


 it means we cannot do the same fuzziness for the endpoint,

Except that we will be encouraging people to use: * = $END
as their standard endpoint pattern, which will provide
most of the necessary fuzz.


 So I'm firmly against such magic.

But that's the point: it's not magic. It's correct numerical computation
under the limitations of floating-point arithmetic. As discussed in
every numerical computing textbook for the last half a century.

Note that this problem occurs for *arithmetic* deductions as well.
If either number is floating point, some loss of precision in the
difference between them is almost inevitable, especially if the two
numbers are very close.

For example:

1, 1.0001, 1.0002 ... *

won't deduce a correct arithmetic sequence either (on most hardware).

In fact that example would be slightly more likely to imply a geometric
sequence, since a division operation loses fewer significant digits than
a subtraction when the arguments are both so close to 1.0)


 This discussion makes me think that maybe
 deducing geometric sequences is too much magic as well.

Geometric sequence inference is fine on Ints and Rats.

But, if we can't perform inferences involving Nums in a sound numerical
way (and it may well be that we can't, without taking a noticeable
performance hit), then I think that we would be better off limiting the
deduction of *both* arithmetic and geometric sequences to starting lists
that contain only Ints and Rats.

Damian


Re: How to make a new operator.

2012-03-21 Thread Damian Conway
 Is it possible to create a new range operator ':' such that:

Do you need to?


 a:b:c is a range from 'a' to 'b' by steps of 'c'.

Perl 6 already has: $a,*+$c...* =$b

E.g. 2, 5 ...^ *=15   2,5,8,11,14


 :b is the same as 0..b

Perl 6 already has ^$b

e,g, ^100  0..99


 a: is the same as a..Inf

Perl 6 already has $a..* or $a...*

e.g. 3..*  3,4,5,6,


 ::c is the same as 0:Inf:c

Perl 6 already has:  0,$c...*

e.g. 0,3...*  0, 3, 6, 9, 12


 : is the same as 0..Inf

Perl 6 already has: ^Inf  0,1,2,3,4,5,


Damian


Re: How to make a new operator.

2012-03-21 Thread Damian Conway
 Interesting... but it doesn't seem to work in Rakudo Star (2012.02):

 @(2,5..10)

You need three dots, not two.

Damian


Re: How to make a new operator.

2012-03-21 Thread Damian Conway
 Ok, so infix:... isn't what I wish for either... Can you help me
 understand Damian's example?


Breaking down that example:

$a,  # Start at $a
*+$c # Generate next number via: sub($prev_num} { $prev_num + $c }
...  # Repeat until...
* =$b   # ...this sub matches: sub($prev_num) { $prev_num = $b }

* used as an argument to an operator is a shorthand for constructing
subroutines,
where the * represents the subroutine's argument.


Damian


Re: DBC-ish PRE and POST phasers, spec clarifications

2012-03-10 Thread Damian Conway
Carl asked:

class A {
method foo($x) {
PRE { $x  10 }
# ...
}
}

class B is A {
method foo($a, $b, $c) {
PRE { [] $a, $b, $c }
# ...
}
}

 When CB.foo is called, are both CPRE blocks meant to be run?

No. Contractual constraints are only inherited by methods of the
same signature.

BTW, that example isn't Liskov substitutable, so it really doesn't
matter what it does under DbC. ;-)

Also, it would be much better if such cases issued a warning in Perl 6,
rather than just silently hiding the inherited method and thereby
breaking the shared polymorphic interface of the hierarchy.


 A modest proposal: we already have excellent IoC primitives with
 Cnextsame et al. Why not let DBC fall out of their use instead of
 trying to impose it from the outside? This poses no problems at all:

Except for the problem that it doesn't actually implement DbC semantics. ;-)

For example:

   class A {
   method foo($x) {
   PRE { $x  10 }
   my $result = 2 * $x;
   return $result;
   POST { $result  $x }
   }
   }

   class B is A {
   method foo($x) {
   PRE { $x  100 }
   callwith($c % 10);
   return -$c;
   }
   }

In a proper DbC system, calling B::foo would always fail, since A::foo's
inherited POST requires the method's result be greater than its original
argument. But under the proposed new semantics, this example succeeds in
returning a result that violates the inherited contract.

Even worse, this example:

   class A {
   method foo($x) {
   PRE { $x  10 }
   my $result = 2 * $x;
   return $result;
   POST { $result  $x }
   }
   }

   class B is A {
   method foo($x) {
   PRE { $x  100 }
   return -$c;
   }
   }

...fails to even test the inherited PRE and POST conditions, which is a
complete violation of DbC.

Note that I'm *not* saying that Carl's example isn't demonstrating
useful behaviour...just that the behaviour it's demonstrating isn't DbC.

For a start, PRE- and POST- inheritance should only occur when a derived
method does indeed have the same signature as some base method, and then
only from that identically signatured method. Secondly, PREs have to be
inherited disjunctively (i.e. be allowed to weaken), rather than being
conjunctively accumulated (i.e. being forced to to strengthened).


 In fact, method-level CPRE and CPOST cease to be a concept, CPRE
 and CPOST submethods can be handled delicately in a corner of the
 MOP somewhere, the abomination that is CCALL-VIA-DBC goes away, and
 all that we're really left with are block-level CPRE and CPOST
 phasers, which already seem like they could work.

 So, what do y'all think?


I think this is probably the only reasonable way forward at the moment.
What we've proposed as a DbC mechanism in the spec can't be implemented
for all the reasons Carl enumerated so well.

However, I'd also want the spec to remove all reference to DbC when talking
about PRE and POST. Or, better still, to state explicitly that PRE and
POST do *not* have DbC semantics when applied to methods (perhaps even
using some of the examples above to illustrate why not).

And if we are ever to properly supply DbC, then I think we'd also want
to explicitly reserve--but not spec--the phaser names REQUIRE and ENSURE
for possible later use (either in-core or via a future 'use contracts'
pragma or module that some heroic soul may attempt write. ;-)

On the other hand, because DbC requires and ensures are really
much more like (inheritable) traits of a method's signature,
rather than phasers tied to the method's block, it seems likely that
any eventual DbC mechanism should not use phasers at all. So perhaps
we ought to reserve the traits 'will require' and 'will ensure' so that the
eventual DbC mechanism could be specified like so:

class A {
method foo(Num $x -- Num $result)
  will require { $x  10 }
  will ensure  { $result  $x }
{
return 2 * $x;
}
}

class B is A {
method foo(Num $x -- Num)
  will require { $x  100 }
{
return $x+1;
}
   }

And, yes, this does indeed imply a syntax for optionally naming the
return value in a signature (which syntax seems to fall out quite
naturally in any case).

Damian


Re: Setting private attributes during object build

2012-02-02 Thread Damian Conway
My thanks to Kris and Moritz for reassuring me that
the Perl 6 initialization semantics remain sane. :-)

In response to yary's original observations, the extra work required to
achieve non-standard semantics doesn't seem unreasonable to me.
Especially as, should one need to do it regularly, one could just create
a role (possibly parametric) to handle all the boilerplate
and then mix just it into any class that requires it.

Damian


Re: Setting private attributes during object build

2012-02-02 Thread Damian Conway
yary wrote:

The current approach is violating the DRY principle. When you write a
.new method that wants to initialize private attributes, you have to
repeat all their names again in the signature of your BUILD submethod:

The other way of looking at this is that redefining the new() is about
changing the constructor interface, whereas defining the BUILD() is
about changing the initialization behaviour.

So the current approach is violating DRY in order to preserve the more
important principle of Separation of Concerns. After all, it doesn't seem
unreasonable that, if you want to modify two behaviours, you have to
rewrite two components to do it.

On the other hand, rather than adding a blessall() alternative,
perhaps we could say that, if the class explicitly redefines new(), then
any call to bless() within that redefined new() will accept both public
and private attributes for auto-initialization...under the theory that,
by redefining new() the class implementor is taking direct
responsibility for the construction...and is willing to live with the
dire consequences if they mess it up.

Incidentally, blessall() seems a dubious name to me, given that we
already have BUILDALL() and CREATEALL(), where the '-ALL' suffix means
something quite different from what the '-all' would mean at the end of
blessall().

Better still, on the principle that abnormal behaviour should always be
explicitly marked and lexically predeclared, perhaps a pragma would
be appropriate:

class A {
has ($!x, $!y, $!z);

method new($x, $y, $z) {
no strict :autoinit;
self.bless(*, :$x, :$y, :$z)
}
}


The whole point of having BUILD() is to separate allocation
 concerns from initialization concerns.

 Here's where I am late to the conversation, I hadn't known that
 distinction. S12 doesn't talk about the why of BUILD/BUILDALL, at
 least not that detail. If BUILD is for allocation, and new is for
 initialization, then hiding private attributes from bless is forcing
 the programmer to use BUILD for initialization which wasn't the
 intent.

You have it the wrong way round: new() is for allocation; BUILD() is for
initialization. From a design point-of-view, BUILD() probably should
have been called INIT(), but that keyword was already taken.


 you must write your own BUILD (as above) in order to present private
 attributes as part of your initialization API.

 And that's not so good, because it forces BUILD to be used for
 initialization,

...which is precisely what it's supposed to be for. :-)

Damian


Re: Setting private attributes during object build

2012-02-01 Thread Damian Conway
Yary wrote:

 If one wants to use any argument in the constructor other than a
 public attribute (positional OR named other than an attribute name),
 one must define a method new( ... ).

Huh? I know I've been out of the loop lately, but this seems fundamentally
wrong.

Constructor args certainly shouldn't be restricted to just the names
of public attributes. And one definitely shouldn't have to redeclare new()
just to allow for more sophisticated initialization. The whole point of having
BUILD() is to separate allocation concerns from initialization concerns.

S12 has an example that explicitly contradicts this constraint that constructor
args have to be public attribute names:

submethod BUILD ($arg) {
$.attr = $arg;
}

Either I'm missing the point here (which is entirely possible ;-) or something
isn't right in the current semantics of object initialization.

Damian


Re: Setting private attributes during object build

2012-02-01 Thread Damian Conway
Moritz clarified:

 In BUILD, the object isn't yet fully constructed, and thus using $.attr
 (which is really a virtual method call in disguise) is wrong. STD and
 niecza already catch that at compile time, and I'm currently trying to
 make rakudo catch it too (branch 'has-self' on github).

Agreed. That example should certainly use $!attr instead.


 More to the point, objects are constructed by .new calling .bless, which
 in turn calls BUILDALL which finally calls BUILD. Since .bless only
 takes named arguments (besides the candidate to be blessed), how could
 BUILDALL know how to call BUILD with positional arguments?

Agreed. That example should be: submethod BUILD( :$arg ) {...}


 Finally Rakudo, Niecza and Pugs all agree that the default .new and thus
 .BUILD only take named arguments, and while that's not authoritative, it
 is a strong indicator that the example above contradicts the compiler
 writer's understanding of object initialization system.

Agreed. I dearly want BUILD to take only named args.


My point was that I don't want the named arguments that BUILD can take
to be restricted to only the names of public attributes...which was, I
thought, yary's complaint when writing:

 If one wants to use any argument in the constructor other than a
 public attribute (positional OR named other than an attribute name),
 one must define a method new( ... ).

If the complaint is that yary wanted to pass positional args to a
constructor, then I have no problem with having to write one's own
non-standard new() method to achieve that. If anything, we should make it
even harder than that. ;-)

But if one can't pass arbitrary named values to the standard new() and
have one (or more!) BUILD methods correctly use them, like so:

class Date {
has Num $!seconds_from_epoch;

multi submethod BUILD (Str :$date) {
$!seconds_from_epoch = _date_from_str($date);
}

multi submethod BUILD (Int :$year, Int :$month, Int :$day) {
$!seconds_from_epoch = _date_from_YMD($year, $month, $day);
}

# etc.
}

and then be able to call:

my $today= Date.new(date = 'Feb 2, 2012');
my $tomorrow = Date.new(year = 2012, month = 2, day = 3);

then we've failed to make Perl 6 even as usable as C++, which is
a tragedy.

I sounds like I simply misunderstood yary's problem, but I'd be
very glad to be reassured that's the case. :-)

Damian


Re: [perl6/specs] a7cfe0: [S32] backtraces overhaul

2011-08-23 Thread Damian Conway
It's a trivial point, but why hidden_from_backtrace instead of
hidden-from-backtrace? Especially given that the associated
method is is-hidden, not is_hidden?

Are we consistently using underscores for multi_word traits
and hyphens for multi-word methods? Wouldn't it be nice to
have a consistent and teachable rule?

And why is this entire message written in questions?
Have I simply been watching too many Whose Line Is It Anyway?
episodes?

Damian?


Re: [perl6/specs] a7cfe0: [S32] backtraces overhaul

2011-08-23 Thread Damian Conway
 The current stance seems to be that low-level things are spelled with
 underscores, while we reserve the minus character for user-space code. Try
 grepping the specs for identifiers of built-ins that have a minus in it -- I
 didn't find any in a quick search.

I had a little more time to look and found...

S12 describes Attribute objects as having a method named 'has-accessor',
but also having a method named 'get_value'.

S19 uses hyphens for all of perl6's long-form command-line flags.

In S28, we find $*EXECUTABLE_NAME and %*META-ARGS listed
within 10 lines of each other.

S32-setting-library_IO.pod and S32-setting-library_Numeric.pod each have
public multi-word method names with hyphens. And both also list other
identifiers that use underscores.

I'm not sure I'm seeing the pattern, though. Apart perhaps from older parts
of the spec use underscores, newer parts use hyphens.

And I'd like there to be a more consistent approach than that
(though I don't really care what it actually is).

Damian


Re: Encapsulating the contents of container types

2011-08-20 Thread Damian Conway
Carl asked:

 * What do we mean when we say 'has @.a is readonly'?
 What do we want it to mean?

Not sure about we, but I want that to mean that nothing outside the
class can alter any component of @.a, no matter how deeply nested that
component may be.


 * Are we fine with references from readonly attributes leaking out of the 
 class?
   Should we be?

No.
No.


 * What language components could be provided to put class implementors
 on the right path so that their classes end up encapsulated by
 default?

Doing nothing should result in the safe behaviour (i.e. full encapsulation).
You ought to have to explicitly request anything else.


One of the *big* selling points of Perl 6 is the prospect of OO done right.
Leaky encapsulation ain't that.

Damian


Re: Tweaking junctions

2010-11-01 Thread Damian Conway
Moritz wrote:

     $value !~~ Junction    $value ~~ $junction

 In general this definition makes it impossible to return a list of
 eigenstates from the junction. Just think of junctions containing Code
 objects.

Well, that's a deficiency in smartmatching: that Callable ~~ Code doesn't
check for identity between the two objects. Likewise the Regex ~~ Regex
doesn't check for identity. Likewise Range ~~ Range testing for identical
endpoints. Etc. ;-)

The definition of eigenvalues() is supposed to be abstractly
descriptive, not specifically constructive. The idea is simply: any
leaf state inside the junction to which the junction could collapse.

Now the implementation I already provided does currently rely on
smartmatching, but that will be fixed pronto, now that you've kindly
pointed out that smartmatching is...well...broken on several interesting
types of states. :-)


 Right; but afaict it's the only thing that can actually be implemented.
 And because it doesn't make all too much sense, it's specced to be private.

Fine. But please change the name anyway.

If we all agree it's not returning eigenstates, and some of us believe it
*can't* every return eigenstates, then it certainly shouldn't be called
C.eigenstates.

Damian


Re: Tweaking junctions

2010-10-29 Thread Damian Conway
Martin D Kealey suggested:

 Well, I think returning or throwing an Unordered exception would be
 the appropriate way to handle those, both for complex numbers and for
 junctions.

For complex numbers that might be true, because the order relationship
between two complex numbers isn't expressible in-band.

But for junctions, the relationship of sometimes , somtimes = is
entirely expressible. It's just: any(True, False).


 And what about when that difference is wrapped up inside a function? In
 other words, what's wrong when I expect the following two snippets to
 work the same way?

sub anything_is_broken($subject) {
grep { ! .test() } $subject.parts()
}


sub everything_is_working($subject) {
! grep { ! .test() } $subject.parts()
}

 Why should it make a difference whether $subject is a junction?

Because, although the two subroutines seem like they're complementary,
they actually only partition the universe when the universe is strictly
one-dimensional. And sometimes not even then.

For example, here's a *non-junctive* scalar subject for which the two
don't provide consistent answers either:

class Part {
has $.value;
method test { $.value != 0 }
}

class Subject {
has Part @.parts;
method parts { @.parts.pick(2) }
}

my Subject $subject .= new(0..9);

say anything_is_broken($subject);# 0 (because .parts picked 3 and 7)
say everything_is_working($subject); # 0 (because .parts picked 9 and 0)

In other words, it isn't the junctive-ness that creates unexpected
behaviour, it's the assumption that every scalar works the same way.


 That's not true for user-defined functions, so I think the real problem
 is that the parallelizing of the expression that contains a junction may
 not be obvious at the point where it happens.

But that's not a unique property of junctions; that not obviousness
is equally true of any scalar that, for example, simply overloads .Num
or .Str or .Bool.

For instance:

if $result { say $result }

can easily print 0, which is not obvious, but is still both correct
and useful (when, for example, $result the result of a call to Csystem).


 Hmmm  maybe one way to improve that might be to say that you can't
 put a junction into an untyped scalar, or indeed in any variable that
 isn't explicitly marked as this thing might contain a junction. That
 would apply, as now, to function parameters and returns, but also to
 variables and aggregate members; indeed, *everywhere*.

But junctions are an intrinsic part of Perl 6. So it's unreasonable to
*not* expect them. And if you want to not expect them, you can just mark
your variables that way, with (ironically):

my $subject where none(Junction);

Besides, are you also going to extend this segregation of junctions to
not allow C0 but true in untyped scalars either? Because how else will
you avoid the non-obviousness of:

 if $result { say $result }

???


 I don't think strong typing is enough, because we explicitly mask the
 application of type constraints by autothreading. Each thread sees a
 thing with the type it expects, but the problem comes when the threads
 are recombined; the result often won't be what's expected.

Huh? If the variables are strongly typed as non-junctive, a junction
will never be able sneak past into or out-of an autothreading.


 Don't get me wrong, I think Junctions are a really clever way of
 writing concise conditional expressions, but I think algebraic
 consistency is more important than clever conciseness.

Aha. I see that we mean different things when we use the term algebraic
consistency. You seem to want all algebras to be universally
consistent; I want each algebra to be internally consistent. Or to put
it another way, you appear to want:

A given operator or function does one consistent thing
(regardless of the specific types of its operands)

whereas I want:

A given operator or function does one thing
(consistent with the specific types of its operands)

In other words, you seem to be arguing for monomorphism, whereas I'm
definitely arguing for polymorphism. Neither is inherently better, but
one is inherently more powerful. While I deeply respect your
position, I'm going to keep arguing for that more powerful alternative.

Damian


Re: Tweaking junctions

2010-10-28 Thread Damian Conway
Martin D Kealey asked:

 Or do we not invert junctions, and run the risk of unexpected
 action-at-a-distance instead?

I think our current approach is correct. That is: we invert
junctions on operators that are themselves intrinsically inverted
(such as !=, !~~, !), but do not invert on those that are not
(such as ==, ~~, =). Or rather, we *never* invert junctions at all, but
merely honour the standard semantics of the prefix:! metaoperator:
hoisting the negation outside the entire operation and applying it
once the underlying operation is complete.

The apparent paradox you demonstrated with the two interpretations of
C$foo  ($bar | $zot) is due to the assumption (employed in
the second interpretation) that  is identical to !=. Certainly that is
true for simple scalar numbers, but not always for vector types such as
tuples, sets, bags, complex numbers...or junctions. That doesn't make
either  or != intrinsically invalid on vector types (though they
obviously are inappropriate for *some* vector types); it just means you
can't reasonably treat the two operators as universally interchangeable,
just because they sometimes are.

In summary, the problem here seems to be that, algebraically,
junctions don't behave exactly like non-junctions. Which is true, but no
more a problem than the fact that, algebraically, complex numbers don't
behave exactly like non-complex numbers, or that sets don't behave
exactly like non-sets, or that Rats don't behave exactly like Nums,
which don't behave exactly like Ints, which don't behave exactly like
ints either.

And, of course, that's why Perl 6 has strong typing. So that, when these
differences in behaviour do matter, we can specify what kind(s) of data
we want to allow in particular variables, parameters or return
slots...and thereby prevent unexpected kinds of data from sneaking in and
violating (un)reasonable expectations or inducing (apparent) paradoxes. :-)


With regard to your other point:

 If it's about parallel data handling, then we have to be prepared to
 (notionally) fork the entire rest of the runtime, even as far as
 having a definition of what return value the parent process sees (from
 exit) when those threads are implicitly collapsed at termination.

That's certainly true, although junctions are supposed to guarantee
to coalesce all the threads they may generate back into a single superimposed
result back in the originating thread.

The problem only arises if an operation or subroutine that has been
junctively threaded terminates without returning. But that's just
having a side-effect, which we already know is inappropriate for
junctions (and hyperoperators, and autothreaded loops, and pretty much
any other kind of parallel construct).

Damian


Re: Tweaking junctions

2010-10-26 Thread Damian Conway
Jon Lang wrote:

 Personally, I don't think that it should be a public method: one thing
 about junctions is that you can use them interchangeably with ordinary
 scalars; giving them a public method breaks that.  In particular, code
 that makes use of a Junction public method would break if you were to
 hand it a non-Junction.

On the other hand, I would argue that, because non-junctive scalars are
just an (uninteresting ;-) special degenerate case of junctions, they
should have a public .eigenvalues() too!  It would, of course, just return
their uninteresting degenerate special-case scalar value.

Alternatively, I would note that Perl 6 already provides a perfectly
good way to handle this issue. If you're calling $someval.eigenvalues(),
you're inherently assuming that you're calling it on a Junction. If
there's any possibility that what you're calling it on *isn't* a
junction, then you should either be unsurprised to get the exception that will
be thrown, or else you should explicitly cater to the possibility with:

 my @values = $val.?eigenvalues;

or perhaps:

 my @values = $val.?eigenvalues // $val;

Although, if that second form is to become the standard safe approach,
that argues to me that non-junctions ought to have a .eigenvalues() too,
so that the first alternative above just DWIMs.


BTW, given Larry's recent clarification about Sets producing a list of
their keys in list context, I have absolutely no objection to
.eigenvalues() returning a Set, rather than a List. Indeed, I think it
would be even more valuable that way.

Damian


Re: Tweaking junctions

2010-10-25 Thread Damian Conway
Ben Goldberg asked:

 I'm probably missing something, but wouldn't it have been easier to
 write that module by using eval STRING to create all of those infix
 operators?

Sure. But the module is already slow to start up. I was concerned
that it would get even slower with an embedded eval. But, in the
name of maintainability, I probably should benchmark it both ways.

Thanks for pointing that out, Ben.

Damian


Re: Tweaking junctions

2010-10-25 Thread Damian Conway
Dave Whipp noted:

 I think that the two proposals are equivalent, in the sense that either can
 be trivially implemented using the other.

Agreed.


 However, I am a little concerned that the transjunction magically changes
 an operator that returns a Boolean value into one that returns a list.

Technically, it turns the operator into one that returns a transjunction.

The surprise occurs because tranjunctions self-eigenvalue in a list context.
That's a huge convenience in direct usages, but not an essential component
of the proposal if indeed it proves too surprising in indirect usages.

However, if we did lose that feature then usages like:

say eigenvalues every(@number)  one(3,7);

sacrifices more than a little of the construct's original appeal, I think.


 If I wanted to write intentionally confusing code (which sometimes happens
 due to carelessness) then I might take advantage of the fact that Cevery
 is, in English, a synonym for Call, not Cany:

  if every(@values)  one(3..7) {...}

Yes, Ted Z. pointed out to me that, as the name of this construct,
every has ambiguity and synonym issues. Other possibilities are:

select(@values)  one(3..7)
those(@values)  one(3..7)
whichever(@values)  one(3..7)
itemize(@values)  one(3..7)
extract(@values)  one(3..7)

...of which, only Cselect really seems a good alternative.

Any other suggestions most welcome!

Damian


Re: Tweaking junctions

2010-10-23 Thread Damian Conway
Brandon mused:

 It occurs to me:  If their purpose is that narrow, why are they wasting
 conceptual space in the core language?

Well, mainly because their purpose isn't narrow at all: it's parallelized data
comparisons (all(@values)  $threshold), and multiway comparisons
(all(@values) ~~ any(@ranges)), and distributed sub calls on a
set of arguments (foo(any @alternatives), and subroutine call
parallelism (foo  bar)($arg), and type unions (my Wax|Polish $shimmer),
and type intersections (my $coefficient where Num  0..1), and parallel
lookup of arrays and hashes ($name ~~ %known_aliases{any $suspect}),
and multiway existence checks (if any %f...@args} :exists), and
convenient multiple file tests ($fh ~~ :r  :w  :!x), and overlapping
or exhaustive matches (my $results = m:ex/foo/), and complex matching
logic expressed declaratively (my $is_valid = Num  {$_0} | Str  /zero|one/).

And, of course, they're in the core because there's no point in having
that much power and usefulness if it's not fast too.

Damian


Re: Tweaking junctions

2010-10-23 Thread Damian Conway
 In general I like where this is going but need a little hand holding
 here- I'm not an expert on junctions or anything perl6-

 So I'm going to go on to propose that we create a fifth class of
 Junction: the transjunction, with corresponding keyword Cevery.

 It seems that by these definitions every isn't quite a junction-

It's an unordered collection of values that can be used like a single
value, is parallelizable, and has an intrinsic associated operation.
That's pretty much a junction. The only difference is that the
associated operation is (in a sense) Cgrep, rather than C,
C||, C^^, or C!


 You'll need to specify but not necessarily in the same order if you
 want junctive autothreading to work on every as it does with other
 junctions.

You're quite right. I should have been more specific about that.
And, yes, I certainly do want to leave open the potential for parallel
evaluation.


 In which case it should probably be returning a junction
 and not an ordered list.

If you look at the implementation I appended, any comparison
on a transjunction returns a transjunction. But it turns out to be
much more useful if they also collapse to a list, which is why I
implemented them as a role added to arrays/lists.


 Which reminds me, .eigenvalues strictly speaking is a set and not a
 list.

Sure, but again, it's much more useful as a list. ;-)


 And while I like the cleanliness of the every expressions I'm still
 having trouble seeing why every should behave differently from
 any, all. Maybe every isn't a junction?

Maybe not, in the strictest sense. But it has many of the same characteristics
and is extremely useful in many of the same kinds of ways as a duck^Wjunction.


 Maybe junctions in general need to behave a little differently when
 being compared against then they do now, so the need for every
 goes away?

Interestingly, that was how they were originally defined (back when they
were called Quantum::Superpositions). Comparing a superposition
produced a superposition of just those values for which the comparison
was true.

But I agree with Larry's decision to make junctions behave normally wrt
comparisons. They're much easier to understand the way they are now.

I am merely trying to reintroduce the useful extra concept of a
collection of numbers that filters under comparisons. But if people
aren't comfortable, I'm happy to leave it as a module (especially since
it's already written).

I would hate this (very worthwhile) discussion to distract from the key
point of the original post: namely, that the private C!eigenstates is
misnamed, and a public C.eigenvalues is missing.

Damian


Re: Tweaking junctions

2010-10-22 Thread Damian Conway
Dave Whipp wrote:

 When this issue has been raised in the past, the response has been that
 junctions are not really intended to be useful outside of the narrow purpose
 for which they were introduced.

Hmm. There are intentions, and then there are intentions. I know
what I intended when I invented the original idea, and it wasn't just the narrow
purpose for which they were added to Perl 6. :-)


 Problem 2 could be solved by defining a new (and public!)
 C.eigenstates method in the Junction class. [...]

 I think that you're proposed solution is a bit too specific:

That's because I didn't explain Part B of my nefarious plan! namely
that, if you'd only give me proper eigenstates, I'd give you an even
nicer alternative.

I actually think that the meta doesn't belong on the operator at all
(though I have no problem with that idea in itself).

Instead, I think the meta should be placed on the data (which, of
course, is what any(), all(), one(), and none() already do).

So I'm going to go on to propose that we create a fifth class of
Junction: the transjunction, with corresponding keyword Cevery.

Then we define:

every(@list)  comparision-op  value
every($junction) comparision-op  value

to mean repectively:

grep  * comparision-op value,  @list;
grep  * comparision-op value,  $junction.eigenstates;

as well as the reverses:

value comparision-op every(@list)
value comparision-op every($junction)

to mean respectively:

grep  value comparision-op *,  @list;
grep  value comparision-op *,  $junction.eigenstates;


So then we get:

 sub factors (Num $n) { ( $n/any(1..$n) ).eigenstates.grep({ $^q.Int == 
 $q }); }

 [which] could be:

 sub factors (num $n) { ^$n G[==] $n/any(1..$n) }

could instead be:

sub factors (Num $n) {
 every( $n/any(1..$n) ) ~~ { $^q.Int == $q });
 # Every quotient of N divided by any lesser integer, where
the quotient is also an integer
}


and:

say UNACCEPTABLE.eigenstates¬».fmt(\t%s\n);

 [which] could be

  say (::Str G[eq] UNACCEPTABLE)».fmt(\t%s\n)

could also be:

say (every(UNACCEPTABLE) ~~ ::Str)».fmt(\t%s\n)
# Everything unacceptable that's a string, formatted as follows...


 Operations other than equality could be used:

 say (^10 G[] one(3,7));
 3 4 5 6

which could also be:

say every(^10)  one(3,7);
# Every value up to 10 that's greater than 3 or 7 but not both

And so on:

say every(factor_of($x)  factor_of($y))  10;
# Every common factor of both X and Y that's greater than 10

say every(@coefficient) ~~ 0..1;
# Every coefficient in the range 0 to 1

say every(@string) ~~ /target/;
# Every string that matches the target pattern

I just think those all read much better than the (otherwise excellent)
meta-operator. In much the same way that the existing junctive types
read better than their functional or operator-oriented alternatives.

I'd like these in the core language (for performance and universal
accessibility), but if not, I already have a nearly-complete
implementation of a module implementing them, which runs successfully on
the current release of Rakudo*. I append said model for your amusement
(and suggestions!).

Damian

-cut--cut--cut--cut--cut--cut--cut--cut-

module Transjunctions;

# Add missing public method (and equivalent function) to junctions
#  Call them .eigenvalues(), so as not to clash with existing misnamed
!eigenstates()...
use MONKEY_TYPING;
augment class Junction {
method eigenvalues (Junction $j:) {
my @values = $j.eigenstates;
@values .= map({ $^val.?eigenstates // $^val }) while
@values.grep(Junction);
return uniq(@values).grep($j) does ::Transjunction;
}

sub eigenvalues (Junction $j) is export { $j.eigenvalues }
}


# Transjunctions are just lists that autofilter when matched...
role Transjunction {
method ACCEPTS (Mu $filter) { self.grep($filter) }
}


# Convenient functions to build transjunctions...
multi sub every (*...@list is copy) returns Transjunction is export {
return @list does Transjunction;
}

multi sub every (Junction $j) is export {
return eigenvalues($j) does Transjunction;
}


# Comparing against a transjunction filters it with the comparison
# Rakudo star seems to require we provide two versions, though
# I had expected the Mu version ought to handle both Junctions and Anys...
multi sub infix:«»  (Transjunction $list, Mu $n) is export
{ $list.grep( *   $n ) does Transjunction }
multi sub infix:«»  (Transjunction $list,$n) is export
{ $list.grep( *   $n ) does Transjunction }
multi sub infix:«»  (Transjunction $list, Mu $n) is export
{ $list.grep( *   $n ) does Transjunction }
multi sub infix:«»  (Transjunction $list,$n) is export
{ $list.grep( *   $n ) does Transjunction }
multi sub infix:«=» (Transjunction $list, Mu $n) is export
{ $list.grep( * = $n ) does 

Tweaking junctions

2010-10-21 Thread Damian Conway
I've been thinking about junctions, and I believe we may need a small
tweak to (at least) the jargon in one part of the specification.

Specificially, in S32-setting-library_Containers.pod, we currently have:

=item !eigenstates

method !eigenstates (Junction $j: -- Parcel)

Returns an unordered list of the values that constitute the junction
(formerly called C.values). It flattens nested junctions of the
same type, so C(1|(2|3)).eigenstates returns an arbitrary
permutation of the list C1, 2, 3.

The problem is the *name* of that method. By definition, the eigenstates
of a junction are those non-superimposed values to which the junction's
superimposed values could actually collapse. Or, to put it another way,
those non-superimposed values that a junction would actually match.

That is, a C$value is an eigenstate of a C$junction if-and-only-if:

$value !~~ Junction$value ~~ $junction

But the C!eigenstates method (as currently defined) does not return
a list of such eigenstates. Instead it merely returns a partially-flattened
list of the raw internal values of the junction...which is not (usually) the
same thing at all.

That's because junctions often contain internal values to which *externally*
they cannot actually collapse...and hence cannot actually match.

Some examples, to illustrate the distinction:

Internal states   Actual eigenstates
Junction(what !eigenstates returns)   (what junction could match)
=   ===   ===
any(1,2,3)  1, 2, 3   1, 2, 3

all(1,2,3)  1, 2, 3   none

one(1,2,3)  1, 2, 3   1, 2, 3

none(1,2,3) 1, 2, 3   infinitely many

any(12, 23)   all(1,2), all(2,3)none

all(1|2, 2|3)   any(1,2), any(2,3)2

one(1|2, 23)   any(1,2), all(2,3)1, 2

one(1|2, 2|3)   any(1,2), any(2,3)1, 3


So the two problems are:

1.  $j!eigenstates doesn't return $j's eigenstates
(i.e. the method is misnamed)

2.  $j!eigenstates doesn't return $j's eigenstates
(i.e. there's no way to get a junction's actual eigenstates,
 which is a very useful thing to be able to do--see below)


Problem 1 could be solved by renaming the method C!eigenstates
to something like: C!internal-states. And, of course, renaming the
corresponding attribute in the Junction class from C$!eigenstates
to something like C$!internal-states.


Problem 2 could be solved by defining a new (and public!)
C.eigenstates method in the Junction class. This method
would be implemented as something like:

method eigenstates(Junction $j: -- List) is cached {

# No feasible way of representing the eigenstates of an injunction...
fail if $j!type ~~ JUNCTION_TYPE_NONE;

# Candidates for eigenstates are all the junction's internal values...
my @possible-eigenstates = $j!internal-states;

# Or, rather, candidates are all its *non-superimposed* internal values
# so we need to iteratively flatten any superimposed values...
@possible-eigenstates
.= map({$^value ~~ Junction ?? $^value!internal-states !! $^value})
while @possible-eigenstates.grep(Junction);

# Actual eigenvalues are those unique candidates
#   that successfully match the original junction...
return uniq(@possible-eigenstates).grep($j);
}

There is no need for this new C.eigenstates method to be private,
because it doesn't expose the internal data of its junction object,
but rather calculates a useful external property of that object.

Some examples of why that the actual eigenstates of a junction are useful
(note that these all assume the above (re)definition of C.eigenstates):

# Find the list of common elements in two lists...
sub intersection (@list1, @list2) {
(any(@list1)  any(@list2).eigenstates;
}


# Find the factors of a number...
sub factors (Num $n) {
( $n/any(1..$n) ).eigenstates.grep({ $^q.Int == $q });
}


# Check for an unacceptable password, and list all when warning...
constant UNACCEPTABLE = any  Godel Escher Bart etc... ;

if $passwd ~~ UNACCEPTABLE {
say Unacceptable password. Don't use any of these:;
say UNACCEPTABLE.eigenstates¬».fmt(\t%s\n);
}


If nothing else, we really do need to rename the current C!eigenstates method.

Damian


PS: I also note that the most recent release of Rakudo* defines the
C.eigenstates method as public, which is inconsistent with the
current specification. That probably needs to be fixed as well.


Re: threads?

2010-10-12 Thread Damian Conway
Leon Timmermans wrote:

 For the love of $DEITY, let's please not repeat ithreads!

$AMEN!

Backwards compatibility is not the major design criterion for Perl 6,
so there's no need to recapitulate our own phylogeny here.

The problem is: while most people can agree on what have proved to be
unsatisfactory threading models, not many people can seem to agree on
what would constititute a satisfactory threading model (or, possibly, models).

What we really need is some anecdotal evidence from folks who are actually
using threading in real-world situations (in *any* languages). What has worked
in practice? What has worked well? What was painful? What was error-prone?
And for which kinds of tasks?

And we also need to stand back a little further and ask: is threading
the right approach at all? Do threads work in *any* language? Are there
better metaphors?

Perhaps we need to think more Perlishly and reframe the entire question.
Not: What threading model do we need?, but: What kinds of non-sequential
programming tasks do we want to make easy...and how would we like to be
able to specify those tasks?

As someone who doesn't (need to) use threading to solve the kinds of
problems I work on, I'm well aware that I'm not the right person to help
in this design work. We need those poor souls who already suffer under
threads to share their tales of constant misery (and their occasional
moments of triumph) so we can identify successful patterns of use
and steal^Wborg^Wborrow the very best available solutions.

Damian


Re: [perl6/specs] 58fe2d: [S12] spec setting and getting values of attribute...

2010-09-30 Thread Damian Conway
On 30 September 2010 06:09,  Moritz wrote:

 After lengthy IRC discussion, we concluded that it's a good idea to provide
 some form of introspection that doesn't bother about perceived privacy
 borders, provided that the implementation makes it feasible.

Wow, that's the first time I've ever been sorry not to be on IRC!

Talk about snatching (directly accessible) defeat from the jaws of
(encapsulated) victory. :-(

Could we at least specify that .get_value() and .set_value() can only
be called if the calling scope declares a Cuse MONKEY_TYPING;
so that violations of good OO practice are explicitly marked in a
consistent and easily searched-for manner?

Damian


Re: [perl6/specs] 58fe2d: [S12] spec setting and getting values of attribute...

2010-09-30 Thread Damian Conway
Carl wrote:

 For what it's worth, we had exactly this discussion a couple of days
 ago on IRC. I represented your views above, Damian.

Thank-you for that.


 As long as C.perl works the way it does, there can be no real
 privacy.

Sigh. That is indeed badly broken. Surely it ought to default to Cdie,
and require class architects to override .perl explicitly if they wish to
break encapsulation.


 And thus C.get_value and C.set_value are just convenient
 access points for the same behaviour.

Yes. People are going to shoot themselves in the foot anyway,
so let's legalize semi-automatic weapons as well.


 I'm still undecided on whether or not I think Cuse MONKEY_TYPING; is
 the right way to enable this kind of privacy breakage. Maybe nothing
 is needed, since the C^ in C$obj.^attributes (or the CHOW)
 already says warning! meta!.

Except that, if the Attribute object is passed around, it may be saying
warning! meta! in a completely different scope, in a completely
different file.

Damian


Re: [perl6/specs] 58fe2d: [S12] spec setting and getting values of attribute...

2010-09-30 Thread Damian Conway
Moritz wrote:

 To re-iterate, Perl 6 has no real privacy by default -- both the
 default .new and .perl methods give you access to private attributes,
 unless you explicitly override them.

At least you *can* explicitly override them (and perhaps factor that out
into a role that you could always use). But even then, I suppose, that's
still all to easy to bypass, with a fully qualified call, if the core
.perl stays
broken. :-(


 I would be fine with changing get_value and set_value method names to all
 uppercase, as an additional warning sign, if that would comfort you in some
 way.

Thank-you, but no. Shouting doesn't really solve my problem.

I'm looking for a consistent way to identify dangerous code. And we
already have that, in the form of Cuse MONKEY_TYPING;. What would
comfort me would be if objects and classes could actually be relied upon
to be properly encapsulated and stable, unless someone explicitly
declares they are monkeying.

As it stands at the moment, it's not clear to me why we even bother with
opaque objects, if it's going to be this trivial to break encapsulation.

Damian


Re: [perl6/specs] 58fe2d: [S12] spec setting and getting values of attribute...

2010-09-30 Thread Damian Conway
Moritz writes:

 Objects that you can't do that with don't make sense to be serialized and so
 .perl can reasonably refuse to work on them.

 method perl {
die Can't serialize objects of type $?CLASS, because ...;
 }

Sure. But now the cautious programmer has to add that to *every* class
hierarchy.
So we start to see endless variations on:

role ProperlyEncapsulated { method perl {die} }

class MyClass does ProperlyEncapsulated {...}
class AnotherClass does ProperlyEncapsulated {...}
class YetAnotherClass does ProperlyEncapsulated {...}

which would be a sad indictment on Perl 6's otherwise brilliant OO model
(and will encourage all the OO bully languages to publicly kick sand
in our face).


 My proposal: the default .perl method should only spit out value for
 public attributes, ie those that have accessors.

I'd be happy with that.

 Maybe .new should also default to his behavior.

I'd be happy with that too.


 Then Damian's position (which I support) is supported and so are monkeys.

 Ook ook!

Apes! I meant apes!!! ;-)


 Moritz
 (who actually writes Perl 6 code on a nearly daily basis).

Damian
(who does too)


Re: [perl6/specs] 58fe2d: [S12] spec setting and getting values of attribute...

2010-09-30 Thread Damian Conway
Jonathan wrote:

 Sounds like the encapsulation breaking thingy probably wants to be looking
 for some pragma to have been used in the lexical scope of the caller, maybe.
 I'd rather that we called it something other than MONKEY_TYPING though.
 Different evil, different pragma. :-)

As long as it's easily searchable and vaguely pejorative (e.g. has the
work MONKEY in it).

Hm. You need to use MONKEY_TYPING when you're monkeying with typing,
so maybe when you're monkeying with what can be seen (and abusing Perl
6 as if it were C)
then you need to use MONKEY_SEE

Damian


Re: How are unrecognized options to built-in pod block types treated?

2010-08-04 Thread Damian Conway
Carl proposed:

 The other path that seems reasonable to me would be to use the same
 naming scheme as for the block types, i.e. reserve all-upper and
 all-lower forms (and die if an unrecognized one of this form is
 encountered), and let the custom ones live in the namespace of
 mixed-case identifiers. That sounds sane to me as well; the only
 question is whether that much structure is needed for config options.

I did not consider this issue when designing S26, but in considering
it now, I think Carl's suggestion is entirely sensible and in line with
what I intended.

Specifically, I think it would be easiest to be consistent and say
that all purely lowercase and all purely uppercase config option names
are reserved, and that unrecognized reserved config options generate
at least a warning when they are parsed. Mixed-case config options
should be freely available to users and the parser should simply
accept them without complaint and include them in the internal data
structure it builds, whereupon they will be available to user-defined
Pod extensions.

Damian


Re: How are unrecognized options to built-in pod block types treated?

2010-08-04 Thread Damian Conway
Aaron wrote:

 I dislike reserved in this context, but understand why the namespace has
 to be shared. For config options, I'd say anything should go, but people
 inventing their own config options should be aware that across N release
 cycles, new options may be introduced.

...which means that sensible people will avoid those namespaces anyway,
so they might as well be reserved...which then enables us to warn any
not-so-sensible people that their choice of an all-lower- or all-upper-case
option name is brittle and likely to end in tears.

BTW, I also like Darren's suggestion to restrict the reserved space for
standard typenames and option names to the ASCII range.

Dåmîäñ


Re: series operator issues

2010-07-22 Thread Damian Conway
On 23 July 2010 01:41, Moritz Lenz mor...@faui2k3.org wrote:

 Use the right tool for the right job:

    square numbers: 0, 1, 4, 9, 16, 25, 36, etc.

   (1..10).map(* ** 2)

Or even just:

(1..10) »**» 2

Note that you can also get most of the effects you want by using
@_ in the series' generator block. For example, here are all the
square numbers:

0, { @_**2 } ... *

and all the factorials:

1, { (@_+1) * @_[*-1]  } ... *

or all the factorials more prettily but less inefficiently:

1, { [*] 1...@_  } ... *


However, those *are* clunky and nigh unreadable, so I certainly wouldn't
object to having the index of the next generated element readily
available as an explicit variable in a series' generator block.

That would make all manner of evil both easier and cleaner. ;-)

Damian


Re: underscores vs hyphens (was Re: A new era for Temporal)

2010-04-11 Thread Damian Conway
Well, if we're not going to try to implement linguistically based
hyphenation/underscoriation rules (and I'd still argue that hyphenating
adjectives to nouns and underscoring everything else isn't exactly
rocket science), then I'd suggest we reconsider a radically different
proposal that was made on this list five years ago:

http://www.mail-archive.com/perl6-language@perl.org/msg22675.html

The relevant suggestion regarding hyphens vs underscores is:

...to allow both characters, but have them mean the same thing.

That is, any isolated internal underscore can be replaced with an
isolated internal hyphen (and vice versa), without changing the meaning
of the identifier.

This would be the death of fine distinctions such as between:

activate_main-sequence_detonator();

and:

activate_main_sequence-detonator();

which would now resolve to the same subroutine...and do so even if
that subroutine had been declared as

sub activate-main-sequence-detonator {...}

But perhaps such distinctions are indeed too fine and subtle, and we
would be better off eliminating the possibility of them entirely.

Hyphen/underscore equivalence would allow those (apparently elite few) who
can correctly use a hyphen to correctly use the hyphen, whilst the
shambling masses can just randomly type underscores or hyphens between
each word, as their atavistic whims dictate.

;-)

Damian


Re: underscores vs hyphens (was Re: A new era for Temporal)

2010-04-10 Thread Damian Conway
Personally, I'd prefer to see the English conventions carried over to
the use of general use of hyphen and underscore in identifiers in
the core (and everywhere else).

By that, I mean that, in English, the hyphen is notionally a
higher precedence word-separator than the space
(or than its intra-identifier stand-in: the underscore).

For example: there's an important difference between:

initiate_main-sequence_detonator_phase()

and:

initiate_main_sequence-detonator_phase()

The former initiates the detonator phase for the main sequence;
the latter initiates the main phase of the sequence detonator.

More simply, there's a difference between:

 $obj1.set_difference($obj2);

and:

 $obj1.set-difference($obj2);

The first is setting a difference; the second is computing a difference-of-sets.

The rule I intend to use and recommend when employing this new
identifier character in multiword names is that you should place an
underscore between ordinary unrelated words, and a hyphen only
between a word and some modifier that applies specifically to that word.

Which, if applied to Temporal, would lead to:

my $now = DateTime.from_epoch(time);

The Cday method also has the synonym Cday-of-month.

(These are also available through the methods Cweek-year and
Cweek-number, respectively.)

There's a Cday-of-week method,

The Cweekday-of-month method returns a number 1..5

The Cday-of-quarter method returns the day of the quarter.

The Cday-of-year method returns the day of the year,

The method Cwhole-second returns the second truncated to an integer.

The Ctime-zone method returns the CDateTime::TimeZone object

(i.e. only C.from_epoch() actually uses underscore).

Oh, and the optional C:timezone argument to C.new() should probably
become C:time-zone for consistency with the C.time-zone() method
(or, preferably, we should jut bite the bullet and go with Ctimezone
throughout).

Damian


Re: underscores vs hyphens (was Re: A new era for Temporal)

2010-04-10 Thread Damian Conway
John Siracusa commented:

 That's certainly an example of how hyphens might gain meaning in Perl
 6 names, but I don't think I can endorse it as a convention.  People
 can't even use hyphens correctly in written English.  I have very
 little faith that programmers will do any better in code

But then the only alternative is to suffer under Slartibartfast's Conundrum:

Slartibartfast: I'd much rather be happy than right, any day.
   Arthur Dent: And are you?
Slartibartfast: Ah, well...that's where it all falls down, of course.

;-)

And is it really so hard to teach: use underscore by default and reserve
hyphens for between a noun and its adjective? Perhaps it *is*, but
then that's a very sad reflection on our profession.

I'm certainly not saying we mightn't collectively find a better (more
useful) rule, but that one doesn't strike me as particularly hard.

Damian


Re: A common and useful thing that doesn't appear to be easy in Perl 6

2010-04-07 Thread Damian Conway
Larry mused:

 Alternatively, maybe there should be some way to express infinite sets.
 Not sure I like the idea of an infinite junction, but something resembling:

    subset PowersOf2 of Int where any(1,2,4...*)
    enum Perms of PowersOf2 Read Write Exec;
    say Exec;  # 4

 Presumably the series in the junction would have to be sufficiently
 monotonic so we can know when we've looked far enough.  Or we just
 allow something like one of:

    subset PowersOf2 is Set(1,2,4...*);
    constant PowersOf2 = Set(1,2,4...*);

 In any case, the idea is that an enum of something like PowersOf2 would
 be smart enough not to use values that aren't in the 'of' type.

I do like the idea of being able to specify the sequence of values of an
enumeration by using a series of some kind.

And I must say the one that feels most natural is the one that plays on
the equivalence of underlying equivalence of enums and constants, namely:

enum Perms Read Write Exec Fold Spindle Mutilate = 1,2,4...*;

This would also mean you could think of a normal enum:

enum Days Sun Mon Tue Wed Thu Fri Sat;

as simply defaulting to C = 1...* .


 We've got these silly series operators; it seems a shame not to use
 them for powers of two when appropriate.

I certainly agree there.

Damian


Re: A common and useful thing that doesn't appear to be easy in Perl 6

2010-04-07 Thread Damian Conway
Daniel Ruoso pointed out:

 Using bitsets in Perl 6 is just as easy as using in Perl 5 -- which
 happens to be the same as using in C, but it's not C...

 constant PERM_WRITE = 0b0001;
 constant PERM_READ  = 0b0010;
 constant PERM_EXEC  = 0b0100;
 constant PERM_NAMES = { PERM_WRITE = 'Write',
PERM_READ  = 'Read',
PERM_EXEC  = 'Exec' };
 subset Perm of Int where *  8;

Sure. This certainly works, but the technique requires the developer to
hard-code each name twice and to hard-code the constant 8 as well.
This seems unfortunately brittle from a maintainability point of view.

I know hardware engineers aren't supposed to care about maintainability,
but I'd like us to make it easier for them to do the right thing than not. ;-)


 The thing that bugs me is that sets have way more uses then bitsets, and
 we might be overspecializing sets to support that semantics.

Yes. I have the same concern.


 If there's a strong case for bitsets, maybe it's worth having a
 specialized declarator.

Or maybe it doesn't need to be core syntax at all and I just need to create
a module that implements my original dream syntax/semantics; namely
a macro implementing a Cbitset type declarator that allows:

use Type::Bitset;

bitset Perms Read Write Exec Fold Spindle Mutilate;
# Declares enumerated constants with successive powers-of-two values
# Also declares: subset Perms of Int where 0 .. [+|] @constant_values;
# Hence allows:

my Perms $perms = Read +| Write +| Mutilate;   # Okay

my Perms $bad_perms = Read +| Write +| 42; # Error

Aw heck, now that I've specified it, the implementation is just a SMOP.
Forget I asked. I'll just write it myself! ;-)

Damian


Re: A common and useful thing that doesn't appear to be easy in Perl 6

2010-04-07 Thread Damian Conway
Jonathan Lang wrote:

 Wouldn't that be C = 0...* ?

Indeed. Thanks for the correction.


 That said, don't we already have a means of assigning specific values
 to individual members of an enum?  I forget the exact syntax,

The exact syntax is:

enum Perms [Read = 1, Write = 2, Exec = 4, Fold = 8, Spindle
= 16, Mutilate = 32]

or

enum Perms  :Read(1), :Write(2), :Exec(4), :Fold(8),
:Spindle(16), :Mutilate(32) 

or any other variation that uses a list of pairs.


 Clumsy, sure;

The clumsiness isn't the main problem, in my view; the explicitness of
having to provide the values is.

Even the hyperoperated version (which isn't currently legal, BTW)
requires an explicit series to generate the values. Yet the whole point
of enums is to avoid explicitly enumerating the values (as far as
possible).

The secondary point here is that an enum type doesn't solve the original
problem, since it won't allow combinations of enumerated values:

enum Perms [Read = 1, Write = 2, Exec = 4, Fold = 8, Spindle
= 16, Mutilate = 32];

my Perms $perms = Read +| Write; # Error

I'm now strongly convinced that a module is the right answer here. We
have the need for a datatype that is essential is a couple of domains,
but much better handled via Sets in most other contexts. So it's
inherently a special-purpose datatype, and hence not appropriate in the
core language. And Perl 6 already provides the macro mechanism needed to
allow such a datatype to be seamlessly added with a convenient and
natural syntax. Which is what I shall eventually do, I suspect.

In that sense this discussion *vindicates* the current design,
demonstrating that it provides the necessary flexibility and tools to
allow someone to implement a new datatype and declarator syntax and
integrate them seamlessly into the language, without having to redefine the
language itself...or modify the compiler.

Damian


Re: A common and useful thing that doesn't appear to be easy in Perl 6

2010-04-07 Thread Damian Conway
 We could make enum declarators even more like constant declarators
 by using a pseudo assignment.  Then we could use = instead of parens:

    enum Perms = Read Write Exec Fold Spindle Mutilate Z= 1,2,4...*;

Hmm. That doesn't seem very like constant declarators. In a
constant declarator,
the constant appears on the lhs and its value on the rhs. In this
proposal, the constants
all appear on the rhs, along with the values. Besides, enums are type
declarators, not
(just) object declarators, and no other type declarator uses a
pseudo-assignment, does it?

If we wanted enums to use something more like the constant declarator
syntax, I'd have thought:

enum Perms Read Write Exec Fold Spindle Mutilate =  1,2,4...*;

was a much closer analog (and syntactically cleaner too).

Damian


A common and useful thing that doesn't appear to be easy in Perl 6

2010-04-06 Thread Damian Conway
An issue came up in a class I was teaching today...

There doesn't seem to be an easy way to create a type that allows a set
of enumerated bit-flags *and* all the combinations of those flags...and
nothing else.

For example:

 enum Permissions ( Read = 0b0001, Write = 0b0010, Exec = 0b0100 );

 my Permissions $rwx = Read +| Write;# Error


I know I could use junctions:

subset BitFlag where Read|Write|Exec;

my BitFlag $rwx = Read | Write;

but it's not easy to recover the actual bitpattern from that, except with:

$bitpattern = [+|] $rwx.eigenstates;

which is suboptimal in readability (not to mention that it requires
MONKEY_TYPING to allow access to the .eigenstates method).


Ideally, what I'd like to be able to do is something like:

enum Permissions is bitset  Read Write Exec ;

# The 'is bitset' starts numbering at 0b0001 (instead of the usual zero)
# and doubles each subsequent enumeration value (instead of the usual ++).
# It also implicitly fills in the various other bitwise-or permutations
# as valid-but-nameless enumerated values

my Permissions $rwx = Read +| Write;# Now fine


The closest I can think of at the moment is something like:

enum NamedPermissions ( Read = 0b0001, Write = 0b0010, Exec = 0b0100 );

subset Permissions of Int where 0 .. [+|]NamedPermissions.enums.values;

my Permissions $rwx = Read +| Write;# Fine

which is still a little too constructive, too explicit (you have to get the
bit values right), as well as being too obscure for such a common task.


Of course, I could always create a macro to encapsulate the explicit
constructive obscurity:

macro bitset ($typename, @value_names)
is parsed(/:s (ident) '' ( ident )+ '' /)
{
# [build code to implement the above trick here]
}

# and later...

bitset Permissions  Read Write Exec ;

but this is such a common requirement in engineering applications that it
would be great if this wheel didn't constantly have to be reinvented.


If anyone can think of a cleaner way to do it within the current semantics,
I'd be very happy to hear of it. I'm jetlagged and bleary from a full day of
teaching and I may well be missing an obvious answer.

Thanks,

Damian


Re: A common and useful thing that doesn't appear to be easy in Perl 6

2010-04-06 Thread Damian Conway
Larry concluded:

 I do freely admit that most Perlfolk are not used to thinking of
 permissions in terms of set theory.  But as I said, we're looking at
 kind of a strange use case here, and perhaps not typical of the kinds
 of sets of small numbers that people will be using in the future.

The reason I raised the issue is because I believe it *is* a very
typical use-case...in certain hardware-oriented domains.


 I kinda hope we can get a bit further away from the machine code
 level of reality one of these decades.  Perl 6 should not be
 optimized for C semantics.

Agreed. But it should at least support those who need to work at
the machine code level, but would prefer not to have to do so in C.

That said, I'd be perfectly happy to encourage the use of proper set
abstractions for this purpose, so long as the long-suffering hardware
engineers can still easily convert the final set to an appropriate
bit-pattern when it's time to pump the results out to the hardware.

Damian


Re: continuation markers for long literals (was Re: r29931 - docs/Perl6/Spec)

2010-03-03 Thread Damian Conway
Surely this is not a common-enough requirement to warrant a special
syntax.

At 80-columns, you can represent integers up to ninety-nine
quinvigintillion, nine hundred ninety-nine quattuorvigintillion, nine
hundred ninety-nine trevigintillion, nine hundred ninety-nine
duovigintillion, nine hundred ninety-nine unvigintillion, nine hundred
ninety-nine vigintillion, nine hundred ninety-nine novemdecillion, nine
hundred ninety-nine octodecillion, nine hundred ninety-nine
septendecillion, nine hundred ninety-nine sexdecillion, nine hundred ninety-
nine quindecillion, nine hundred ninety-nine quattuordecillion, nine
hundred ninety-nine tredecillion, nine hundred ninety-nine duodecillion,
nine hundred ninety-nine undecillion, nine hundred ninety-nine
decillion, nine hundred ninety-nine nonillion, nine hundred ninety-nine
octillion, nine hundred ninety-nine septillion, nine hundred ninety-nine
sextillion, nine hundred ninety-nine quintillion, nine hundred ninety-
nine quadrillion, nine hundred ninety-nine trillion, nine hundred ninety-
nine billion, nine hundred ninety-nine million, nine hundred ninety-nine
thousand, and nine hundred ninety-nine.

Surely that's enough for the vast majority of users, isn't it?

And if you *do* need anything bigger (perhaps to represent the burgeoning
U.S. national debt) then there's always some variation on:

my $debt = +(
123456789012345678901234567890123456789012345678901234
  ~ 567890123456789012345678901234567890123456789012345678
  ~ 901234567890123456789012345678901
);

or even:

my $debt = +(
123_456_789_012_345_678_901_234_567_890_123_456_789_012_345_678_901_234
  ~ 567_890_123_456_789_012_345_678_901_234_567_890_123_456_789_012_345_678
  ~ 901_234_567_890_123_456_789_012_345_678_901
);

if you like to group your thousands for better readability.

With adequate constant folding, both of those are still compile-time constants.

Damian


Re: r29768 - docs/Perl6/Spec

2010-02-19 Thread Damian Conway
 +    rhyme((1,2),3,:miceblind)   # rhyme has 2 arguments

 Should that say 3 arguments?

I believe so.


 (If not, please can somebody clarify what
 the 2 arguments are.)

 (1,2) and 3.  Named arguments (mice in this case) are handled separately.

That interpretation is not consistent with the other examples
immediately above and below it.

Damian


Re: Gripes about Pod6 (S26)

2010-02-10 Thread Damian Conway
Carl observed:

 Partly that is because documentation isn't at the forefront of things
 that need to be implemented for Perl 6 to be useful, so it's kind of
 lagging behind the rest.

 Partly it's because Damian is the owner of that synopsis, and he
 practices a kind of drive-by-updating to it. As a case in point of
 this latter effect, the extensive changes made by Damian in August
 *still* haven't hit the Pugs repo.

The latter is entirely true but, fortunately, also very easily remedied.
I hereby disclaim all present and future ownership of S26. :-)

By all means put the latest update on the repo (or maybe remove S26
entirely), and start redesigning it collaboratively.

Please note that I am not in any way upset, angry, petulant, or
otherwise disaffected. I only want the very best for every aspect of
Perl 6. If the experience of respected and active developers suggests
that Pod 6 isn't a step in the right direction, I can only feel
disappointed in myself, apologize for my failure, and gratefully turn
the task over to those with better ideas and more time and energy to
devote to the problem.


As regards Pod vs Pandoc (which is pretty clearly the leading
contender of the structured text notations), I do think Pod has some
decided advantages. For example, I feel it's better to have four basic
metasyntaxes (X, =IDENT, :OPTION, #=) and most with identifier-based
labels, than to have over two dozen (plus embedded HTML and TeX) all
with symbolic labels.

I guess I feel that Pandoc/Markdown/ReST/etc. are optimized for writing
documentation source, whereas Pod is optimized for reading
documentation source. I'm not sorry I aimed for the latter, whatever the
deficiencies in the result.


Carl also suggested:

 I think that the future of S26 is very much dependent on whether it'll
 be able to respond to the needs of Perl 6 developers. Right now it
 doesn't respond to much of anything.

Outwardly this is self-evidently true. One need only look at the (lack of)
commit log for S26. :-(

Inwardly, something else entirely is happening. A design(er) can only
respond effectively when subjected to a clear net force pushing or
pulling in some well-defined direction. The redesign of Pod has been
subject to an enormous number of such forces. Unfortunately they push
and pull it in every possible mutually contradictory direction, thereby
producing very little overall impetus.

So I would encourage those of you who are going to collectively take
over the shepherding of this synopsis to go back through the p6l
archives and review the many many posts commenting on and requesting
features for Perl 6 documentation.

In particular, please look carefully at the very different needs of
those who document OO code, procedural code, frameworks, modules,
applications, design documents, presentations, and Perl itself. You will
find that many of these contributors ignore, discount, or actively
disparage the needs of their fellow users.

For example, in this very thead:

 I'm not writing a book, I'm writing code. And if I was writing a book,
 I wouldn't be dumb enough to write it in POD.

Yet what is the Perl documentation itself but a series of book chapters?
And surely that documentation is the largest single use of Pod anywhere?
Should we not write Perl's own documentation in Perl's own documentation
notation? Should we really discourage the use of standard headings to
consistently mark the common components of these (and most other)
Perl-related documents?

I sincerely hope that the future community of designers of Perl 6 's
documentation format will find a way to honour and support the very
different needs of *all* the creators and users of Perl, not just the
needs of the most prominent, or the needs of the most experienced, or
the needs of the most loquacious.

I have always thought that was the *real* challenge
of post-modern language design.

Damian


Re: S26 - The Next Generation

2009-09-17 Thread Damian Conway
Aaron Sherman asked:

 Should there be an explicit way to step this down to just parsing the bits
 that are called out as pod?

The original conception allowed for Pod to be independent of the
interleaved language. That has now been supplanted by a model that views
Pod as an integral part of Perl. There's definitely a trade-off there,
but one we've decided to make.

So, no, there are no longer any plans to extend Pod to documenting
*everything*, except so far as Perl 6 will be ale to subsume everything
(in line with Larry's musings of braided languages).


 There is no explicit mention in the document as to what happens at the Perl
 level when the closing bracket is reached at a point that is not the end of
 a line (i.e. it is not followed by whitespace that contains a newline
 character). Here's an example:

    my $a #-[stop the presses!] = 4;

Except for the #~ instead of #=, that's valid (and documented) Perl 6.

That is, Pod comments work exactly like non-Pod comments.
As Synopsis 26 now states:

That is, declarator Pod blocks are syntactically like ordinary Perl 6
single-line comments and embedded comments.


   * This new declarator block form is special. During source code parsing,
     normal Pod blocks are simply appended into an array attribute of
     surrounding Comment object in the AST (which is just $=POD, at the
     top level). However declarator blocks are *also* appended to the
     .WHY attribute of the declarator at the start of the most recent
     (or immediately following) line.

 I'd very much like to establish that at default optimization levels for
 execution, this information is not guaranteed to be maintained past the
 creation of the AST.

Unfortunately, it is. Perl 6 defines that Perl 6 programs can always
access their own Pod at runtime (via $=POD). You probably can't even
optimize the information away in the absence of any compile-time
reference to $=POD, since there are plenty of symbolic ways to refer to
$=POD at run-time.

Damian


Re: S26 - The Next Generation

2009-09-17 Thread Damian Conway
yary asked:

 Can some concept/implementation of $=POD lazyness only incur the
 memory and performance hit on access?

IANAImplementor, but I suspect that virtually all of the performance hit
could be incurred at run-time, if it happened to be implemented that
way. The memory hit too, if necessary, but that would then make the
performance hit hit very hard indeed. I suspect that it would be better
to preserve the Poddish parts of the AST structure and just have them
transmogrify into the appropriate Pod objects on demand.

Damian


Re: Looking for help updating Perl 6 and Parrot part of Perl Myths talk

2009-09-14 Thread Damian Conway
Darren Duncan wrote:

  pg 36 - About the Perl Best Practices book, you should be clear to
 mention that what is considered best practices has evolved significantly
 since that book came out, so teams can't simply agree on We'll just follow
 PBP guidelines and call it a day, but should study more modern resources
 also;

While it's certainly true that best practices have evolved (and
modernized ;-) since PBP came out, teams *can* still simply agree to
follow PBP. They won't we as well off as if they'd thought about the
issues themselves (i.e. read and followed the advice in Chapter 1) and
explored the various modern/evolved resources now available, but they'd
still be much better off than they are at present.

Not everyone has the time, inclination, or capacity to evaluate
the myriad possibilities and make informed personal judgements in
every case.

Ideally, if you mention PBP, describe it as a starting point (which is
how it describes itself in Chapter 1, btw), and the various Enlightened
and Modern Perl movements as evolutionary resources for going much
further in certain very specific directions.


  in particular the recommendation to use Class::STD/etc is outdated,
 and people should use Moose instead.

There is no doubt that Moose is an excellent and very advanced framework,
but both the above assertions are highly debatable, especially if you
s/moribund Class::Std/actively developed Object::InsideOut/.

Damian


Re: Looking for help updating Perl 6 and Parrot part of Perl Myths talk

2009-09-14 Thread Damian Conway
Darren Duncan wrote:

 So another proposal I have is to add to the slideshow mentions of the
 Enlightened and Modern Perl movements and where one can go to read more,
 this being supplemental to PBP.

With that suggestion I'd whole-heartedly concur.


 My own opinion is that the modern best way to use inside-out objects is in
 combination with Moose, as the physical representation used for objects
 behind the scenes, rather than each user class having direct package
 lexicals like %foo_attr and %bar_attr.

No doubt that's a best-of-both-worlds solution...for those who can handle it.
I guess my point is simply that not everyone can handle it. Just as not
everyone could handle raw inside-out techniques, which is why Class::Std
was written in the first place.

But, as you say, this is now far off-topic, so let's leave it at that.

Damian


Re: S26 - The Next Generation

2009-09-08 Thread Damian Conway
Jon Lang elaborated:

 I don't think that there will be a problem.  First, #= is easy enough
 to distinguish from #=; I don't foresee any confusion.

I'm not so sure. #= is a lot more like #= that =alias is. And the one
character of difference is on the non-significant (right-hand) side.
Need to think about it and role-play it a little.


 With the ability to attach multiple declarator blocks to a single
 declarator, it should be trivial to replace any one of them with a
 declarator alias:

    #=
    class Foo {
        #= Class Foo
        #= a sample class used to illustrate.
        #= This particular class has nothing in it.
    }

See that's precisely my problem. I don't think the #= stands out at all
there as being an alias.


    #= Class Aclass
    class Foo {
        #= a sample class used to illustrate.
        #= This particular class has nothing in it.
        #= Xthis assigns to the 'class' declarator alias.

And this illustrates my other qualm, that the two forms are just too similar.

And, yes, having the aliasing mechanism be something postfix(able) creates
issues of when the aliases come into existence.


 I tend to agree.  I only proposed numbering as a way of being able to
 access different declarators without having to explicitly label them.
 I can definitely understand if this option gets dropped as being too
 error-prone with regard to maintenance.

That's my plan.


    =alias
    class Database::Handle {
        =alias
        has IO $!handle;

        =alias open
        my Bool method open ($filename) {...}

        =alias close
        my Bool method close() {...}

        =for para
            Note that the Aopen method of class Aclass
            stores the resulting low-level database handle
            in its private Ahas attribute, while the Aclose
            method closes that handle.
    }

 The problem with this example is that '=alias name' isn't a declarator
 alias; it's a block alias.

I'm proposing to change that and allow explicit names on declarator
aliases as well.
Or, rather, to unify the two into a block-or-declarator alias.

        my Bool method open ($filename) {...} #=[m1] #= Here's a
 block for Am1.
        my Bool method close () {...}         #=m2

 And given that brief names are going to be preferred, this could
 result in very compact, yet still readable, combinations of declarator
 aliases and blocks.

Yes, this is a definite advantage of the proposal. No question.
But I'm still concerned that the two syntaxes are just so similar.
I'll continue pondering the trade-off.

Damian


Re: S26 - The Next Generation

2009-09-08 Thread Damian Conway
Jon Lang huh'd:

 Huh.  Would you be able to do something like:

    =begin pod
    Welcome to $?FILE.

 ...and have it interpolate the file's name?  Or would you need some
 special markup for this, such as:

    =begin pod
    Welcome to A$?FILE.

The latter. Variables are just too common in documentation to
have (some of) them interpolate automagically.

 Or would you have to alias the variable and then refer to it?

No. I envisage that A would recognize an alias starting with a sigil,
and auto-alias it for you.

Damian


Re: S26 - The Next Generation

2009-09-07 Thread Damian Conway
Raiph elucidated:

 Hmm. I was thinking Pod would be parsed by a P6/PGE grammar, one that
 could be relatively easily edited/extended to suit another context, because,
 I thought, it could then be made available as a stock --doc subsystem that
 all PCT based languages get more or less for free.

Sure, that might be possible. The problem is one of syntax. Pod, as currently
specified, defines two syntaxes for magic comments that define documentation.

The difficulty is that both those syntaxes might already be in use in
other languages (the /^ \h* \= ident/ syntax most certainly will be),
so you end up having to change the Pod parsing syntax on a per-language
basis. I can't really see that being very attractive to the implementors
of other languages, nor the inconsistency being very attractive to users
of those languages.


 We need a way of referring to ambient code within Pod, without the
 Podder having to write more code to get it.

 I was thinking it would be possible to reference (compiler) variables
 representing eg. the name and sig of a block being parsed, or a block
 or declaration which has just been parsed, or which is just about to be
 parsed, and that simply referencing these variables would be ok and
 would save the need to create explicit named anchors.

Well, that certainly *is* possible in Pod, which will definitely have
access to any compile-time
Perl variables, including the following usually bits of information:

$?FILE  Which file am I in?
$?LINE  Which line am I at?
?ROUTINE   Which routine am I in?
?BLOCK Which block am I in?
$?SCOPE Which lexical scope am I in?
$?PACKAGE   Which package am I in?
$?MODULEWhich module am I in?
$?CLASS Which class am I in? (as variable)
$?ROLE  Which role am I in? (as variable)
$?GRAMMAR   Which grammar am I in?

But that's not necessarily enough. I can imagine many other pieces of code that
you might want both in the source and in the documentation, but which it would
not be easy to extract from the introspective variables. For example:

PRE
=alias precondition
{
 $_  0
}

or:

if ($?TESTING)
=alias example1
{
 my $tree = TreeClass.new();
 $tree.size() == 0  :okTrees start life empty;

 $tree.insert(node value);
 $tree.size() == 1  :okInsertion increases tree size;
}


Not to mention all of the clever uses I can't think of yet. ;-)

Damian


Re: S26 - The Next Generation

2009-09-07 Thread Damian Conway
Jon Lang kept his promise:

 I promised some further thoughts; here they are:

Much appreciated.


 As written, declarator aliasing attaches the alias to a piece of code,
 and draws both the name and the alias from that.  What about using a
 special case of the declarator block for this?  That is:

    class Database::Handle { #=alias
        has IO $!handle; #=alias
        my Bool method open ($filename) {...} #=alias

        =for para
            Note that the Amethod method of class Aclass
            stores the resulting low-level database handle
            in its private Ahas attribute.

    }


or:

   class Database::Handle { #=
       has IO $!handle; #=
       my Bool method open ($filename) {...} #=

       =for para
           Note that the Amethod method of class Aclass
           stores the resulting low-level database handle
           in its private Ahas attribute.

   }

Definitely interesting ideas, especially the second one. My concern
would be that they compete
with the #= blocks which might also be needed on such declarations.


 Regardless of what syntax you use for declarator aliasing, I'd also
 recommend some sort of numbering scheme if you alias more than one
 declarator of the same type in the same lexical scope:

It's definitely an issue I hadn't considered properly. However, I
think the correct
solution is not numbering (which is always fraught with problems when subsequent
maintenance adds an extra declarator in the middle), but rather naming. Like so:


=alias
class Database::Handle {
=alias
has IO $!handle;

=alias open
my Bool method open ($filename) {...}

=alias close
my Bool method close() {...}

=for para
Note that the Aopen method of class Aclass
stores the resulting low-level database handle
in its private Ahas attribute, while the Aclose
method closes that handle.
}

I know this looks redundant. But the whole point of logical names is you
don't have to change them when the physical name changes:


=alias
class Database::Handle {
=alias
has IO $!handle;

=alias open
my Bool method open_file ($filename) {...}

=alias close
my Bool method close_and_sync() {...}

=for para
Note that the Aopen method of class Aclass
stores the resulting low-level database handle
in its private Ahas attribute, while the Aclose
method closes that handle.
}


 If you adopt the declarator block basis for declarator aliasing, you
 could even let the documenter choose his own names:

    class Database::Handle { #=
        has IO $!handle; #=

        my Bool method open ($filename) {...} #=m1
        my Bool method close () {...} #=m2

 An unrelated possibility would be to allow empty A tags in a
 declarator block, with 'A' being replaced with the name of the
 declarator to which the block is attached:

These are both very useful ideas.
I'll ponder them carefully in preparation for the next revision.

Thanks, Jon!

Damian


Re: S26 - The Next Generation

2009-08-25 Thread Damian Conway
Smylers pointed out:

    * Hence it must always parsed using full Perl 6 grammar: perl6 -doc

 Having a multi-character option preceded by a single hyphen doesn't play
 well with bundling of single-character options...

You make many good points. Changed to:  perl --doc

Thanks,

Damian


Re: S26 - The Next Generation

2009-08-19 Thread Damian Conway
Moritz wrote:

 However it seems we have to pay a price: each act of rendering a Pod
 file actually means executing the program that's being documented (at
 least the BEGIN blocks and other stuff that happens at compile time),
 with all the security risks implied. So we'll need a *very* good
 sandbox. Is that worth it?

I believe so. The sheer range of approaches that people said they wanted
Pod to support made it impossible for Pod to support anyone, unless
everyone can configure Pod directly. The choice then becomes: do we
provide Pod with a DSL for configuration, or do we just use
Perl 6 as its metalanguage? The answer seemed pretty obvious then.
I'm certainly not smart enough to design a config language that's powerful
enough to do everything everyone wants documentation-wise. But Larry is.
And already did. ;-)

Sure, there are downsides: Pod becomes much more tightly tied to Perl 6.
And the black hats can indeed do bad things with it.

But, you know, the bad guys have been able to do that with CPAN modules
for a long time now, and the incidence of that happening is vanishingly
small. I'm prepared to bet that most people who download something from
CPAN don't scour the source checking for system('rm -rf /')'s, nor do
they run that code in a sandbox.

And the people who *do* take such precautions will simply start to do
the same thing for any documented code (or coded documentation :-). Or
maybe the sandbox will just be an option to disable any DOC blocks
except the default one. Or else maybe perl -doc will just run under an
augmented taint mode that suspects not just anything that emerges from
an input op, but also anything created in a DOC'd command.


 Two minor comments:

        A valid identifier is a sequence of alphanumerics and/or
        underscores, beginning with an alphabetic or underscore
    

 Is there a good reason to deviate from Perl 6's definition of an
 identifier? For the sake of consistentcy I'd just say that the Perl 6 rules
 apply.

Great idea. Should definitely be that way. Patch applied.


    sub fu (             #= This text stored in Cfu.WHY

 This seems to be ignorant of multi subs.

Not ignorant of. Just not an example of. ;-)


 If I write

    multi sub fu () {    #= some Pod

 Then fu is a multi, not a particular candidate. Does it actually
 attach to the .WHY of the candidate? Or of the multi?

Of the particular candidate. I'll make that clearer.
(If you want to document the entire multi, attach the documentation to
the proto.)

Damian


Re: S26 - The Next Generation

2009-08-19 Thread Damian Conway
Raiph commented:

 Couldn't the pod processing be encapsulated, perhaps in PGE/NQP, so
 that it could be reused in a different Parrot language, provided that
 said language supports declarators and comments, or even just comments
 (if one downgrades the impact of encountering an attached comment
 that has no declarator to a warning). The latter would fully restore
 the generic applicability of the POD 5 parser, right?

While I'm all in favour of other languages using Pod as a documentation format,
I think that's unlikely. Pod says that anything of the form:

   =identfiier

*anywhere* as the first non-whitespace of a line, is considered a Pod directive.
I can't see many other language designers being willing to limit their
assignment
statements that way.


 While I like the design, and I think it's near enough complete, and I
 think a reader who knows perl and pod well could understand your
 current description of that design, I think it could do with a major
 rewrite to make it less confusing to work out what you really mean as
 against what's currently written. ;) However, I think it's too early
 to attempt such a rewrite, or even to comment on specific problems; I
 plan to wait another couple weeks for some list back-and-forth before
 commenting further about clarity and/or proposing edits and/or
 providing patches.

I agree that a rewrite would certainly help it. And will be happy to
kibitz anyone
who volunteers to do so! ;-) Or, of course, to accept patches.


 You don't say whether attached pod allows for configuration info or
 formatting codes.

It does. I don't say it doesn't, and I do show attached comments with it
(e.g. the $chainsaw example). I'll make it explicit however.


 (Incidentally, .WHY seems a bit too cute; what about .DOC or .POD?
 Same with .WHEREFORE; my boring suggestion is .CODE.)

I think you're going to have to take that up with Larry. Presumably the WHO,
HOW, WHERE, WHENCE, etc. should go too? Personally (and I say this as
the guy who pioneered you think that's cute now... ;-) I think the
interrogatives
work very well, especially because they stay so well out of the way of anything
a sane person (pace Larry) would use to name an ordinary method.


 Declarator aliases, as specced, seem to me the weakest part of the
 design. Declarator aliases seem to only allow one my, one has, etc. in
 a given context.

We could certainly consider allowing a fourth form of alias like so:

=alias IDENTIFIER
DECLARATOR

which would use the specified identifier as the alias's name, rather
than the declarator. Lets see what other people think.


 Having to use non-attached pod syntax to do an
 attached thing seems very weird.

I think they have to be different, because they do opposite things...or
at least things in opposite directions. A declarator block says this
Pod belongs to this code; an alias says this code can be referred to
in subsequent Pod. I'd be happy to be proved wrong if someone can
come up with a better mechanism than aliases that still allows
us to pull code into Pod.


 Having to use aliases at all to refer
 to things that the Perl 6 compiler already has a name for seems like
 an ugly/heavyweight/suboptimal approach.

I think aliases are essential. We need a way of referring to ambient code
within Pod, without the Podder having to write more code to get it.

Damian


Re: S26 - The Next Generation

2009-08-19 Thread Damian Conway
Jonathan Dataweaver Lang enquired:

 Will ther be any ambiguity between Pod and wraparound operators that
 begin with =?

No. Lines that start with an '=' that is *immediately* followed by an
identifier are always Pod. If there's a space after the '=' it's always
an assignment. You could *create* an ambiguity, by defining an operator
such as infix:=x but then you get precisely what you deserve. ;-)

    if really_long_expression
       == value { ... } # Pod, or equality operator?

Always equality. Pod is always =IDENT. Only.


 Note the recent revisions to how Perl comments work - in particular,
 an embedded comment is now spelled #`[ ... ].  Should embedded
 attached Pod be spelled as #=`[ ... ]?

Larry and I discussed this and concluded that #=[ is better.
I can see the logic of #`[= but I just can't see the aesthetics of it.
I'd much rather have to only look at the second character to determine
it's Pod, not a vanilla comment. Besides, I think people will simply learn
that #symbol[ is an embedded comment, where symbol specifies
what kind of comment it is (I can certainly envisage other kinds
besides just vanilla and Pod-flavoured)

Damian


Re: S26 - The Next Generation

2009-08-19 Thread Damian Conway
 Could we also get =numbered and =term directives that are
 equivalent to =item :numbered and =item :term, respectively, for
 use with abbreviated blocks? E.g.:

    =numbered First Item
    =numbered Second Item
    =numbered Third Item

That's just:

 =item # First Item
 =item # Second Item
 =item # Third Item

or even just:

 =item# First Item
 =item# Second Item
 =item# Third Item


    =term First Name
    Definition
    =term Second Name
    Definition

This doesn't work, because it doesn't conform to the general syntax
of abbreviated blocks (which is that the content starts immediately
after the typename). The term of a term/definition is basically a
very complicated bullet point, and hence needs to be configured with
an option.

Of course, we could make a special exemption to the general syntax, or
say that in this one case the first line of content is special, but I'm
*really* loathe to inject special cases when a general mechanism
already exists.


 Within tables, you should probably replace whitespace with multiple
 whitespace as a column delimiter; otherwise, the space between two
 words in an identifier would trigger a new column:

Indeed. That was both the intention and the implementation in Perl6::Perldoc,
but it definitely needs to be mentioned explicitly. Thank-you.


 When using the code block alias, are the outermost curly braces
 considered to be part of the ambient code?

Yes. All ambient code is actual code.


 Why is =END a block, and not a directive?

Damn good question. I can't think of any reason off the top of my head.
I'll need to ponder that.

Damian


Re: S26 - The Next Generation

2009-08-19 Thread Damian Conway
Kyle suggested:

 Pod itself is a DSL.

Sure. But to allow arbitrary processing and rendering of Pod, a DSL
isn't enough.

 If we're committed to giving guns to books, can we default to having
 the safety on? Can it be so that 'perl6doc foo.pl' does not execute
 any code without an option to allow it?

There is no perl6doc. There is only: perl6 -doc
That is, running the Perl interpreter in a special mode to get
documentation.


 Perl 5 programmers are sometimes surprised to find that 'perl -c
 strange.pl' can execute code. Imagine their surprise to find that
 'perl6doc' does too.

But the reason will be exactly the same. Namely, because in Perl you
can't tell what's documentation and what's code until you parse the
mixture. And you can't parse Perl (5 or 6) without executing stuff.

Look, I'm sure we *will* have a safety mode of parsing Pod (maybe:
perl -undoc) But it can't be on by default, otherwise no-one can
write anything but vanilla Pod and expect it to work. It's like
saying that 'use' is potentially dangerous (which it *is*) so can we
have it off by default. In Perl, the answer has to be no.

Damian


Re: S26 - The Next Generation

2009-08-19 Thread Damian Conway
Jonathan Dataweaver Lang proposed:

 OK.  Let me propose an alternative (which I expect will be immediately
 shot down):

BANG!

;-)


 Allow '=begin alias', '=end alias', and '=for alias' as special cases:
 the Perl parser makes an exception for them and doesn't treat them as
 the start or end of POD Blocks, merely as single-line directives; but
 the Pod parser treats them as normal Pod Blocks, with the contents
 being attached to the alias.

Well, clearly I'm not going to be in favour of introducing exceptions to
the general syntax.

However, I had originally thought that we should have =alias and
=dealias directives to delimit code extractions. In the end I liked the
use of the code's own delimiters better, but I guess if people preferred
to have two directives as delimiters, we could consider that instead.

Let's see what others think.

Damian


Re: S26 - The Next Generation

2009-08-16 Thread Damian Conway
Darren Duncan asked:

 But one thing I'm not sure whether or not it was addressed is regards to
 whether free-form documentation is still supported or can be effectively
 combined with embedding documentation into the places that it is
 documenting.

Yes and yes.

Normal Pod blocks weren't mentioned in the executive summary because
they haven't changed. Except that they got much better, because now you
can indent them to match the layout of the code they're interleaving.
Or, indeed, indent them simply to indicate the Pod's own lexical
structure.

The Necrotelecomnicon example was originally written like so
(before I removed the Pod blocks...to keep the example properly
focussed):

=head2 IPC magic

=para
The base class for doing deep and dangerous things with IPC
is

#= Base class for comms necromancy hierarchy
class Magic::Necrotelecomnicon {
has $.elemental;  #= Source of all power
has $!true_name;  #  Source of all self-protection (not documented)

method cast(Spell $s)
#= Initiate a specified spell normally
{
do_raw_magic($s);
}

#= Initiate a specified spell abnormally
method kast(Spell $s) {
do_raw_magic($s, :alternative);
}
}

which, by default (and in the absence of any semi-literate or
OO-bsessive modules one might explicitly CDOC use),
will simply produce something like:

IPC Magic

The base class for doing deep and dangerous things with
IPC is

Name:  Magic::Necrotelecomnicon:
Desc:  Base class for comms necromancy hierarchy

Attrs:
.elemental   : Source of all power

Methods:
.cast(Spell $s)  : Initiate a specified spell normally
.kast(Spell $s)  : Initiate a specified spell abnormally


Damian


Re: comments as preserved meta-data (was Re: Embedded comments ...)

2009-08-13 Thread Damian Conway
Raiph Mellor raiph.mel...@gmail.com wrote:

 Anyhoo, I'd love to see a session of brainstorming, with nitty gritty
 detail, about possible ways to get what you guys and Mark and I and
 perhaps others think we would like to see in the way of super tightly
 woven together comments and code, where said brainstorming initially
 works within the creative constraint of leveraging the P6 spec as is,
 plus reasonable extrapolation of unspecced bits. Think grammar
 morphing, aspects of macros, the existing unfinished POD6 spec, and
 any other relevant existing bits I'm forgetting.

Excellent idea. But may I suggest you perhaps might like to hold off
that discussion until next week?

@Larry had some very fruitful discussions about the long-overdue Pod
spec during YAPC::EU last week and, as a result, I plan to (finally!!!)
release a new version of S26 this week-end. I very much hope that this
new revision will satisfy The Overmeer Desiderata [1] too.

Damian


[1] Sounds like a Robert Ludlum novel, eh?


Re: comments as preserved meta-data (was Re: Embedded comments ...)

2009-08-13 Thread Damian Conway
Raiph Mellor raiph.mel...@gmail.com hyperpunned:

 With this whiny man exchange ultimately having bourne supreme fruit,
 the apocalypse watch for the post damian weekend begins...

ARRRG!

Damian ;-)


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: XOR does not work that way.

2009-06-22 Thread Damian Conway
Perl 6's approach to xor is consistent with the linguistic sense of
'xor' (You may have a soup (x)or a salad (x)or a cocktail), and also
with the IEEE 91 standard for logic gates. See:

http://ozark.hendrix.edu/~burch/logisim/docs/2.1.0/libs/gates/xor.html

for a concise explanation of both these senses of xor.

Damian


Re: Multi-d array transforms (was Re: Array rotate)

2009-06-12 Thread Damian Conway
Larry mused:

   �...@a.mung

 the .mung could return

    A) a modified @a (treat @a as mutable)
    B) a new array (treat @a as immutable)
    C) a remapped array whose elements refer back to @a's elements

 Currently .rotate is defined as A, but I could easily switch it to B,

I, for one, would vastly prefer to see the majority of (or even all)
container methods being non-mutating (with sugary shortcuts for the most
common mutators, if necessary).

A major advantage of having both .= and . in the language is that they
make it easy to see when something is (and isn't!) being altered in-place.
The fewer special-case it-uses-plain-dot-but-it's-actually-a-mutator
exceptions we have, the better.

In fact, I would even be happy with requiring @a.=push and @a.=shift, if
it meant that there were *no* special cases. One extra character is a
small price to pay for perfect SWIM (and not just Say What I Mean,
the real benefit is the other SWIM: See What I Meant).

Of course, this assumes that @a.=shift, @a.=push, etc. aren't actually
implemented with a copy-modifier-and-replace, but are optimized to
in-place mutators, under the hood.

Damian


Re: Amazing Perl 6

2009-05-28 Thread Damian Conway
Daniel Carrera wrote:

 This is a really good list. Mind if I copy it / modify it and post it
 somewhere like my blog?

That's fine.


 One question:

    * Compactness of expression + semi-infinite data structures:

       �...@fib = 1,1...[+]        # The entire Fibonacci sequence

 Very impressive. That's even shorter than Haskell. What's [+] ? How does
 this work?

The ... operator takes a list on the left and a generator sub (or block)
on the right. It creates a lazy list consisting initially of the left
operand. When the left operand runs out, the right operand is invoked to
generate extra values. The generator grabs as many existing values from
the end of the list as it needs arguments, then appends its result to the
end of the lazy list. Lather, rinse, repeat, as often as necessary.

In the Fibonacci example, the generator sub is [+], which is a
shorthand for infix:+. So, after 1,1 the generator grabs the last
two values (i.e. 1,1), adds them with infix:+, and puts 2 on the end
of the list. Next time a value is needed, infix:+ grabs the final
two list elements (now: 1,2), adds them, and appends 3 to the list.
Et cetera, et cetera.

For the use of ... to generate lists see: infix:..., the series operator
under http://perlcabal.org/syn/S03.html#List_infix_precedence. For the
[+] syntax, see http://perlcabal.org/syn/S03.html#Nesting_of_metaoperators


 PS: A really mean, but very effective, way of emphasizing the ease,
    expressiveness, compactness, and readability of Perl 6 code is to
    take each of the examples and show the same thing written in Java. ;-)

 It might be appropriate to compare some examples with Ruby or Python.

Only if the comparisons are suitably invidious. ;-)

Damian


Re: Amazing Perl 6

2009-05-28 Thread Damian Conway
Jon Lang suggested:

 Start with the addition operator, '1 + 1'.  Apply the reducing
 metaoperator to it so that it works syntactically like a function:
 '[+] 1, 1'.  Instead of calling it, pass a code reference to it:
 '[+]'.

No. [+] isn't the Code object for [+]; it's the Code object for infix:+.
See http://perlcabal.org/syn/S03.html#Nesting_of_metaoperators


 What I'm wondering is how the list knows to feed two items into '[+]'.
  While 'infix:+' must accept exactly two arguments, '[+]' can accept
 an arbitrarily long (or short) list of arguments.

And since [+] is infix:+, that's how it knows. :-)

Damian


Re: Amazing Perl 6

2009-05-28 Thread Damian Conway
Mark J. Reed asked:

 So how is this:

 Any infix operator (except for non-associating operators) can be surrounded 
 by square brackets in term position to create a list operator
  that reduces using that operation:

 reconciled with this:

 Any ordinary infix operator may be enclosed in square brackets with the same 
 meaning

The first refers to (meta)operators encountered where a term is expected;
the second refers to operators encountered where an infix is expected
(i.e. after a term).


 ?  And if [+] means infix:+, how do I refer to the Code of the
 list operator [+]?

prefix:[+]

Damian


Re: Amazing Perl 6

2009-05-28 Thread Damian Conway
Daniel Ruoso asked:

 prefix:[+]

 Is that really? I mean... [ ] is a meta-operator,

Sure. But once you []-meta an infix operator, you get a prefix operator.
See http://perlcabal.org/syn/S03.html#Reduction_operators, which states:

Any infix operator (except for non-associating operators) can
 be surrounded by square brackets in term position to create a
 list operator

and has an example of actually implementing the prefix:[+] operator.

Damian


Re: Amazing Perl 6

2009-05-27 Thread Damian Conway
Here are a few of my favourite Perl 6 selling points:

* Compactness of expression:

say 'Hello, World!';

* Compactness of expression + semi-infinite data structures:

@fib = 1,1...[+]# The entire Fibonacci sequence

* Junctions make comparisons much more natural:

if $dice_sum == 7 | 11 {
say 'Natural!'
}
elsif $dice_sum == 2 | 3 | 12 {
say 'Craps!'
}

* Given/when takes that even further:

given $dice_sum {
when 7 | 11 { say 'Natural!' }
when 2 | 3 | 12 { say 'Craps!' }
}

* Junctions + n-ary comparison help too:

if 0  all(@coefficients) = 1 {
say 'Coefficients are already normalized.';
}

* Junctive comparisons + the max operator:

if any(@new_values)  all(@existing_values) {
$upper_limit = [max] @new_values;
}

* .invert and .push makes hashes (especially hoa's) vastly more useful
(and .perl makes debugging vastly easier):

my %comments =
perl6 = Amazing Revolutionary,
perl5 = Essential Amazing,
perl4 = Classic,
perl1 = Classic;

my %epithets;
%epithets.push(%comments.invert);

say %comments.perl;
say %epithets.perl;

* Unicode source and data overthrows US cultural hegemony!
(oh, and Hinrik has the coolest name in the entire Perl community :-)

my @recepción;
my $Gruß  = 'olá'
my $óvoµa = 'Hinrik Örn Sigurðsson';

push @recepción, $Gruß, $óvoµa!;


* Unary method call + topicalization simplifies multiple operations
on objects:

for @parcels {
.address;
.weigh;
.ship;
while .shipping {
.fold;
.spindle;
.mutilate;
}
.deliver;
}

* Subtypes make typing far more precise (and hence more useful):

my $filename of Str where /\w**8 '.' \w**3/;

my $octet of Int where { 0 = $^value = 255 }



* Command-line parsing using standard language features:

sub MAIN ($text, Bool :f($foo), Str :B($bar), *...@files)
{
...
}

# Can then be invoked as:

 my_prog.p6 -f  -Bbaz  'two words'  file1 file2 etc


* Grammars built into the language:

grammar Expr::Arithetic {
rule Expression { Mult ** $OP= + -}
rule Mult   { Pow  ** $OP= * / %  }
rule Pow{ Term ** $OP= ^  }

token Term {
Literal
| '('  Expression  ')'
}

token Literal { [+\-]? \d+ [ \. \d+ ]?  }
}

* Grammar inheritance:

grammar Expr::Algebraic is Expr::Arithetic {
token Literal {
alpha+
| Expr::Arithetic::Literal
}
}

* Only perl can parse Perl 5 but Even Perl 6 can parse Perl 6:

given $source_code {
$parsetree = m:keepall/Perl::prog/;
}


And that's without even mentioning all the new OO features, multiple
dispatch, roles, delegation, macros, etc., etc. The problem with demo-
ing the awesomeness of Perl 6 is always running out of demo time before
running out of demo-able awesomeness.

Damian

PS: A really mean, but very effective, way of emphasizing the ease,
expressiveness, compactness, and readability of Perl 6 code is to
take each of the examples and show the same thing written in
Java. ;-)


Re: Docstrings in Perl 6

2009-05-03 Thread Damian Conway
Hinrik Örn Sigurðsson wrote:

 I've been thinking lately about how Perl 6 might offer functionality
 similar to Python's docstrings. That is, documentation which is tied
 directly to a particular routine, class or module[1]. This is
 something which would is very useful in a REPL, and for documentation
 readers[2].

For the latest S26 proposal that I'm (very quietly) working on, I'm
considering two possible mechanisms to support tying docs to specific
components of a program.

The first is an Cis doc trait:

method reverse (
Bool $recursive  is docReverse any nested LLists too
)
is docReturns a copy of the LList with the order of elements reversed.
{
my @result;
for @.list {
@result.unshift($_);
}
return @result;
}

The second is a generalized Pod comment form:

method reverse  #={ Returns copy of LList with order of elems reversed. }
(
Bool $recursive  #={ reverse nested LLists too }
)
{
my @result;
for @.list {
@result.unshift($_);
}
return @result;
}

Each approach has advantages and disadvantages.
Feedback via this forum would be most welcome.


 Something similar could be done for MODULE, CLASS, GRAMMAR, ROLE,
 TOKEN, and REGEX.

Indeed. And with both of the above alternatives that's also true.


 One advantage to using Pod blocks in place of actual strings a la
 Python, is that the documentation is still independent of the source
 code, and need not be in the same file.

That's certainly true of your proposal. However, many might argue that
one *disadvantage* of using Pod blocks plus :name that way is that the
documentation is independent of the source code, and need not be in the
same file. ;-)

Damian


Re: Getting rid of want()

2009-03-31 Thread Damian Conway
Moritz Lenz wrote:

 Instead we should provide a very DWIMmy way to (lazily) create objects
 that behave differently in different contexts.

That's precisely what the Contextual::Return module does for Perl 5.

It's less than perfect in Perl 5, because it has to be implemented via
runtime trickery, and hence is too slow. But that problem will disappear
in Perl 6 (and perhaps eventually in Perl 5 too) as I'll be able to use
macros to remove the runtime overheads.


 Patrick pointed out that it can currently be done with

 return $value but role { method Bool {
 $code_for_boolean_context_here } };

This is essentially what Contextual::Return does, only with a
dwimmier syntax.


 And if you propose to keep want(), how would you think it could work?

The only thing C::R doesn't handle that want() does is determining the
arity of a list context (i.e. how many elements are expected back).
That information can be very handy for optimization. And, yes, C::R
would already
handle it if I could think of a clean interface that was implementable
in Perl 5 without source filters.

Damian


Re: Junction Algebra

2009-03-29 Thread Damian Conway
Richard Hainsworth conjectured:

 1) Is the following true for an any junction?
 any( ... , any('foo','bar')) === any(...,'foo','bar')

 If yes, then
 if an 'any' junction is contained in an outer 'any', the inner 'any' can be
 factored out?

Yes. More precisely, an 'any' that is directly nested inside another
'any' can be flattened.
By directly, I mean with no intervening levels of non-'any'
junctions. That is, not like:  any(...,all(...,any('foo', 'bar')))


 2) Also, is the following true for nested 'all' junctions? viz.
 all(... , all('foo', 'bar')) === all(...,'foo','bar')

Yes, with a similiar directly caveat, as above.


 3) Conjecture: The following is true of all junction types, eg.,
 junc(..., junc(...)) === junc(..., ...)

No. As Patrick so ably pointed out, this is not true for 'one' nor for 'none'


Damian


Re: On Junctions

2009-03-28 Thread Damian Conway
 I stand corrected. That said: with the eigenstates method now private,
 it is now quite difficult to get a list of the eigenstates of the
 above expression.

Yes, that's a concern. Most of the interesting junction-based algorithms
I've developed in the past rely on two facilities: the ability to
extract eigenstates, and the ability to thresh a junction: to
determine which eigenstates caused a boolean expression involving the
junction to be true.

However, I suspect that if these two capabilities prove to be
all(not easy, very useful) in Perl 6, there will soon be a module
that facilitates them. ;-)

Damian


Re: On Junctions

2009-03-27 Thread Damian Conway
Jon Lang wrote:

 For that matter, I'm not seeing a difference between:

any( 12 ) # any of all of (1, 2)

 ...and:

any( 1, 2 ) # any of (1, 2)

Those two are very different.

 any(1,2) == 2  is true

 any(12) == 2  is false


Nested heterogeneous junctions are extremely useful. For example, the
common factors of two numbers ($x and $y) are the eigenstates of:

all( any( factors($x) ), any( factors($y) ) )


 If I'm not mistaken on these matters, that means that:

any( 1|2, 12, 5|15, 515 ) eqv any(1, 2, 5, 15)

No. They have equivalent eigenstates, but they are not themselves equivalent.
For example, any( 1|2, 12, 5|15, 515 ) compares == to 12;
whereas any(1, 2, 5, 15) doesn't.


 And I expect that similar rules hold for other compound junctions.  In
 short, I won't be surprised if all compound junctions can flatten into
 equivalent simple junctions.

In general, they can't; not without changing their meaning.

Damian


Re: Logo considerations

2009-03-24 Thread Damian Conway
Earlier I wrote:

 Maybe just something like one of the attached graphics
 (only redone by someone with actual graphical design skills ;-)?

It occurs to me that this comment might be misread as an implied
criticism of Conrad's original artwork as well. Just wanted to make it
very clear that was definitely not the case.

Damian


Re: Should $.foo attributes without is rw be writable from within the class

2008-09-17 Thread Damian Conway

Larry wrote:


You have to have a way of talking about your own attributes *as if*
they were not your own attributes, and $.foo is that way.  


When thinking about this, it's also important to remember that, in Perl 6, not 
everything with a sigil is automatically writeable. For example:


constant $answer = 42;
$answer = 99;  # Kaboom!

sub foo( $bar ) {
$bar = 42  # Biff!!
}

$baz := 86;
$baz++;# Zowie!!!


Likewise a $.foo attribute defaults to read-only,
whereas a $!foo attribute defaults to read-write.

Damian


Re: adverbial form of Pairs notation question

2008-09-08 Thread Damian Conway

On Sat, Sep 06, 2008 at 07:06:30PM +1100, Илья wrote:
: Hello there,
: what :foo should exactly produce?
: At first I was expecting:
: foo = 
: but in Rakudo:
: foo = []
: and it looks like the right thing on the other hand.


At YAPC::EU I pointed out to Larry that we have an adverbial form that
defaults to true:

   :foo

and one that defaults to false:

   :!foo

but none that defaults to undef.

After rejecting my very reasonable suggestion of:

   :¡foo

(;-) Larry then proposed that:

   :foo()

should be identical to:

   :foo(undef)

I mention this merely to point out that Larry's response in this thread seems
to revise that proposition somewhat, and I would like to suggest that, if
:foo() is now to mean something more sophisticated that :foo(undef), then we
should still find a cheap way of building adverbs with undef values.

Damian


Re: Perl 6 fundraising and related topics.

2008-03-26 Thread Damian Conway

Richard Hainsworth wrote:


Consider the position you put me, or another sponsor, in.


I want to endorse everything Richard then went on to say.

I have already contacted Uri and expressed my dismay at his entirely 
inappropriate interjection of an advertisement for our Perl College event into 
this discussion about funding for critical Perl projects and personnel. And I 
am especially upset that anyone might ever feel pressured to be involved in 
any project or sponsorship just because my name and reputation were invoked on 
its behalf.


It's critical that we find ways to support those in the Perl community who are 
either building our future or (just as importantly) maintaining our present. 
But injecting UCE into such discussions does not further that goal, and I am 
sincerely sorry that it was done in my name.


Damian



Re: [svn:perl6-synopsis] r14421 - doc/trunk/design/syn

2007-06-22 Thread Damian Conway

Mark Overmeer wrote:


Then, when you want to add some docs to the method, to help the
correct use, add it, for instance like:

  method isValidPostalCode(str $postalcode) returns bool {...}
 ` Check wether the postal code confirms to the standards
 `$postalcode: a string with blanks trimmed.
 `return: the string is not cleaned-up.

or maybe (exact syntax open to discussion)

  method isValidPostalCode(str $postalcode) returns bool {...}
  #=  Check wether the postal code confirms to the standards
  #=$postalcode
  #=  a string with blanks trimmed.
  #=return
  #=  the string is not cleaned-up.


Would the following syntax suffice?

   method isValidPostalCode(str $postalcode) returns bool {...}
   =PURPOSE  Check weather the postal code confirms to the standards
   =ARG $postalcode
   a string with blanks trimmed.
   =RETURN
   the string is not cleaned-up.

Because you can already do precisely that in the current design of Pod 6.

And having done it, the current Pod::Parser will extract all of that
information (including the source code), preserving the sequential and
hierarchical relationships, and present you with an internal object
representation that your documentation tool can then analyze and
convert to whatever content and layout you prefer (including
non-semantic Pod that you can then feed into any of a dozen
back-ends).

Damian


Re: Referring to source code within Perldoc: the new A code

2007-06-22 Thread Damian Conway

Mark Overmeer wrote:


IMO, POD6 should not provide the possibility to build such tools: it
should *be* the tool. With a nice (compact) standard definition how
to document each of the designed features in Perl6


And this is a succinct statement of one half of our fundamental philosophical 
difference.


The other half is that I still believe that Pod should be an enabler and 
medium for creating nice (compact) standard definitions of how to document 
Perl 6. I don't want to create One True Documentation scheme; I want to create 
a means to develop a range of True Documentation schemes...a range of schemes 
suited to different documentation goals, different paradigms, different source 
code structures, and different readers.


Damian


Re: Referring to source code within Perldoc: the new A code

2007-06-21 Thread Damian Conway

Mark Overmeer wrote:

[...yet another honest and heartfelt plea for Pod 6 to be something
entirely different from what it is currently designed to be.]

The solution is simple, you know, Mark. Why not just write up your own
alternate S26, redesigning Pod 6 the way you think it should work, and
then publish your proposal for consideration here?

After all, Larry's track record is clear: he's never once allowed
someone's reputation or status (even his own!) to deter him from
replacing an existing design with someone else's superior one.

So, as you feel you have a better alternative, why not document it and
put it before the community for consideration and assessment? If it is
indeed better, I have no doubt we will happily steal it. Even if only
parts of your proposal are better, your technological distinctiveness
is sure to be assimilated. ;-)

Damian


Re: Referring to source code within Perldoc: the new A code

2007-06-21 Thread Damian Conway

Smylers reported:


I was with you right up until the mention of C=encoding; what's that
got to do with anything?


CP bug. Patched. Thanks!

Damian


Re: Referring to source code within Perldoc: the new A code

2007-06-21 Thread Damian Conway

Juerd wrote:


Damian Conway skribis 2007-06-21 11:45 (+1000):
A dedicated OO documentation tool could certainly do a better job in that 
case, I heartily agree. I'm looking forward to using one.


This dedicated OO documentation must be core, because Perl itself is
heavily OO. 


Yes. I completely agree that such a tool not be standard and universally 
available. Just as the pod-to-whatever back-ends of the documentation chain 
must also be.


Damian


Re: Referring to source code within Perldoc: the new A code

2007-06-21 Thread Damian Conway

brian asked:


Couldn't most of this be figured out by making Pod6 extensible (or
whatever the right term is). Pod6 would be more of the syntax and basic
operation, but other people could have custom directives that their
Pod6 translators and formatters could then use. That is, not all of
this has to be in the spec if the spec has a way to make it possible
later. :)


Yes. That's exactly what we've done. Pod 6 has:

=item  a C=use directive that allows you to load behaviours for
   any user-defined blocks or formatting code you want

=item  a standard mechanism by which user-defined blocks are available
   (just make the block names mixed-case)

=item  a standard mechanism for adding new formatting codes (the M metacode)



And, as far as writing a new S26, does this mean that this really isn't
open to discussion? That is, if we want something different than you
want we have to have competing specs and there won't be any compromise?


Of course not. Indeed it's a *plea* for something more concrete to discuss, a 
suggestion of a way to get past the philosophical impasse of one group saying 
this does everything you want, without nailing down the specifics of how, 
whilst another says this isn't good enough, without clearly indicating what 
would be.


What I was actually suggesting was that this design *isn't* set in stone, and 
that the best way to convince Larry that the existing design could be better 
is to actually offer a better design.


Damian


Referring to source code within Perldoc: the new A code

2007-06-19 Thread Damian Conway

Here's the first draft (documented in Pod 6, of course ;-).

Feedback and suggestions are most welcome.

(But please don't bother explaining to me this feature won't suffice
 as the high-level automatic code-to-documentation mechanism that Markov
 has been championing. I promise that I'm very well aware of that fact.
 This new formatting code isn't intended to replace such advanced
 autodocumentation tools...only to make such tools unnecessary in the
 simple cases and--in the non-simple cases--to make such tools easier to
 create, by providing a symbolic intermediate-level representation for
 interwoven code and Pod.)

Damian

-cut--cut--cut--cut--cut-

=head3 Ambient aliases

The CA formatting code specifies an Balias to an ambient antecedent.
This is like a Lplacement link|#Placement links, except
that the text that is inserted to replace the CA formatting code is
some portion of the Lambient section(s)|#General syntactic structure
of the current document, rather than the entire contents of some
external document.

Hence, the CA code makes it possible to incorporate pieces of
ambient text (typically source code) into Pod documentation.
Specifically, the CA code is replaced by searching backwards through
all preceding non-Pod parts of the document, to locate the nearest prior
substring that matches the contents of the CA code.

The contents of an CA code can specify a back-reference of this type
in one of two ways:

=item  as a Iprefix keyword, or

=item  as a Idelimited text range.

By default, CA aliases are keyword oriented. That is, the contents
of an CA block are treated as a keyword or prefix that introduces
the desired text. That text is located by searching backwards from the
location of the CA code, to find the nearest preceding instance of
the specified prefix in any previous ambient block. The text that is
then used to replace the CA is the first symbol following that
located prefix. In this context, a symbol is defined as a sequence of
non-whitespace characters terminated by a transition from an identifier
character to a non-identifier character.

For example, in the following:

=begin code
class Pet {

has $name;

=DESCRIPTION
The class Aclass provides a Ahas attribute.
=end code

the CAclass formatting code would be replaced by Pet, since that
is the sequence of non-whitespace characters that immediately follows
class in the preceding ambient source code. Likewise, the CAhas
formatting code would be replaced by $name, because that is the
longest sequence of non-whitespace characters that follows a has and
terminates in an identifier-to-nonidentifier boundary.

=begin para
=config C :allowR
In other words, any formatting code of the form CARprefix
is replaced by the substring of the nearest preceding
ambient block that matches the pattern:
=end para

=for code :allowR
/  .*  Rprefix \s*  ( \S*? \w )  [\W | $] /

This default is designed to work well for the commonest kind of
back-reference in ambient text: a reference to a code construct that
was defined using a prefix keyword and whose name ends in an identifier.

The second and more general way of specifying an alias is to specify
both a prefix and a postfix delimiter for the replacement text. If the
contents of an CA formatting code include a range marker (C..),
the sequence before the C.. is treated as the left delimiter of the
replacement text, and the sequence after the C.. is the right
delimiter. In this case, there are no other constraints on the
replacement text. In particular, it may contain any number of non-
identifier or whitespace characters. For example:

class Pet {

method eat(Food $meal) {...}

=for DESCRIPTION
The Amethod() method has the following argument list: A(..)

This would be interpreted as:

The eat() method has the following argument list: Food $meal

because the CA(..) specifies an alias to the closest preceding ambient
text that is left-delimited by a '(' and right-delimited by a ')'.

To specify an alias in which the sequence C.. is itself
a left- or right-delimiter (rather than the separator between the two),
use a CV code:

constant @range = 0..99;

=para
The maximum value is AV;


=head4 Explicit aliasing

The replacement strings for CA formatting codes are normally
specified implicitly, by the closest preceding ambient text that matches
the contents of the CA code.

However, it is possible to override this behaviour and create an
Iexplicitly defined alias, using the C=alias directive:

class Agent {...}
=alias component Agent

class Transaction is Activity {

=DESCRIPTION
The Aclass class represents a transaction activity between two
Acomponent objects.

In the preceding example, CAclass is a normal keyword alias
(which would be replaced by the closest preceding prefixed match:
Transaction). However, CAcomponent is a defined alias
(which would be replaced by the explicitly 

  1   2   3   4   5   6   7   8   9   10   >