Re: 3 kinds of yadda

2018-09-10 Thread Trey Harris
When executed:

   - ??? is warn.- ... is fail.
   - !!! is ‘die`.

Otherwise, they’re identical (notably, when *not* executed, which is the
usual case). You’d use ??? when you’re not implementing something yet but
it needs to be callable (say, a debugging function).

Given the difference in behavior between fail and die (fail is an unthrown
exception which is suppressed unless called in Sink context or used in an
expression as anything but a Failure or to test truth or definedness), I’d
suggest that !!! be used in a block that’s being used for its return value
(unless “always false and undefined” is an acceptable return value until
you get around to implementing it and you want to be able to call it in the
meantime), and ... elsewhere.

sub warner() { ??? }

my $x = warner(); # "Stub code executed" warning here
say "Hi!"; # Hi! is printed.

vs.

sub failer() { ... }

my $x = failer(); # nothing happens yet
say "Hi!"; # Hi! will be printed
say $x; # "Stub code executed" will be thrown here.

vs.

sub dier() { !!! }

my $x = dier(); # code will stop execution here with a "Stub code
executed" exception
say "Hi!"; # never gets here

​

On Mon, Sep 10, 2018 at 4:22 PM yary  wrote:

> Semantically
>  !!! is "if control flow hits here, it's an error"
>  ... is "The implementation is elsewhere, or this is not yet implemented"
>
> at least that's my impression
>
> -y
>
> On Mon, Sep 10, 2018 at 12:04 PM, Parrot Raiser <1parr...@gmail.com>
> wrote:
>
>> There are 3 kinds of yadda, yadda operator:
>>
>> !!! dies with a message: Stub code executed
>>   in block  at yad1 line 2
>>
>> ... dies with an identical message
>>
>> ??? produces the message, but continues operating.
>>
>> The only difference I can find between !!! and ... is that !!!
>> produces bizarre behaviour  when run from the command line. (Bash
>> appears to be editing the code before P6 sees it.)
>>
>> What is supposed to be the difference between !!! and ...? (And bonus
>> points if you can explain what bash is doing.)
>>
>
>


Re: This seems to be wrong

2016-09-18 Thread Trey Harris
D’oh! I’m blind.

But I see there’s a multi method Str defined on Any, and you can’t do
@inputs.map( .Str ), either (Use of uninitialized value $_ of type Any in
string context). Why not? (There’s no multi method Num on Any, even though
the docs about Cool <https://docs.perl6.org/type/Cool> seem to imply there
should be…)
​

On Sun, Sep 18, 2016 at 6:15 PM Brandon Allbery <allber...@gmail.com> wrote:

>
> On Sun, Sep 18, 2016 at 6:06 PM, Trey Harris <t...@lopsa.org> wrote:
>
>> Not work? It results inMethod 'prefix:<+>' not found for invocant of
>> class 'Any', but the docs
>> <https://docs.perl6.org/language/operators#prefix_+>
>>
>> say it is defined as a multi on Any….
>>
>>
> No, they say it's a multi sub, not a multi method on Any. And the prefix:
> syntax doesn't seem to work directly with the quick workaround for that, so
> it ends up being
>
> for @inputs.map({ .:<+> }) { ... }
>
>
>
>
> --
> brandon s allbery kf8nh   sine nomine
> associates
> allber...@gmail.com
> ballb...@sinenomine.net
> unix, openafs, kerberos, infrastructure, xmonad
> http://sinenomine.net
>


Re: This seems to be wrong

2016-09-18 Thread Trey Harris
On Sun, Sep 18, 2016 at 6:30 PM Brandon Allbery allber...@gmail.com
<http://mailto:allber...@gmail.com> wrote:


> On Sun, Sep 18, 2016 at 6:29 PM, Trey Harris <t...@lopsa.org> wrote:
>
>> But I see there’s a multi method Str defined on Any, and you can’t do
>> @inputs.map( .Str ), either (Use of uninitialized value $_ of type Any
>> in string context). Why not? (There’s no multi method Num on Any, even
>> though the docs about Cool <https://docs.perl6.org/type/Cool>
>>
>> seem to imply there should be…)
>>
>>
> Same reason I had to wrap it in a Block --- it's not recognizing .Str as a
> closure, it's running it immediately. Perhaps you wanted *.Str?
>
Right, got it.

Does not being defined on Any explain why the error for @input.map( .Str )
is different (Use of uninitialized value $_ of type Any in string context)
than the error for @input.map( .Num ) (Method 'Num' not found for invocant
of class 'Any'), but both*.Str and *.Num work in the .map?


>
>
> --
> brandon s allbery kf8nh   sine nomine
> associates
> allber...@gmail.com
> ballb...@sinenomine.net
> unix, openafs, kerberos, infrastructure, xmonad
> http://sinenomine.net
>
​


Re: Is this a bug?

2016-09-18 Thread Trey Harris
On Sun, Sep 18, 2016 at 16:49 Parrot Raiser <1parr...@gmail.com> wrote:

say { $_ } was the correct thing to use there. (I'm trying to avoid
> any mention of O-O for the moment.)
>
“Trying to avoid any mention of O-O” seems like a Perl 6 obfuscation or
golf constraint, not a desirable development or learning goal. Perl 6
doesn’t *force* you to write programs in an object-oriented style; you can
do it in functional or procedural or whatever style suits you. But you’re
going to have a bad time if you try to deny Perl 6’s fully OO nature. This
is in stark contrast to Perl 5, where OO was bolted on, and you could say
that the non-OO core was more “real” than the object-oriented sugar found
in modules you had to use.

Writing something like say($_) for reverse lines — which is what I think is
closest to what you wanted — isn’t any more or less “object-oriented” than
the more idiomatic .say for reverse lines;. In Perl 5, some rather
byzantine rules governed the use of the implicit $_; almost all of the
convenience afforded by those rules can be gained through the use of
topicalized objects, so the byzantine rules are gone — but the convenience
is gone too unless you’re willing to use the topic in the .foo style.

I think perhaps you see a dot, and dot signifies OO, so the .say... version
might *look* more OO than the say(... version in some sense, but that’s
pretty much cosmetic. You’re *using* some objects by interacting with the
Perl 6 core either way. It’s your choice not to write your logic in an OO
style, but you can’t prevent OO from happening during execution.

(This really isn’t some half-hearted attempt to force you into OO through
the backdoor; you really can skip OO for all *your* logic. You just can’t
pretend you’re not using an object-oriented language when you have to touch
code you’re not in control of, whether an OO library or the Perl 6 core.
But pretty much the entirety of what you need to know about OO if you
choose to do that is various syntax and some desiderata about the calling
semantics.)

say {} was a "what happens if I do this" exercise.
>
> What is this  -> ;; $_? is raw { #`(Block|170303864) … } output?
>
> On 9/18/16, Brent Laabs  wrote:
> > Remember you can call a block with parentheses:
> >
> >> say { 11 + 31 };
> > -> ;; $_? is raw { #`(Block|140268472711224) ... }
> >> say { 11 + 31 }();
> > 42
> >
> >
> > On Sun, Sep 18, 2016 at 12:58 PM, Elizabeth Mattijsen 
> > wrote:
> >
> >> I think you want:
> >>
> >>   .say for reverse lines;
> >>
> >> not sure what you are trying to achieve otherwise, but:
> >>
> >>say { }
> >>
> >> producing something like
> >>
> >>-> ;; $_? is raw { #`(Block|170303864) … }
> >>
> >> feels entirely correct to me.   :-)
> >>
> >>
> >> Liz
> >>
> >> > On 18 Sep 2016, at 21:52, Parrot Raiser <1parr...@gmail.com> wrote:
> >> >
> >> > This code:
> >> > 1 #! /home/guru/bin/perl6
> >> > 2
> >> > 3 # Ask for some lines and output them in reverse
> >> > 4 # Work out the appropriate EOF symbol for the OS
> >> > 5
> >> > 6 my $EOF = "CTRL-" ~ ($*DISTRO.is-win ?? "Z" !! "D");
> >> > 7
> >> > 8 say "Please enter some lines and end them with $EOF";
> >> > 9
> >> > 10 say { for reverse lines() {} };
> >> > 11
> >> > 12 # End
> >> > produces this:
> >> > Please enter some lines and end them with CTRL-D# obviously from
> >> line 8
> >> > -> ;; $_? is raw { #`(Block|170303864) ... }# but
> >> this?
> >>
> >>
> >
>
​


Re: Justification for the "reversed" instruction format

2016-09-08 Thread Trey Harris
Ah, nice, good to know my concern was unwarranted.

On Thu, Sep 8, 2016 at 3:04 PM Aaron Sherman <a...@ajs.com> wrote:

> In Perl 6, we apply those constraints when you pass off the call to the
> ultimate recipient, and that's important because that recipient can have
> multiple signatures (and signatures can be added *after* you define the
> flip).
>
> For example:
>
> $ cat foo.p6
>
>
> sub flip() { -> $b, $a, |c { f($a, $b, |c) } }
>
> multi sub counter(Int $start, Int $end, :$by=1) {
> $start, *+$by ... $end
> }
> multi sub counter(Str $start, Str $end, :$by=1) {
> ($start.ord, *+$by ... $end.ord).map: {.chr}
> }
>
> my  = flip 
>
> say flip-counter  10,   2, :by(2);
> say flip-counter 'q', 'k', :by(2);
> say flip-counter 3.7,   1, :by(2);
>
> $ perl6 foo.p6
> (2 4 6 8 10)
> (k m o q)
> Cannot resolve caller counter(Int, Rat, Int); none of these signatures
> match:
> (Int $start, Int $end, :$by = 1)
> (Str $start, Str $end, :$by = 1)
>   in block  at foo.p6 line 3
>
>
>
>
>
> Aaron Sherman, M.:
> P: 617-440-4332 Google Talk, Email and Google Plus: a...@ajs.com
> Toolsmith, developer, gamer and life-long student.
>
>
> On Thu, Sep 8, 2016 at 2:41 PM, Trey Harris <t...@lopsa.org> wrote:
>
>> On Thu, Sep 8, 2016 at 9:23 AM Aaron Sherman a...@ajs.com
>> <http://mailto:a...@ajs.com> wrote:
>>
>> I don't know Haskell, but isn't flip just:
>>>
>>> sub flip() { -> $b, $a, |c { f($a, $b, |c) } }
>>>
>>> And then:
>>>
>>> perl6 -e 'sub flip() { -> $a, $b, |c { f($b, $a, |c) } }; my  =
>>> flip  yas(1,2,3)'
>>> 213
>>>
>>> Yes—but my worry about that was that it wouldn’t carry over signature
>> constraints and coercions as a specific argument-flipper sub written with
>> the same signature (flipped). Haskell does deep type inference, unlike Perl
>> 6, so simply writing flip f x y = f y x is sufficient to get exactly the
>> same behavior in constrained or coercive contexts.
>>
>>
>>> Aaron Sherman, M.:
>>> P: 617-440-4332 Google Talk, Email and Google Plus: a...@ajs.com
>>> Toolsmith, developer, gamer and life-long student.
>>>
>>>
>>> On Wed, Sep 7, 2016 at 6:13 PM, Brandon Allbery <allber...@gmail.com>
>>> wrote:
>>>
>>>> On Wed, Sep 7, 2016 at 6:08 PM, Parrot Raiser <1parr...@gmail.com>
>>>> wrote:
>>>>
>>>>> There is a "flip" in P6, to reverse the characters in a string, and a
>>>>> "reverse", to return the elements of a list. Would either of those be
>>>>> an equivalent?
>>>>>
>>>>
>>>> Not without an "apply" mechanism used for function / method / operator
>>>> invocations. Which is almost viable in Perl 6 since the parameters get
>>>> passed as a list --- except that the list is only visible within the
>>>> implementation, not at the call site (which is what "apply" does).
>>>>
>>>> --
>>>> brandon s allbery kf8nh   sine nomine
>>>> associates
>>>> allber...@gmail.com
>>>> ballb...@sinenomine.net
>>>> unix, openafs, kerberos, infrastructure, xmonad
>>>> http://sinenomine.net
>>>>
>>>
>>> ​
>>
>
>


Re: Justification for the "reversed" instruction format

2016-09-08 Thread Trey Harris
On Thu, Sep 8, 2016 at 9:23 AM Aaron Sherman a...@ajs.com
 wrote:

I don't know Haskell, but isn't flip just:
>
> sub flip() { -> $b, $a, |c { f($a, $b, |c) } }
>
> And then:
>
> perl6 -e 'sub flip() { -> $a, $b, |c { f($b, $a, |c) } }; my  = flip
>  yas(1,2,3)'
> 213
>
> Yes—but my worry about that was that it wouldn’t carry over signature
constraints and coercions as a specific argument-flipper sub written with
the same signature (flipped). Haskell does deep type inference, unlike Perl
6, so simply writing flip f x y = f y x is sufficient to get exactly the
same behavior in constrained or coercive contexts.


> Aaron Sherman, M.:
> P: 617-440-4332 Google Talk, Email and Google Plus: a...@ajs.com
> Toolsmith, developer, gamer and life-long student.
>
>
> On Wed, Sep 7, 2016 at 6:13 PM, Brandon Allbery 
> wrote:
>
>> On Wed, Sep 7, 2016 at 6:08 PM, Parrot Raiser <1parr...@gmail.com> wrote:
>>
>>> There is a "flip" in P6, to reverse the characters in a string, and a
>>> "reverse", to return the elements of a list. Would either of those be
>>> an equivalent?
>>>
>>
>> Not without an "apply" mechanism used for function / method / operator
>> invocations. Which is almost viable in Perl 6 since the parameters get
>> passed as a list --- except that the list is only visible within the
>> implementation, not at the call site (which is what "apply" does).
>>
>> --
>> brandon s allbery kf8nh   sine nomine
>> associates
>> allber...@gmail.com
>> ballb...@sinenomine.net
>> unix, openafs, kerberos, infrastructure, xmonad
>> http://sinenomine.net
>>
>
> ​


Re: Justification for the "reversed" instruction format

2016-09-07 Thread Trey Harris
There’s a very common functional programming pattern, usually called flip;
its implementation in Haskell is simply:

flip   :: (a -> b -> c) -> b -> a -> cflip f x y =  f y x

Getting the same behavior out of a bespoke function in Perl 6 would be easy
for any particular case, but writing a general version of flip that would
work universally with all binary operators would be a pain to get right
(while maintaining *exactly* the same behavior and errors as the original
in all conditions), wouldn’t it?

If so, R is syntactic sugar, but very helpful syntactic sugar.

On Tue, Sep 6, 2016 at 12:59 PM Aaron Sherman 
wrote:

Oh, and note that you can pass R'd reductions as if they were normal prefix
> ops:
>
> $ perl6 -e 'sub dueet(, *@list) { op @list }; say dueet :<[R-]>,
> 1..100'
> -4850
>
>
>
> On Tue, Sep 6, 2016 at 12:51 PM, Aaron Sherman 
> wrote:
>
>>
>>
>> $ perl6 -e 'my @numbers = 1..100; say [-] @numbers; say [R-] @numbers'
>> -5048
>> -4850
>>
>> In general, it's kind of pointless with bare infix ops, as you can just
>> reverse the arguments, but when reducing or the like, it becomes much more
>> valuable.
>>
>>
>>
>> On Tue, Sep 6, 2016 at 12:43 PM, Parrot Raiser <1parr...@gmail.com>
>> wrote:
>>
>>> I've just stumbled across "reversed operators", e.g. say 4 R/ 12; # 3
>>> in the documentation. I'm curious to know why the language includes
>>> them? I'm having trouble understanding where they would be useful.
>>>
>>
>>
> ​


Re: Should Cgrep and Creverse work in CAny ?

2008-06-30 Thread Trey Harris

In a message dated Mon, 30 Jun 2008, Ovid writes:
I just noticed you included 'reverse' in that list of methods.  I 
thought junctions were inherently unordered, thus making reverse 
kind of useless (which leads me even more to believe that I've 
misunderstood the question).


Yes--Junction is a sister of Any, not a subtype of Any.  That's how 
you get the autothreading--accept Any or a subtype thereof, and when 
you get a junction, you autothread.  Accept Junction or Object and you 
can inspect the junction directly.


At least, that's how *I* think it works... :)

--
Trey Harris  http://www.lopsa.org/
President, LOPSA   -- The League of Professional System Administrators
Opinions expressed above are not necessarily those of LOPSA.


Re: Rakudo test miscellanea

2008-06-26 Thread Trey Harris

In a message dated Thu, 26 Jun 2008, Moritz Lenz writes:

I assume that 'Num' is meant to be a non-complex.
Then it seems to make sense to assume:
Int is Rat
Rat is Num
Num is Complex
or am I off again?


S29 seems to have been assuming this, if I'm reading the multis correctly.

--
Trey Harris  http://www.lopsa.org/
President, LOPSA   -- The League of Professional System Administrators
Opinions expressed above are not necessarily those of LOPSA.


Re: given vs for

2008-04-25 Thread Trey Harris

In a message dated Fri, 25 Apr 2008, Moritz Lenz writes:


Paul Fenwick pjf at perltraining.com.au writes:


for ($foo) {
when ($_  500)  { ++$_ }
when ($_  1000) { --$_ }
default  { say Just right $_ }
}


Ahh... that's exactly what I was looking for.  Thanks.

Makes you wonder why the 'given' keyword was added, when for/when is so close...


I'd assume 'given' provides scalar context onto its argument, 'for'
obviously provides list context.

But I guess the main difference is that 'for' is associated with
iteration, and IMHO it feels unnatural to iterate over one item.


In 5.10, given seems to copy its argument, whereas for aliases it.  (I 
haven't looked at the code; maybe it's COW-ing it.)  If you add a Csay 
Value is now $foo; to the end of the below program, and then change 
Cfor to Cgiven and run the program with values of $foo less than 500 
or greater than 1000, you'll see the difference: with Cfor, the value 
remains changed after the block, with Cgiven it is not.


I do not believe this distinction is true in Perl 6, is it?

Trey


Re: given vs for

2008-04-25 Thread Trey Harris

To loop back to my earlier question:

In Perl 5.10:

use strict;
use warnings;
use feature qw(switch say);

my $foo = 10;
for ($foo) {
when ($foo  50) { $_++ }
}
say for: $foo;

$foo = 10;
given ($foo) {
when ($foo  50) { $_++ }
}
say given: $foo;

Prints:

for: 11
given: 10

In Perl 6, that same code (minus the three Cuse lines) should print:

for: 11
given: 11

Correct?

Trey


Re: what should be the default extension?

2008-01-07 Thread Trey Harris

In a message dated Mon, 7 Jan 2008, Richard Hainsworth writes:


May I suggest the following extension to the 'use ' pragma, viz.
use module name written in unicode and case sensitive in filename as 
constrained by local system


Oh please, no.

The entire point of the wording currently in the synopsis is so that we 
can have platform-independent location of libraries.  The name mangling 
capability hypothesized lets the same Cuse get the requested resource, 
regardless of the file (or database location!) where the resource is 
actually located on the platform running Perl.


Your proposal would force us to have platform-dependent locations, and 
hence platform-dependent programs.  Do you really want to see dozens of 
switches like


  given $?OS {
 when m:i:/win/ { use Foo in WinFoo.pm }
 when m:i:/nix/ { use Foo in UnixLikeFoo.pm }
  }

at the top of programs?

The broken operating system, or rather family of systems (and I converted 
away from them about three years ago), still is used by 90% of users. In 
practice, it does matter what happens in that environment.


Yes--but better for implementators to make that decision than for each and 
every Perl programmer (most of whom will have no experience with most OS's 
Perl runs on, so will be making such decisions blind!) to make them 
separately (and differently).


But also consider, whatever operating system is in use, it has to know how by 
default to handle a file - interpret it as a script, run it as a native 
executable, pipe it to an editor or renderer etc. That information has to be 
associated with the file in some way. One operating system uses name 
extensions, another looks at the first line for a #! etc.


Personally, I find it useful to have a visible clue in the name (via an 
extension) as to the content of the file. This seems to me more widespread 
than just an OS requirement, as otherwise why have *.tar *.tar.gz *.pdf *.doc 
*.png etc or even .* for hidden files in unix?


The .tar, etc., are typically named for transport, where you may need to 
know the filetype without having the benefit of its contents for 
examination.  *.pdf and *.doc are filetypes that did not exist until after 
Windows did, and so the required-extension behavior ossified.  The .* 
convention merely came about because it was a convenient kludge put into 
ls for the purpose.


By way of illustration,
   % mv foo.png foo.jpg
does not convert the file's image type.  If it did (or if it refused to do 
the move) you'd have an argument there.


If it doesnt matter - as far as perl6 is concerned - how the module is named 
(see Larry Wall's response regarding unicode and case-sensitivity), then the 
extensions too are irrelevant, no? So if I choose to call my perl6 scripts 
*.p6 it should not matter? Other than for the sake of tradition or conformity 
with the tribe's sense of propriety :)


Sure, knock yourself out.  Call it .perl6 if you like, or 
.niftynewlanguagethatisn'tquitecompatiblewith.pl (except those violate 
eight.3 rules).


And that brings me to another question. Should it matter what the name of the 
file is? For modules in perl5 as far as I can discern, the name of the module 
in the file name has to conform with the package name inside the script. I 
have found this default behaviour annoying at times.


To do otherwise is to again require platform-dependence.  If you truly 
want to force it, load the code manually with Crequire in a CBEGIN 
block.


By extending the 'use' pragma to include information about which container it 
can be found in, filenames become truly irrelevant.


Quite to the contrary--they become much more relevant.

Moreover, the initiation file for a large project might just be a 
configuration file containing all the module names, together with use 
Main main in ProjectDebugStage.v03


And that configuration file would be a huge comb of $?OS and $?OSVER 
switches in a typical platform-independent development.  And even so, the 
whole thing would be far more brittle than the automatic-location system 
we have today, as problematic as it is (not very, actually...).


Trey


$?OS semantics

2008-01-07 Thread Trey Harris

Sorry, quoting myself...

In a message dated Mon, 7 Jan 2008, Trey Harris writes:

 given $?OS {
when m:i:/win/ { use Foo in WinFoo.pm }
when m:i:/nix/ { use Foo in UnixLikeFoo.pm }
 }


It strikes me that $?OS and $?OSVER should probably not be strings (as 
they now are in Pugs) and should be objects--in fact, they can both be the 
same object, just with different stringifications.  Auto-instantiated 
singletons of classes named for the OS, to be precise.


That way, you could do Config-and OS-specific-type stuff through the $?OS 
object--which is nice, though not that important--but better yet you can 
do


  given $?OS {
 when Windows { ... }
 when MacOS   { ... }
 when Linux   { ... }
 when Unix{ ... }
 default  { ... }
  }

Rather than having to do string-matching (and one would assume that Linux 
and MacOS are subtypes of Unix, etc.)


Then we can have roles that describe cross-cutting behavior of various 
OS's (like POSIX):


  my trytolink;
  give $?OS {
 when OS::HasSymlinks { trytolink := *symlink; }
 when OS::HasLinks{ trytolink := *link; }
 default  { trytolink :=
- ($old, $new) { fail X::LinkNotAvailable }
  }
  }

  # (Aside: Is there some way to do create a two-argument sub that ignores
  #  its arguments?  Would - (undef, undef) or - (*, *) or - (Any, Any)
  #  work?)

So $?OS isn't the type of OS, it's *the OS*, and you can manipulate the 
OS through it.


Thoughts?

Trey


Re: $?OS semantics

2008-01-07 Thread Trey Harris

In a message dated Mon, 7 Jan 2008, Larry Wall writes:

On Mon, Jan 07, 2008 at 11:42:06AM -0500, Trey Harris wrote:

So $?OS isn't the type of OS, it's *the OS*, and you can manipulate the
OS through it.


Note that $?OS is the OS that is-or-was running at compile time,
whereas $*OS is the OS running right now (at run time).  Those don't
have to be the same, especially for modules distributed in some kind
of universal bytecodeish format.


Understood.  My earlier suggestions apply to $*OS and $*OSVER as well 
though.


That is, $?OS is a compile-time constant, while $*OS is a variable.  In 
fact, if someone invents a way for a process to freeze and restore the 
execution context in a different place, $*OS could change more than 
once.


Good point.  So you wouldn't want to assign a static behavior to my 
trytolink example; instead you'd probably want to do


  Role BestEffortLinkAble {
  method trytolink ($old, $new) { ... }
  }

And mix the role in to $*OS.  Then call $*OS.trytolink() to get the proper 
behavior at the proper time.


Trey


:($obj) syntax (was Re: [svn:perl6-synopsis] r14479 - doc/trunk/design/syn)

2008-01-05 Thread Trey Harris

In a message dated Thu, 3 Jan 2008, [EMAIL PROTECTED] writes:

+But these bindings Ido autovivify:

my %hash;
my $val := %hashfoobar;

my @array;
-my $obj = [EMAIL PROTECTED]; # $obj is a Capture object - see S02
+my $cap = [EMAIL PROTECTED]; # $obj is a Capture object - see S02
+my :($obj) := $cap;   # @array[0][0] created here


I'm wondering about that last line there.  Going by S02, I see:

   * There is now a generalized adverbial form of Pair notation. The
   following table shows the correspondence to the fatarrow notation:

   Fat arrow   Adverbial pair  Paren form
   =   ==  ==
   [...]
   '' = $x:($x)

which looks like C:($obj).  So I was reading the line

   my :($obj) := $cap;   # @array[0][0] created here

as saying, create an anonymous Pair, with $obj bound to its value, and 
bind the Pair to $cap (causing $obj to be bound to the value portion of 
$cap).


But I was told on #perl6 that :($obj) refers to a Signature.  If so, I 
think the relevant passage in S02 for deciphering the syntax is:


  A signature object (Signature) may be created with colon-prefixed
  parens:
  my ::MySig ::= :(Int, Num, Complex, Status :mice)

So in that case, $obj refers to... what?  The variable's just been 
created, so its value is undef, so it's equivalent to a one-arg Signature 
with an undef item, and it's being used as an lvalue, so I don't 
understand.


Also, someone on #perl6 said that the colon could be omitted with no 
change in effect.  I don't get that, either.


Given its use in the autovivification discussion in S09, the Pair idea 
made sense to me, but the Signature explanation is very confusing.  I'd 
appreciate some help understanding it.


Trey


Re: perl 6 and web open source projects

2007-12-03 Thread Trey Harris

In a message dated Tue, 4 Dec 2007, cdumont writes:


oh, it might not be relevant in many ways but :

http://iamseb.com/seb/2007/12/perl-on-rails-why-the-bbc-fails-at-the-internet/

http://www.bbc.co.uk/blogs/radiolabs/2007/11/perl_on_rails.shtml

There's one thing I would like perl6 to shine in, is web and open source.
I know it's not the purpose of the language
and that the above articles are placed in a particular
context but I guess this can explain to some extends
why both perl don't have a widespread use in entreprise
and in open source project
(I have looked for them but they are little and some of them
like movable type moves to php at each upgrade)


May I divert from where this discussion would clearly go if your comment 
were directly responded to (into a massive flame-fest, that is) just to 
point out that this is not the purpose of the p6-l@ list?


This list is to discuss the Perl 6 core language.

The very notions of enterprise use and open source use and web use 
are so amorphous that it is hard to imagine core language features that 
would foster or discourage them.  A language is an ecosystem, and it's 
hard to argue that Perl has done poorly in any of the three; the fact that 
other languages may currently have more forward momentum reflects, as much 
as anything else, that Perl reached saturation in these areas many years 
ago.


If you want to make specific recommendations with regards to the language 
Perl 6, go ahead.  But a free-for-all on Perl's successes and failures in 
particular arenas is not what this list is for.


Trey


Re: how typish are roles

2006-10-28 Thread Trey Harris

In a message dated Sat, 28 Oct 2006, chromatic writes:
When you specify a type to constrain some operation, you specify that 
the target entity must perform that role.


That statement is very concise and direct. If the fuzziness I observed 
about the identity of the basic building block of type was unintentional, 
this statement should be added to S06.


I think the question (which you didn't directly raise, but I've heard 
from others) of whether role or class will have primacy is kind of 
as pointless as asking whether subroutines or code blocks have 
primacy: you can't use the former without the latter; the former is a 
useful abstraction for the latter, especially when code gets larger or 
is meant for sharing; and while each have places where they're more 
appropriate, either can be used in place of the other given a bit of 
syntactic twiddling.


Well... maybe.  I believe strongly that you can build a really good 
system with roles as the fundamental abstraction and where classes are a 
specialization, but doing the other way around is much more difficult 
and less cohesive.


But I wasn't suggesting that, any more than I was suggesting that code 
blocks based on anonymous subroutines would be as cohesive as subroutines 
based on code blocks.  I was just saying that both roles and classes could 
be equally first-class participants in the type system by my reading of 
S06 and S12: I don't see any necessity, short a statement like yours I 
quoted above, for classes to be coerced into a role before they can act as 
a type.


Trey


where constraints as roles (was Re: how typish are roles)

2006-10-28 Thread Trey Harris

In a message dated Sat, 28 Oct 2006, Trey Harris writes:


In a message dated Sat, 28 Oct 2006, chromatic writes:
When you specify a type to constrain some operation, you specify that the 
target entity must perform that role.


That statement is very concise and direct. If the fuzziness I observed about 
the identity of the basic building block of type was unintentional, this 
statement should be added to S06.


Incidentally, this would mean that a Cwhere clause or junctive type 
defines an anonymous role, and a type parameter defines a lexical role, 
doesn't it?  Seems like a useful characteristic of these constructs to 
make explicit, perhaps in LS12/Roles.


I find this a little unintuitive given the way these typing particles are 
used, though... If I were insane in a different way than I actually am, I 
might think I could use this every constraint is a role behavior to 
write:


   sub pairs_up_to (Int $x where { $^x % 2 == 0 } ) {
   (1..^$x:by(2)) = (2..$x:by(2))
   }

   pairs_up_to(4)};# 1 = 2, 3 = 4

   try { pairs_up_to(3) }
   err say $!; # No compatible subroutine found

   my $even_three = 3 but where { $_ % 2 == 0 };  # Huh?
   try { pairs_up_to($even_three) }
   err say $!;# What?

Not a useful example, I admit--which is why I had assumed Cwhere 
constraints were not roles, because I can't think of a useful example of 
treating them as roles.  But I suppose if you're determined to shoot 
yourself in the foot like that, you'll find some way (like overloading 
C% so it always returns 0).


You could probably even make Perl be able to call the sub in the second 
Ctry, perhaps by making the anonymous roles generated by Cwhere first 
match by AST equivalence before testing their value against the constraint 
or something.


Not that I think Perl should be able to do that... I'm just saying I 
*might* think it would, given how roles usually work (and if I could come 
up with a less contrived case, I might actually expect it to).


But *why* wouldn't it work?  One of two reasons I think:

1. The first Cwhere clause in the sub signature defines a different
   anonymous role from the second Cwhere clause after Cbut, even
   though they're defined identically.  In that case, $even_three would
   have no practical difference from any other 3, because it merely mixes
   in a role that never gets used.

2. The assignment would throw a mistyped value exception, just like
   my Num $foo = 'hi, mom' does.  (Except it doesn't.  Should it?  I
   don't see a test that addresses this in the suite, nor something in
   the Synopses to say that that assignment should fail.)

In either case, Cwhere clauses create roles that values might do without 
even realizing they're doing them, and which mutable objects might do and 
then not do, willy-nilly, even in the course of the scope in which they 
were typed to do it... which I think is new unless I just haven't been 
paying attention.


sub saturate (Color $c where { $^c.saturation  100 } ) {
$c.saturation = 100;  # ???
correct_gama($c);
}

Did that mutation throw an exception, by changing $c's type to one it 
can't have in this sub?  If no, did we just lose gradual typing (assuming 
correct_gamma cares)?  Can we detect that, or do the roles created by 
Cwhere not participate in gradual typing?  If Cwhere constraints 
weren't roles, this would make sense to me again.


It's duck-typing, but a very different type of duck typing than, say Ruby 
has... it isn't a duck because it walks and quacks, but because when you 
examine it with your particular duckish litmus test (your Cwhere 
clause), the litmus test turns the duckish color (Bool::True) you're 
looking for.


A trifling issue, I guess, as you can just ignore how Cwhere works so 
long as it does work.  But when I see a statement like every X is really 
syntactic sugar for a Y, I want to poke at all the X's to see how they 
behave deeply as Y's.


Trey


Re: how typish are roles

2006-10-25 Thread Trey Harris

In a message dated Wed, 25 Oct 2006, TSa writes:

from the recent threads 'class interface of roles', 'set operations for 
roles' and 'signature subtyping and role merging' I wonder how typish 
roles actually are. Some seem to consider roles as lightweight particles 
that serve to compose classes. I see them as the heavyweights in the 
type department. Doing a role is like a contract about certain 
functionality. So, what does @Larry think?


I'll let @Larry speak for @Larry, but at one point I was told that when 
CArray or CHash appear in signatures, those are roles, not classes; if 
you examined a particular Array or Hash, the class would be some 
implementation of the Array or Hash role, perhaps something like 
CPugsSparseArray or CParrotOpaqueHash or so on. So I'd tend to agree 
that roles are the heavyweights in the type department.


I've spent a few minutes with no luck trying to draw the actual discussion 
out of the #perl6 logger, but I'm pretty sure this was the gist.


My (probably lame) interpretation of the Weltanschauung of Perl's typing 
is that roles, classes, type parameters, and type sets (junctive types, 
subsets, and mixtures thereof) are all equally relevant to the type 
system, and are all equally typish (though perhaps some are more 
primitive and some are more sugary).


Unless you're actually composing or inheriting from something, you 
shouldn't care whether its type derives from a role, a class, a type set, 
or a type parameter.  (And if you are composing or inheriting from it, 
you're not so much interested in its typishness as its behavior.  Your new 
type will be/do whatever type(s) it inherited/composed, and will also 
be/do itself; beyond that, you shouldn't care)


My gut feeling is that in real-world Perl 6 code we'll see a lot of both 
classes and roles being used as types.  Roles will be more common typing 
particles when interacting with the Perl core or parts of other large code 
bases, and when you desire type safety.  Classes will be more common when 
you just have a local need to have something to instantiate, or you want 
SMD or MMD.  When programming in the large, the benefits of having a role 
will often be clearer; when programming in the small, a class will often 
(Cbut not always ;) be more expeditious.


I think the question (which you didn't directly raise, but I've heard from 
others) of whether role or class will have primacy is kind of as 
pointless as asking whether subroutines or code blocks have primacy: 
you can't use the former without the latter; the former is a useful 
abstraction for the latter, especially when code gets larger or is meant 
for sharing; and while each have places where they're more appropriate, 
either can be used in place of the other given a bit of syntactic 
twiddling.


I know that S12 states The type system of Perl consists of roles, 
classes, and subtypes but I don't have a clear picture of the inner 
workings or the formal model of this type system. E.g. what actually 
constitutes a type? How are the classes related to types? There is this 
fuzzy concept that a class is also a role of the same name as far as 
typing is concerned. How is the subtyping relation defined?


I can read S12 as saying that classes always do an eponymous role, and so 
role is what typing is really based on.  Or alternatively, since when a 
role is used as if it were a class, it constructs an anonymous class that 
composes it, that class is what typing is really based on.  But I don't 
see that it matters one way or the other; they seem functionally 
equivalent to me--as would having type based on Cwhere subsets, or 
having all these things participate equally, or any other angle you might 
want to look at it from.  The behavior seems pretty ecumenical to me.


In other words, I agree that it's fuzzy, but I personally read the 
fuziness as intentional, so as to allow implementations flexibility and 
prevent bad dependencies on particular inner workings of the type 
system.


Trey


Re: Edge case: incongruent roles

2006-10-13 Thread Trey Harris

In a message dated Fri, 13 Oct 2006, Jonathan Lang writes:

Since Baz does both Foo and Bar, you cannot use type-checking to
resolve this dilemma.


Why not?  Why shouldn't this work:

  my Foo $obj1 = getBaz();  # object is a Baz
  $obj1.baz();  # Foo::baz is called

  my Bar $obj2 = getBaz();  # object is a Baz
  $obj2.baz();  # Bar::baz is called

  my Baz $obj3 = getBaz();  # object is a Baz
  $obj3.baz();  # Depends on Bob's implementation of ::Baz

All three objects happen to be Baz's, yes.  But the client code doesn't 
see them that way; the first snippet wants a Foo, the second wants a Bar. 
They should get what they expect, or Baz can't be said to do either.


If methods are entirely dispatched *by name* (duck typing), then I 
agree, we have a problem.  But Perl 6 supposedly supports a) multiple 
inheritance, b) multiple dispatch, c) traits, and d) DBC.  I believe the 
union of those requirements means that methods must be dispatched in a 
more sophisticated way than just looking for a matching name.


(I know a guy who works in building maintenance and also does moonlighting 
as a computer tech.  In either of his two roles, he could be said to do 
windows.  But what windows he does when someone asks him to do windows is 
disambiguated by his current role.)



The way things are now, it would appear that Bob's stuck.  Short of
rewriting one of ( Foo and foo ) or ( Bar and bar ) to use a different
method name in place of baz, he can do nothing to resolve the
syntactic collision between Foo and Bar while continuing to let foo
and bar run properly.


Duck-typing would give you this dilemma, no question about it.  But I 
think Perl 6 is beyond duck-typing.


The dilemma only arises in the context of calling .baz on a *Baz*--and Bob 
hasn't written the class Baz yet.  The question remaining is just one of 
disambiguation syntax and/or what happens when Bob chooses to do nothing 
about disambiguation (compile-, compose- or instantiation-time error, or 
some arbitrary default dispatch?).


Trey



--

Thoughts?




--


Re: Don't tell me what I can't do!

2006-10-08 Thread Trey Harris

In a message dated Wed, 4 Oct 2006, Smylers writes:


Trey Harris writes:

I remember not so many years ago when there were a lot of modules
floating around that required you to do no strict of various flavors
in order to use them.


Really?  How?


I wrote imprecisely.  Not to use them in the sense of Cuse Package, 
but use in the sense of make use of them as described in the perldoc's 
synopsis--usually by dint of requiring undeclared package variables, 
barewords, or symbolic refs.  Alias is one example, there were others.


You could always work around, but the docs assumed you had strictures 
turned off, so you were left to your own devices to determine what 
internal implementation decision was leading to problems operating under 
your level of stricture.  (For example, a package that had string 
constants defined as subroutines like Csub ERRCODE() { ERRCODE } would 
behave differently than one that assumed barewords would work, but both 
might use identical examples of Cmoose ERRCODE in their perldocs.)



I still run across modules that need no warnings.  (I won't name
names, because some of their authors post to this list ;)


Again, I can't see how.  If you use Cuse warnings in your program then
it is lexically scoped and only affects your code, not that of other
files you load in.


Again, I meant in code use, not in just loading--uninitialized value 
warnings being the main culprit there.



C-w does affect all files, but that's one of the reasons why Cuse
warnings is an improvement over C-w, because it lets the author of
each bit of code have control over it.


Yes indeed.

Trey


Re: Abstract roles, classes and objects

2006-10-04 Thread Trey Harris

In a message dated Sun, 1 Oct 2006, Aaron Sherman writes:

Trey Harris wrote:

In a message dated Fri, 29 Sep 2006, Aaron Sherman writes:

[snip]
However, that's not to say that a class can't be abstract, just that a 
class that does an interface (a role with nothing but abstract methods) 
must implement the role's interface.


So why would it generate an error?  Why wouldn't it merely result in B 
being abstract too, assuming that contra my prior mail, classes can be 
abstract?


What use is an interface if it doesn't give you a guarantee? If I say, all 
dogs can bark, and you define a dog that can't bark, that's not abstract, 
that's a failure to meet the interface requirements of a dog.


No--I wouldn't define a dog that can't bark, I'd define a dog that *can* 
bark, but I wouldn't say *how* it could bark (conjecturing an is 
abstract class trait I give a sample implementation of below):


  class Dog is abstract { method bark () { ... } #[ ... ]  }
  class Pug is Dog { method bark () { self.vocalize($.barkNoise) } }

  my Dog $fido .= new; # exception, instantiating abstract class
  my Dog $fido  = Pug.new; # good, $fido can bark

Seems like there would be three ways to achieve the guarantee: an explicit 
is abstract marker like above to prevent instantiation; some way to 
infer concreteness (this gets into my earlier question of whether 
yada-yada is enough to do so) so you can prevent instantiation; or simply 
disallow abstract classes entirely.


It sounds like the assumption thus far has been that the existance of 
roles imply that abstract classes are disallowed, so you'd write:


  role Dog { method bark { ... } #[ ... ] }
  class Pug does Dog { method bark { .vocalize($.barkNoise) } }

S12 says: Classes are primarily for instance management, not code reuse.
Consider using Croles when you simply want to factor out
common code.

But if I want to write code that handles the instance management for 
several related classes but cannot be instantiated itself, that must be a 
role and not a class.  But instance management, as the S12 quote says, is 
the purpose of classes, not roles.  Is it a deep requirement of the 
MOP/MRP that only one of classes and roles can be abstract?


I've looked at my uses of uninstantiable classes in Perl 5 for the past 
few years, and I think that almost all of them could be done as roles 
(though for some of them the cognitive dissonance of calling a set of 
object-management methods a role still bothers me).  But there's one 
case where I can't figure out how to do it except for throwing a runtime 
exception in a class.


For a system monitoring application, I have a class heirarchy like the 
following (bare names indicate concrete instantiable classes, brackets 
indicate uninstantiable abstract ones):


+ [SystemMonitor]
  -   CPUMonitor
  -   DiskMonitor
  +   ScriptedMonitor
  +   [HardwareMonitor]
  -   FanMonitor
  -   TempMonitor
  -   PowerSupplyMonitor

Here, SystemMonitor is abstract and sets up the data collection and 
storage routines.  Its concrete subclasses implement how to actually get 
the data and any munging the data requires, but otherwise inherit their 
behavior from SystemMonitor.  ScriptedMonitor is a concrete class that 
gets a script attribute which it runs and a closure attribute it uses to 
munge the data the script generates.


Turns out that there are many HardwareMonitors that all run the same suite 
of hardware monitoring scripts and performs the same munging on them, but 
has almost the same behavior as ScriptedMonitor.  So I handled that by 
subclassing it with a new abstract class, HardwareMonitor, which factored 
out the new behavior all the hardware monitors shared. I then subclassed 
*that* with concrete classes implementing the last little unfactorable 
bits.  So Abstract - Concrete - Abstract - Concrete.


new(), for instance, was defined only in SystemMonitor (but threw an 
exception if you tried to call it on SystemMonitor, thus making the class 
abstract); gatherData() is called in SystemMonitor but is defined only in 
the direct subclasses of SystemMonitor, and is overridden in 
HardwareMonitor with a call to the superclass method 
(ScriptedMonitor::gatherData).  HardwareMonitor's subclasses just define 
some munging methods that HardwareMonitor's processData() methods calls.


In this way, I never repeat myself, I use polymorphism so that I never 
write any conditionals involving the type of anything (except in the case 
of new() throwing an exception to prevent instantiation of an abstract 
class), and related code goes together.  This is a good thing.


In Perl 6, the abstract SystemMonitor could be a role, and a concrete 
ScriptedMonitor could be a class that does SystemMonitor, but it's not at 
all clear to me what HardwareMonitor would be, since classes can't be 
abstract and roles can't inherit from classes.  I guess it would be a 
role, but then we'd have something like:


- role

Re: Don't tell me what I can't do!

2006-10-04 Thread Trey Harris

In a message dated Wed, 4 Oct 2006, chromatic writes:

The assumption I remember from the design meetings was always No library
designer has the knowledge or the right to tell me how fast or strict my
program has to run.  Whatever BD you do in the privacy of your own modules
is fine, but if it leaks out past encapsulation boundaries, expect that
somewhere you might offend community standards.


Yes, but by the same token, no library designer should force you to be 
*less* strict than you wish to.  I remember not so many years ago when 
there were a lot of modules floating around that required you to do no 
strict of various flavors in order to use them.  I still run across 
modules that need no warnings.  (I won't name names, because some of 
their authors post to this list ;)


It should at the very least be *possible* to write modules that can be 
used in every level of strictness from one-liners to 
every-possible-stricture, everything-typed, everything-contracted systems. 
If it's fairly easy to do, so much the better--there's a better chance 
that you won't have to fork somebody else's module to get it to work with 
the level of BD you want.


As for the core--in DBC, which is what started this thread in the first 
place, the compiler and runtime do various correctness inferences based on 
contracts.  If you call some code that doesn't have a contract, you can 
either blow up, or you can just assert that the code you're calling is 
correct--at which point you can no longer guarantee your own contract. 
It's not a stricture that can be lexically toggled off and on like a 
pragma.


So if Perl 6 is going to support DBC, the core needs to support DBC too. 
Nobody is forcing you to use DBC in order to use the core modules, though.


In fact, most DBC systems I'm aware of run in production with 
contract-checking turned off; the checks are for testing and debugging. 
So even DBC programs themselves have to be able to run at a lower level of 
strictness.



In my opinion,Perl 6 should spell no bondage:

#!/usr/bin/perl6


No, it should spell no more, or less, bondage than you want.

Trey


Re: Don't tell me what I can't do!

2006-10-04 Thread Trey Harris

In a message dated Wed, 4 Oct 2006, jesse writes:

On Wed, Oct 04, 2006 at 12:01:22PM -0700, chromatic wrote:

The point is that the person writing the program decides which handcuffs or
costumes all of the code has to wear, not the person writing the libraries.
If you want to set a policy for your organization, that's fine.  It is just
Not Okay for me or anyone to write a module right now that dictates exactly
the strictness of every program written in the next twenty years that uses
it.


Perhaps I'm misunderstanding what you mean by person writing the
program and person writing the libraries. In fact, I've _gotta_
be.  I'd like to be able to put my strictures in a library rather than
forcing them into the main body of a program.  Are you saying
you don't want to let people do this?


I read it as yes, you *can* put strictures on the using code into a 
library, though I wouldn't do it and would say that any module that does 
so shouldn't be released on CPAN for general use.  But even if you can do 
that, you *must* always be able to turn the strictures back off. 
chromatic, is that a fair paraphrase?


I don't have any problem with that sentiment--if I were you and needed to 
enforce some style on other programmers who work with me, I'd just tell 
them to use my library and not unuse it.  It's a human problem, not a 
technical one, if they insist on unusing it by nefarious means.


That philosophy doesn't present any problems with DBC checks, which as I 
mentioned before probably have to handled as a program-global flag rather 
than as a lexical pragma anyway.  (I'm toying with the notion of 
jurisdictions that packages could subscribe to across which a set of 
contracts would be enforceable, allowing them to do DBC while still using 
or being used by code out in some other lawless jurisdiction. Code that 
doesn't explicitly join some jurisdiction would by default be lawless, 
thus living by the philosophy chromatic's espousing.  I think that could 
be made to work, though jurisdictions would have to be at a package, not 
scope, level.  I need to think about it more, though.)


Trey


Re: Abstract roles, classes and objects

2006-10-04 Thread Trey Harris

In a message dated Wed, 4 Oct 2006, Jonathan Lang writes:

In Perl 6, the abstract SystemMonitor could be a role, and a concrete
ScriptedMonitor could be a class that does SystemMonitor, but it's not at
all clear to me what HardwareMonitor would be, since classes can't be
abstract and roles can't inherit from classes.


S12 says:
* A role is allowed to declare an additional inheritance for its
* class when that is considered an implementation detail:
*
* role Pet {
* is Friend;
* }


Thanks.  This is what I was missing.  I read the above, together with A 
role may not inherit from a class, but may be composed of other roles, as 
specifying that any class doing Pet must already be a Friend, not that 
doing Pet caused you to inherit from Friend.


I now see that what it meant was a role may not *inherit* from a class, 
because inheritance is a concept that only applies to instantiated 
objects, but a role can *cause* its class to inherit from a class, which 
works out to pretty much the same thing...


So long as .post_data would work on a TempMonitor object below:

  role SystemMonitor {
 method post_data ($value, :$units, :$timestamp) {
# complete implementation here
 }
  }
  class ScriptedMonitor is SystemMonitor {
 # post_data never mentioned
  }
  role HardwareMonitor is ScriptedMonitor {
 method post_data { next METHOD }
  }
  class TempMonitor is HardwareMonitor {
 method post_data ($value, *%_) { call($value, :units(Celsius), |%_) }
  }

I'm happy.  It sounds like it should.

Trey


Re: RFC: multi assertions/prototypes: a step toward programming by contract

2006-09-29 Thread Trey Harris

In a message dated Thu, 28 Sep 2006, Aaron Sherman writes:

Jonathan Lang wrote:

Aaron Sherman wrote:

Jonathan Lang wrote:
 Actually, it's a promise made by a package (not a class) to meet the
 specification given by a role (which can, and in this case probably
 does, reside in a separate file - quite likely one heavily laced with
 POD).

That's a fine thing to want to do. Not something that I was thinking of
initially, and only tangentially related, but a good idea. I think you
get this for free by embedding a proto (or perhaps a sigform) inside
of a role:

role Foo { sigform bar($baz) { ... } }


What would be the difference between this and

   role Foo { sub bar($baz) { ... } }


One thing that occurs to me: following this contract or promise 
analogy, what does C... mean in a role or class?


Unless I've missed somewhere in the Synopses that explicates C... 
differently in this context, yada-yada-yada is just code that complains 
bitterly (by calling Cfail) if it is ever executed.  So that's fine for 
an abstract routine at runtime--code calls it, and if it hasn't been 
reimplemented, it fails.


But unless something else is going on with C..., as far as the language 
is concerned, a routine with body C {... } *is* implemented, as surely 
as a routine with body C{ fail } is implemented.  So the routine is only 
abstract insofar as you'll need to reimplement it to do anything useful 
with it.


Roles are types, and we've been talking about doing a role as making a 
promise.  But does just mixes in the role, implementations and all.  If 
your yada'ed routine ever gets *called*, you fail, so it would behoove you 
to implement any role you do, unless you're writing an abstract class on 
purpose.


But as we have no abstract adverb presently, it seems to me that the 
compiler has no way of inferring whether a give nclass doing a role 
actually has implemented what it's supposed to in order to meet the role's 
specification or not.  We only find out if the contract was not met or the 
promise was not kept at runtime.


Is my inference correct?

Trey


Re: RFC: multi assertions/prototypes: a step toward programming by contract

2006-09-29 Thread Trey Harris

In a message dated Fri, 29 Sep 2006, Aaron Sherman writes:
First the high-level point: I'm dropping the RFC, because, as TimToady 
pointed out on IRC, we're not quite far enough down the line to see the 
breadth or certainty of the need yet.


Yes, but I don't think the conversation should stop.  These are important 
semantics of the object model and we should be at least roughly on the 
same page so that when someone gets the tuits to work on it, it's clear 
what the direction is.


That said, this is a different point, above and I think it's an easy one to 
take on.


role A { method x() {...} }
class B { does A; }

does generate an error per If a role merely declares methods without 
defining them, it degenerates to an interface: from S12.


However, that's not to say that a class can't be abstract, just that a class 
that does an interface (a role with nothing but abstract methods) must 
implement the role's interface.


So why would it generate an error?  Why wouldn't it merely result in B 
being abstract too, assuming that contra my prior mail, classes can be 
abstract?  Do you have to be explicit about it and say


  role A  { method x() { ... } }
  class B { does A; method x() { ... } }

?  That seems un-Perlishly verbose to me; we had DRY before Ruby ever did.

Nothing is said of what happens when you compose a role that has both 
defined and undefined methods, but IMHO, that's at most a warning if 
they remain undefined after composition, since you might want to use 
that class as a trait at runtime where target objects will define that 
method.


As I said on IRC, I don't read the part of S12 you quote as being the 
definition of interface; I merely read it as being an analogy to the 
concept of interface found in other languages.  I'd find it absurd if 
merely changing


  role Existential { method is { ... }; method isnt { ... } }

to

  role Existential { method is { ... }; method isn't { ! .is } }

resulted in the role changing its instantiability.


Certainly this:

class A { method x() {...} }

is very explicit, and should be allowed, given that it is a promise that 
sometime before x is called, it will be defined. It's a runtime error if 
that promise is not kept.


Did you mean to have class B and does A there, as in my un-Perlish 
example above?  If so, then see my response above.  If not... I'm a little 
surprised.  Since roles and classes share the package namespace, I 
wouldn't expect you to be able to declare a class with the same name as a 
preexisting role, even if you implemented all the role's interfaces within 
that class


One more point for the hypothetical future object-model 
designer/implementer with the even more hypothetical tuits, so that it 
doesn't get lost: note that in a DBC context, { ... } is insufficient for 
an abstract routine.  PRE and POST blocks would ordinarily be included as 
well.  A routine missing a PRE or POST would be considered to have:


   method is {
 PRE  { True }
 POST { True }
 ...
   }

which under DBC rules would be the same as having no POST at all... but 
would unfortunately cause any future PREs to be ignored!


(Under design-by-contract rules, POSTs are and-ed from least-derived to 
most-derived, but PREs are or-ed.  In fact, in Eiffel, PRE is called 
require and POST is called ensure, but only in base classes; in 
derived classes, you must type require else and ensure then to make 
explicit that your assertions are being or-ed or and-ed with assertions 
elsewhere in code.)


Trey


Re: RFC: multi assertions/prototypes: a step toward programming by contract

2006-09-29 Thread Trey Harris

In a message dated Thu, 28 Sep 2006, Jonathan Lang writes:

while roles can be abstract, classes and packages should not be.


Really?  I think I need to let that sink in and percolate a bit.

I'm rather fond of creating abstract superclasses to factor out common 
object-management code.  I have many classes in Perl 5 with code like 
this:


   sub new {
 my $proto = shift;
 my $class = ref($proto) || $proto;
 if ($class eq __PACKAGE__) {
croak Attempt to instantiate abstract class $class;
 }
 # Proceed with common object instantiation
   }

and then the concrete subclasses either don't define new at all or do 
their own subclass-specific initializations and call NEXT to get the 
common initializations.  I've been thinking that a role is not the proper 
place for this sort of code, as it is tightly coupled to implementation, 
and my understanding of the gestalt of roles is that they should be 
loosely coupled to their users' implementations.


But if only a role can be abstract, I guess I'd have to use a role (or 
fall back to the Perl 5-ism above and check my .HOW and throw a runtime 
exception).


If you define a BUILD in a role, will it be called when an object of a 
class that does the role is instantiated, as part of the .new BUILD walk?


Trey


Re: RFC: multi assertions/prototypes: a step toward programming by contract

2006-09-27 Thread Trey Harris

In a message dated Wed, 27 Sep 2006, Aaron Sherman writes:

Any thoughts?


I'm still thinking about the practical implications of this... but what 
immediately occurs to me:


The point of multiple, as opposed to single, dispatch (well, one of the 
points, and the only point that matters when we're talking about multis of 
a single invocant) is that arguments are not bound to a single type. So at 
first gloss, having a single prototype in the core for all same-named 
multis as in your proposal seems to defeat that use, because it does 
constrain arguments to a single type.


I would hate for Perl 6 to start using CAny or CWhatever in the sort 
of ways that many languages abuse Object to get around the restrictions 
of their type systems.  I think that, as a rule, any prototype 
encompassing all variants of a multi should not only specify types big 
enough to include all possible arguments, but also specify types small 
enough to exclude impossible arguments.


In other words, to use your proposal, our proto moose (Moose $x:) should 
assert not just that all calls to the multi moose will have an invocant 
that does Moose, but also that all objects of type Moose will work with a 
call to the multi moose.  That may have been implicit in your proposal, 
but I wanted to make it explicit.


In practice, the ability to use junctive types, subsets, and roles like 
any other type makes the concept of single type a much less restrictive 
one in Perl 6 than in most languages.  For example, if you wanted Cmax 
to work on both arrays and hashes, you could have


  our proto max (Array|Hash $container)

Or you could define an CIndexed role that both Array and Hash do and 
have:


  our proto max (Indexed $container)

So maybe this is a reasonable constraint.  But it seems odd to me that 
Perl might then not allow me to write a Cmax that takes, say, Bags or 
Herds or whatever.  And as I said before, I think a prototype of


  our proto max (Whatever $container)

is incorrect too.  What I really want is for max to be callable on 
anything that can do max, and not on anything that can't.  Following that 
observation to its logical conclusion, at some point we get to the core 
containing prototypes like:


  our proto max(Maxable $container)
  our proto sort(Sortable $container)
  our proto keys(Keyable $container)

which (I think) results in no better support for contracts, but merely 
requires gratuitious typing (in both senses of the word): where before we 
could just write our routine multi max..., now we need to write both 
multi max... and remember to add does Maxable so Perl will let us 
compile it.


My apologies if I'm attacking a strawman here; perhaps there's a saner way 
to allow the flexibility for users to define novel implementations of 
global multis while still having the prototypes well-typed.


All that said, the globalness of multis does concern me because of the 
possibility of name collision, especially in big systems involving multis 
from many sources.  Your proposal would at least make an attempt to define 
a multi not type-conformant with a core prototype throw a compile-time 
error, rather than mysterious behavior at runtime when an unexpected multi 
gets dispatched.


Trey




call, call(), .call, and captures

2006-09-20 Thread Trey Harris

From S06:


  sub bar ($a,$b,$c,:$mice) { say $mice }
  sub foo (\$args) { say $args.perl; bar.call($args); }

  The C.call method of CCode objects accepts a single CCapture
  object, and calls it without introducing a CCALLER frame.

And from S12:

  In addition to Cnext METHOD, the special function Ccall dispatches
  to the next candidate, possibly with a new argument list:

  call;   # calls with the original arguments
  call(); # calls with no arguments
  call(1,2,3);# calls with a different set of arguments

And back in S06:

  The entire argument list may be captured by the C\$args parameter.
  It can then be passed to Ccall as C[,] =$args:

  # Double the return value for thermo
  thermo.wrap( - \$args { call([,] =$args) * 2 } );

The inconsistency between these three things called call is vexing to 
me.  One is a method and takes a capture and only a capture. The second is 
a special function and takes an argument list, but also has a special 
arglistless form that passes on the original arguments.  The third is a 
function that takes only a function list, but apparently lacks a 
arglistless form (otherwise, why bother with capturing an arglist in the 
example?).


I believe the current spec works.  I just think the inconsistency is 
bad--the three things called call do very similar things, but take 
completely different arguments.  I suspect this is just historical smear 
and we just need to back up and normalize.


(Let me quickly note here that I don't think it's possible to write a 
subroutine or method that can take either a bare argument list or a 
Capture and treat them the same, because of the intractable ambiguity that 
would arise in the case of an argument list that actually contains a 
single capture as its only positional element.  If I'm mistaken, then 
other avenues open up.  But I don't think I am.)


Audrey confirmed to me on IRC that the motivation for the arglistless form 
was that passing on the original arguments will likely be one of the most 
common uses of call.  And I certainly can't argue with that, I agree.


But why, then, does .call not have an argumentless form?  (Because we 
can't write user-defined methods, short of Cis parsed tricks, that 
differentiate between .meth and .meth()?  We can't write user-defined subs 
that do that either, AFAIK...)


Might I propose the following normalization:

1. .call, method definition call(), and .wrap call all take captures. 
2. .call() and both types of call() all pass on the arguments of the

   current subroutine.
3. To call with no arguments, use .call(\()) and call(\()).
4. Introduce some syntax for getting a capture of the current argument
   list explicitly.  Perhaps $?ARGS or $?_ or $?CAPTURE.  One shouldn't
   have to choose between repeating your 20 parameters in order to take a
   capture of them, and eliminating your nice self-documenting 20
   parameter names so you can use the easy \$arglist trick.

Trey


Re: Capture sigil

2006-09-20 Thread Trey Harris

In a message dated Wed, 20 Sep 2006, Larry Wall writes:

The obvious ASCII for ¢ would be c/ or C/ or c| or c| or maybe just |.


I like ¢,but:

   c/$foo # ASCII of ¢$foo
   d/$foo # d() divided by $foo

is rather confusing.  (Same goes for |).

So the Term Term exclusion makes me rather lean towards |.  Whether it's
the canonical sigil or the ASCII of ¢ doesn't much matter to me.

Trey

Re: Capture sigil

2006-09-20 Thread Trey Harris
Oops, I hate typos that result in my writing exactly the opposite of what 
I meant:


In a message dated Wed, 20 Sep 2006, Trey Harris writes:


In a message dated Wed, 20 Sep 2006, Larry Wall writes:

The obvious ASCII for ¢ would be c/ or C/ or c| or c| or maybe just |.


I like ¢,but:

  c/$foo # ASCII of ¢$foo
  d/$foo # d() divided by $foo

is rather confusing.  (Same goes for |).


Oops, I meant same goes for c|.  I like |:


So the Term Term exclusion makes me rather lean towards |.  Whether it's
the canonical sigil or the ASCII of ¢ doesn't much matter to me.


Trey

Re: any(@originals) ~~ { .foo eq $bar} (was Re: renaming grep to where)

2006-09-19 Thread Trey Harris

In a message dated Tue, 19 Sep 2006, Markus Laire writes:


On 9/19/06, Trey Harris [EMAIL PROTECTED] wrote:

In a message dated Mon, 18 Sep 2006, Darren Duncan writes:
  @filtered = @originals.where:{ .foo eq $bar };

Note that this can be written:

@filtered = any(@originals) ~~ { .foo eq $bar};


This doesn't seem to be correct.


See S09.  In particular,

@result = any(@x) ~~ {...};

is equivalent to

@result = grep {...}, @x;


Testing a concrete example in pugs (r13034):
  pugs my @a = (1..10);
  (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
  pugs any(@a) ~~ { $_  0 }
  (Bool::False)
  pugs any(@a) ~~ { $_  0 }
  (Bool::True)
  pugs any(@a) ~~ { $_ % 2 }
  (Bool::False | Bool::True)


This feature is unimplemented.

Trey


Re: renaming grep to where

2006-09-18 Thread Trey Harris

In a message dated Mon, 18 Sep 2006, Darren Duncan writes:


Putting aside legacy issues for the moment,

I suggest that it might be appropriate to rename the .grep list operator to 
.where, so we can say, for example:


 @filtered = @originals.where:{ .foo eq $bar };


Note that this can be written:

   @filtered = any(@originals) ~~ { .foo eq $bar};

Trey


Re: Cwhen outside of Cgiven

2006-09-08 Thread Trey Harris

In a message dated Thu, 7 Sep 2006, Mark Stosberg writes:

To refine this point a bit, the spec is clear that 'when' is useful not
just with 'given' but with any block that sets $_.


Thanks, I was not being terribly precice when I conflated when with given. 
Of course, CATCH is another case where when is frequently used (and where 
the semantics of when should be like given, exiting the surrounding block 
once the when block has finished).


Trey


Cwhen outside of Cgiven

2006-09-07 Thread Trey Harris

markstos++ pointed out the following behavior:

  use v6-alpha;

  {
when 1 ~~ 0 {
  say Surprise!
}
  }

This code prints Surprise!, because $_ is undef, which is false, just 
like 1 ~~ 0 is.


I'd like to make the following suggestions for Synopsis clarification:

1. It will be a very common pitfall, I think, to write Cwhen as a 
synonym for Cif.  For an extra layer of safety for such a novitiate 
mistake, a boolean used as an argument to when should emit a warning 
unless suppressed with an explicit C?().


   when   1 ~~ 0  # warning
   when ?(1 ~~ 0) # no warning

2. I think Cwhen should either be disallowed outside of Cgiven, or it 
should be made to do something useful.  I have no strong opinion on which, 
but I can see a smartmatching-against-topic construct being useful.  So I 
suggest the following:


   Upon exit, Cwhen emits a WhenExitSuccess control exception (a
   subclass of the ExitSuccess exception thrown by other blocks)

   Cgiven catches WhenExitSuccess exceptions and immediately returns.

   Other blocks ignore WhenExitSuccess exceptions (or usually just ignore
   all ExitSuccess exceptions), so Cwhen something acts exactly like

   if $_ ~~ something

   except Cwhen... else is disallowed.

If this is allowed, I personally think a when statement modifier seems 
reasonable too, but that's Larry's call.


If these semantics are not followed, I do think Cwhen should be 
disallowed outside of Cgiven (or blocks of some other when-allowing 
trait that given has but standard blocks do not).  The upon exit 
immediately exit the surrounding block semantics seem to be rather seldom 
useful outside of Cgiven.


Trey


Re: multi method dispatching of optional arguments (further refined)

2006-09-04 Thread Trey Harris

In a message dated Tue, 5 Sep 2006, Ph. Marek writes:
I now had a look at http://dev.perl.org/perl6/doc/design/syn/S06.html 
but didn't find what I meant. Sorry if I'm just dumb and don't 
understand you (or S06); I'll try to explain what I mean.


I don't think you're dumb; the Synopses just require that you intuit 
certain things from each other, from examples in other Synopses, and so on 
in a Perlish sort of way; what you're looking for is not spelled out 
explicitly.  It can be found by noticing how you specify subtypes, along 
with noticing that subtypes can be specified as parameter types.  There's 
also an example showing explicitly what you want in S12.



In Perl5 this looks like

sub SomeThing
{
  my($a, $b)[EMAIL PROTECTED];

  return b+2 if ($a == 4);
  return a+1 if ($b == 3);
  return a*b;
}
[...]
What I am asking is whether there will be some multimethod dispatch depending
on the *value*, not the *type*, of parameters.
Perl6 could possibly do something with given; but matching on multiple
variables seems to be verbose, too.
I'm looking for something in the way of

sub SomeThing(Num $a, Num $b) where $a==4 is $b+2;
sub SomeThing(Num $a, Num $b) where $b==3 is $a+1;
sub SomeThing(Num $a, Num $b) { return $a * $b }


It's just

   multi sub SomeThing(Num $a where {$^a == 4}, Num $b) { $b + 2  }
   multi sub SomeThing(Num $a, Num $b where {$^b == 3}) { $a + 1  }
   multi sub SomeThing(Num $a, Num $b)  { $a * $b }


but without specifying the signature multiple times (or maybe we should, since
it's MMD). Now


Yes, the signatures are different--the first two multis specify subtypes 
as their signatures, the last specifies a canonical type.


Trey


but semantics (was Re: Naming the method form of s///)

2006-09-01 Thread Trey Harris

In a message dated Thu, 31 Aug 2006, Juerd writes:

Hm. I don't know how but works exactly, but in the realm of syntactic
sugar, this is appealing:

   $foo but s/foo/bar/


I like it.

This should be easy to make work in theory, but for the problem with 
Cbut's semantics which I'll get to in a moment.  Cbut can already take 
a closure in addition to a role or enum:


  my Point $p .= new;
  $p.x = 3;
  $p.y = 0;

  my Point $z = $p but { .y = 17 };

in which case,

  $x but { ... }

just translates into

  do given $x { ...; $_ }

So extending it so that

  $x but s/foo/bar/

just translates into

  $x but { s/foo/bar/ }

seems like very simple and natural sugaring. You can obviously already use 
that latter syntax of simply wrapping the substitution in a closure. 
Except distressingly it doesn't do anything


I think these semantics are Almost Right, but yet Entirely Wrong.  The 
problem is that Cbut reads to me as a *mutating* operator.  That is, I 
would expect the above code snippet to give me a C$z.y of 17, but leave 
C$p.y as 0.  Surely this is what one would expect from analogy of


  0 but True

which I wouldn't think anyone wants to cause all uses of 0, from then on, 
to booleanize true.


But yet Cbut with a closure doesn't copy, given the translation above, 
or even allow modification, since Cgiven doesn't either. $_ (in the 
above case, $p) is set to point to the same object, and so $p.y and $z.y 
are both modified (or rather, they both refer to the same object, which is 
modified during assignment).


In other words, I would actually expect

  $x but { ... }

to translate to

  do given $x - $_ is clone { ...; $_ }

where Cis clone is a conjectural way of calling .clone if the argument 
is an object type but reduces to Cis copy if the argument is a value 
type.  (Neglecting for the moment that a pointy block doesn't appear to be 
a valid argument for Cgiven.  Is this correct?  If so, why?)


I do not think that Cbut should mutate its LHS, regardless what its RHS 
is.


Trey



Re: but semantics (was Re: Naming the method form of s///)

2006-09-01 Thread Trey Harris

In a message dated Fri, 1 Sep 2006, Juerd writes:


Trey Harris skribis 2006-09-01  0:17 (-0700):

I think these semantics are Almost Right, but yet Entirely Wrong.  The
problem is that Cbut reads to me as a *mutating* operator.  That is, I
would expect the above code snippet to give me a C$z.y of 17, but leave
C$p.y as 0.  Surely this is what one would expect from analogy of


In the terminology that I have been using, that would not be a mutating
operator, but a copying operator, exactly because the operand $p remains
untouched.


Yes... I changed copying to mutating back and forth a couple times, 
and then gave up, because of the is clone semantics I actually wanted 
and didn't have a name for.



where Cis clone is a conjectural way of calling .clone if the argument
is an object type but reduces to Cis copy if the argument is a value
type.


Oh, I like is clone with these semantics. Though everything is an
object, so you'd need a different explanation...


Well, I'd say value type and reference type, except we don't have 
references anymore either.  value type versus non-value type, I guess. 
Whether it defines .SKID or not?


Trey


Re: Nested statement modifiers.

2006-09-01 Thread Trey Harris

In a message dated Fri, 1 Sep 2006, Paul Seamons writes:


I'm not sure if I have seen this requested or discussed.


This was definitively rejected by Larry in 2002:

http://www.nntp.perl.org/group/perl.perl6.language/9343

He has not revisited the issue in the several times it has come up since.

Trey


Re: Nested statement modifiers.

2006-09-01 Thread Trey Harris

In a message dated Fri, 1 Sep 2006, jerry gay writes:


On 9/1/06, Trey Harris [EMAIL PROTECTED] wrote:

In a message dated Fri, 1 Sep 2006, Paul Seamons writes:

 I'm not sure if I have seen this requested or discussed.

This was definitively rejected by Larry in 2002:

http://www.nntp.perl.org/group/perl.perl6.language/9343

He has not revisited the issue in the several times it has come up since.


perhaps a sentence to that effect belongs in S04, which has no mention
of nested statement modifiers, for or against.


Well, that's because Synopses at least in theory only refer to changes 
from Perl 5.  Perl 5 doesn't allow more than one statement modifier, and 
Perl 6 doesn't either.


Trey


Contextual::Return (was Re: could 'given' blocks have a return value?)

2006-08-30 Thread Trey Harris

In a message dated Tue, 29 Aug 2006, Mark Stosberg writes:

my $rm = sub { given $rm_param {
   when Code  { $rm_param(self)   }
   when Hash  { %rm_paramrun_mode }
   default{ self.query.param($rm_param) }
   }}();


This is eerily like Contextual::Return, which made me wonder if it's even 
required in Perl 6.


Obviously we can do

return do given want {
  when :($) { ... }
  ...
};

But return do given want flows so badly, I desperately want some sugar 
for this.  Is there some and I missed it?


Trey



Re: named arguments: What's the signature?

2006-08-29 Thread Trey Harris

In a message dated Tue, 29 Aug 2006, Mark Stosberg writes:



Regarding The S06 description of named arguments:
http://feather.perl6.nl/syn/S06.html#Named_arguments

What I find missing here is documentation of the signature to use
if you want to declare I accept an arbitrary number of named
arguments. (Like the param() methods common in Perl5 do).

Maybe it's the slurpy hash?

sub foo (*%h) {...} ?

The spec could use some clarification on this point.


I think it's already there:

  Slurpy parameters follow any required or optional parameters. They are
  marked by a C* before the parameter:

  sub duplicate($n, *%flag, [EMAIL PROTECTED]) {...}

  Named arguments are bound to the slurpy hash (C*%flag
  in the above example). Such arguments are evaluated in scalar context.
  Any remaining variadic arguments at the end of the argument list
  are bound to the slurpy array (C[EMAIL PROTECTED] above) and are evaluated
  in list context.

Trey


Re: clarifying the spec for 'ref'

2006-08-25 Thread Trey Harris

In a message dated Fri, 25 Aug 2006, Mark J. Reed writes:

I think the justification for Luke's POV is the number of operations
each class provides.   But my perspective agrees with Juerd -
subclasses can remove functionality as well as adding it, and I
definitely view constant as an add-on modifier, not a default that
has to be overridden.


Can someone suggest some reading I can do to understand how that works?
I can't wrap my head around the idea of subclasses removing functionality. 
Does this mean you can't write


  class Super { method something { ... } }

  sub foo (Super $bar) { $bar.something() }

and expect foo($obj) to work, because $obj might be:

  class Sub is Super { # remove .something--how does that happen? }

  foo($obj); # Boom!?

So what happens?  Do you arrange somehow for polymorphism to be 
interrupted, so that the call to foo() acts as though there was a 
nonconformant type?  Does foo() get scanned somehow to notice that 
.something() is getting called, and $obj doesn't support .something, so 
that bubbles up such that foo() can't be called in the first place?  (If 
that's true, how do you do duck-typing, since duck-typing code almost by 
definition has branches that would call such invalid methods?)


I had been toying with writing some tests for the DBC blocks.  But the 
idea of removing functionality from a subclass completely blows away my 
understanding of DBC, so I'd particularly like some reading to help me 
understand how DBC works in a language that lets you remove functionality.


Trey


Re: clarifying the spec for 'ref'

2006-08-25 Thread Trey Harris

In a message dated Fri, 25 Aug 2006, jerry gay writes:

perhaps trey meant subclasses can add constraints as well as
functionality instead of subclasses can remove functionality as well
as adding it.

just a guess.
~jerry


Ok... same thing from a DBC perspective.  Subclasses can add functionality 
(by AND'ing postconditions), or remove constraints (by OR'ing 
preconditions), but they can't traditionally remove functionality or add 
constraints.  I just want to read about how that works.


Trey


Re: clarifying the spec for 'ref'

2006-08-25 Thread Trey Harris

In a message dated Fri, 25 Aug 2006, Mark J. Reed writes:


On 8/25/06, Trey Harris [EMAIL PROTECTED] wrote:

 subclasses can remove functionality as well as adding it



Can someone suggest some reading I can do to understand how that works?
I can't wrap my head around the idea of subclasses removing functionality.


Why not?  Is it any weirder than simply changing that functionality
beyond recognition?


If changing that functionality beyond recognition means changing its 
external behavior (as opposed to its internal behavior) so that it acts 
differently from what the superclass had promised to do, then no, it's not 
any weirder--but I can't figure out how the contract would work, either.


To extend the contract analogy, if I lease you a house, I may allow you 
to sublease the house, and I may even agree to take my rent directly from 
the sublessee rather than from you.  But the sublessee can't just say to 
me, yeah, so, I'm going to pay you 1000 yen, not 1000 dollars, and 
expect me to just put up with it or work around the missing money.  I made 
assumptions based on the original contract. If the sublessee says he wants 
to pay me more or more promptly or in cash under the table, great. If he 
wants to listen to opera in the evenings instead of of watching TV, that's 
internal behavior having nothing to do with our contract and I don't care.


The changes have to be either in my favor or irrelevant to the contract. 
Otherwise, I'm going to demand we renegotiate--in other words, that you 
don't pretend to be a superclass whose behavior you're not willing to 
emulate, so that when I see you I can treat you as what you are, not what 
you're pretending to be.


isa means is a.  It doesn't mean is roughly of a class analogous to.


You can always fake removing functionality even if the language
doesn't actually support it.  Consider:

class Super { method something {...} }

class Sub is Super { method something { throw new MissingMethodException; } }

or whatever that ends up looking like.

In Ruby and C++, a subclass can make a method private that is public
in its superclass, effectively removing it.  (Java disallows such
shenanigans).


But why would you want to, just because ConstArray isa Array, not the 
other way around just feels right? Pluto isa Planet feels right too, 
but one can't construct a reasonable definition that doesn't pull things 
in that you don't want to consider Planets.


Remember, one of the goals of Perl 6 is to make it more friendly to very 
large software projects.  Java disallows such shenanigans is one example 
of precisely why Java has become so popular for large projects.  (The 
exception-throwing example is clearly, well, an exception, and you can 
always do that.)


When software gets large, you need to be able to impose some constraints 
on behavior.  Maybe this is a stricture or something.  In any case, I'm 
not trying to make a ideological argument here.  I don't care if you can 
remove functionality or add constraints if that helps me get my job done 
(I'm just skeptical that it will).


I just want to think about the DBC features of Perl 6, and I don't know 
how they could work in the context of loosening contracts in subclasses, 
and I'd like somebody to point me to how, that's all.  Design-by-Contract 
is all about formal definitions.



Does this mean you can't [...] expect foo($obj) to work


Of course you can expect foo($obj) to work.  It might not, if the
subclass definition does something weird, but that's always the case
whether removing functionality is on the table or not, and it's no
reason to change your reasonable expectations. You can be paranoid
about it if you want, but it's not a very Perlish form of paranoia.
(Yes, there are Perlish forms of paranoia.  Taintedness checking, for
instance...)


When I said expect it to work, that was shorthand for it *will* work, 
in the absence of a bug.  That's what DBC is all about--that one can 
program based on the expectations of the contract, and you don't have to 
write error-catching code every single time you use an object's exported 
functionality.


I'll agree that DBC isn't very Perlish, in much the same way that strict 
was not very Perlish in Perl 5 (for at least the first five years of its 
existence, and probably even till today).  But in Perl 6 strict is the 
default, so by definition now Perlish. :-)


If DBC is in the language, then some people will use it, most people won't 
because they don't like the inconvenience, and over time if it actually 
results in more solid software, more people will choose to adopt it (like 
strict).


But in order to allow that choice, the language has to impose some 
groundrules for everyone.  strict couldn't exist in Perl 5 if lexicals 
could autovivify.  And--*by my understanding of DBC*--subclasses can't 
remove promised functionality or impose surprising constraints.  So a) 
Perl 6 can't support DBC, contrary to the Synopses, b) you can't remove 
functionality

Re: clarifying the spec for 'ref'

2006-08-25 Thread Trey Harris

In a message dated Fri, 25 Aug 2006, Mark J. Reed writes:


OK, I admit I wasn't thinking about things from a DBC perspective, and
misunderstood DBC to be a reference to some database module.  I here
am new and I didn't have context.  My bad.

But if we're talking design-by-contract, I don't see how Array is
Array::Const can work, either, since I consider the inability to
modify the elements of a constant array an explicit part of its
contract.


Well, usually you don't specify things an object *can't* do as part of its 
contract, unless those things would be judged harmful if allowed. (See 
below).


You might specify the contract of the ConstArray by saying that after any 
of the methods offered have been called, particular values will be 
unchanged--but that feature would maintain for non-constant subclasses. 
In other words, .elems could be specified at the constant superclass 
level, and its contract might say that .elems won't modify the elements, 
but that part of the .elems POST will maintain even in non-constant 
subclasses.  A rw accessor, on the other hand, would not even be specified 
in the constant superclass, so the ConstArray contract would have nothing 
to say about modification.



Therefore, if we're supporting DBC, I would say that Array and
Array::Const should not have an is-a relationship at all, but should
be sibling classes, inheriting from an abstract sequence-type parent
class whose definition makes no statements one way or the other about
modifications to elements.


Sure.  One *could* write a superclass, say AbstractArrayThing, that 
could not be instantiated and would have no mutating methods, and have its 
PRE and POST blocks written as I mentioned above.  The ConstArray would be 
a subclass that would simply add a constructor. You could specify its 
ongoing constedness explicitly by a class invariant block (not currently 
specified in Synopses, but such a thing often exists in DBC and could be 
constructed from a combo of ENTER and LEAVE at the class level) saying 
that the array will still be the same array before and after every method 
call.


I think that probably makes most sense and avoids the Array isa 
ConstArray cognitive dissonance.  But then people would have to get into 
the habit of writing AbstractArrayThing when they want to allow for 
constant arrays to be passed in.  That way lies the madness of Java where 
you're constantly writing factories to warp something so that it conforms 
to the API of this other thing merely because it happens to live in the 
wrong part of the class heirarchy.


I think Larry nailed it with his observation about the difference between 
class and role and trait.  'Constant' is a trait of another type, not a 
type into itself.


Trey


Re: clarifying the spec for 'ref'

2006-08-25 Thread Trey Harris

In a message dated Fri, 25 Aug 2006, Juerd writes:


Trey Harris skribis 2006-08-25 11:33 (-0700):

Ok... same thing from a DBC perspective.  Subclasses can add functionality
(by AND'ing postconditions), or remove constraints (by OR'ing
preconditions), but they can't traditionally remove functionality or add
constraints.  I just want to read about how that works.


The keyword is traditionally. We're used to a dynamic language that
bends the rules all the time, including runtime. Why would Perl stick to
academic limitations, while optimizing for the most common use is the
standard?

   my Array::Const @foo;
   @foo ~~ Array;  # False?! Please, no.

Though in practice I expect is ro to be used, not a subtype or subset.


Explain to me how nontraditional DBC might work in an internally 
consistent way. Otherwise, this is hand-waving.  :-)


Trey


Re: clarifying the spec for 'ref'

2006-08-25 Thread Trey Harris

In a message dated Fri, 25 Aug 2006, Daniel Hulme writes:


If changing that functionality beyond recognition means changing its
external behavior (as opposed to its internal behavior) so that it
acts  differently from what the superclass had promised to do, then
no, it's not  any weirder--but I can't figure out how the contract
would work, either.


That's because you're used to one way of thinking about class
inheritance: that the subclass can do everything that the superclass can
do, and more. In this scheme, you might have a Square class, with a
field representing its corner and another giving its side length. Then,
you could build on this to have Rectangle as a subclass, which adds an
extra side length, and extra accessors for it. This is a really bad way
of making your subclasses work, but your Rectangle has all the fields
and methods of your Square, and some extra ones.


Mmmm, no... depending on usage, I'd most probably have 
Shape-Polygon-Regular-Square, and Shape-Polygon-Rectangle, and write 
a FourSided role (perhaps a subrole of the Sided role, or maybe Sided can 
be parameterized so that Sided4 could work) to capture the code that can 
be shared between Squares and Rectangles.  I'm saying that subclasses 
*must* extend the promised capabilities of their parent classes, but that 
extending capability shouldn't be the only determinant of when you extend 
and when you make a sibling or a role or a trait.


But yes, if you didn't want to have any branching in your inheritance pole 
(not tree), you'd have to make Square the superclass of Rectangle.



Another way of looking at it is that the Rectangle is the more
generalised one, so it should be the superclass. It has a corner and two
side lengths, and associated accessors. Now, your Square is a subclass
of this. A Square in this scheme isa Rectangle, with the constraint that
the two side lengths are always equal. (Never mind the storage
considerations: that's internal.)


The problem comes up when code tries to do this:

  sub stretchWidth (Rectangle $r, Rat $ratio) {
  PRE { $ratio  0 }
  $r.w *= $ratio;
  POST { now($r.w) == before($r.w) * $ratio
   and
 now($r.h) == before($r.h)}
  }

The pre and postconditions make perfect sense in the context of a 
Rectangle--we need a positive stretch ratio, and only the width will be 
modified, not the height.  But then:


  for any(@shapes) ~~ Rectangle - $s {
  stretchWidth($s, 2);
  }

Again, looks perfectly reasonable--but one of @shapes was a Square, which 
is also a Rectangle.  Hit that one, POST fails, and boom!  Either .w is 
going to fail for being unmodifyable, or .w and .h are both bindings to 
.side, and so stretchWidth's postcondition will fail.



Most languages use the first scheme of class inheritance, but some offer
the second. Perl 6, AFAICS, has the first for subclasses, but offers the
second with subtypes and where clauses. I don't believe I've previously
used a language that offered both, so I'm interested to see how this
conjunction of features will turn out.


Yep.  I'm excited.

Trey


Re: clarifying the spec for 'ref'

2006-08-25 Thread Trey Harris

In a message dated Fri, 25 Aug 2006, Juerd writes:


Trey Harris skribis 2006-08-25 13:26 (-0700):

Explain to me how nontraditional DBC might work in an internally
consistent way. Otherwise, this is hand-waving.  :-)


Perl *is* hand-waving.


Yeah, but hand-waving on how it manages the behavior it exhibits.  The 
behavior itself should be defined and internally consistent.  To wit, you 
should be able to write a test.  I can't figure out what a test for 
a hypothetical nontraditional DBC would look like.


In any case, Larry's settled this issue.

Trey


Re: clarify: does Dog is Mammal load Mammal for you?

2006-08-22 Thread Trey Harris

In a message dated Mon, 21 Aug 2006, Jonathan Scott Duff writes:

But, assuming for the moment that Cis Mammal autoloads CMammal.pm,
does that mean that

   class Dog is Mammal-4.5

is valid?


Yes, it must be valid.  See 
http://dev.perl.org/perl6/doc/design/syn/S11.html#Versioning :


 So you can just say

 my Dog $spot .= new(woof);

 and it knows (even if you don't) that you mean

 my Dog-1.3.4-cpan:JRANDOM $spot .= new(woof);

For this not to extend to subclassing seems bizarre.


This seems like something we shouldn't encourage as it
tends toward tight coupling of implementations where it should be
tight coupling of abstractions.


Different sites have different needs.  Sites with strong regulatory or 
auditing requirements to not modify existing code without review (where 
the definition of modifying includes changing upstream dependencies) 
must be able to specify the longname of classes in this context.  Tight 
coupling should not be encouraged, but it must be allowed for these cases.


My question is, if a program is running where two versions of Dog are 
loaded, say 1.3.4 and 2.1, and a file contains:


  use Dog-1.3.4-cpan:JRANDOM;

  class Poodle is Dog {
 ...
  }

will the compiler know that 'Dog' in this file must always refer to 1.3.4, 
and not 2.1, as most other references to the shortname would?  If not, 
sites that need dependency stability will have to write


  use Dog-1.3.4-cpan:JRANDOM;

  class Poodle is Dog-1.3.4-cpan:JRANDOM {
 ...
  }

which I don't necessarily have any problem with, but this behavior needs 
to be defined.


Incidentally, isn't C(Any) in longnames supposed to be * now?  S11 still 
uses C(Any).


Trey


Re: clarify: does Dog is Mammal load Mammal for you?

2006-08-22 Thread Trey Harris

Oops, Luke Palmer alerted me to the fact that I screwed up in the below.

In a message dated Tue, 22 Aug 2006, Trey Harris writes:
My question is, if a program is running where two versions of Dog are loaded, 
say 1.3.4 and 2.1, and a file contains:


 use Dog-1.3.4-cpan:JRANDOM;

 class Poodle is Dog {
...
 }

will the compiler know that 'Dog' in this file must always refer to 1.3.4, 
and not 2.1, as most other references to the shortname would?  If not, sites 
that need dependency stability will have to write


I misstated my worry here.  In this case, by the same rule that my Dog 
$foo gets the right version because the longname is aliased to the 
shortname in the lexical scope of the use, it would work.


What I'm actually concerned about is the case where the Dog CPAN 
distribution includes Poodle.pm.  I think that we need Poodle.pm to be 
written like:


  use Dog-1.3.4-cpan:JRANDOM;
  class Poodle-1.3.4-cpan:JRANDOM is Dog { ... }

If it's written:
  use Dog;
  class Poodle-1.3.4-cpan:JRANDOM is Dog { ... }

then in a running Perl program that has previously loaded Dog-2.1-*, 
Poodle-1.3.4 will become a subclass of Dog-2.1, which causes any code 
using Poodle-1.3.4 to be unable to protect itself from an unforseen 
upstream dependency change.


Such wordiness seems unfortunate and error-prone.  I don't believe the 
specs yet have anything to say about how filesystem layout exists in the 
world of versioned packages, but it would be nice if a distribution's 
packages can use a shortname and automatically refer to other packages in 
the same distribution before the compiler looks elsewhere within %*INC (or 
its moral equivalent).


Trey


Re: Patch for S06 (and also S03)

2006-08-07 Thread Trey Harris

In a message dated Mon, 7 Aug 2006, Daniel Hulme writes:


Sorry to patch the patch, but in

-Other sigils binds only to the Ilast argument with that name:
+Other sigil binds only to the Ilast argument with that name:

the replacement makes no more sense than the original. Other sigils
bind or Any other sigil binds would work here.


My fault--I told agentzh++ fix 'other sigils binds' without specifying 
what it should be fixed to ('other sigils bind').


Trey


Re: S04 - forbidden coding-style

2006-07-21 Thread Trey Harris

In a message dated Fri, 21 Jul 2006, Ruud H.G. van Tol writes:


Larry Wall schreef:


Maybe we should just make statement modifiers
uppercase and burn out everyone's eye sockets. :)


Or maybe
  {
  }.
  while $x ;


Actually, can't that be made to work already (already by the language 
spec, not by the current compiler featureset) by


method Block::while ($block: Bool $true is deferred) {
   $block() while $true 
}


That would require parens around the boolean expression, though, but I'm 
sure you can fix that with a parsing constraint.


Trey


Re: Containers

2006-07-11 Thread Trey Harris

In a message dated Tue, 11 Jul 2006, Aaron Sherman writes:

But would it be reasonable to also provide a named-only parameter to
each for that purpose?

our List multi Container::each(Bool :$stop, Container [EMAIL PROTECTED])

So that:

for each(:stop, =; 1..*) - ($line, $lineno) {
  say $lineno: $line;
}

would only iterate until one of the containers was exhausted (in this
case, the filehandle).

Should this be added? Should zip have the same modifier?


It sounds reasonable to me, but :stop reads badly.  Maybe C:strictly? 
Maybe it's not a function of a flag to each, but a marking that certain 
lists should be tapped non-exhaustively:


  for each(=; :with(1..*)) - ($line, $lineno)

Where with is almost certainly the wrong word.  That way, you could 
write:


  for each(@queue1; @queue2; :with(1..*)) - $t1, $t2, $job_num {
  say Running job #$job_num;
  $proc1.run_task($t1); # Can deal with $t1 being undef
  $proc2.run_task($t2); # Ditto with $t2
  }

And you'll eat the rest of @queue1 or @queue2's elements even if they 
don't match up exactly.


This all makes me wonder if there's any problem with mixing and matching 
these loop modifying subs:


  for each(roundrobin(@queue1; @queue2); :with(1..*)) - $task, $job_num {
  say Running task {$task.id}(#$job_no);
  $task.run(:$job_num);
  }

I hope not.

Trey


Re: Containers

2006-07-11 Thread Trey Harris

In a message dated Tue, 11 Jul 2006, Aaron Sherman writes:

On Tue, 2006-07-11 at 09:53 -0700, Trey Harris wrote:

It sounds reasonable to me, but :stop reads badly.  Maybe C:strictly?
Maybe it's not a function of a flag to each, but a marking that certain
lists should be tapped non-exhaustively:


:stop wasn't a great choice, but :with is going to be complicated. I
don't THINK there's such a thing as a named slurpy, so:


   for each(=; :with(1..*)) - ($line, $lineno)


would have to be:

for each(=, :with(1..*))

with the signature:

(Container :@with, Container [EMAIL PROTECTED])

I think

But I don't think that will do, because it fails when you don't know
WHICH list would be the longest (or you have to specify them all
as :with, and that's rather counter-intuitive). Perhaps a stand-alone
adverb, :parity makes more sense.


I don't understand how the word parity is being used here...  It's not 
in the mathematical sense of even vs. odd, nor in the telecomm sense of 
bit-counting (since one would want to stop if one out of four iterators 
stopped generating, but also if two out of four did).  In the colloquial 
sense of parity meaning equality amongst peers, perhaps it makes more 
sense, but it's a rather overloaded an poorly-understood word, IMHO.



Unless there's an obvious problem with it, let's go with :parity for
now, and we can change it if its usage becomes confusing.


I think both are needed, somehow.  The default behavior of each should be 
as before (returning undef as necessary).  If the boolean switch (:stop, 
:parity, whatever) is set, then each should stop generating as soon as any 
argument stops generating.  I'm not denying that need.  But I'm saying 
that there is also a need for a mixed-case usage.


This is another one of those cases where you have to have at least three 
items to see a difference, at (0|1|2)-ary the semantic differences 
collapse.


One would like to be able to say all of stop once this iterator runs out 
(these adverb names are intentionally awful):


   for each(:stop_on_exhaustion(=), @line_id_cookies; 1..*)

Stop when anything besides this iterator runs out:

   for each(=; @lines_to_merge; :attach_as_needed(1..*))

Stop when any iterator runs out:

   for each(:stop, @subjects; @objects; @verbs) - $s, $o, $v


This all makes me wonder if there's any problem with mixing and matching
these loop modifying subs:

   for each(roundrobin(@queue1; @queue2); :with(1..*)) - $task, $job_num {
   say Running task {$task.id}(#$job_no);
   $task.run(:$job_num);
   }

I hope not.


This makes me re-think each a bit... it might have to return an
iterator:

our Iterator multi Container::each (Bool :$parity , Container [EMAIL PROTECTED] 
)

Given that, you could string eaches all you like, but otherwise it's not
terribly useful.


They need to chain and nest intelligently.

Trey


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

2006-04-30 Thread Trey Harris

In a message dated Sun, 30 Apr 2006, [EMAIL PROTECTED] writes:

The whitespace in the middle may include any of the comment forms above.
-Because comments always count as whitespace, the dots in
+Because comments always count as whitespace, the C\. in

-$object.#{ foo }.say
+$object\#{ foo }.say

reduce to a long dot rather than the range operator.  Valid ways to


The reference to the range operator doesn't make sense anymore.

Trey


Re: S05.pod

2006-04-17 Thread Trey Harris

In a message dated Mon, 17 Apr 2006, Sean Sieger writes:


from

There are no C/s or C/m modifiers (changes to the meta-characters
replace them - see below).

to

There are no C/s or C/m modifiers (change to the meta-characters
that replace them - see below).


I don't think so  There are no meta-characters that replace /s and /m 
one-for-one, so it can't be an imperative command to change.  It's the 
plural noun changes, as in, they are replaced with changes to the 
meta-characters.  The original is correct.


Trey


Re: Perl 6 OO and bless

2006-01-18 Thread Trey Harris
Excuse my ignorance of the finer points, but I thought the reason for 
bless's continued existence was so that the same sort of brilliant OO 
experimentation that Damian and others have done with pure Perl 5 can 
continue to be done in pure Perl 6 without having to hack p6opaque?


Trey


Re: [S29] pick on other things than junctions

2005-04-04 Thread Trey Harris
In a message dated Mon, 4 Apr 2005, Ingo Blechschmidt writes:
 What does pick return on hashes? Does it return a random value or a
 random pair? (I suppose returning a pair is more useful.)

I'd assume in all cases that pick returns an *alias*, and in the case of
hashes, an alias to the pair:

  # Add entropy to your hash
  for 1..$entropy_thresshold {
  %hash.pick.value *= rand $scribble_factor;
  }

Trey



Re: [S29] pick on other things than junctions

2005-04-04 Thread Trey Harris
I'd assume you'd get an *alias* to a random pair:

  # Test error-correction
  for 1..$entropy_threshhold {
 %hash.pick.value = rand $scribble_factor;
  }

Trey

In a message dated Mon, 4 Apr 2005, Ingo Blechschmidt writes:

 Hi,


 I remembered Damian saying that pick does not only work on junctions,
 but on arrays and hashes, too (and I even found his posting :):
 http://groups.google.com/groups?selm=420DB295.3000902%40conway.org).

 Are the following assumptions correct?
   my $junc = 1|2|3;
   print $junc.pick; # 1, 2, or 3
   print pick $junc; # same

   my @array = a b c;
   print @array.pick; # a, b, or c
   print pick @array; # same

 What does pick return on hashes? Does it return a random value or a
 random pair? (I suppose returning a pair is more useful.)


 --Ingo



-- 


Re: [S29] pick on other things than junctions

2005-04-04 Thread Trey Harris
In a message dated Mon, 4 Apr 2005, Ingo Blechschmidt writes:
 What does pick return on hashes? Does it return a random value or a
 random pair? (I suppose returning a pair is more useful.)

I'd assume in all cases that pick returns an *alias*, and in the case of
hashes, an alias to the pair:

  # Add entropy to your hash
  for 1..$entropy_thresshold {
  %hash.pick.value *= rand $scribble_factor;
  }

Trey


Re: [S29] pick on other things than junctions

2005-04-04 Thread Trey Harris
Yikes.  Sorry about the ressends... my email client kept dying and I
thought the mail was lost.  Guess not. :-)

Trey

In a message dated Mon, 4 Apr 2005, Trey Harris writes:

 In a message dated Mon, 4 Apr 2005, Ingo Blechschmidt writes:
  What does pick return on hashes? Does it return a random value or a
  random pair? (I suppose returning a pair is more useful.)

 I'd assume in all cases that pick returns an *alias*, and in the case of
 hashes, an alias to the pair:

   # Add entropy to your hash
   for 1..$entropy_thresshold {
   %hash.pick.value *= rand $scribble_factor;
   }

 Trey


-- 


placeholder attachment?

2004-04-19 Thread Trey Harris
Can anyone explain the rules of placeholder attachment?  i.e., in the
example in Perl6::Placeholder's manpage,

  grep { $data{$^value} } 1..10;

C$^value is clearly intended to attach to the outer closure C{
$data{$^value} }, not the inner closure C{$^value}.  But how does the
compiler know?  What is the general rule?

It's easy to just say don't nest placeholder-using closures, but that
doesn't seem workable in practice since every block is a closure, unless
placeholders are forbidden from all but the most trivial cases.  Absurdly
trivial, it seems.  How about

  $sub = { if $^a { $^b = $^a } };

?  Are there two C$^a's, one masking the other?  Or just one?  If two,
then the code should fail at runtime for attempted assignment to an
undefined lvalue (because $^b isn't set) or more likely at compile-time
for a missing required parameter.  If there's just one C$^a, wouldn't
C$^b get set to the topic of the Cif, i.e. C$^a (or is the topic of
an Cif's first closure always Ctrue?), leading to the expression being
equivalent to

  $sub = ( if $^a { $^a = $^a } };

?  Or will Perl DWIM and attach both $^a and $^b to the outer sub?  If so,
how did it know to do that, and not attach it to whatever sub contains the
assignment to $sub?

I'm probably just confused here, but I'd appreciate some straightening
out, as it's relevant to something I'm working on.  Apo 6 seems to be
silent on this (which perhaps indicates that I'm making this a lot harder
than it is).

Trey


Re: placeholder attachment?

2004-04-19 Thread Trey Harris
In a message dated Mon, 19 Apr 2004, Larry Wall writes:
 On Mon, Apr 19, 2004 at 04:48:05AM -0600, Luke Palmer wrote:
 : Trey Harris writes:
 :  Can anyone explain the rules of placeholder attachment?  i.e., in the
 :  example in Perl6::Placeholder's manpage,
 : 
 :grep { $data{$^value} } 1..10;
 [...]
 : In your first example, it does what you mean because the hash subscript
 : isn't a closure.  Curlies are always closures, except when they're not
 : (to be specific, in hash subscripts and hash constructors).

 Yes, that's the basic rule.  In Perl 5 the curlies are (potentially)
 blocks, though the optimizer throws away the block entry and exit
 when it thinks it can.  In Perl 6 we'll just say that those aren't
 blocks.  If you really want a block inside a subscript, you can always
 use do {}.  (But merely putting semicolons inside a subscript turns
 it into a multidimensional subscript, not a block.)

Okay, thanks for setting me straight there.

 :  It's easy to just say don't nest placeholder-using closures, but that
 :  doesn't seem workable in practice since every block is a closure, unless
 :  placeholders are forbidden from all but the most trivial cases.  Absurdly
 :  trivial, it seems.  How about
 : 
 :$sub = { if $^a { $^b = $^a } };
 :
 : I want this to work.  It could look at Cif's signature and see that
 : the closure it is expecting wants arguments, and since it doesn't, it
 : knows that they belong outside.  But that doesn't generalize.

 I don't think I want that to work.

Alright, you're the boss.  But it does make placeholders nearly useless,
does it not, by essentially limiting them to subs containing single
expressions?

 : I think a better solution would be to associate all placeholders with
 : the outermost closure that introduced a placeholder.  For example:
 :
 : $sub = { { $^a + $^b } };
 :
 : Would bind them both to the inner one, while:
 :
 : $sub = { $^a; { $^a + $^b } };
 :
 : Would bind them both to the outer one.

 This is the sort of twisty thinking that some people can keep straight
 and some people can't.  That's why we simplified the list of rules
 from the original placeholder RFC, after all.

What is the list of rules?  That's why I asked, and I'm still not clear
exactly what happens in the example I gave.  Saying that my example
shouldn't work only eliminates one of the possibilities, the one where it
works, while leaving all the ways it might not work open. It being
guaranteed to do what I don't mean is a step towards making what I mean be
something closer to what it does, but it would be helpful if I knew what
it does so that I can more finely adjust what I mean.  :-)

Trey


Re: backticks

2004-04-17 Thread Trey Harris
In a message dated Fri, 16 Apr 2004, Juerd writes:
 Except for the shocking number of closed-minded people on this list.

Stop it, stop it, STOP IT.

I'm not asking you to stop voicing your opinion about the discussion at
hand--that would be closed-minded, after all.

I'm asking you to stop interpreting disagreement as censorship, prejudice,
closed-mindedness, or whatever else.  It's not.

In any case, the argument in re 'what operator to access
keywordishly-keyed hashes' is spinning out of control and not getting
anywhere.  This is precisely why we leave it to Larry (and @Larry) to
exercise his benevolent dictatorship.

Open issues in regards to what to do with qx() (I'll post my thoughts on
that a bit later) and discussion thereof, or on a truly new syntax (other
than the ones proposed by Larry and Juerd or a return to Perl 5 ambiguity)
or some other brilliant unification in regards to hash keys would I think
still be welcomed here.

But the argument back and forth--which is prettier, which takes more
keystrokes, what's a keystroke, isn't it too much like
some-other-language-we-don't-like, no it's more like
yet-another-language-we-do-like, etc. ad nauseam is just petty bickering
at this point.

Can we all just take a deep breath here and let the issue be resolved as
time fulfills?  No progress is being made at this point.  Let it rest.

(No, Juerd, I'm not being closed-minded or censoring you.  This equally
applies to everyone who just wants to restate some new wrinkle of a point
already discussed to death.)

Trey
--
Trey Harris
Vice President
SAGE -- The System Administrators Guild (www.sage.org)
Opinions above are not necessarily those of SAGE.


Re: backticks

2004-04-15 Thread Trey Harris
In a message dated Wed, 14 Apr 2004, David Storrs writes:
 Actually, what I'd like to know is when it was decided that %hash{key}
 meant %hash{key()}??  Was it in one of the Apocalypses?

Perhaps it wasn't spelled out, but the implication was certainly there.
Barewords are gone.  Braces create a closure.  A closure consisting only
of pairs returns a hash reference.  A closure immediately following a hash
or hashref dereferences the hash.  By inference, {key} is a closure
consisting of Ckey, which can't be a bareword since barewords are gone.
Hence it must be a sub call to key().

Trey
-- 
Trey Harris
Vice President
SAGE -- The System Administrators Guild (www.sage.org)
Opinions above are not necessarily those of SAGE.


E6: assume nothing

2003-07-31 Thread Trey Harris
To take the E6 example of currying part:

   List::Part::part.assuming(labels = sheep goats)

One had to curry in Clabels to be the same as it was defined in Cpart
originally, i.e. C sheep goats .

What if one wanted to curry in whatever the default is, i.e., assuming
nothing (different from assuming nothing), so that if List::Part::part
changed its default for Clabels to C oves caperes , the client
code would pick that up?

-- 
Trey Harris
Vice President
SAGE -- The System Administrators Guild (www.sage.org)
Opinions above are not necessarily those of SAGE.


Re: E6: assume nothing

2003-07-31 Thread Trey Harris
In a message dated Thu, 31 Jul 2003, Austin Hastings writes:
 assuming(labels = undef)

Okay... I think you're wrong, because this would have to be a special case
(defaults take effect only when *nothing* is passed in, not when the
argument is undefined) but, assuming you're right... if I want to pass
undef to labels, what would I write?

-- 
Trey Harris
Vice President
SAGE -- The System Administrators Guild (www.sage.org)
Opinions above are not necessarily those of SAGE.


Re: L2R/R2L syntax (was Re: Everything is an object.)

2003-01-09 Thread Trey Harris
In a message dated Thu, 9 Jan 2003, Damian Conway writes:
 One *might* argue that ~ ought to be of higher precedence than ~
 (i.e. that invocants ought to be bound ahead of other arguments).

 If so, then:

$foo ~ print ~ $*STDERR

 is really:

$foo ~ print $*STDERR:

 is really:

$foo ~ print $*STDERR: $foo

 So yes.

 But don't do that!

Well, shades of C++, how about just

  $*STDERR ~ $foo;

or

  $foo ~ $*STDERR;

?  Stylistically, I often find myself needing to embed a complex
expression in a print(), and as anyone who's read my articles knows, I
really despise parens in normal sub calls (not method calls).  Yes, yes, I
could do $*STDERR.print() instead, but I'm trying to reduce visual
clutter, not resort to a mechanism that requires it :-)

Trey
-- 
I'm looking for work.  If you need a SAGE Level IV with 10 years Perl,
tool development, training, and architecture experience, please email me
at [EMAIL PROTECTED]  I'm willing to relocate for the right opportunity.




Re: right-to-left pipelines

2002-12-09 Thread Trey Harris
In a message dated Mon, 9 Dec 2002, Stéphane Payrard writes:



 [snipped]

  so it's easy to build up more complex right-to-left pipelines, like:
 
  (@foo, @bar) :=
  part [/foo/, /bar/],
  sort { $^b = $^a }
  grep { $_  0 }
  @data;
 
 

 I would like perl6 to support left-to-right part/sort/grep pipelines.
 Left to right syntax is generally good because it facilitates the flow
 of reading.

It is good for a rather deeper reason than just facilitating the flow of
reading.  Psycholinguistic experiments show that the human brain can't
absorb the meaning of such language structures when an unbound referent
has not been filled.  Consider the difference in comprehensibility of

  I gave my friend who I saw last July in the park near the summer
  cottage one afternoon when it was rainy but fairly warm my standard
  talk on linguistic complexity.

vs.

  I gave my standard talk on linguistic complexity to my friend who I saw
  last July in the park near the summer cottage one afternoon when it was
  rainy but fairly warm.

Pipelines in general--get everything done HERE, then hand it off to
something THERE, and then somewhere ELSE--are much easier for the mind to
comprehend than nested structures where the referent on which the whole
structure depends is found at the beginning or the end.

I can say

  The dog bit the cat who chased the rat who stole the cheese which
  spoiled in the barn which was built by the farmer who married the
  teacher who

more or less indefinitely.  We should definitely have the ability to
pipeline as effectively in Perl, and that means left-to-right.

Trey
-- 
I'm looking for work.  If you need a SAGE Level IV with 10 years Perl,
tool development, training, and architecture experience, please email me
at [EMAIL PROTECTED]  I'm willing to relocate for the right opportunity.




Re: right-to-left pipelines

2002-12-09 Thread Trey Harris
In a message dated Mon, 9 Dec 2002, Adam D. Lopresto writes:

 Looks to me like with a few appropriate methods, you have left-to-right
 ordering for free.

 (@foo, @bar) := @a
 . grep { $_  0}
 . sort { $^b = $^b }
 . part [/foo/, /bar/];

Yes, exactly.

 Of course, that means that grep and sort and part are all methods of the Array
 class, so the standard way to write them would be

 grep @a: {$_  0};

 instead of

 grep {$_  0} @a;

 H.  Odd.  I'm guessing it wouldn't be possible to extend the indirect
 object syntax to allow

 grep {$_  0} @a:;

Eh, here you give a nod to backwards compatibility (not to mention to
removing extraneous symbols), I think, and define universal multimethods
taking a block and an array or an array of blocks and an array (or an
array of rules and an array, etc.).

That way, all the following would work:

  (@foo, @bar) := @a.grep{foo}.sort{byBar}.part[/foo/, /bar/];
# do you need parens around the parameters?
  (@foo, @bar) := part [ /foo/, /bar/ ]
sort byBar
  grep {foo} @a;
  (@foo, @bar) := part :(
sort :(
  grep :@a {foo})
byBar)
  [/foo/, /bar/];

That last is atrocious--but the fact that it is available doesn't mean
that it should be encouraged.

 (object can go anywhere in argument list, so long as it's marked with a
 :.  But now I'm trying to speculate about Larry's colon, something best
 left to others).

That would allow

  (@foo, @bar) := part [ /foo/, /bar/ ] :(
sort byBar :(
  grep {foo} :@a));

as well as

  (@foo, @bar) := part [ /foo/, /bar/ ] :(
sort :(
  grep :@a {foo})
byBar);

or

  (@foo, @bar) := part :(
sort {foo} :(
  grep {foo} :@a))
  [ /foo/, /bar/ ];

This is really awful, IMHO.  I say just define the multimethod letting you
rearrange the arguments back to the old style and get on with it.
Extending colon to allow it to move willy-nilly through the argument list
may be useful in simple cases, but if nested will be incomprehensible.

This is exactly the same as natural languages, by the way--we can deal
with one or two levels of interior clause nesting, but beyond that we lose
track of what clause is playing what role.  The question becomes, is
moving the indirect object around useful enough in the small
comprehensible cases that we're willing to accept the ability to write the
large incomprehensible ones?

 But somehow it seems like an increase in readability, especially if things were
 renamed.  Imagine renaming grep to where or suchthat.  And then the
 antigrep can be except.

As synonyms, or total renamings for the array-method form?  I neither like
populating the language with superfluous names, nor do I like having to
remember Cgrep is Csuchthat when used as an array method, which
you'll have to do if you try to transform the functional style to the
method-pipeline style.

Trey
-- 
I'm looking for work.  If you need a SAGE Level IV with 10 years Perl,
tool development, training, and architecture experience, please email me
at [EMAIL PROTECTED]  I'm willing to relocate for the right opportunity.




fonts (was Re: perl6 operator precedence table)

2002-11-14 Thread Trey Harris
Sorry for the one-month-old response, but this message fell between the
cracks and I was just reviewing all my old new mail

In a message dated Sun, 20 Oct 2002, Me writes:

  Somebody fairly recently recommended some decent fixed-width
 typefaces.
  I think it may have been MJD, but I can't find the reference right now
  (could be at work).

 Michael Schwern recently suggested Monaco,
 Neep or, if you can find them, Mishawaka or ProFont.

 I investigated and found this link to be useful:

 http://www.tobias-jung.de/seekingprofont/

I really like the font I have on my iMac called QuickType.
Unfortunately, I can't figure out where it comes from, as none of my font
files have a name resembling anything like that.  I need to find a utility
that will identify what file a given font comes from.

Trey




Literate programming (was Re: perl6 operator precedence table)

2002-10-24 Thread Trey Harris
Larry,

As long as you're trying to figure out how to shoehorn in the last few
available punctuation symbols, and thinking about if there are any
bracketers left, I wondered if there was a chance of a chunking operator
for literate programming?  So you can do something like this, if 
were the operator:

  =doc code

  We loop through the array, operating on each item:

  =cut

  for list - $item is rw { # is 'is rw' assumed with for? I forget...
operation
  }

  =doc code

  The operation performed is incrementing each item by one:

  =chunk operation

  $item++;

  =cut

Trey




Re: Indeterminate math

2002-10-15 Thread Trey Harris

In a message dated Tue, 15 Oct 2002, Angel Faus writes:


  Mathematically, 1/0 is not +Infinity.  It's undefined/indeterminate
  in the set of rational numbers.  The IEEE may say otherwise.

 Mathematically, 1/0 is whatever you define it to be.

Well, sure.  That's as axiomatic as saying, mathematically, the number
one is whatever you define it to be.  But a mathematical system that has
a definition which is inconsistent with the rest of the system is a flawed
one.  If you let 1/0 be *anything*, then ordinary algebraic logic falls
apart.  Those silly proofs where it is proven that 1 = 2, 1 + 1 = 1,
etc., all depend on division by zero being possible (regardless of what
its value is).  You have to keep division by zero illegal to avoid these
absurd results.  Hence, to my mind at least, exception-throwing or NaN is
a better solution than infinity.

But will it really matter one way or the other?  Probably not, so we
should stop quibbling.  Perhaps if someone could demonstrate a real-world
need for either NaN or infinity in this case, or else a case for why
exception-throwing should *not* go away, we'd be able to bring the
discussion somewhere more fruitful.

For my part: division by zero is so often a programmer error, and so
rarely a useful thing to do, that it seems to me that exception-throwing
should remain the behavior in Perl 6.

Trey




Re: Indeterminate math

2002-10-15 Thread Trey Harris

In a message dated Tue, 15 Oct 2002, Jonathan Scott Duff writes:
 People have used the terms error and exception interchangably in
 this disucssion.  To me, an error is something that stops program
 execution while an exception may or may not stop execution depending
 on what the user decides to do about exceptions.

I'm not familiar with that dichotomy.  In the OO languages I'm familiar
with, errors fall into two basic classes, compile time and run time.
Compile time errors are 'fatal', in the sense that they will prevent the
program from ever beginning execution.  Runtime errors throw exceptions,
which may be caught, and if not caught at the top level of execution, will
cause the program to abort (or do whatever else it is supposed to do by
default when an error propagates that far).  Java (and at least one of the
Eiffel runtimes I've used) makes a further division in the runtime
category between exceptions, which must be handled or declared, and
errors, which are conditions like out of memory which are so baroque
or whose potential for ocurring is so pervasive as to make required
handling a ridiculous burden on the programmer.

But you still *may* attempt to handle these errors, if you wish--they are
still exceptions.  For instance, running on a system in which programs can
give previously allocated memory back to the operating system, a program
might attempt to use a fast but memory-intensive algorithm, but, upon
catching the OutOfMemoryError exception, return the memory to the OS and
fall back to a slower but less greedy algorithm.

Perl obscures things a bit by its free movement between compile- and
runtimes, in some sense collapsing the two types of errors into one, or
rather making it possible for either to manifest in the guise of the
other.  For example, a string eval could cause the ordinarily compile-time
syntax error, which would generate a runtime exception, or a BEGIN block
might try to perform a division by zero, in which case the ordinarily
runtime DivByZero exception would be thrown at compile time (and probably
cause the program to never begin execution in the sense we ordinarily
think about it).  So the compile-time vs. runtime error distinction goes
away, so far as the programmer is concerned.

Since I assume that Perl will not require that subroutines declare the
exceptions they might throw (but I guess we'll find out in the next Apo!),
the dichotomy Java sets up goes away, too.  So, I think it is completely
reasonable to use error and exception as interchangeable terms.  If
there is a difference, it may be merely in point of view.  Errors
happen, while exceptions are thrown and caught.

 1/0 could throw an exception, yet continue execution.  Somewhere I
 expect we should be able to define a policy for what to do in these
 situations.

   use Policy DivideByZero = Nan;
   use Policy DivideByZero = Inf;
   use Policy DivideByZero = DivideByZeroException;

 I'm sure someone else can pick a better syntax than I.

I think miko just suggested one, though I'm still digesting it.

Trey




Re: Indeterminate math

2002-10-15 Thread Trey Harris

In a message dated Tue, 15 Oct 2002, Michael G Schwern writes:

 On Tue, Oct 15, 2002 at 01:44:50PM -0500, Jonathan Scott Duff wrote:
  People have used the terms error and exception interchangably in
  this disucssion.  To me, an error is something that stops program
  execution while an exception may or may not stop execution depending
  on what the user decides to do about exceptions.

 Unless I've missed my mark, Perl errors have always been trappable [1].  Does
 that make them exceptions?  We've been calling them errors for years now.

The Perl trainers I've seen have been calling Perl errors exceptions for
years now, mostly, I think, to shut up the Javaphiles who think that
they're the only ones that have such a wondrous and unprecedented thing
(at least, that's why I always did it ;-)

 Put another way, is there a significant difference between:

 eval {
   $foo = 1/0;
   print Bar;
 }
 if( $ =~ /^Illegal division by zero/ ) {
   ... oops ...
 }

 and

 try {
 $foo = 1/0;
   print Bar;
 }
 catch {
 when /^Illegal division by zero/ {
   ... oops ...
   }
 }

None that I can see.

Trey




Re: Draft Proposal: Declaring Classwide Attributes

2002-10-14 Thread Trey Harris

In a message dated Mon, 14 Oct 2002, Michael Lazzaro writes:
 So if the first two should be shorter than the third, one way to do
 that would be something like:

   class SomeClass {
   cmethod class_method {...}   # via a keyword
   method  instance_method  {...}   # via another keyword
   sub dont_care_method {...}   # check it yourself, as 1st arg
   }

 Except for the fact that the word 'cmethod' is not a terribly intuitive
 choice.

I don't know about this precisely, but I will say that I have a strong
intuition that Csub within a class block Ishould mean something, and
be neither a syntax error nor a synonym for Cmethod.

Trey




Re: Draft Proposal: Declaring Classwide Attributes

2002-10-13 Thread Trey Harris

In a message dated Sun, 13 Oct 2002, Piers Cawley writes:
 I like that idea:

class SomeClass {
  method class_method ( Class $class: ... ) { ... }
  method instance_method  ( SomeClass $self : ... ) { ... }
  method dont_care_method (   $self : ... ) { ... }
}

I was going to say the same thing, but then I remembered that Perl 6
methods, unlike the sub 'methods' in Perl 5, won't get the invocant as the
first real argument--it will be the topic instead.  And I don't think you
can do multiple-dispatch on topic, can you?

Trey




Re: Private contracts?

2002-10-12 Thread Trey Harris

In a message dated Fri, 11 Oct 2002, Larry Wall writes:
 A public inner class:

 our class Node {...}

 That last one actually declares a subclass of the current class, just as

 our $foo;

 puts $foo into the current package.

When you say subclass, do you mean below the current class in the
naming heirarchy, i.e.

  class BTree;
  our class Node {...}

would create BTree::Node?  Or do you really mean *subclass*, i.e., our
class causes Node to inherit from BTree?  I hope it's the former, but the
word subclass does usually imply inheritance

Trey




Re: Fw: perl6 operator precedence table

2002-10-09 Thread Trey Harris

In a message dated Wed, 9 Oct 2002, Larry Wall writes:
 If only we had Unicode editors, we could just force everyone to use
 the infinity symbol where they mean it.  It seems a shame to make a
 special case of the .. operator.  Maybe we should ... to mean and so
 on forever:

 a[0...; 0...:10; 0...:100]

 Except then we couldn't use it to mean what Ruby means by it, which
 might be handier in real life.  (It means to exclude the endpoint,
 so 0...4 is the same as 0..3.  But then, that's kind of odd too.)

Oh, but then (0...) would mean all numbers from zero to infinity,
excluding infinity which would have the same effect in the real world,
wouldn't it? :-)

Trey




Re: Interfaces

2002-10-08 Thread Trey Harris

In a message dated Tue, 8 Oct 2002, Michael G Schwern writes:

 On Sun, Oct 06, 2002 at 06:17:37PM -0400, Daniel B. Boorstein wrote:
  I think there may be some confusion here. In java, there's no special syntax
  to declare a method an optional part of the interface. All concrete classes
  that implement the Collection interface still must define full-bodied
  Cadd(Object element) methods. It just so happens that by convention some
  classes simply throw an UnsupportedOperationException, perhaps like so:

 A!  No wonder I couldn't find any syntax for it!  Thanks for clearing
 that up.

 Still, the objections still hold, though now it's a stylistic objection
 rather than syntactic.  It's disturbing that they'd put these optional
 methods into the core Java API, thereby encouraging their use (Sun did it,
 so I can to!).  Cannonizing the idea weakens the whole concept of an
 interface and contract.

 It really ought to be one of those sure you can do this, but please don't
 things.

It's a RuntimeException.  You can't require that all RuntimeExceptions be
declared if thrown; otherwise, every method would have to declare throws
OutOfMemoryException, CannotLoadClassException,
TheEndTimeIsUponUsException, ...  for every single runtime error.  You
can subclass RuntimeException.  So if Sun hadn't provided an
UnsupportedOperationException, anyone else could easily have done so.

And they'll be able to in Perl, too, whatever you do.  I often code

method foo {
  die Abstract method foo not implemented in concrete class .
 (ref $_[0] || $_[0]) . , died;
}

In my abstract superclasses, which is the very same thing.

Trey




Re: RFC: [] as the solitary list constructor

2002-10-06 Thread Trey Harris

In a message dated Sun, 6 Oct 2002, Noah White writes:


 On Sunday, October 6, 2002, at 01:50  AM, Brent Dax wrote:

  Parens don't construct lists EVER!  They only group elements
  syntactically.  One common use of parens is to surround a
  comma-separated list, but the *commas* are creating the list, *not* the
  parens!
 

 Following this rule would mean that

   $a = ();# $a is a list reference with 0 elements

 should not be a list reference at all and would appear inconsistent.

No, because there are zero commas.  Squint and you can see them. :-)

Trey




Re: Private contracts?

2002-10-05 Thread Trey Harris

In a message dated Sat, 5 Oct 2002, Allison Randal writes:
 More useful: keep a site-wide or company-wide file of version aliases to
 make sure everyone uses the same version, and to make upgrades to the
 next version as simple as editing a single file.

Ah, but the usual case is this:

You download from CPAN class A that depends on version 1.0 of class N.
You then download class B that also depends on version 1.0 of class N.
You create an application that uses both classes A and B (and thus N
through the dependencies.) Some time later, you discover a bug that
requires you to upgrade class B, but the upgrade now depends on class 1.1
of class N.  Class A hasn't been upgraded yet, and turns out not to work
well with version 1.1 of N.  So you need both versions 1.1 and 1.0 of
class N running in the application--preferably without having to modify
any of your app, class A, or class B.

This could be made to work (assuming that classes A and B both specify
which version of N they need).

Trey




Re: Private contracts?

2002-10-04 Thread Trey Harris

In a message dated Fri, 4 Oct 2002, [EMAIL PROTECTED] writes:

 On Fri, Oct 04, 2002 at 09:13:45AM -0400, Chris Dutton wrote:
   How exactly does one weaken a precondition?
 
  At least in Eiffel, if you redefine a method, you may not give it
  stringer preconditions than the original method, but you may have
  stronger postconditions.  In essence, you're not requiring any more of
  the client, but you can ensure more to them on completion, thus
  maintaining the parent's contract.

 But what does it mean to be stronger?  How does Eiffel figure out if
 a given precondition is stronger or weaker than another?

Like I said before, boolean logic.  Preconditions are OR'd together
(starting with the deepest subclass and working back to the most ancestral
class, in order to short-circuit most effectively), postconditions are
AND'd together (in the opposite order, same reason).

You responded that it couldn't work that way in Perl because Perl has
expressions that are more complicated than booleans.  I asked you what you
meant by that, since the only definition of passing a condition I'm
aware of in Perl is a boolean expression returning true.  You haven't
responded to that one yet. :-)

Trey




Re: Private contracts?

2002-10-04 Thread Trey Harris

In a message dated Fri, 4 Oct 2002, [EMAIL PROTECTED] writes:

 On Fri, Oct 04, 2002 at 06:26:31PM -0400, Trey Harris wrote:
   But what does it mean to be stronger?  How does Eiffel figure out if
   a given precondition is stronger or weaker than another?
 
  Like I said before, boolean logic.  Preconditions are OR'd together
  (starting with the deepest subclass and working back to the most ancestral
  class, in order to short-circuit most effectively), postconditions are
  AND'd together (in the opposite order, same reason).

 I can see too many problems with that technique, I think one was
 already mentioned where subclasses can unintentionally weaken
 preconditions to the point of eliminating them.  I'm sort of casting
 about looking for another way.

Could you illustrate a case?  I don't know what you're talking about.
It's completely valid to eliminate a precondition, because true is the
weakest possible precondition.

By definition, an assertion P is weaker than another assertion Q iff Q
implies P.  Requiring a computer to determine if some condition A,
expressed in arbitrary computer code, is weaker than some condition B,
also expressed in arbitrary computer code, is unsolvable in the general
case and equivalent to the halting problem.

So, you either abandon the general case and incorporate a theorem prover
into the compiler (!) or you make use of the following theorem:  (P or Q)
is weaker than Q, because Q implies (P or Q).

Trey







Re: Private contracts?

2002-10-03 Thread Trey Harris

In a message dated Thu, 3 Oct 2002, Michael G Schwern writes:

 On Thu, Oct 03, 2002 at 03:59:08PM -0400, Mike Lambert wrote:
  With pre/post conditions, a subclass is allowed to weaken the
  preconditions or strengthen the postconditions.

 How exactly does one weaken a precondition?

You weaken a precondition by adding ORs; you strengthen a postcondition by
adding ANDs.

Trey




Re: Private contracts?

2002-10-03 Thread Trey Harris

In a message dated Thu, 3 Oct 2002, Allison Randal writes:
 So far, classes are uppercase and properties are lowercase, but that's
 convention, not law.

Do runtime (value) properties and compile-time (variable) properties share
the same namespace?

That is, to go back to an earlier discussion, if there is a system-defined
value property Ctrue which marks a value as true in boolean contexts,
can I also define a compile-time property Ctrue that makes the variable
evaluate as true, whatever its value?

Trey




Re: Private contracts?

2002-10-03 Thread Trey Harris

In a message dated Thu, 3 Oct 2002, John Williams writes:

 On Thu, 3 Oct 2002, Trey Harris wrote:

  Incidentally, has there been any headway made on how you DO access
  multiple classes with the same name, since Larry has (indirectly) promised
  us that?  I.e., I import two classes LinkedList and BTree, both of
  which define a Node class?

 Hopefully, LinkedList defines a LinkedList::Node class, and BTree defines
 a BTree::Node class.  Either by explicitly naming them that or by virtue
 of being defined as an inner class (which might also make it private).

Ah, but that's the way you do it now--name the classes differently.
(Easy--assuming you control the source code!)  In Perl 6, we're supposed
to be able to use multiple versions of the same class concurrently, which
I think would imply also being able to use multiple classes that happened
to be named the same thing.

Trey




Re: Delegation syntax?

2002-10-03 Thread Trey Harris

In a message dated Thu, 3 Oct 2002, Michael Lazzaro writes:

 On Thursday, October 3, 2002, at 04:25  PM, Michael G Schwern wrote:
  Class::Delegation?

 Yeah, it's one of the best I've seen: it makes sense, does everything I
 want, and is easy to explain even to newbies.  The perl5 hash-based
 syntax is still pretty scary, tho.

 Dunno, I keep wishing for something that's a one-liner for simple
 cases.  I guess something like:

   # $.data_manager receives all method calls for which
   # it has a matching public interface.

   class DataSnippet {
   attr $data_manager is DataManager receives ( -ALL );
   }

Looks like a simple Perl 6 grammar munge to me--it's a simple postfix
conditional which takes the declaration before it, gets its type (or looks
at the code, TMTOWTDI) and creates accessors in the namspace of the
caller.  Doesn't appear particularly magical to me.  In fact, if you
didn't mind writing it

  attr data_manager = DataManager, receives = -ALL;

you could easily write it in Perl 5 today.


   # alternative syntax, also useful on a method-by-method basis...
   # Note that if steer() has an implementation, it's dispatched there
 too.

   class Car is interface {
   attr $left_front_wheel;
   attr $right_front_wheel;
   ...

   method steer ( ... ) is dispatched( $left_front_wheel,
 $right_front_wheel ) { ... };
   }

This is doable now too:

  dispatch steer = $left_front_wheel, $right_front_wheel;

Could be written in Perl 5, simply enough, as

  sub dispatch {
 no strict 'refs';
 my ($method, dispatchees) = _;
 *{caller().::$_[0]} =
   sub {
 $_-$method(_) foreach dispatchees;
   };
  }

I think my point here is that there are clearly places where we need
stronger built-in support in Perl of some OO concepts.  Delegation may not
be one of them--it's easy enough to graft on, and TMTOWTDI may be good
here.

 Incidentally, I think the Car above is an example of why it might be ok
 to allow attributes in interfaces.  (I would definitely argue it's ok
 to give default method implementations in interfaces.  You don't have
 to if you don't believe in it, but hey, some people prefer it.)  You're
 basically saying that the interface attaches these named attribs to
 anything that use it.  It usually isn't considered proper, but I don't
 know if it's evil enough to explicitly disallow.

 The biggest problem I see with interface attribs myself is
 implementational, not philosophical; if you've got attribs being
 assembled from multiple interfaces, it makes implementation of
 subclasses even more difficult to optimize.  (Of course, we already
 have multiple inheritance, so that ship's probably long sailed already.)

I don't understand.  A public attribute will have an autocreated accessor.
So put the accessor in the interface, not the attribute.  If you put the
attribute in the interface, you've committed to having it as an attribute.
If you decide to turn it into a computed method, you're out of
luck--unless you make the attribute a tied variable itself (gak!).

Trey




RE: Private contracts?

2002-10-03 Thread Trey Harris

In a message dated Thu, 3 Oct 2002, Garrett Goebel writes:

 Michael G Schwern:
  On Thu, Oct 03, 2002 at 05:30:49PM -0400, Trey Harris wrote:
   In a message dated Thu, 3 Oct 2002, Michael G Schwern writes:
  
On Thu, Oct 03, 2002 at 03:59:08PM -0400, Mike Lambert wrote:
 With pre/post conditions, a subclass is allowed to weaken the
 preconditions or strengthen the postconditions.
   
How exactly does one weaken a precondition?
  
   You weaken a precondition by adding ORs; you strengthen a
  postcondition by adding ANDs.
 
  As expressions in Perl run a tad beyond simple boolean logic,
  could you give a concrete example?

I don't know what you mean.  How can a precondition be anything but
boolean?

 all inherited pre-conditions pass
   or
 class' own pre-conditions pass

I'm afraid I'm a bit lost here.  What does pass mean besides evaluates
to true in a boolean context?  And if that's what pass means, then
can't you just OR the preconditions together, in subclass-to-superclass
order?

Trey




Re: Regex query

2002-09-24 Thread Trey Harris

In a message dated Tue, 24 Sep 2002, Chip Salzenberg writes:

 According to Trey Harris:
  According to Larry,
$a = (1,2,3);
  is equivalent to
$a = [1,2,3];
  because they're both equivalent to
$a = scalar(1,2,3)

 But that's the bit we're arguing about.  If you allow

$a = (1,2)

 then what about

$a = (1)

 ?  And if someone says that I have to write:

$a = (1,)

 then I am going on the warpath.  That Way Lay Python.

*shrug* Regardless of whether we like it, what Larry said is true unless
and until he invokes Rule 2.  And unless he invokes Rule 2,
Cscalar(1,2,3) is equivalent to C[1,2,3].

My suggestion is merely that one-tuples lacking the comma cannot be
constructed with parens (round brackets) and that list-flattening context
has the effect of voiding top-level round parens (but not square
brackets).

So

  $a = (7);

would assign 7 to $a, and

  push a, (7,3,2);

would push the elements 7, 3 and 2 to the end of a, but

  push a, [7,3,2];

would push a single element containing the arrayref [7,3,2] onto the end
of a.

I agree it's weird, but it seems to DWIM, doesn't it?  I just don't think
a reduction that C() is equivalent to C[] is workable.

If you want to assign $a the value [1], then you write

  $a = [7];

I would think that

  $a = (7,);

would be legal as well, but only in order to handle the DWIM of

  $a = (1,
2,
3,
   );

where you kill the middle two lines--not as the preferred (and certainly
not as the only) way to create a one-tuple.  Making

  $a = (7);

create a single-element list is just unworkable.  It requires that
programmers get precedence exactly right, and it badly violates the
principle of least surprise.

Trey




Re: Regex query

2002-09-24 Thread Trey Harris

In a message dated 24 Sep 2002, Aaron Sherman writes:
 That doesn't really work. Because now you introduce the case where:

   $x = (1,2,3);
   y = (1,2,3);
   $z = [1,2,3];
   push a, $x, y, $z, (1,2,3), [1,2,3];

 Behaves in ways that will take hours to explain to newbies, and I assure
 you it ain't WIM. Not even a little bit.

Hmm.  What *I* would mean, anyway, would be that a gets pushed nine
elements: ([1,2,3], 1, 2, 3, [1,2,3], 1, 2, 3, [1,2,3]).  And that works
under my proposal.  But I may have an idiosyncratic idea of WIM. :-)

But I think Dan's right.  I think we should just let this drop for now,
let Larry take a look at the mess we've gotten ourselves into, and let him
decide whether he needs to Rule-2 something or not.

Trey




Re: Regex query

2002-09-24 Thread Trey Harris

In a message dated Tue, 24 Sep 2002, Jonathan Scott Duff writes:

 On Tue, Sep 24, 2002 at 11:14:04AM -0400, Aaron Sherman wrote:
  Again, we're wading into the waters of over-simplification. Let's try:
 
  sub foo1(){ my foo=(1,2,3); return foo; }
  sub foo2(){ my $foo = [1,2,3]; return $foo; }
  sub foo3(*@list) { print list.length, \n; }
  foo = (1,2,3);
  foo3(foo, [1,2,3], foo2(), foo1());
 
  Ok, so what is the output? 12? 10? 8?
 
  More importantly, why? I could argue the case for each of the above
  numbers, but I think 12 is the way it would be right now.

 Hrm.  I think it must be 8.  Since foo3() flattens it's parameters, we
 get this:

   foo3(1, 2, 3, [1,2,3], [1,2,3], 1, 2, 3);

 and since the two [1,2,3] are scalar things, we have 8 scalar things
 in our list.  Splat doesn't look inside the thing it flattens AFAIK,
 so it doesn't flatten the two [1,2,3].

Yes, but would the lack of parens in

  foo3 foo, [1,2,3], foo2, foo1;

change anything? (I think and hope not.)

Trey




Re: Paren madness (was Re: Regex query)

2002-09-24 Thread Trey Harris

In a message dated Tue, 24 Sep 2002, Mike Lambert writes:
 Consider:
 $a = (1);
 and
 ($a) = (1);

Yes?  They both do the same thing--set $a to 1.  It looks like the bottom
one is a list assigned to a list, but that might be optimized out, as it
doesn't matter.

  5.  Assignment to arrays and lists.
 
$a = (1, 2, 3); # Same as Perl 5's $a = [1,2,3];

 $a = (1) should then do $a = [1], according to the above.

I most definitely did not write that.  Did you read my conclusion?
One-tuples are special and can't be created simply with round parens.

 This implies that:

 ($a) = (1) implies that $a is [1], something I don't particularly agree
 with.

Once again, did you read my conclusion?  One-tuples are special.


 How would you resolve this contradiction you've created? (Or do you think
 the last example is perfectly fine?)

No contradiction.  One-tuples are special.

 What about:
 $a = 1,2,3

I don't know.  I think Larry must adjudicate.

 ($a) = (1,2,3)

$a gets 1, I think.  Otherwise you can't do list assignment where you
throw away the trailing elements, which is a very common and useful thing
to do in Perl 5.  Losing that ability in Perl 6 would be a great loss.

 $a = (1,2,3)

By definition, according to Larry, $a is [1,2,3].

 ($a) = 1,2,3

Same as without the parens.  Larry must decide.

 Do you still believe those should be identical? They have the same
 problems mentioned above, and likely other issues as well.

Oh, wait, I think I see where you're going.  You didn't read the whole
thread to date before responding.  I later quoted my own text there and
said that arbitrary X was not what I meant.  I meant a single scalar item,
such as 7, but I changed it to X in an effort to be general without
considering what that meant.  My mistake.

Trey




Paren madness (was Re: Regex query)

2002-09-23 Thread Trey Harris

I think this discussion has gotten out of hand, and I hope that Larry,
Damian or Allison will grace us with a resolution soon. :-)

May I suggest that we start with some DWIMmy examples and try to arrive at
a mechanism that will make them all DWIM?  Here are my opinions, feel free
to shoot them down if you disagree:

1.  Subroutines calls.

Given the prototype

sub func(*@ary);

Then

func(X, Y, ..., Z)

should be equivalent to

(func X, Y, ..., Z)

Given the prototype

sub func($scalar);

with no other definitions of func(), then

func(X, Y, ..., Z)

should raise an exception, while

(func X, Y, ..., Z)

should be equivalent to

((func X), Y, ..., Z)

and create a list.

2.  Scalar assignment.

my $a;# 1.
$a = X;

my $a;# 2.
$a = X;

my $a;# 3.
($a) = X;

my($a) = X;   # 4.

my($a) = (X); # 5.

These should all do the same thing, regardless of X.

3.  Precedence.

Adding an additional set of parentheses around an expression already
surrounded by parentheses should never cause that expression to change
meaning.  That is to say

(N) === ((N))

(=== meaning is equivalent to) for all expressions N.  Precedence is one
of the hardest things for many programmers, especially unsophisticated
ones, to grasp.  At least in Perl 5, the programmer can always overdo it
with parentheses if she is unsure.  Requiring that the programmer get
precedence *exactly* right, because one too many parens will result in
coercion of the expression into a list, and thus usually coerced
numerically back to the value 1, is completely unacceptable.

4.  Numeric value.

The progression spoken about at great length previously:

+()# == 0
+(0)   # == WHAT?  0? 1?
+(0,1) # == 2
+(0,1,2)   # == 3
+(0,1,2,3) # == 4
+(0,...,n) # == n + 1

is largely irrelevant to the ways people use Perl.  It may look odd framed
so clearly as a progression, but programmers do not ordinarily create
literal lists simply in order to take the length of them.  This is a cute
programming puzzle that sadistic technical interviewers will foist on
frightened young job candidates in a few years, but I think it has little
bearing on language design.

Thus, item 3 on precedence above usually applies even in the N === (N)
case (though it may sometimes fail to apply because of parsing rules).

And the answer to WHAT above is 0, aesthetics of the progression be
damned.

5.  Assignment to arrays and lists.

The following should be vaild:

  ($a, $b) = ($b, $a);  # swaps $a and $b
  ($a, $b) = (1, 2);# $a == 1, $b == 2
  ($a, $b, $c) ^*= 2;   # doubles each of $a, $b and $c
  a = (1, 2, 3); # Same as Perl 5
  $a = (1, 2, 3); # Same as Perl 5's $a = [1,2,3];

6.  List slicing.

These expressions should both be valid and have the value 2:

  (1,2,3,4)[1]
  [1,2,3,4][1]

7.  Miscellanea.

  for 1,2,3,4 { ... }

should be equivalent to

  for (1,2,3,4) { ... }

and

  for 1,[a,b,c],3 { print x; }

should print xxx.

What

  for (1,(a,b,c),3 { ... }

and

  for 1,(a,b,c),3 { ... }

do is left for Larry and/or Damian to answer, but whatever they do, the
two lines should be equivalent.

Now that I've ventured away from DWIMs and more into WIHDTEMs (What In
Hell Does This Expression Mean), is the above equivalent to

  for 1,qw(a b c), 3 { ... }

as well?

A final unresolved question.  I take it that the splat operator is a
deeply flattening operator.  For instance,

  *[1,[2,[3,4,5]],6]

will be converted into

  [1,2,3,4,5,6]

It seems that, if the new order does allow the creation of
multi-dimensional things using simply (), that we also need a shallowly
flattening operator.  That is, it would convert the above list into

  [1,2,[3,4,5],6]

Otherwise, the flattening required by the new syntax can go wild and cause
unwanted flattening in data structures being passed around.

--

In conclusion, my reading of what Larry has said is compatible with the
above--ASSUMING that

  $a = (7);

causes $a to have the value 7, not the value [7].  If it has the value
[7], as seems to be the result of the reduction that many here have been
doing, then we have a very large problem with precedence, because as I
said in item 3, we can't rely on people getting the paren count exactly
right.  Several other DWIMs above also fall apart.

So, if you want to create a one-item list, you're left with

  $a = [7];

or possibly

  $a = (7);

It seems to me that the vagaries of the one-element list and the coarse
level of control provided by the flattening operator has gotten us into
this level of confusion.  I hope Larry, Damian, Allison or somebody in
charge :-) can help us out of it.

Trey




Re: Paren madness (was Re: Regex query)

2002-09-23 Thread Trey Harris

In a message dated Mon, 23 Sep 2002, Luke Palmer writes:
 Y'all have it backwards.

   [1,*[2,[3,4,5]],6]  # [1,2,[3,4,5],6]
   [1,*[2,*[3,4,5]],6] # [1,2,3,4,5,6]

 Flat flattens outwards, not inwards.

Ah.  *slaps head* of course.  That makes much more sense.  Thanks.

So then, I think if there's just some clarification about how one-tuples
are formed, I think everything I wrote in my earlier mail can DWIM
correctly.  There seems to be no magic here, quotations from LoTR to the
contrary. :-)

Trey




Re: Paren madness (was Re: Regex query)

2002-09-23 Thread Trey Harris

Replying to myself to clear a few things up...

In a message dated Mon, 23 Sep 2002, Trey Harris writes:

 2.  Scalar assignment.

 my $a;# 1.
 $a = X;

 my $a;# 2.
 $a = X;

 my $a;# 3.
 ($a) = X;

 my($a) = X;   # 4.

 my($a) = (X); # 5.

 These should all do the same thing, regardless of X.

This is, I imagine, where Simon saw magic.  I suspect that, for all X, it
would be magic if true (pretty neat magic, though!).  I started with a
literal 7 instead of an abstract X, and then went back and changed it.  I
shouldn't have done so.

 5.  Assignment to arrays and lists.

 The following should be vaild:

   ($a, $b) = ($b, $a);  # swaps $a and $b
   ($a, $b) = (1, 2);# $a == 1, $b == 2

That last line should read

($a, $b) = (1, 2);# $a = 1, $b = 2

 7.  Miscellanea.
 What

   for (1,(a,b,c),3 { ... }

There's a missing paren here.  Should read

for (1,(a,b,c),3) { ... }

 A final unresolved question.  I take it that the splat operator is a
 deeply flattening operator.  For instance,

   *[1,[2,[3,4,5]],6]

 will be converted into

   [1,2,3,4,5,6]

 It seems that, if the new order does allow the creation of
 multi-dimensional things using simply (), that we also need a shallowly
 flattening operator.  That is, it would convert the above list into

   [1,2,[3,4,5],6]

 Otherwise, the flattening required by the new syntax can go wild and cause
 unwanted flattening in data structures being passed around.

I take this back.  Apparently splat was always shallowly flattening.
Something bothers me about that, but it seems better than the alternative.
Can anyone think of a cause where you need a deeply flattening operator?
Seems to be that there's a common one that I can't quite put my finger
on...

 In conclusion, my reading of what Larry has said is compatible with the
 above--ASSUMING that

   $a = (7);

 causes $a to have the value 7, not the value [7].  If it has the value
 [7], as seems to be the result of the reduction that many here have been
 doing, then we have a very large problem with precedence, because as I
 said in item 3, we can't rely on people getting the paren count exactly
 right.  Several other DWIMs above also fall apart.

 So, if you want to create a one-item list, you're left with

   $a = [7];

 or possibly

   $a = (7);

I think this might be the answer.  One-tuples can't be created with a
simple (N).  If you want a one-tuple, you use [], and if you want to
coerce a list context onto something that might return a single element,
you use ().  That's analogous to how it works in Perl 5, and
list-vs.-array behavior is one thing that I'd argue is *not* broken in
Perl 5.  Being able to use arbitrary lists as lvalues, being able to index
lists as if they were arrays, being able to construct lists easily out of
disparate scalar and list constituents, etc., are one of the major things
that make Perl a joy to use.

Trey




Re: Regex query

2002-09-23 Thread Trey Harris

In a message dated 24 Sep 2002, Aaron Sherman writes:
 Grrr... I want that to work, really I do, but since, as Larry has
 pointed out, there's no functional difference between an array ref and
 an array in Perl 6, they would be the same. This is because push is
 almost certainly defined as:

 sub push(target, *@list) { ... }

 Regardless of this entire conversation, that problem exists in Perl 6 as
 described in the apocalypses, doesn't it? The way to avoid this is to
 say that array refs behave the same as arrays in every way *except* as
 pertains to list flattening, and in that case, explicit flattening is
 required, otherwise the ref is kept in the flattened array.

 Does this make sense?

Yikes.  You might be right.  According to Larry,

  $a = (1,2,3);

is equivalent to

  $a = [1,2,3];

because they're both equivalent to

  $a = scalar(1,2,3)

which converts the list to an arrayref.  This only tells us about the
behavior of lists in scalar context, though--it says nothing about the
behavior of parens in a list or list-flattening context.  Is this key to
push's behavior?  Perhaps parens do not construct a list in list context,
but leave whatever is receiving the list and caused the list context to
deal with the elements, i.e., it auto-flattens a paren'ed list if one is
present but not a square-bracketed one?

In that case, we could once again DWIM so that

  push a, 1, 2, 3;

is equivalent to

  push a, (1,2,3);

but not to

  push a, [1,2,3];

I agree, though, that this is getting highly magical.  Perhaps
parens-creating-arrayrefs is something that be considered specialized and
arcane and not something that programmers should do, because square
brackets are much more consistent.  I know that's a dodge, but maybe
it's the right dodge. :-)

Trey




Re: Regex query

2002-09-23 Thread Trey Harris

In a message dated 24 Sep 2002, Aaron Sherman writes:
 This is because push is
 almost certainly defined as:

 sub push(target, *@list) { ... }

That should be

  sub push(target is rw, *@list);

but otherwise I think that's right.

Now, implementation in Perl 6 (though I assume it's actually written in
Parrot).  This would obviously work:

  sub push(target is rw, *@list) {
  target[@target.length ..
  target.length + list.length - 1] = list;
  }

Now, how to do it more Perlishly?

  target = *(target, list);

?  Or would that have to be

  target = (*@target, *@list);

?  Surely

  target = (target, list);

or

  target = (*@target, list);

would not work.  Or would it?

Trey






  1   2   >