Re: class interface of roles

2006-10-11 Thread TSa

HaloO,

Jonathan Lang wrote:

What do you mean by uncomposed class?


The self always refers to the object as instance of the composed
class. Methods are therefore resolving to the outcome of the
composition process. But super in a role refers to methods from
the class definition even when the final method comes from method
combination in the composition process.



I think the word super is already to overloaded to be used for
this purpose.  Setting that aside for now...


Better ideas? Is there a super keyword already? Or do you mean
overloaded in general OO and type speak?



Do you mean that super.blah() appearing in a method defined in a
role A should require that all classes which do A need to provide a
blah implementation?  (or produce a composition time error if they
don't)


Yes, this is exactly what I mean with superclass interface of roles.



I hope not; that's exactly what declaring an unimplemented method in
a role is supposed to do.


My idea is that the type system calculates a type bound for the class
from the definition of the role. That includes attributes and their
accessor methods. It's a matter of taste how explicit this interface
is declared or how much of it is infered.



 (And declaring an implemented method does
the same thing, with the addition that it also suggests an
implementation that the class is free to use or ignore as it sees
fit.)


We have a priority conflict here. The question is if the class or the
role is seeing the other's methods for method combination.



A Role should be able to say to do this Role you need to implement
these methods and have a compile/composition time error if not.


Agreed.


I agree as well. But on a wider scope then just method provision.



(There does need to be a way to call, in a Role A, both the blah
 defined in A and whatever the blah the final class may use.


Yes, this is the subject of the current debate. I'm opting for a
method combination semantics that allows the role to call the class
method.



$self.blah() is the later, $self.A::blah() or similar is likely to
be the former.)


No, there doesn't.  Given that Cclass Foo does A and Crole A does 
B, There needs to be a way to call, in class Foo, both the blah 
defined in Foo, the blah defined in A (so that Foo can reimplement 
A's version as a different method or as part of its own), and the 
blah defined in B;


From the class all composed parts are available through namespace
qualified names. But a role is a classless and instanceless entity.
The self refers to the objects created from the composed class. The role
is not relevant in method dispatch. That is a method is never dispatched
to a role. But the role should be able to participate in the method
definition of the composed class.


and there needs to be a way to call, in role A, 
both the blah defined in Foo and the blah defined B; but role A 
does not need a way to explicitly call a method defined in A.


I'm not sure if I get this right. But as I said above a role can not
be dispatched to. Which method do you think should take precedence
the role's or the class's? That is who is the defining entity in the
method combination process? I would hope it is the role if a as of now
unknown syntax has declared it. Perhaps it should be even the default.
The rational for my claim is that a role is composed several times
and then every class doing the role automatically gets the correct
version. Otherwise all classes are burdened with caring for the role's
part in the method.


 It 
should assume that if Foo overrides A's implementation of blah, Foo 
knows what it's doing; by the principle of least surprise, Foo should

 never end up overriding A's implementation of blah only to find that
 the original implementation is still being used by another of the 
methods acquired from A.


Could you make an example because I don't understand what you mean with
original implementation and how that would be used by role methods.
Method dispatch is on the class never on the role. As far as dispatch is
concerned the role is flattend out. But the question is how the class's
method is composed in the first place.


Regards,
--


Re: class interface of roles

2006-10-11 Thread TSa

HaloO,

Jonathan Lang wrote:

So if I'm reading this right, a class that does both A and B should be
lower in the partial ordering than a class that does just one or the
other.  And if A does B, then you'll never have a class that does just
A without also doing B, which trims out a few possible nodes and paths
from the lattice for practical purposes:

 Any={}
   |  \
   |   \
   |\
   | \
   |  \
 B={y}  C={z}
  / \  |
 /   \ |
/ \|
   /   \   |
  / \  |
 /   \ |
 A|B={x,y}   B|C={y,z}
\ /
 \   /
  \ /
   \   /
\ /
A|B|C={x,y,z}


Correct. The lattice is a structural analysis of the roles.



I note that while the lattice is related to whatever role hierarchies
may or may not exist, it is not the same as them.  In particular,
roles that have no hierarchal relationship to each other _will_ exist
in the same lattice.  In fact, all roles will exist in the same
lattice, on the first row under Any.  Right?


Yes, if they are disjoined structurally. Otherwise intersection roles
appear as nodes under Any.



 Or does the fact that
A does B mean that A would be placed where A|B is, and A|C would
end up in the same node as A|B|C?


To get at the node labeled A|B above you either need a definition

 role A does B { has $.x }

or an outright full definition

 role A { has $.x; has $.y }

So, yes the node should be called A and A|C coincides with A|B|C.

I'm not sure if this ordering of roles can be called duck typing
because it would put roles that have the same content into the
same lattice node. The well known bark method of Dog and Tree
comes to mind. But the arrow types of the methods will be different.
One has type :(Dog -- Dog) the other :(Tree -- Tree) and a joined
node will have type :(DogTree -- Dog|Tree). This might just give
enough information to resolve the issues surrounding the DogTree
class.



By most specific, you'd mean closest to the top?


No, closer to the bottom. The join operator | of the lattice produces
subtypes with a larger interface that is more specific. It's like
the more derived class in a class hierarchy.


Regards, TSa.
--


Runtime role issues

2006-10-11 Thread Ovid
Hi all,

I posted this to Perl6 users, but I was Warnocked, it was the wrong list, or 
both.  Here's another stab at it.

In doing a bit of work with traits (roles) in Perl 5 
(http://perlmonks.org/?node_id=577477), I've realized some edge cases which 
could be problematic.

First, when a role is applied to a class at runtime, a instance of that class 
in another scope may specifically *not* want that role.  Is there a way of 
restricting a role to a particular lexical scope short of applying that role to 
instances instead of classes?

Second, how can I remove roles from classes?  I've create some code which adds 
an is_selected method to some classes but when I'm done, I'd like top easily 
remove that role.  How do I do that?  Seems closely related to my first 
question, but it's still a distinct issue, I think.

Third, http://dev.perl.org/perl6/doc/design/syn/S12.html says:

  You can also mixin a precomposed set of roles:

$fido does Sentry | Tricks | TailChasing | Scratch;

Should that be the following?

$fido does Sentry  Tricks  TailChasing  Scratch;

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



Re: Runtime role issues

2006-10-11 Thread TSa

HaloO,

Ovid wrote:

Third, http://dev.perl.org/perl6/doc/design/syn/S12.html says:

  You can also mixin a precomposed set of roles:

$fido does Sentry | Tricks | TailChasing | Scratch;

Should that be the following?

$fido does Sentry  Tricks  TailChasing  Scratch;


If you follow my idea of a type lattice build from roles with | as join
and  as meet operator these two mean something completely different.
The first is the join or union of the roles while the second is their
meet or intersection. The first creates a subtype of the roles the
second a supertype. But the typishness of roles is debated.

Regards, TSa.
--


Re: Runtime role issues

2006-10-11 Thread TSa

HaloO,

Ovid wrote:

First, when a role is applied to a class at runtime, a instance of
that class in another scope may specifically *not* want that role.
Is there a way of restricting a role to a particular lexical scope
short of applying that role to instances instead of classes?


I think you'll need an intermediate class that you use to apply your
role. Classes are open and that implies the possibility to merge
further roles into them. But this applies for all users of the class.
How this works when there are already instances I don't know.



Second, how can I remove roles from classes?


Is that a wise thing to do? Roles are not assigned and removed
as a regular operation. What is your use case?


Regards, TSa.
--


P5's s[pat][repl] syntax is dead

2006-10-11 Thread Aaron Sherman

@larry[0] wrote:


Log:
P5's s[pat][repl] syntax is dead, now use s[pat] = repl


Wow, I really missed this one! That's a pretty big thing to get my head 
around. Are embedded closures in the string handled correctly so that:


s:g[\W] = qq{\\{$/}};

Will do what I seem to be expecting it will?

How will that be defined in the Perl6-based parser? Will macros be able 
to act as an LVALUE and modify their RVALUE in this way, or is this just 
some unholy magic in the parser?



+ s[pattern] = doit()
+ s[pattern] = eval doit()

[...]

+There is no syntactic sugar here, so in order to get deferred
+evaluation of the replacement you must put it into a closure.  The
+syntactic sugar is provided only by the quotelike forms.

[...]

+This is not a normal assigment, since the right side is evaluated each
+time the substitution matches (much like the pseudo-assignment to declarators
+can happen at strange times).  It is therefore treated as a thunk, that is,
+as if it has implicit curlies around it.  In fact, it makes no sense at
+all to say
+
+s[pattern] = { doit }


Please clarify quotelike forms, since to my untrained eye, the above 
appeared to be contradictory at first (I read quotelike forms as s/// 
not s{...}).


Very interesting.



Re: Runtime role issues

2006-10-11 Thread Paul Seamons
 First, when a role is applied to a class at runtime, a instance of that
 class in another scope may specifically *not* want that role.  Is there a
 way of restricting a role to a particular lexical scope short of applying
 that role to instances instead of classes?

Seems like you could use an empty intermediate role to accomplish the same 
thing while leaving the shared class alone.

Shared Class A
Mixin Role B

Class C isa A does B
Class D isa A

Shared Class A is unmodified.

Otherwise, I think that any runtime modification of a class should affect all 
instances and future instances of that class.

On closer inspection, is it even possible to add a Role to a Class at runtime?  
 
I thought that Class and Role composition outside of compile time resulted in 
a new pseudo Class for the subsequent instances of that composition - in 
which case the original Class would remain unmodified.

Paul


Re: P5's s[pat][repl] syntax is dead

2006-10-11 Thread Larry Wall
On Wed, Oct 11, 2006 at 10:32:13AM -0400, Aaron Sherman wrote:
: @larry[0] wrote:
: 
: Log:
: P5's s[pat][repl] syntax is dead, now use s[pat] = repl
: 
: Wow, I really missed this one! That's a pretty big thing to get my head 
: around. Are embedded closures in the string handled correctly so that:
: 
:   s:g[\W] = qq{\\{$/}};
: 
: Will do what I seem to be expecting it will?

Yes, the right side is implicitly closurized and evaluated repeatedly
by the left side.

: How will that be defined in the Perl6-based parser? Will macros be able 
: to act as an LVALUE and modify their RVALUE in this way, or is this just 
: some unholy magic in the parser?

This is just a macro with a fancy is parsed rule, I think.  It eats the =
in complete disregard for precedence.  Nothing much to generalize, I think.

: + s[pattern] = doit()
: + s[pattern] = eval doit()
: [...]
: +There is no syntactic sugar here, so in order to get deferred
: +evaluation of the replacement you must put it into a closure.  The
: +syntactic sugar is provided only by the quotelike forms.
: [...]
: +This is not a normal assigment, since the right side is evaluated each
: +time the substitution matches (much like the pseudo-assignment to 
: declarators
: +can happen at strange times).  It is therefore treated as a thunk, that 
: is,
: +as if it has implicit curlies around it.  In fact, it makes no sense at
: +all to say
: +
: +s[pattern] = { doit }
: 
: Please clarify quotelike forms, since to my untrained eye, the above 
: appeared to be contradictory at first (I read quotelike forms as s/// 
: not s{...}).

s{...} is also a quotelike form.  Basically I mean anything where
you get to choose your own quote characters, whether or not they are
brackets.

: Very interesting.

Yeah, we whacked on possible syntaxes a goodly long time on IRC the
other night.  Trying to balance out history and visuals and semantics
and failure modes was all quite interesting, but in the absence of
more Unicode keys on the keyboard I'm liking this notation pretty
well, particularly since we've already used pseudo assignment in
other places to thunkize the right side.

Larry


signature subtyping and role merging

2006-10-11 Thread TSa

HaloO,

with my idea of deriving a type lattice from all role definitions
the problem of subtyping signatures arises. Please help me to think
this through. Consider

role Foo
{
   sub blahh(Int, Int) {...}
}
role Bar
{
   sub blahh(Str) {...}
}
role Baz does Foo does Bar # Foo|Bar lub
{
  # sub blahh(IntStr,Int?) {...}
}

The role Baz has to be the lub (least upper bound) of Foo and Bar.
That is the join of two nodes in the lattice. This means first of
all the sub blahh has to be present. And its signature has to be
in a subtype relation : to :(Int,Int) and :(Str). Note that
Int : IntStr and Int|Str : Int. The normal contravariant subtyping
rules for functions gives

+- : ---+
||
   :(IntStr,Int?) : :(Int,Int)
  |  |
  +--- : ---+
and

+- : ---+
||
   :(IntStr,Int?) : :(Str)

I hope you see the contravariance :)

The question mark shall indicate an optional parameter that
allows the subtype to be applicable in both call sites that
have one or two arguments.

The choice of glb for the first parameter makes the sub in Baz
require the implementor to use the  supertype of Int and Str
which in turn allows the substitution of Int and Str arguments
which are subtypes---that is types with a larger interface.

Going the other way in the type lattice the meet FooBar of the
two roles Foo and Bar is needed. But here the trick with the
optional parameter doesn't work and it is impossible to reconcile
the two signatures. This could simply mean to drop sub blahh from
the interface. But is there a better way? Perhaps introducing a
multi?

Apart from the arity problem the lub Int|Str works for the first
parameter:

+- : ---+
||
   :(Int|Str,Int)  : :(Int,Int)
  |  |
  +--- : ---+

+ : ---+
|   |
   :(Int|Str) : :(Str)


Regards, TSa.
--


Re: class interface of roles

2006-10-11 Thread Jonathan Lang

TSa wrote:

Jonathan Lang wrote:
 What do you mean by uncomposed class?

The self always refers to the object as instance of the composed
class. Methods are therefore resolving to the outcome of the
composition process. But super in a role refers to methods from
the class definition even when the final method comes from method
combination in the composition process.


Still not following.  Can you give an example?


 I hope not; that's exactly what declaring an unimplemented method in
 a role is supposed to do.

My idea is that the type system calculates a type bound for the class
from the definition of the role. That includes attributes and their
accessor methods. It's a matter of taste how explicit this interface
is declared or how much of it is inferred.


Note that it's entirely possible for attributes to not make it into
the final class, if the accessor methods get redefined in such a way
as to remove reference to the attributes.  This is part of the notion
that roles supply an outline of what the class should do, but only the
class actually supplies the definitive details of how to do it.

As I see it: is and does declarations in a role impose
requirements on the final class: it must derive from another class
(is), or it must compose another role (does).  method and has
are each one part requirement and one part suggestion: for method,
the class is required to include a method that matches the given name
(which, of course, includes the method's signature), and a particular
closure is suggested that the class can accept or override.

For has, the class is required to provide accessor methods
corresponding to the attribute's read/write capabilities (a rw method
if it's a rw attribute; a regular method if it's a regular attribute;
and no method if it's a private attribute); like any other method, a
closure is suggested that the class may accept or override.  In
addition, the role suggests that a given attribute be added to the
class' state information.  This suggestion is implicitly accepted if
any of the methods that are used by the final class refer to the
attribute; it is implicitly rejected if none of them do.  The same
rule applies to private methods.

Thus, the only things that I'd recommend using to calculate a
type-boundary would be the superclasses (provided by is) and the
method names (provided by method and has).


  (And declaring an implemented method does
 the same thing, with the addition that it also suggests an
 implementation that the class is free to use or ignore as it sees
 fit.)

We have a priority conflict here. The question is if the class or the
role is seeing the other's methods for method combination.


I believe that I address this later on; if not, please clarify.


 (There does need to be a way to call, in a Role A, both the blah
  defined in A and whatever the blah the final class may use.

Yes, this is the subject of the current debate. I'm opting for a
method combination semantics that allows the role to call the class
method.


Agreed.


 $self.blah() is the later, $self.A::blah() or similar is likely to
 be the former.)

 No, there doesn't.  Given that Cclass Foo does A and Crole A does
 B, There needs to be a way to call, in class Foo, both the blah
 defined in Foo, the blah defined in A (so that Foo can reimplement
 A's version as a different method or as part of its own), and the
 blah defined in B;

 From the class all composed parts are available through namespace
qualified names. But a role is a classless and instanceless entity.
The self refers to the objects created from the composed class. The role
is not relevant in method dispatch. That is a method is never dispatched
to a role. But the role should be able to participate in the method
definition of the composed class.


Also agreed.  In particular, I'm referring to _how_ a role should
participate in the method definition of the composed class; I am not
referring to method dispatch, which is limited to the class hierarchy.


 and there needs to be a way to call, in role A,
 both the blah defined in Foo and the blah defined B; but role A
 does not need a way to explicitly call a method defined in A.

I'm not sure if I get this right. But as I said above a role can not
be dispatched to. Which method do you think should take precedence
the role's or the class's? That is who is the defining entity in the
method combination process?


I agree with the idea behind the current definition of this: if the
class provides its own definition for a method, that should take
precedence over the role's definition.  If it doesn't, then it adopts
the role's definition as its own.


I would hope it is the role if a as of now
unknown syntax has declared it. Perhaps it should be even the default.
The rational for my claim is that a role is composed several times
and then every class doing the role automatically gets the correct
version. Otherwise all classes are burdened with caring for the role's
part in the method.


Huh?


  

Re: signature subtyping and role merging

2006-10-11 Thread mark . a . biggar
This is the dog does bark vs tree does bark problem.  You can assume that 
the two methods blahh have naything semantically to do with each other at 
all.  Unless ther is a specif annotation from the programmer creating the Role 
union that they are the same you must assume that they are different.  
Therefore your proposed signiture merge is nonsense in the general case.  Even 
if the signature are the same the only case where you are justified in assuming 
that are the same method is if both composed Roles inherited the method from 
a common ancestor and even then you must solve the diamond inheritence problem.

--
Mark Biggar
[EMAIL PROTECTED]
[EMAIL PROTECTED]
[EMAIL PROTECTED]

 -- Original message --
From: TSa [EMAIL PROTECTED]
 HaloO,
 
 with my idea of deriving a type lattice from all role definitions
 the problem of subtyping signatures arises. Please help me to think
 this through. Consider
 
 role Foo
 {
 sub blahh(Int, Int) {...}
 }
 role Bar
 {
 sub blahh(Str) {...}
 }
 role Baz does Foo does Bar # Foo|Bar lub
 {
# sub blahh(IntStr,Int?) {...}
 }
 
 The role Baz has to be the lub (least upper bound) of Foo and Bar.
 That is the join of two nodes in the lattice. This means first of
 all the sub blahh has to be present. And its signature has to be
 in a subtype relation : to :(Int,Int) and :(Str). Note that
 Int : IntStr and Int|Str : Int. The normal contravariant subtyping
 rules for functions gives
 
  +- : ---+
  ||
 :(IntStr,Int?) : :(Int,Int)
|  |
+--- : ---+
 and
 
  +- : ---+
  ||
 :(IntStr,Int?) : :(Str)
 
 I hope you see the contravariance :)
 
 The question mark shall indicate an optional parameter that
 allows the subtype to be applicable in both call sites that
 have one or two arguments.
 
 The choice of glb for the first parameter makes the sub in Baz
 require the implementor to use the  supertype of Int and Str
 which in turn allows the substitution of Int and Str arguments
 which are subtypes---that is types with a larger interface.
 
 Going the other way in the type lattice the meet FooBar of the
 two roles Foo and Bar is needed. But here the trick with the
 optional parameter doesn't work and it is impossible to reconcile
 the two signatures. This could simply mean to drop sub blahh from
 the interface. But is there a better way? Perhaps introducing a
 multi?
 
 Apart from the arity problem the lub Int|Str works for the first
 parameter:
 
  +- : ---+
  ||
 :(Int|Str,Int)  : :(Int,Int)
|  |
+--- : ---+
 
  + : ---+
  |   |
 :(Int|Str) : :(Str)
 
 
 Regards, TSa.
 -- 




Re: signature subtyping and role merging

2006-10-11 Thread Jonathan Lang

On 10/11/06, TSa [EMAIL PROTECTED] wrote:

HaloO,

with my idea of deriving a type lattice from all role definitions
the problem of subtyping signatures arises. Please help me to think
this through. Consider

role Foo
{
sub blahh(Int, Int) {...}
}
role Bar
{
sub blahh(Str) {...}
}
role Baz does Foo does Bar # Foo|Bar lub
{
   # sub blahh(IntStr,Int?) {...}
}


Please, no attempts to merge signatures.  Instead, use multiple
dispatch (though technically this doesn't kick in until the role is
composed into a class).  Thus:

 role Foo
 {
 multi blahh(Int, Int) {...}
 }
 role Bar
 {
 multi blahh(Str) {...}
 }
 role Baz does Foo does Bar # Foo|Bar lub
 {
 # multi blahh(Int, Int) {...}
 # multi blahh(Str) {...}
 }

Remember that the name and the signature are used together to identify
the routine for dispatch and composition purposes.

Also, sub is an odd choice to use while illustrating role composition;
while subs _are_ allowed in roles AFAIK, they're generally not put
there.  Methods and submethods are by far more common.

--
Jonathan Dataweaver Lang


Re: Runtime role issues

2006-10-11 Thread Ovid
--- TSa [EMAIL PROTECTED] wrote:
  First, when a role is applied to a class at runtime, a instance of
  that class in another scope may specifically *not* want that role.
  Is there a way of restricting a role to a particular lexical scope
  short of applying that role to instances instead of classes?
 
 I think you'll need an intermediate class that you use to apply your
 role. Classes are open and that implies the possibility to merge
 further roles into them. But this applies for all users of the class.
 How this works when there are already instances I don't know.

Ah, that makes sense.
 
  Second, how can I remove roles from classes?
 
 Is that a wise thing to do? Roles are not assigned and removed
 as a regular operation. What is your use case?

I don't think I have a clear use case here because the examples that
come to mind all involve adding and then quickly removing the extra
behaviors when I'm done with them.  That's going to be fraught with
bugs.

The intermediate class solves the problem but it instantly suggests
that we have a new design pattern we have to remember.  Basically, if
I can't lexically scope the additional behavior a role offers, I
potentially need to remove the role or use the intermediate class
pattern.

I suppose one could look at this as separation of concerns.  If I
have an MVC framework, instances of objects in the M, V, or C portions
might want to exhibit different behaviors, depending upon what I'm
doing with them, but I don't necessarily want those behaviors to bleed
over to the other layers of my application.  Whether or not this is a
clean way of looking at the problem, I don't know.

Cheers,
Ovid

--

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


Re: Synposis 26 - Documentation [alpha draft]

2006-10-11 Thread Damian Conway

Jonathan Lang wrote:


The only thing that I'd like to see changed would be to allow a more
flexible syntax for formatting codes - in particular, I'd rather use
something analogous to the 'embedded comments' described in S02,
replacing the leading # with an appropriate capital letter (as defined
by Unicode) and insisting on a word break just prior to it.


It was a deliberate decision to restrict the delimiters to angles. Unlike 
embedded comments, formatting codes are predominantly embedded in text, not 
code, so it's important to keep them easy-to-locate (i.e. with a consistent 
delimiter) and not to allow too many syntaxes (which increases the chance of 
unintended codes in normal text).


A leading word break is not really practical either, since documenters will 
need to use codes in the middle of words:


PractIise (and then practIice) saying GarEccedilon!




I'd also prefer a more Wiki-like dialect at some point (e.g.,
'__underlined text__', '_italicized text_' and '*bold*' instead of
'Uunderlined text', 'Iitalicized text' and 'Bbold'); but that
can wait.


That's Kwid. Which Ingy has proposed as a standard Perldoc dialect.
You'll be able to flip into kwid mode (for Perldoc parsers that support it) 
using:

=begin kwid

=end kwid


Damian


s[pattern] = { doit } illegal, why?

2006-10-11 Thread Jonathan Lang

While I agree with most of the changes made to the s[]... notation,
there's one oddity that I just spotted:

S05 says:

This is not a normal assigment, since the right side is
evaluated each time the substitution matches (much like the
pseudo-assignment to declarators can happen at strange times).
It is therefore treated as a thunk, that is, as if it has
implicit curlies around it. In fact, it makes no sense at all
to say

s[pattern] = { doit }

because that would try to substitute a closure into the string.


So I can't say something like

   s[(\d+)!] = { my $num = 1; $num *= $_ for 0..$0; return $num; }

or

   s:s:g[(\w+): (\d+) dB] =
 @() - $name, $num {
   $num = exp($num/10, 10);
   say $name has excessive wattage: $num Watts if $num  100;

   $name: $num Watts;
 }

or

   s:s:g[, (\w+): (.+) ,] = @() - $key, $val { $key = $val }

?  That seems like a pretty significant limitation.  Could closures be
an exception to the implicit curlies rule?  That is: if you supply
your own closure on the right, the substitution algorithm accepts it
as is; if you supply anything else, it gets wrapped in a closure as
described.

--
Jonathan Dataweaver Lang


Re: s[pattern] = { doit } illegal, why?

2006-10-11 Thread Larry Wall
On Wed, Oct 11, 2006 at 05:55:45PM -0700, Jonathan Lang wrote:
: While I agree with most of the changes made to the s[]... notation,
: there's one oddity that I just spotted:
: 
: S05 says:
: This is not a normal assigment, since the right side is
: evaluated each time the substitution matches (much like the
: pseudo-assignment to declarators can happen at strange times).
: It is therefore treated as a thunk, that is, as if it has
: implicit curlies around it. In fact, it makes no sense at all
: to say
: 
: s[pattern] = { doit }
: 
: because that would try to substitute a closure into the string.
: 
: So I can't say something like
: 
:s[(\d+)!] = { my $num = 1; $num *= $_ for 0..$0; return $num; }

 s[(\d+)!] = { my $num = 1; $num *= $_ for 0..$0; return $num; }
 s[(\d+)!] = { my $num = 1; $num *= $_ for 0..$0; return $num; }.()
 s[(\d+)!] = do { my $num = 1; $num *= $_ for 0..$0; return $num; }

: or
: 
:s:s:g[(\w+): (\d+) dB] =
:  @() - $name, $num {
:$num = exp($num/10, 10);
:say $name has excessive wattage: $num Watts if $num  100;
: 
:$name: $num Watts;
:  }

 s:s:g[(\w+): (\d+) dB] = do
   given @() - [$name, $num] {
 $num = exp($num/10, 10);
 say $name has excessive wattage: $num Watts if $num  100;

 $name: $num Watts;
   }

: or
: 
:s:s:g[, (\w+): (.+) ,] = @() - $key, $val { $key = $val }

 s:s:g[, (\w+): (.+) ,] = - $key, $val { $key = $val }.(@())
 s:s:g[, (\w+): (.+) ,] = do for @().each - $key, $val { $key = $val }

: ?  That seems like a pretty significant limitation.  Could closures be
: an exception to the implicit curlies rule?  That is: if you supply
: your own closure on the right, the substitution algorithm accepts it
: as is; if you supply anything else, it gets wrapped in a closure as
: described.

Could do that too (and there's even precedent with attribute defaults),
but outlawing it (at least for now) keeps people from cargo culting
P5's s{foo}{bar} into P6's s{foo}={bar}.

Larry


Re: s[pattern] = { doit } illegal, why?

2006-10-11 Thread Larry Wall
On Wed, Oct 11, 2006 at 06:29:00PM -0700, Larry Wall wrote:
:   s:s:g[, (\w+): (.+) ,] = - $key, $val { $key = $val }.(@())

Hmm, that won't work, since @() is a single argument.  It'd have to be one of:

s:s:g[, (\w+): (.+) ,] = - [$key, $val] { $key = $val }.(@())
s:s:g[, (\w+): (.+) ,] = - $key, $val { $key = $val }.(|@())

Larry


Re: s[pattern] = { doit } illegal, why?

2006-10-11 Thread Jonathan Lang

In short, nearly every case where I'm looking to use a raw closure
can be handled almost as easily by prefacing it with Cdo (if the
block doesn't take parameters) or Cdo given (if it does).  A bit
more wordy than I'd like, but acceptable; it still reads well.
Although I'd recommend pointing this option out in S05, right after
you say that s[pat] = { doit() } won't work.

On 10/11/06, Larry Wall [EMAIL PROTECTED] wrote:

 s:s:g[, (\w+): (.+) ,] = do for @().each - $key, $val { $key = $val }


Minor point: Since the right side gets called for each left-side
match, isn't the C.each redundant?  For that matter, isn't the
Cfor overkill as well?  C@() will only ever have two elements per
call, after all...


: Could closures be
: an exception to the implicit curlies rule?  That is: if you supply
: your own closure on the right, the substitution algorithm accepts it
: as is; if you supply anything else, it gets wrapped in a closure as
: described.

Could do that too (and there's even precedent with attribute defaults),
but outlawing it (at least for now) keeps people from cargo culting
P5's s{foo}{bar} into P6's s{foo}={bar}.


This would be the ye olde code doesn't do a text substitution
anymore issue, right?  And there _is_ still the possibility of
permitting it in some later subversion of Perl 6, once people have
gotten Perl 5 out of their systems...

--
Jonathan Dataweaver Lang


Re: Synposis 26 - Documentation [alpha draft]

2006-10-11 Thread Damian Conway

Dave Whipp wrote:

I'm not a great fan of this concept of reservation when there is no 
mechanism for its enforcement (and this is perl...).


What makes you assume there will be no mechanism for enforcement? The standard 
Pod parser (of which I have a 95% complete Perl 5 implementation) will 
complain bitterly--as in cyanide--when unknown pure-upper or pure-lower block 
names are used.


The whole point of reserving these namespaces is not to prevent users from 
misusing them, but to ensure that when we eventually get around to using a 
particular block name, and those same users start screaming about it, we can 
mournfully point to the passage in the original spec and silently shake our 
heads. ;-)


Damian