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
> 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-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-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 C, 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 C 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: [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? [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: 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
> Thank you damian, i will apply that patch,

Much appreciated, Herbert!

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 block"except 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: 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
> 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: 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
> 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-22 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-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: 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
> 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: DBC-ish PRE and POST phasers, spec clarifications

2012-03-12 Thread Damian Conway
Moritz observed:

> And here the problem already starts. Signatures with where-blocks can't
> by compared by a Turing machine. At least we know which signatures we
> can compare and which we can't. So we need to think about that case too.

Indeed. Although it's not as bad as it might be. A where-block on a parameter
can be viewed as an implied 'requires', while an where-block on a return type
is like an implied 'ensures'.

So if you have a base-class method with a 'where' on its parameter and a
derived-class method without a 'where' on the corresponding parameter,
you're okay.

And likewise, if a base-class method has no a 'where' on its return type
and the return type of the corresponding derived-class method does have
a 'where', your still okay.

On the other hand the other four cases:

* method Base::foo($x)  {...}
vs
  method Der::foo($x where {something})  {...}

* method Base::foo(--> Type where {something})   {...}
vs
  method Der::foo(--> Type)  {...}

* method Base::foo($x where {something})  {...}
vs
  method Der::foo($x where {something_else})  {...}

* method Base::foo(--> Type where {something})   {...}
vs
  method Der::foo(--> Type where {something_else)  {...}

could all quite reasonably be presumed to be (at least potential) Liskov
violations and loudly complained about:

Possible Liskov violation on Der::foo() parameter $x at Der.pm line 42
(The 'where' makes it potentially more restrictive than in the base
 class method it overrides. Bad programmer! No DbC for you!!!)

As long as we can support decidable cases and report undecidable cases,
I think that's enough.


> Though of course then we need a mechanism to silence that warning.

no warnings :DbC;

or perhaps:

no warnings 'Liskov? Hah! I guffaw at your primitive Earth
superstitions!!!' => 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).
>
> Or we simply reuse the convention from POST and CATCH that the
> interesting value (either exception or return value) is passed in as $_.

But that's less explicit and obvious than named return values! :-(

Not to mention much less "Nyah, nyah, Haskell...look what we've got!!!". ;-)

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 C is called, are both C 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
> C 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 C and C cease to be a concept, C
> and C submethods can be handled delicately in a corner of the
> MOP somewhere, the abomination that is C goes away, and
> all that we're really left with are block-level C and C
> 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
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-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-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: 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: [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: [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: 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 C).


> 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 C<0 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-27 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-25 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
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 C
> is, in English, a synonym for C, not C:
>
>  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 C really seems a good alternative.

Any other suggestions most welcome!

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-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 C.
>
> 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) C, 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 is
misnamed, and a public C<.eigenvalues> is missing.

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

Then we define:

every(@list)
every($junction)   

to mean repectively:

grep  *  ,  @list;
grep  *  ,  $junction.eigenstates;

as well as the reverses:

  every(@list)
  every($junction)

to mean respectively:

grep*,  @list;
grep*,  $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) ~~ //;
# 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 Transjunction }
multi sub infix:«<=» (Transjunction $list,$n) is export
{ $list.grep( * <= $n ) does Tr

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 C<1, 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 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   

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

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

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

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

one(1|2, 2&3)   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
to something like: C. 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 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
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: [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
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 C. 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
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 C,
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 C is
> the right way to enable this kind of privacy breakage. Maybe nothing
> is needed, since the C<^> in C<$obj.^attributes> (or the C)
> 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
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 C
so that violations of good OO practice are explicitly marked in a
consistent and easily searched-for manner?

Damian


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

2010-08-04 Thread Damian Conway
Darren suggested:

> Use namespaces.

The upper/lower/mixed approach *is* a
namespace approach.


> Explicit versioning is your friend.
>
> Can I get some support for this?

Not from me.  ;-)

I think it's a dreadful prospect to allow people to
write documentation that they will have to rewrite when
the Pod spec gets updated. Or, alternatively, to require all
Pod parsers to be infinitely backwards compatible across
all versions. :-(

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: 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: series operator issues

2010-07-22 Thread Damian Conway
On 23 July 2010 01:41, Moritz Lenz  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
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: 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 C method also has the synonym C.

(These are also available through the methods C and
C, respectively.)

There's a C method,

The C method returns a number 1..5

The C method returns the day of the quarter.

The C method returns the day of the year,

The method C returns the second truncated to an integer.

The C method returns the C 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 C
throughout).

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 =  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  =  1,2,4...*;

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

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
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 C type declarator that allows:

use Type::Bitset;

bitset Perms ;
# 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
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 ;
>    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  = 1,2,4...*;

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

enum Days ;

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


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 () '<' (  )+ '>' /)
{
# [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: 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,:mice)   # 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-21 Thread Damian Conway
Jon Lang asked:

> Not actually S26; but closely related: should $=POD and .WHY be
> read-only?

I had assumed so.


> Also, should there be other Pod variables besides $=POD?
> If so, which ones?

The original idea was that every Pod block with any kind of TYPENAME
would be available as $=TYPENAME. For example: $=USAGE, $=OPTIONS,
$=SYNOPSIS, etc.

In particular, $=DATA is likely to be heavily used.


> Back on the subject of S26: should declarator blocks and aliases be
> able to introspect the object with which they're associated?  That is,
> should you be able to say things like A<.WHAT> or A<.^methods>?  (If
> so, be sure never to say A<.WHY>.)

We pretty much have to provide a way for a Pod object to know what Perl
object it's associated with. The whole point is to create an open-ended
mechanism to allow people to twiddle how Pod is rendered. To do that,
they need to be able to walk the documentation tree (a.k.a. $=POD) and
extract useful information from any class, code, or variable declarations
associated with a particular comment-style node in the doctree.

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: 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: 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: 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: 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 A
>    class Foo {
>        #= a sample class used to illustrate.
>        #= This particular class has nothing in it.
>        #=> X

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 A method of class A
>>            stores the resulting low-level database handle
>>            in its private A attribute, while the A
>>            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 A.
>        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
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 A method of class A
>            stores the resulting low-level database handle
>            in its private A attribute.
>
>    }
>

or:

>   class Database::Handle { #=>
>       has IO $!handle; #=>
>       my Bool method open ($filename) {...} #=>
>
>       =for para
>           Note that the A method of class A
>           stores the resulting low-level database handle
>           in its private A 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 A method of class A
stores the resulting low-level database handle
in its private A attribute, while the A
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 A method of class A
stores the resulting low-level database handle
in its private A attribute, while the A
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-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* \= / 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  :ok;

 $tree.insert("node value");
 $tree.size() == 1  :ok;
}


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

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
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-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
> 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
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 #[ is an embedded comment, where  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
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
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 C<&fu.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-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 C),
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  hyperpunned:

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

ARRRG!

Damian ;-)


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

2009-08-13 Thread Damian Conway
Raiph Mellor  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: 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 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-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
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
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-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 => ,
perl5 => ,
perl4 => ,
perl1 => ;

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 {  ** $=< + - >   }
rule Mult   {   ** $=< * / % > }
rule Pow{  ** $=< ^ > }

token Term {

| '('')'
}

token Literal { <[+\-]>? \d+ [ \. \d+ ]?  }
}

* Grammar inheritance:

grammar Expr::Algebraic is Expr::Arithetic {
token Literal {
+
| 
}
}

* "Only perl can parse Perl 5" but "Even Perl 6 can parse Perl 6":

given $source_code {
$parsetree = m:keepall//;
}


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 C trait:

method reverse (
Bool $recursive  is docs too>
)
is doc 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 L with order of elems reversed. }
(
Bool $recursive  #={ reverse nested Ls 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( 1&2 ) # 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(1&2) == 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, 1&2, 5|15, 5&15 ) eqv any(1, 2, 5, 15)

No. They have equivalent eigenstates, but they are not themselves equivalent.
For example, any( 1|2, 1&2, 5|15, 5&15 ) compares == to 1&2;
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: RFD: Built-in testing

2009-01-20 Thread Damian Conway
Larry observed:

> My feeling on this is that the compiler should simply hardwire this
> particular adverb so that all the tests can be autogenerated, and the
> multi system never needs to see those versions.

I strongly agree.


> We are merely hijacking the adverb syntax so that is clear which
> operator is being modified. There is no need for the late binding of
> multi. It's just a "reserved adverb" if you will. Which probably means
> it should be something unlikely to collide with user-defined adverbs.
> Maybe something in all caps. For what it's worth, :OK<> can be typed
> with one hand while the other holds down the shift key. :)

Typical right-hander fascism!

We do indeed want to encourage testing by making it easy to write tests,
but naming it :TEST<> makes it far easier to *read* tests, which seems
to me a better long-term optimization.

We would probably also want a mechanism for switching tests on or off in
a given compilation unit, or globally, so they can be placed in (and left in!)
production code. Perhaps we could use the same mechanism for PRE{...}
and POST{...} blocks as well? Which also suggests that a general TEST
{...} block (which only runs if testing is enabled) might be valuable?

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: List.uniq

2008-09-08 Thread Damian Conway

Moritz Lenz wrote:


There are some tests for List.uniq in the test suite, and pugs
implements it, but it's not in S29.
Damian seems to have though we should have it.
So should we have it? 


I still think we should. If only because I've seen it re-(mis)-implemented so 
many times.


I'd also suggest that it have the same interface as .sort. Namely that you can 
pass a block to specify either a unary key-extractor or a binary comparator 
function.


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: Documenting Perl6 part 2

2007-07-11 Thread Damian Conway

Just a brief note to reassure Mark--and everyone else who's interested--
that I'm not ignoring his post...I'm just fully occupied at the moment
with other (paying) work. In the meantime I'm thinking very carefully
about what Mark suggested. I'll reply properly as soon as I am able.

Damian


Re: [svn:perl6-synopsis] r14421 - doc/trunk/design/syn

2007-06-22 Thread Damian Conway

Mark Overmeer wrote:

>> 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.
>
> This is syntactically what can be done with the current design,
> but is semantically very different.

I don't think so. It's all just mark-up, no matter what the specific
syntax looks like. The semantics are provided by the behaviour of the tools 
that parse and interpret that mark-up. If the tools treat:


  =ARG $postalcode
  a string with blanks trimmed.

the same as they treat:

  `$postalcode: a string with blanks trimmed.

then semantically the two are exactly the same.


> Besides the point that I do not really like the YELLING all the time,

So you create a Pod module that defines "quieter" user-defined block names, 
and write:


  =use OOdoc:ver<6.0.0>

  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.


> You gave the hint that comments are also in the parse tree.

They can be. Better still, the (raw) Pod can also be kept in the parse 
tree...since, like comments, the Perl parser still has to recognize it, even 
when it's focusing on extracting Perl.



> So, that is sufficient for me:

And for others too, I hope.

Defining Perl 6 and Pod 6 independently opens up so many options for
building documentation tools:

* As you've observed, you can build them on top of the Perl 6
  parser, using any mark-up syntax that will fit in a comment;

* And, as I've indicated, you can build them on top of
  the Pod parser, using the standard Pod syntax;

* Or you can build them on top of the Perl 6 parser, but using the
  standard Pod syntax...by parsing Pod from within the appropriate
  nodes of the Perl AST using the Pod parser;

* Or you can build them on top of the Pod parser, using the standard
  Pod syntax, by parsing any code-bearing "ambient" nodes within the
  Pod DOM using the Perl 6 parser;

* Or you can even build them by using *both* parsers at once and
  then walking the two resulting hierarchical representations (AST
  and DOM) in parallel, since Perl 6 has very good support for such
  concurrent tree traversals.

I don't believe any one of those alternatives will prove to be *the*
universal best approach for implementing all documentation tools, but I
do believe that having all those alternatives will make it as easy as
possible for us to collectively create the best tools for the each of
the many approaches to documentation that the Perl community is
ultimately going to want to support.

And that's what keeping Perl 6 and Pod 6 separate buys you: choice,
options, alternatives, the possibility of creating very different styles
of documentation for very different styles of programming. And for
different kinds of programmer: for the Busy Documentor, tools that
extract documentation automatically from code; for the Exacting
Documentor, a structural mark-up that allows precise manual control over
what's documented...and how; for the Pragmatic Documentor, tools that
allow structural mark-up and automatic extraction to be sensibly mixed.

And therefore I see the very fact that you don't like my design of Pod 6
as a strong argument in *favour* of that design, since that design aims
to provide the necessary syntactic extensibility and the essential
building blocks (parser, DOM, module support) required for the
proponents of each individual documentation philosophy to create a
mark-up system and supporting tools best suited to their specific needs
and objectives.

Damian


  1   2   3   4   5   6   7   8   9   10   >