Re: supertyping

2006-12-13 Thread Jonathan Lang

Luke Palmer wrote:

Jonathan Lang wrote:
> Agreed.  The question is whether you think of a role as a set of
> methods ("intension set") or as a set of instances ("extension set").
> FWIW, it wasn't until this thread that I even registered that the
> latter possibility existed.  Given the above contrast between roles
> and subtypes, I would really like to keep the extension set mindset
> limited to subtypes and the intension set mindset limited to roles: a
> role is an interface (i.e., a set of methods); a type is a set of
> possible instances.

Eh, a proposal is nothing if you can't make sense of it from both
mindsets, because they both are real.  While you may think of a role
as an interface, it still does have objects that can obey it, so the
set of such objects still exists.  My brain seems to prefer the
extensional mindset, but it's important to try to make sense of
everything from both.  Hmm, the extensional is the more "spookily
theoretical" of the two, since Perl will know the interface, but it
won't create the set of all possible, eventual instances.


OK.  With this in mind, I suppose that set operations, per se, are
indeed out.  Let's see what can be done with "does" and "done_by" (for
lack of a better name).

First, note that

 role Foo does Bar does Baz { ... }

is exactly the same as

 role Foo {
   does Bar;
   does Baz;
   ...
 }

Likewise, I'd expect

 role Foo done_by Bar { ... }

to be equivalent to

 role Foo { done_by Bar; ... }

or

 role Foo { ... ; done_by Bar }

The contents of the curly braces should always define the interface
that the role brings to the table.  Furthermore, "done_by" statements
should have no effect whatsoever on Foo's interface, other than to
define restrictions on what is legal in Foo (maybe).  In extension set
terminology, the above means that "Foo = ...; Bar (+)= Foo".  In
effect, "Foo done_by Bar" means "modify Bar to include 'does Foo'".

In this way, mixtures of "does" and "done_by" work in an intuitive
way: only "does" helps establish what the role is capable of, while
"done_by" feeds those capabilities into another, existing role.

Which gets back to the issue of whether roles should be mutable or
not.  If roles are immutable, then "done_by" is going to have to levy
some rather heavy-handed restrictions on the new role, specifically to
avoid new capabilities being back-edited into existing roles.  If
roles are mutable, "done_by" needn't impose any restrictions - but the
creator of the new role has the responsibility to ensure that any
additions that he makes doesn't break any existing classes.

Unfortunately, this approach completely misses the boat in terms of
what I was looking for in supertyping - namely, the ability to reuse
portions of an existing interface (such as the aforementioned "extract
an Order role out of the Num role") - useful when using modules where
the module designer overcomplicated things, but you don't want to
rebuild everything from scratch.  That, I think, is the common feature
of both goals: the ability to compensate for another coder who didn't
do things exactly the way you want them done, but who was reasonably
close.


Note that I *am* arguing for a back-editing behavior.  You are of
course allowed to remove anything (by not declaring it), and you are
also allowed to add new methods as long as they have a default
implementation.  You are not allowed to add new unimplemented, or
required, methods.


Note that the "default implementation" requirement need only be
specified in terms of the done_by roles: "method foo(Foo: ) { ... }"
is perfectly legitimate, as long as &Foo::foo:(Bar: ) and
&Foo::foo:(Baz: ) are more solidly defined, given "Foo done_by(Bar)
done_by(Baz)".

(BTW: as I see it, all methods defined in Foo are "required".  I'd
prefer "unimplemented" or "abstract" as the description for methods
with '{ ... }' as the body.)


The reasoning for this is mostly utility.  How are you supposed to
generalize Num to Complex (okay, fine, I'll try to come up with
another example.  Is it okay if it is also from math?) if Num didn't
know that an "imaginary part" existed?


I suspect that Num vs. Complex is considered to be a poor choice for
an example because Num and Complex are going to be standard types
already.


You could really consider that syntax sugar if you like:

role Foo {
method foo() { "hello" }
}
role Bar superdoes Foo {
method bar() { "world" }
}

Is equivalent to declaring Bar with no methods, and then adding:

multi sub bar(Bar:) { "world" }

Modulo some minor differences, but the semantics are essentially the
same.  I don't think we'd want to disable back-editing because then we
would be encouraging the idiom I just demonstrated, which is less
clear (IMO).


My understanding is that subs can't have invocants; only methods and
submethods can, and both of those must be defined within a role or
class.


Back-editing seems weird from an intensional mindset, but perfectly
natural fro

Re: RFC: Proposal for dynamic binding

2006-12-13 Thread Bob Rogers
   From: Allison Randal <[EMAIL PROTECTED]>
   Date: Sat, 09 Dec 2006 21:55:35 -0800

   Bob Rogers wrote:

   > This is also my definition of "dynamic scoping".  Were you not aware of
   > this behavior of "local", or are we talking about different things
   > entirely?

   I was talking about the lifetime of the temporization not static vs. 
   dynamic scoping.

OK, then I think we agree.  (Your original statement was ambiguous about
whether you were talking about scope or lifetime, but then your next
statement used the word "scope.")

   But, this does help me better understand what you're getting at. The 
   proposal only mentions "dynamic scope" three times, but reading through 
   it again now I can see that the whole proposal is a literal 
   implementation of a classic textbook definition of dynamic scope.

Yes.  But I've been calling it "dynamic binding" because it's the
variable binding that has dynamic scope.  I'm willing to adopt your
terminology, but you'll have to bear with me, because I've been saying
"dynamic binding" for quite a while now.  But what would you have me use
for the verb, if not "to bind"?

   [For reference, Wikipedia says: "In dynamic scoping, each identifier has 
   a global stack of bindings. Introducing a local variable with name x 
   pushes a binding onto the global x stack (which may have been empty), 
   which is popped off when the control flow leaves the scope. Evaluating x 
   in any context always yields the top binding."]

I saw this, too.  I assume this is just a conceptual simplification for
teaching purposes; it would be silly to create a literal stack for each
variable when only a handful of them will ever be rebound this way at
any given time.  None of the compilers I'm aware of do it this way.

   >But I'm still unclear how this distinction is made in a Perl 6
   > program.  If you write
   > 
   >temp $foo = 37;
   > 
   > is this assignment or binding?  And in either case, how do you specify
   > the other?  Larry?  (Not that understanding this is likely to be
   > necessary for getting Parrot to do the right thing.)

   That's assignment. Binding would be:

  temp $foo := 37;

Great; thanks.

   >> Could you be more specific about the proposed implementation?  What
   >> issues do you have with it?  Is it worth fixing, or should I give up?
   > 
   >Mainly, I don't see the proposal as it stands as a solution for 'temp' 
   >and 'local'. Dynamic binding as you define it (what I'm calling 
   >thread-locals), is a completely different problem. The proposal needs a 
   >description of the problem it is solving, instead of describing one 
   >problem and solving a different one.
   > 
   > Does the Perl 5 example above convince you that it is the same problem?
   > Or at least a subset, given that I didn't follow the "assignment
   > vs. binding" thing?

   We're now talking about 3 different things: dynamic binding, dynamic 
   scoping, and temporization. Dynamic binding is any association of a 
   value with an identifier, when that association is made at runtime. It's 
   much broader than what we're talking about here. So, let's stop using 
   that term.

Now I'm confused again.  Isn't that exactly what we're talking about,
but generalized to include binding of non-variables?

   On dynamic scoping and temporization, I agree that they're related 
   problems, in that some definitions of temporization use dynamic scoping. 
   But either feature can be used without the other, so it's better to 
   separate the implementation of dynamic scoping from the implementation 
   of temporization.

OK.

   >Also, the particular implementation suggested -- the Location class 
   >hierarchy of abstract and instantiable classes, the stack of stored 
   >values -- is more heavy weight than the underlying concept merits.
   > 
   > If you can think of a lighter-weight approach, I'm all ears.  I proposed
   > something fairly lightweight nearly a year ago, with nearly the same
   > functionality, though it only addressed globals.  Leo quite reasonably
   > objected that it didn't fully implement Perl 5 "local", and I agreed
   > that it was too particular to globals to be generalized, so I withdrew
   > it.  The new approach attempts to address that limitation by introducing
   > PMC classes to support structure and variable binding distinctly in an
   > extensible way.  Now it appears that I need to be both (a) more
   > complete, to handle assignment as opposed to just binding, and (b)
   > lighter in weight.  Please pick just one. ;-}

   Lighter weight, by separating out the problems into separate components. 
 Assignment and binding are relevant to temporization, not to dynamic 
   scoping.

???  Do you mean "The assignment versus binding distinction is relevant
to temporization, not ..."?  If so, I'm perfectly happy to ignore it.

   > I would like to see this implemented, so I'm willing to go back to the
   >

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

2006-12-13 Thread larry
Author: larry
Date: Wed Dec 13 17:50:39 2006
New Revision: 13490

Modified:
   doc/trunk/design/syn/S04.pod

Log:
Generalized the do/gather syntax to other similar dynamic scoping constructs.


Modified: doc/trunk/design/syn/S04.pod
==
--- doc/trunk/design/syn/S04.pod(original)
+++ doc/trunk/design/syn/S04.podWed Dec 13 17:50:39 2006
@@ -12,9 +12,9 @@
 
   Maintainer: Larry Wall <[EMAIL PROTECTED]>
   Date: 19 Aug 2004
-  Last Modified: 5 Dec 2006
+  Last Modified: 13 Dec 2006
   Number: 4
-  Version: 45
+  Version: 46
 
 This document summarizes Apocalypse 4, which covers the block and
 statement syntax of Perl.
@@ -410,7 +410,18 @@
 statement or block, and executes it once.  Unlike C, its return
 value is a specified by calling the C function one or more
 times within the dynamic scope of the gather.  The returned values are
-flattened into a lazy list.
+flattened into a lazy list.  A C is not considered a loop.
+
+Other similar C-only forms may also take bare statements,
+including C, C, C, and C.  These constructs
+establish a dynamic scope without necessarily establishing a lexical
+scope.  (You can always establish a lexical scope explicitly by using
+the block form of argument.)  As statement introducers, all these
+keywords must be followed by whitespace.  You can say something
+like C, but then you are calling it using function call
+syntax instead, in which case the C argument must be a block.
+For purposes of flow control, none of these forms are considered loops,
+but they may easily be applied to a normal loop.
 
 =head1 Switch statements
 


Re: 6-on-5 and read only aliasing

2006-12-13 Thread Kevin Z

VINE

On 12/13/06, Nicholas Clark <[EMAIL PROTECTED]> wrote:


For the effort to implement a Pugs backend to run Perl 6 on Perl 5, one
part that was looking tricky was how to make read only aliases of
read-write values. Data::Bind fakes the functionality with magic, but I
think that it's going to have limitations with corner cases.

The better solution appears to be to add a type to the core, akin to
references (SvRV) which acts as an automatic alias type.

Since 5.000 there have been 16 internal types in Perl, which feels like a
nicer number to keep than go to 17.

With change 29544 I've finished moving things around to abolish the need
for the PVBM type, probably the least used of any of the internal types.
Its functionality, storing tables for fast Boyer-Moore string scanning,
can be achieved by using PVGV after a bit of rearranging of flags and
structures.

So to keep at the nice number of 16, there is a placeholder for a new
type,
tentatively named BIND, for 6-on-5 aliasing. It's all yours, 6-on-5
hackers.

I'm not exactly sure what is needed for 6-on-5, beyond read only aliases
to read-write values, but I think that implementing a workable version of
that should be fairly straightforward. Probably something like:

a: Make all data reading functions, as their first action, check if they
have
   a BIND, and if so dereference it immediately.
   Functions like sv_2iv_flags, sv_2uv_flags etc
b: Make all data writing functions, as their first action, check if they
have
   a BIND. If it's not read only, dereference it immediately.
   Otherwise, leave it be, and it will hit that function's readonly check
   for the correct error. (Look for PL_no_modify, which holds the string
   "Modification of a read-only value attempted"
c: Ensure that the macro SvOK() chases the dereference.
   (As it's likely that the dereference itself won't have any of the SV
flags
set that mark it as "true"


Although some niggling sense of doubt tells me that it will get fun before
it gets pretty.

Suggestions for a better name for BIND welcome. 4 letters or fewer.

Nicholas Clark

PS blead source is at rsync://public.activestate.com/perl-current/





--
Outside the mind, there is no Lotus Sutra..& outside the Lotus Sutra, there
is no mind...

(Hakuin)

antiparanoid.blogspot.com


Re: supertyping

2006-12-13 Thread Luke Palmer

In spite of Larry's comments, I will continue to entertain this idea
until it is solid to myself that I would be comfortable accepting it.

On 12/13/06, Jonathan Lang <[EMAIL PROTECTED]> wrote:

Agreed.  The question is whether you think of a role as a set of
methods ("intension set") or as a set of instances ("extension set").
FWIW, it wasn't until this thread that I even registered that the
latter possibility existed.  Given the above contrast between roles
and subtypes, I would really like to keep the extension set mindset
limited to subtypes and the intension set mindset limited to roles: a
role is an interface (i.e., a set of methods); a type is a set of
possible instances.


Eh, a proposal is nothing if you can't make sense of it from both
mindsets, because they both are real.  While you may think of a role
as an interface, it still does have objects that can obey it, so the
set of such objects still exists.  My brain seems to prefer the
extensional mindset, but it's important to try to make sense of
everything from both.  Hmm, the extensional is the more "spookily
theoretical" of the two, since Perl will know the interface, but it
won't create the set of all possible, eventual instances.


> But that makes no sense at all because these are the ones which are
> specialized further down in the subtyping chain. There has to be
> some extra that the supertype defines for the subtypes.

No, there doesn't.  For example, let's assume that whoever created the
Num role forgot to define an Order role for it.  Supertyping would let
you create that role for yourself and would ensure that it has the
proper relationship with Num.  That's what supertyping of roles should
be about: extracting subsets of its interface for use elsewhere (which
is part of the reason I'm leery about calling it "supertyping"; the
important part isn't the greater number of instances that it can have,
but instead the simpler interface that it provides).


Note that I *am* arguing for a back-editing behavior.  You are of
course allowed to remove anything (by not declaring it), and you are
also allowed to add new methods as long as they have a default
implementation.  You are not allwed to add new unimplemented, or
required, methods.

The reasoning for this is mostly utility.  How are you supposed to
generalize Num to Complex (okay, fine, I'll try to come up with
another example.  Is it okay if it is also from math?) if Num didn't
know that an "imaginary part" existed?

You could really consider that syntax sugar if you like:

   role Foo {
   method foo() { "hello" }
   }
   role Bar superdoes Foo {
   method bar() { "world" }
   }

Is equivalent to declaring Bar with no methods, and then adding:

   multi sub bar(Bar:) { "world" }

Modulo some minor differences, but the semantics are essentially the
same.  I don't think we'd want to disable back-editing because then we
would be encouraging the idiom I just demonstrated, which is less
clear (IMO).

Back-editing seems weird from an intensional mindset, but perfectly
natural from an extensional mindset (you are just defining functions
on things).  If you don't think of a role as a set of methods, but
rather a tree of sets of methods (like inheritance), then back-editing
seems more natural (you just insert a different parent above the old
role).


One problem with this is that the default return value for Num.im
ought to be zero; the default return value for Complex.im ought to be
whatever the imaginary component of the number is.  So role Complex
would need both

method im (Complex: ) { return .im }
method im (Num: ) { return 0 }


Good point.  Hmm, that's a bit awkward.

It can actually be averted in the Complex case, by defining the .im
attribute to default to 0.  But that is a hack that will not
generalize.

For now (because of this example, in fact), I'm inclined to change the
proposal to "please don't design the language to prevent a module from
implementing supertyping".  I think disallowing reopening of roles
will prevent that.

Maybe we allow reopening of roles, but new method declarations have to
come with defaults; that way you are not (as above) invalidating
existing objects, just adding behavior to them.  That is a tricky
issue, though, because such definitions might add conflicts and
invalidate those objects anyway.  Maybe more-recently added methods
have less priority than older ones.  That stinks.  Hmm.  I need to
think about this.

Luke


6-on-5 and read only aliasing

2006-12-13 Thread Nicholas Clark
For the effort to implement a Pugs backend to run Perl 6 on Perl 5, one
part that was looking tricky was how to make read only aliases of
read-write values. Data::Bind fakes the functionality with magic, but I
think that it's going to have limitations with corner cases.

The better solution appears to be to add a type to the core, akin to
references (SvRV) which acts as an automatic alias type.

Since 5.000 there have been 16 internal types in Perl, which feels like a
nicer number to keep than go to 17.

With change 29544 I've finished moving things around to abolish the need
for the PVBM type, probably the least used of any of the internal types.
Its functionality, storing tables for fast Boyer-Moore string scanning,
can be achieved by using PVGV after a bit of rearranging of flags and
structures.

So to keep at the nice number of 16, there is a placeholder for a new type,
tentatively named BIND, for 6-on-5 aliasing. It's all yours, 6-on-5 hackers.

I'm not exactly sure what is needed for 6-on-5, beyond read only aliases
to read-write values, but I think that implementing a workable version of
that should be fairly straightforward. Probably something like:

a: Make all data reading functions, as their first action, check if they have
   a BIND, and if so dereference it immediately.
   Functions like sv_2iv_flags, sv_2uv_flags etc
b: Make all data writing functions, as their first action, check if they have
   a BIND. If it's not read only, dereference it immediately.
   Otherwise, leave it be, and it will hit that function's readonly check
   for the correct error. (Look for PL_no_modify, which holds the string
   "Modification of a read-only value attempted"
c: Ensure that the macro SvOK() chases the dereference.
   (As it's likely that the dereference itself won't have any of the SV flags
set that mark it as "true"


Although some niggling sense of doubt tells me that it will get fun before
it gets pretty.

Suggestions for a better name for BIND welcome. 4 letters or fewer.

Nicholas Clark

PS blead source is at rsync://public.activestate.com/perl-current/


Re: Past-pm basic string types

2006-12-13 Thread Patrick R. Michaud
On Tue, Dec 12, 2006 at 01:57:20PM -0800, Allison Randal wrote:
> Patrick R. Michaud wrote:
> >I can modify PAST-pm to provide a "send exactly this string to PIR" 
> >option for PAST::Val.  
> 
> Yes, good idea for the simple case.

After sleeping on it overnight, I realized that PAST-pm already
has this feature.

Currently PAST-pm checks the PAST::Val node's "ctype"
attribute to decide whether to encode the literal value 
as a Parrot form -- if the node doesn't have ctype that indicates
"string constant", then PAST-pm just uses the literal value
directly in the output.

So, just don't set "ctype", and whatever the node has as
its "name" attribute will go directly into the PIR output.

Here's an example:

$ cat x.pir
.sub main :main
load_bytecode 'PAST-pm.pbc'
.local pmc valnode, blocknode, pir

##  $S0 is the string we want to appear in the output
$S0 = '"\n"'
valnode = new 'PAST::Val'
valnode.'init'('vtype'=>'.String', 'name'=>$S0)
blocknode = valnode.'new'('PAST::Block', valnode, 'name'=>'anon')

##  compile the tree to PIR and print the result
$P99 = compreg 'PAST'
pir = $P99.'compile'(blocknode, 'target'=>'pir')
print pir
.end

$ ./parrot x.pir

.sub "anon"
new $P10, .String
assign $P10, "\n"
.return ($P10)
.end

Eventually the handling of "ctype" is going to change -- first,
the name will change to be more descriptive (but I'll leave a 'ctype'
accessor in place to give compilers time to switch); second, any
ctype specifications will be held in a HLL class mapping table 
instead of in each PAST::Val node.

There is a good chance that PAST-pm will treat PAST::Val nodes
of type .String as needing their values to be encoded for Parrot,
but to protect against this punie (and other compilers) can
use .Undef:

$S0 = '"\n"'
valnode = new 'PAST::Val'
valnode.'init'('vtype'=>'.Undef', 'name'=>$S0)

Since the node isn't a string type, PAST-pm will use the "name"
$S0 value directly in the output PIR without performing any
encoding on the literal value, and the generated PIR from the node
would look like

new $P10, .Undef
assign $P10, "\n"

And this does exactly what you want.  :-)

Pm


Re: [perl #41082] [RESOLVED] [PATCH] Cygwin: conflicting types for _LIB_VERSION

2006-12-13 Thread Greg Bacon
In message <[EMAIL PROTECTED]>,
"Jerry Gay via RT" writes:

: According to our records, your request regarding 
:   "[PATCH] Cygwin: conflicting types for _LIB_VERSION" 
: has been resolved. 

Is this a known issue? What was the resolution?

Thanks,
Greg


Re: Strange error message with anon subroutine

2006-12-13 Thread Gaal Yahas
On Wed, Dec 13, 2006 at 11:31:33AM -0800, Ovid wrote:
>   *** Cannot use this control structure outside a 'routine' structure
>   at 99.pugs line 103, column 13-22
> 
> Take out the returns, and it works fine.  Can someone tell me what I'm
> missing?  Is this a bug.

Perl 6 differentiates between a bare Code and Routine objects. Replacing
"->" with "sub" should get you what you want.

-- 
Gaal Yahas <[EMAIL PROTECTED]>
http://gaal.livejournal.com/


Re: Strange error message with anon subroutine

2006-12-13 Thread Larry Wall
On Wed, Dec 13, 2006 at 11:31:33AM -0800, Ovid wrote:
: In trying to compress a list, I wrote the following code:
: 
:   my $compress = do {
:   my $previous;
:   $compress = -> $x {
:   if !defined $previous or $x ne $previous {
:   $previous = $x;
:   $x;
:   }
:   else {
:   ();
:   }
:   };
:   }
:   my @compressed = map $compress, ;
:   @compressed.say;
: 
: That's a bit more verbose than I intended, but that's partially because
: of this:
: 
:   my $compress = do {
:   my $previous;
:   $compress = -> $x {
:   if !defined $previous or $x ne $previous {
:   $previous = $x;
:   return $x;
:   }
:   else {
:   return ();
:   }
:   };
:   };
: 
: As soon as I put the return statements in an anonymous subroutine, I
: get this error message:
: 
:   *** Cannot use this control structure outside a 'routine' structure
:   at 99.pugs line 103, column 13-22
: 
: Take out the returns, and it works fine.  Can someone tell me what I'm
: missing?  Is this a bug.

Nope, spec.  S06 says:

[Pointy block] also behaves like a block with respect to control
exceptions.  If you C from within a pointy block, it will
return from the innermost enclosing C or C, not the
block itself.  It is referenced by C<&?BLOCK>, not C<&?ROUTINE>.

See also the section in S04 discussing control exceptions, where it says:

A C always exits from the lexically surrounding sub
or method definition (that is, from a function officially declared
with the C, C, or C keywords).  Pointy blocks
and bare closures are transparent to C.

So all you really need to do is change the pointy to an official sub:

my $compress = do {
my $previous;
$compress = sub ($x) {
if !defined $previous or $x ne $previous {
$previous = $x;
return $x;
}
else {
return ();
}
}
}

: Also, I noticed I accidentally left off the final semi-colon on the do
: block.  It ran anyway and that surprised me.

S04:

Outside of any kind of expression brackets, a final closing curly
on a line (not counting whitespace or comments) always reverts
to the precedence of semicolon whether or not you put a semicolon
after it.

Larry


Re: Introspection and list question

2006-12-13 Thread Larry Wall
On Wed, Dec 13, 2006 at 10:55:28AM +0200, Gaal Yahas wrote:
: L stipulates the
: results of a gather are flattened to a lazy list. I'm not sure how far
: that flattenning goes, but one of these should do the trick, I think

It would only flatten a recursive structure with the help of something
that recurses.  The flattening of gather/take itself is only one level,
insofar as the various takes are treated as "pushes" onto the list
being gathered.

: (Pugs does not yet implement gather/take):

Actually, it does, but only the block form.  The generalization to any
statement (using C syntax) was a very recent change.

The following prints (1, 2, 3, 4, 5) in current pugs:

#!/usr/bin/pugs

my $a = [1,2,[3,4],5];

multi flattener ($x) {
take $x;
}
multi flattener (Array @array) {
for @array -> $elem {
flattener($elem);
}
}

sub flatten ([EMAIL PROTECTED]) {
for @args -> $arg {
return gather { flattener($arg) }
}
}

$a.flatten.perl.say;

Larry


Strange error message with anon subroutine

2006-12-13 Thread Ovid
In trying to compress a list, I wrote the following code:

  my $compress = do {
  my $previous;
  $compress = -> $x {
  if !defined $previous or $x ne $previous {
  $previous = $x;
  $x;
  }
  else {
  ();
  }
  };
  }
  my @compressed = map $compress, ;
  @compressed.say;

That's a bit more verbose than I intended, but that's partially because
of this:

  my $compress = do {
  my $previous;
  $compress = -> $x {
  if !defined $previous or $x ne $previous {
  $previous = $x;
  return $x;
  }
  else {
  return ();
  }
  };
  };

As soon as I put the return statements in an anonymous subroutine, I
get this error message:

  *** Cannot use this control structure outside a 'routine' structure
  at 99.pugs line 103, column 13-22

Take out the returns, and it works fine.  Can someone tell me what I'm
missing?  Is this a bug.

Also, I noticed I accidentally left off the final semi-colon on the do
block.  It ran anyway and that surprised me.

Cleaner ways of writing that code are welcome, too.

Cheers,
Ovid

--

Buy the book -- http://www.oreilly.com/catalog/perlhks/
Perl and CGI -- http://users.easystreet.com/ovid/cgi_course/


Re: Gather/Take and threads

2006-12-13 Thread Larry Wall
On Wed, Dec 13, 2006 at 11:01:10AM -0800, Larry Wall wrote:
: Of course, it's also possible that the flipside is true--that
: gather/take is just another normal way to set up interthread queueing,
: if the thread is spawned in the dynamic scope of the gather.
: Under that view all the subthreads share the outer dynamic scope.
: Maybe that's saner...

And a subdivision of that view is whether subthreads are naturally
collected at the end of the dynamic scope that spawned them, or
whether they are considered independent unless some dynamic scope
"claims" them all for collection.  In that case a gather would one
way (the normal way?) to require termination of all subthreads before
terminating its lazy list.

Larry


Re: supertyping

2006-12-13 Thread Larry Wall
On Wed, Dec 13, 2006 at 11:25:40AM +, Smylers wrote:
: Jonathan Lang writes:
: 
: > For the record, I think that "superdoes" should be spelled "done_by".
: 
: I think it's unlikely that Larry will incorporate any keywords that
: contain underscores -- certainly not without at least searching for a
: single word that sums up the concept in question.

And I'm not even gonna do that if I can't be convinced of a use case
beyond "Num does Complex".  And since my sinuses are full of the crud
that is going around right now, I'm not in a very convincable mood.
With the little sense of smell I have left, this smells like INTERCAL's
"COME FROM" statement to me, trading a teeny bit of notational convenience
in one spot for oversized headaches elsewhere.  Most Perl programmers
are not interested in type theory, and complexifying the little bit of
intentional typing we're introducing with roles will simply cause most
people to avoid it like the plague.  We might *possibly* get away with
reopening roles like we can reopen a class:

role Num is also does Complex {
method im {...}
}

but roles are really supposed to be fairly immutable in the Perl 6
scheme of things, so such a declaration would probably have to require
that the Num role never have been composed into anything else yet.

Or we could say that you can't reopen the Num role; you can only
reopen the Num class and mix in the Complex role.  That's where it
stands at the moment.

Larry


Re: Gather/Take and threads

2006-12-13 Thread Larry Wall
Of course, it's also possible that the flipside is true--that
gather/take is just another normal way to set up interthread queueing,
if the thread is spawned in the dynamic scope of the gather.
Under that view all the subthreads share the outer dynamic scope.
Maybe that's saner...

Larry


Re: supertyping

2006-12-13 Thread Jonathan Lang

TSa wrote:

Jonathan Lang wrote:
> Assuming that I understand the terminology correctly, I'll go further
> and say that one of the big differences between roles and subtypes
> (using the terms in their perl 6 contexts) is that roles conceptually
> operate on intension sets - everything about them is defined in terms
> of their set of capabilities - while subtypes (i.e., objects with
> "where" clauses) operate on extension sets - they're defined in terms
> of the valid set of instances.

You understand the terminology correctly. I'm kind of split
of which approach to favor. I can understand Smylers objection
that the very existence of these two sets and the contradictory
results that set ops produce on them should prevent the usage of
set syntax for type construction. OTOH, I know of nothing else
that conveys the intent as terse.


Agreed.  The question is whether you think of a role as a set of
methods ("intension set") or as a set of instances ("extension set").
FWIW, it wasn't until this thread that I even registered that the
latter possibility existed.  Given the above contrast between roles
and subtypes, I would really like to keep the extension set mindset
limited to subtypes and the intension set mindset limited to roles: a
role is an interface (i.e., a set of methods); a type is a set of
possible instances.


> That's the brittleness: the set of methods that you are permitted to
> define in the superrole is restricted to the set of methods in the
> role being generalized.

But that makes no sense at all because these are the ones which are
specialized further down in the subtyping chain. There has to be
some extra that the supertype defines for the subtypes.


No, there doesn't.  For example, let's assume that whoever created the
Num role forgot to define an Order role for it.  Supertyping would let
you create that role for yourself and would ensure that it has the
proper relationship with Num.  That's what supertyping of roles should
be about: extracting subsets of its interface for use elsewhere (which
is part of the reason I'm leery about calling it "supertyping"; the
important part isn't the greater number of instances that it can have,
but instead the simpler interface that it provides).


> The write-up that I saw in the original message seems to carry the
> implication of the alternative approach (of back-editing the new
> methods into the subrole).  Note that if you go this route, you really
> should allow yourself to define multiple versions of the new method:
> one for the superrole, and one for each of the subroles used to define
> it.  I'd rather not go this route, though.

Hmm, looks like this is exactly where I intent to go. If we detach
method dispatch from the class that in the end provides the method
table for its instances we get the picture that the Complex supertype
creates dispatch targets for &im:(Num) and &im:(Complex) and since
Num <: Complex dispatch goes to the simple 0 returning role default
when called on a Num.


One problem with this is that the default return value for Num.im
ought to be zero; the default return value for Complex.im ought to be
whatever the imaginary component of the number is.  So role Complex
would need both

   method im (Complex: ) { return .im }
   method im (Num: ) { return 0 }

That's what I was referring to in terms of having multiple copies of a
given method.


Well, and of the debate of how to retype an object. I see the .im
method in a position to do the right thing when given the invocant
and the rhs of the assignment. The thing I don't know is how the
syntax looks like. Does one write a STORE block into the method
body? And how is the container involved in the process?


Synopsis 6, "Lvalue subroutines".


> Mind you, once you've defined a supertype, you can freely create new
> subtypes of it, and you can add whatever features you want to those
> new subtypes, be they lvalue access, new methods, or anything else.

This is unquestioned. But my whole point is to get the Num nicely
embedded in the Complex without touching the Num implementation.


No can do.  As soon as you add anything to Complex that isn't in Num,
you've changed Num.


> IMHO, the correct way to create an unordered Complex role from a Num
> role is to use supertyping to remove the ordering capabilities from
> Num, and then use subtyping to add "imaginary component" capabilities
> to that.  Yes, this means that a simple partial ordering check between
> Complex and Num will result in a "no relation" result; but that's a
> shortcoming of the type-checking system, not the type definition
> system.

Sorry again, the whole point is to get Num <: Complex in the first
place. How else should a subtyping directed dispatch system pick
methods? No relation can also be achieved with a unrelated
implementation of Complex.


I agree that "no relation" is not the desired outcome here - but
neither is 'Num <: Complex'.  The implication of 'Num <: Complex' is
that Num can do anything that C

[perl #41082] [PATCH] Cygwin: conflicting types for _LIB_VERSION

2006-12-13 Thread via RT
# New Ticket Created by  Greg Bacon 
# Please include the string:  [perl #41082]
# in the subject line of all future correspondence about this issue. 
# http://rt.perl.org/rt3/Ticket/Display.html?id=41082 >


Building r16097 on Cygwin fails:

[...]
src/platform.c
config/gen/platform/cygwin/math.c:11: error: conflicting types for 
'__fdlib_version'
/usr/include/math.h:409: error: previous declaration of '__fdlib_version' was 
here
config/gen/platform/cygwin/math.c:11: error: conflicting types for 
'__fdlib_version'
/usr/include/math.h:409: error: previous declaration of '__fdlib_version' was 
here
make: *** [src/platform.o] Error 1

Removing the const qualifier from _LIB_VERSION's definition in
config/gen/platform/cygwin/math.h (see attached patch) at least
allows miniparrot to build, but running it is another story:

[...]
gcc -o miniparrot.exe -s -L/usr/local/lib   compilers/imcc/main.o \
 -L/usr/src/parrot/blib/lib -lparrot  -lcrypt -lreadline src/null_config.o
Invoking Parrot to generate runtime/parrot/include/config.fpmc --cross your 
fingers
./miniparrot.exe config_lib.pasm > runtime/parrot/include/config.fpmc
make: *** [runtime/parrot/include/config.fpmc] Error 53

Greg
Index: config/gen/platform/cygwin/math.c
===
--- config/gen/platform/cygwin/math.c   (revision 16097)
+++ config/gen/platform/cygwin/math.c   (working copy)
@@ -8,7 +8,7 @@
 
 #include 
 
-const _LIB_VERSION_TYPE _LIB_VERSION = _IEEE_;
+_LIB_VERSION_TYPE _LIB_VERSION = _IEEE_;
 
 /*
  * return true if the Numval has a negative sign.



Re: Gather/Take and threads

2006-12-13 Thread Larry Wall
On Wed, Dec 06, 2006 at 07:44:39PM -0500, Joe Gottman wrote:
: Suppose I have a gather block that spawns several threads, each of which
: calls take several times.  Obviously, the relative order of items returned
: from take in different threads is indeterminate, but is it at least
: guaranteed that no object returned from take is lost?

Currently gather/take is defined over a dynamic scope, and I think
that a different thread is a different dynamic scope (after all,
why does it have its own call stack?), so by default you get nothing
from another thread, and the other thread would get a "take outside
of gather" error.  You'd have to set up some kind of queue from the
other thread and take the output of that explicitly.

The microthreading done by hyperops perhaps doesn't count though.
In playing around the other day with a list flattener without explicit
recursion, I found that pugs currently returns hyper-takes in random
order:

pugs> say ~gather { [1,2,[3,4],5]>>.take }
1 2 4 5 3
pugs> say ~gather { [1,2,[3,4],5]>>.take }
2 1 4 5 3

The random order is according to spec, assuming take is allowed at all.
But perhaps it shouldn't be allowed, since the threaded side of a
hyperop could conceivably become as elaborate as a "real" thread, and
maybe we should not make a distinction between micro and macro threads.
And it's not like a take can guarantee the order anyway--the hyperop
is merely required to return a structure of the same shape, but that
does not enforce any order on the actual take calls (as shown above).
Only the return values of take end up in the same structure, which is
then thrown away.

In fact, I'd argue that the value returned by take is exactly the
value passed to it, but I don't think that's specced yet.  A take is
just a side effect performed "en passant" under this view.  Then we
could write things like:

while take foo() {...}
@thisbatch = take bar() {...}

Larry


Re: supertyping

2006-12-13 Thread TSa

HaloO,

Jonathan Lang wrote:

Assuming that I understand the terminology correctly, I'll go further
and say that one of the big differences between roles and subtypes
(using the terms in their perl 6 contexts) is that roles conceptually
operate on intension sets - everything about them is defined in terms
of their set of capabilities - while subtypes (i.e., objects with
"where" clauses) operate on extension sets - they're defined in terms
of the valid set of instances.


You understand the terminology correctly. I'm kind of split
of which approach to favor. I can understand Smylers objection
that the very existence of these two sets and the contradictory
results that set ops produce on them should prevent the usage of
set syntax for type construction. OTOH, I know of nothing else
that conveys the intent as terse.



Incidently, I'm using terms like "supertype", "subtype", "superrole",
"subrole", etc. strictly due to a lack of a better alternative.
"Supertyping" only leads to a larger set of instances because a
parameter that asks for the supertype is willing to accept a subtype
in its stead.


Yes, this is how the argument goes. A supertype constraint allows
more instances to pass the test because the set of requirements is
smaller.



That's the brittleness: the set of methods that you are permitted to
define in the superrole is restricted to the set of methods in the
role being generalized.


But that makes no sense at all because these are the ones which are
specialized further down in the subtyping chain. There has to be
some extra that the supertype defines for the subtypes.


 Since Num doesn't include methods re or im,
an attempt to include either method in a Complex superrole would be an
error according to this approach, or it would involve changing Num to
include methods re and im in the alternative approach.


Then I did read Luke's post wrongly. Sorry.



The write-up that I saw in the original message seems to carry the
implication of the alternative approach (of back-editing the new
methods into the subrole).  Note that if you go this route, you really
should allow yourself to define multiple versions of the new method:
one for the superrole, and one for each of the subroles used to define
it.  I'd rather not go this route, though.


Hmm, looks like this is exactly where I intent to go. If we detach
method dispatch from the class that in the end provides the method
table for its instances we get the picture that the Complex supertype
creates dispatch targets for &im:(Num) and &im:(Complex) and since
Num <: Complex dispatch goes to the simple 0 returning role default
when called on a Num. So to support supertyping the lookup process
of methods has to scan upwards in the inheritance and role hierarchy
instead of just looking into a table in the class the object is blessed
into. But I think this is how dispatch works, doesn't it? The lookup
result might be cached for efficiency.



Look at it according to the normal flow: if you subtype a role with
read/write capabilities, the new role cannot have fewer rw
capabilities than the role that it's composing has.  Reversing this,
if a role does not have a particular rw capability, then a superrole
cannot add it.  This is a variation on the "adding methods to the
superrole" debate.


Well, and of the debate of how to retype an object. I see the .im
method in a position to do the right thing when given the invocant
and the rhs of the assignment. The thing I don't know is how the
syntax looks like. Does one write a STORE block into the method
body? And how is the container involved in the process?



Mind you, once you've defined a supertype, you can freely create new
subtypes of it, and you can add whatever features you want to those
new subtypes, be they lvalue access, new methods, or anything else.


This is unquestioned. But my whole point is to get the Num nicely
embedded in the Complex without touching the Num implementation.



IMHO, the correct way to create an unordered Complex role from a Num
role is to use supertyping to remove the ordering capabilities from
Num, and then use subtyping to add "imaginary component" capabilities
to that.  Yes, this means that a simple partial ordering check between
Complex and Num will result in a "no relation" result; but that's a
shortcoming of the type-checking system, not the type definition
system.


Sorry again, the whole point is to get Num <: Complex in the first
place. How else should a subtyping directed dispatch system pick
methods? No relation can also be achieved with a unrelated
implementation of Complex.


Regards, TSa.
--


Re: supertyping

2006-12-13 Thread TSa

HaloO,

Luke Palmer wrote:

Woah, that was a terrible passage.  Let's try again.  If your
declaration is "role Foo superdoes Bar".

   * it is illegal to add a required method to Foo if Bar doesn't
already implement it or require it


With "required method" you mean an unimplemented method with a {...},
right?


   * any required method for Foo automatically becomes a required
method for Bar, even if it wasn't there before


Yes, I wouldn't allow yada methods in the superrole that are not
implemented in the subrole it is based on. Lifting a yada method
that exists in the subrole is fine of course.


Regards, TSa.
--


Re: supertyping

2006-12-13 Thread Ruud H.G. van Tol
Jonathan Lang schreef:

> what we need here is something that very
> clearly says "the reverse form of 'does'": if A does B, then B ___ A.
> Far more important that if it's one word or two is: "what fits most
> naturally in the gap?"

follows, trails, tracks, enforces, obeys, tolerates, enacts, endorses,
passes, ratifies, allows, permits, takes, occupies, lets, shapes, molds,
munges, shadows, marks, filters, limits, brands, models, forms, sculpts,
figures, profiles, outlines, affects, carves, whittles, cuts, styles,
casts

-- 
Groet, Ruud



supertyping

2006-12-13 Thread Jonathan Lang

Smylers wrote:

Jonathan Lang writes:
> For the record, I think that "superdoes" should be spelled "done_by".

I think it's unlikely that Larry will incorporate any keywords that
contain underscores -- certainly not without at least searching for a
single word that sums up the concept in question.


Entirely possible.  OTOH, what we need here is something that very
clearly says "the reverse form of 'does'": if A does B, then B ___ A.
Far more important that if it's one word or two is: "what fits most
naturally in the gap?"

--
Jonathan "Dataweaver" Lang


Re: supertyping

2006-12-13 Thread Jonathan Lang

TSa wrote:

Secondly I figure you are operating on the extension set a role
defines. That is union produces a supertype aka the larger set
of instances. This is in accordance to the usual type theory
approach. Note that Jonathan operates on the intension set of roles
that is union produces a subtype.


Assuming that I understand the terminology correctly, I'll go further
and say that one of the big differences between roles and subtypes
(using the terms in their perl 6 contexts) is that roles conceptually
operate on intension sets - everything about them is defined in terms
of their set of capabilities - while subtypes (i.e., objects with
"where" clauses) operate on extension sets - they're defined in terms
of the valid set of instances.

Incidently, I'm using terms like "supertype", "subtype", "superrole",
"subrole", etc. strictly due to a lack of a better alternative.
"Supertyping" only leads to a larger set of instances because a
parameter that asks for the supertype is willing to accept a subtype
in its stead.


> Things work a little differently for required methods.  When a
> superrole requires a method be implemented, we (the language
> designers) have a choise to make: it is illegal if the superrole
> requires a method that the subroles don't implement or don't
> themselves require, or it simply adds the new method to the required
> list of the subroles which don't implement it.  I'm inclined to say
> the former, even though it seems a little more brittle.

I can see no brittleness. The role that is supertyped is already
fully defined when the superrole is about to be created. Thus it can
be checked if required but unimplemented methods---that is ones with
a {...} body---are present. These should be rejected on the rational
that the pre-existing code can't retroactively be made to implement
the method.


That's the brittleness: the set of methods that you are permitted to
define in the superrole is restricted to the set of methods in the
role being generalized.  Since Num doesn't include methods re or im,
an attempt to include either method in a Complex superrole would be an
error according to this approach, or it would involve changing Num to
include methods re and im in the alternative approach.

The write-up that I saw in the original message seems to carry the
implication of the alternative approach (of back-editing the new
methods into the subrole).  Note that if you go this route, you really
should allow yourself to define multiple versions of the new method:
one for the superrole, and one for each of the subroles used to define
it.  I'd rather not go this route, though.


>  It means that
> when you are implementing a role in a class, all you have to look at
> for what you need to do is the role and the roles that it includes;
> you don't need to scan the entire source for superroles which
> encompass the one you are implementing.  That is the user-friendly way
> to put it, but there is an analogous argument for independent
> modularity (you don't want the definition of a new superrole to
> invalidate objects that already exist).

Well spoken.


And agreed.


> Things get a little tricky when you think about "does" and "superdoes"
> together:
>
>role Foo does Bar superdoes Baz {...}
>
> What does that mean?  Okay, Foo is a subset of Bar, and a superset of
> Baz.  Already by simply declaring this we have mandated that "Baz does
> Bar".  If Baz doesn't already conform to the interface of Bar, Foo
> better fill in the gaps for it.


Sorry, but no.  If Baz doesn't already conform to the interface of
Bar, you're dead in the water.  "Filling in the gaps" amounts to
changing Baz, which is not in Foo's purview.


In the thread 'signature subtyping and role merging' I have argued
the need of merging method signatures that come in from different
superroles. This is less of a problem when creating superroles because
one can drop the method from the interface and maintain the subtyping
relation. So filling in the gaps is a hard task in general. I mean
in your example Foo has to define all methods required by Bar so that
Baz has at least the default provided by Foo. The gap between Baz and
Bar might also contain unresolvable name clashes that are of course
no problem as long as Bar and Baz are unrelated.


This is why I think that having both "does" and "done_by" declarations
in a role definition is a mistake: the whole thing becomes a cryptic
mess far too quickly.


A thing that is still unclear to me is how the issue of the supertype
intercepting lvalue uses of its methods is resolved. Preferably in a
declarative style. I mean a simple 'is rw' trait will hardly do because
you have to return a complete object of which only an attribute is
written to. The former subtype value has to be made available for the
lvalue method for constructing the new supertype lvalue.


Look at it according to the normal flow: if you subtype a role with
read/write capabilities, the new role cannot have fewer rw
capabili

Re: supertyping

2006-12-13 Thread Ruud H.G. van Tol
TSa schreef:
> Smylers:
>> Jonathan Lang:

>>> For the record, I think that "superdoes" should be spelled
>>> "done_by".
>>
>> I think it's unlikely that Larry will incorporate any keywords that
>> contain underscores -- certainly not without at least searching for a
>> single word that sums up the concept in question.
>
> Starting from 'does' that means 'machen' in German and then
> reversing it to 'vermachen' and looking that up in a dictionary
> I end up at 'bequeath'. So it might read
>
>role Foo bequeaths Bar {...}
>
> But I'm non-native after all.

delegated_to, performed_by, but why not just "by"?
(role Vigilante by Charles Bronson)

-- 
Groet, Ruud



Re: supertyping

2006-12-13 Thread TSa

HaloO,

Smylers wrote:

Jonathan Lang writes:


For the record, I think that "superdoes" should be spelled "done_by".


I think it's unlikely that Larry will incorporate any keywords that
contain underscores -- certainly not without at least searching for a
single word that sums up the concept in question.


Starting from 'does' that means 'machen' in German and then
reversing it to 'vermachen' and looking that up in a dictionary
I end up at 'bequeath'. So it might read

  role Foo bequeaths Bar {...}

But I'm non-native after all.

Regards, TSa.
--


Re: supertyping

2006-12-13 Thread TSa

HaloO Luke,

good to hear from you again!

you wrote:

I'd tend to agree.  This is an important feature of an object system
for me,


And I hope for the rest of @Larry, too.



There is a nice duality in this specification. When you say:

   role Foo does Bar does Baz {...}

You are saying Foo = Bar (*) Baz (*) ...;  # intersection of Bar, Baz,
and the following spec

When you say:

   role Foo superdoes Bar superdoes Baz {...}

You are saying Foo = Bar (+) Baz (+) ...;  # union of Bar, Baz, and
the following spec


First of all it strikes me as odd that you have union as (+) and
intersection as (*). Is that the official definition? I would like
to see (|) and (&) because of the duality to the logical ops. Besides
the fact that (+) could mean Bag addition and (*) the cartesian
product.

Secondly I figure you are operating on the extension set a role
defines. That is union produces a supertype aka the larger set
of instances. This is in accordance to the usual type theory
approach. Note that Jonathan operates on the intension set of roles
that is union produces a subtype.



Things work a little differently for required methods.  When a
superrole requires a method be implemented, we (the language
designers) have a choise to make: it is illegal if the superrole
requires a method that the subroles don't implement or don't
themselves require, or it simply adds the new method to the required
list of the subroles which don't implement it.  I'm inclined to say
the former, even though it seems a little more brittle.


I can see no brittleness. The role that is supertyped is already
fully defined when the superrole is about to be created. Thus it can
be checked if required but unimplemented methods---that is ones with
a {...} body---are present. These should be rejected on the rational
that the pre-existing code can't retroactively be made to implement
the method.



 It means that
when you are implementing a role in a class, all you have to look at
for what you need to do is the role and the roles that it includes;
you don't need to scan the entire source for superroles which
encompass the one you are implementing.  That is the user-friendly way
to put it, but there is an analogous argument for independent
modularity (you don't want the definition of a new superrole to
invalidate objects that already exist).


Well spoken.


Things get a little tricky when you think about "does" and "superdoes" 
together:


   role Foo does Bar superdoes Baz {...}

What does that mean?  Okay, Foo is a subset of Bar, and a superset of
Baz.  Already by simply declaring this we have mandated that "Baz does
Bar".  If Baz doesn't already conform to the interface of Bar, Foo
better fill in the gaps for it.  As for the ..., anything which
conforms to it and Bar ought to be in Foo.  So I think the equation
ends up:

   Foo = Bar (*) (Baz (+) ...);

In words, you are a Foo if you are a Bar and you either are a Baz or
conform to my interface.


In the thread 'signature subtyping and role merging' I have argued
the need of merging method signatures that come in from different
superroles. This is less of a problem when creating superroles because
one can drop the method from the interface and maintain the subtyping
relation. So filling in the gaps is a hard task in general. I mean
in your example Foo has to define all methods required by Bar so that
Baz has at least the default provided by Foo. The gap between Baz and
Bar might also contain unresolvable name clashes that are of course
no problem as long as Bar and Baz are unrelated.



Whew, I was really only going to reply with an "I dig it" sort of
response, but I seem to have written some sort of complete theory. :-)


I missed you in the 'set operations for roles' thread. Your theory is
basically what was discussed there. Unfortunately nothing made it into
the synopsis except the dropping of '|' as the separator for
pre-composed roles. Actually not even the set operators are in S03.


A thing that is still unclear to me is how the issue of the supertype
intercepting lvalue uses of its methods is resolved. Preferably in a
declarative style. I mean a simple 'is rw' trait will hardly do because
you have to return a complete object of which only an attribute is
written to. The former subtype value has to be made available for the
lvalue method for constructing the new supertype lvalue.

Regards, TSa.
--


Re: supertyping

2006-12-13 Thread Smylers
Jonathan Lang writes:

> For the record, I think that "superdoes" should be spelled "done_by".

I think it's unlikely that Larry will incorporate any keywords that
contain underscores -- certainly not without at least searching for a
single word that sums up the concept in question.

Smylers


supertyping

2006-12-13 Thread Jonathan Lang

Luke Palmer wrote:

When you say:

   role Foo superdoes Bar superdoes Baz {...}

You are saying Foo = Bar (+) Baz (+) ...;  # union of Bar, Baz, and
the following spec


For the record, I think that "superdoes" should be spelled "done_by".


It may seem like that should be Foo = (Bar (+) Baz) (*) ...;  (indeed,
I thought that for a while and then corrected myself).  But if
anything that is a Bar is a Foo, anything that is a Baz is a Foo, and
some other stuff is also a Foo (this being the important case), then
that should clearly be a union.


Note that in your usage of the set operations, "Bar (+) Baz" requires
"Bar.^methods (*) Baz.^methods" and "Bar (*) Baz" requires
"Bar.^methods (+) Baz.^methods".  This means that the spec that
follows would act to further limit the methods that end up in Foo,
such that only methods that appear in Bar, Baz, _and_ the spec would
end up in Foo.  (As a secondary issue, your definition of "Bar (+)
Baz" strikes me as counterintuitive; but maybe that's because I tend
to view roles as sets of methods.)


Things work a little differently for required methods.  When a
superrole requires a method be implemented, we (the language
designers) have a choice to make: it is illegal if the superrole
requires a method that the subroles don't implement or don't
themselves require, or it simply adds the new method to the required
list of the subroles which don't implement it.  I'm inclined to say
the former, even though it seems a little more brittle.


I agree with your inclination; but bear in mind that this would make
it illegal to define Complex as a superrole of Num, since Complex has
methods that Num doesn't have.  Also bear in mind that if Complex is a
superrole of Num, a parameter that asks for a Num should by all rights
reject a Complex that's handed to it.

I agree with the idea of being able to define superroles (for lack of
a better name); my problems lie entirely with the proposed
implementation of the concept.  I'll reiterate my alternative:

When using set operations with roles, treat the roles as sets of
methods.  Each set operation defines an anonymous role with the
resulting set of methods; as with any other anonymous thing, it can be
bound to a name.  In addition, a few of the set operations establish
.does() relationships between the new role and the roles used to
create it:

  role C ::= A (+) B # C.does(A) and C.does(B)
  role D::= A (*) B # A.does(D) and B.does(D)
  role E ::= A (-) B # A.does(E)

and so on.  In particular, these lines would be equivalent to

  role C does A does B {}
  role D done_by A done_by B {}
  role E done_by A except B {}

...with the added benefit that you don't have any confusion as to how
"does", "done_by", "except", etc. interact with each other or with the
new spec.  Further, grouping of set operations makes it easy to define
"staged composition":

  (A (+) B) (*) C

would mean "compose an anonymous role as the union of A and B, and
then compose an anonymous role as the intersection of that and C".
Among other things, this would allow method definitions in C to
override those of the anonymous union.

--
Jonathan "Dataweaver" Lang


Re: Introspection and list question

2006-12-13 Thread Gaal Yahas
On Tue, Dec 12, 2006 at 02:19:46PM -0800, Ovid wrote:
> First, how do I do introspection in Pugs?  CPAN's Perl6::Bible hasn't
> been updated in a while, but the various ways to get a list of methods
> (from
> http://search.cpan.org/dist/Perl6-Bible/lib/Perl6/Bible/S12.pod#Introspection
> or http://tinyurl.com/yxukar) don't appear to work.  They all throw
> syntax errors or "No compatible subroutine" errors.

In general you're better off looking at http://spec.pugscode.org/ for
more updated synopses, but in regard to introspection, the APIs aren't
well specced yet.

> Also, I'm having trouble with problem 7 in
> http://www.ic.unicamp.br/~meidanis/courses/mc336/2006s2/funcional/L-99_Ninety-Nine_Lisp_Problems.html
> or http://tinyurl.com/tt9e7.  Basically, it's flattening nested lists
> and I'm embarrassed to admit that I can't figure this out in Perl6. 
> Thoughts?  I've been reading synopses and grepping through Pugs, but to
> no avail.

L stipulates the
results of a gather are flattened to a lazy list. I'm not sure how far
that flattenning goes, but one of these should do the trick, I think
(Pugs does not yet implement gather/take):

sub flatten1 (@list) {
gather for @list {
take $_;
}
}

sub flatten2 (@list) {
gather for @list {
take $_.does("List") ?? flatten2 $_ !! $_;
}
}


-- 
Gaal Yahas <[EMAIL PROTECTED]>
http://gaal.livejournal.com/