Properties

0 views
Skip to first unread message

Luke Palmer

unread,
Nov 27, 2003, 2:02:30 AM11/27/03
to Language List
Here's a series of questions/confirmation requests about how properties
work (but specifically run-time properties, not traits):

Use C<but> to assign a property to a I<value>:

$a = $b but foo; # $a has property foo, $b does not

Properties are just out-of-band methods:

if $x.foo { print "$x has property foo" }
$x.bar = 1; # Or $x = $x but bar

Which makes meta-properties (eg. C<nothing>) easy to fathom.

(That one seems a little dangerous from an error checking point of view.
Is there such thing as a 'method not found' error?)

To get a hash of out-of-band properties, use either the C<btw> or the
C<props> method, depending on whether our language designers are feeling
cute.

Luke

Larry Wall

unread,
Nov 27, 2003, 4:21:23 PM11/27/03
to Language List
On Thu, Nov 27, 2003 at 12:02:30AM -0700, Luke Palmer wrote:
: Here's a series of questions/confirmation requests about how properties

: work (but specifically run-time properties, not traits):
:
: Use C<but> to assign a property to a I<value>:
:
: $a = $b but foo; # $a has property foo, $b does not

That is correct.

: Properties are just out-of-band methods:

I had been thinking of the value as an object of a singleton class
that has an extra method. In other words, properties would merely be
mixins. But that would imply that the property hides any real method
of the same name. On the other hand, it would be nice to be able to
promote an inert property to an active method. But I think that has
to be done on purpose, not by accidentally having a method of the same
name. So I suspect it needs to be an error to have a name collision
between a property and a method unless the method specifically says
that it's emulating a property. This will fit it more with Perl 6's
idea of how to compose classes, We won't be doing mixins--we'll be
doing something better. It resembles something in the literature
called "Traits", but we're generalizing that, and calling it "roles".
(Oh, apparently C# 2.0 is thinking along the same lines with its
"partial classes", though I haven't looked at those in detail.)

A role is like a chunk of class that can be incorporated into other
classes. It's a bit like mixins, but it's safer than mixins because
it detects name collisions at class composition time. There's also a
resemblence to generics, insofar as a role is at least parameterized on
its super class, since a given role can be incorporated into different
classes. (And if a role can be parameterized on one class, there's no
reason in principle it can't be parameterized on multiple classes.)

The basic underlying philosophy is that classes should not be used
both to create objects and to specify the scope of reusable code.
At least, they should not be forced to do both of those. So I think
Perl 6 will attempt to divorce those concerns.

Needless to say, Apocalypse 12 will talk a lot more about roles.
But let me just say that I'm currently thinking of a property as a
funny role composed into a singleton class. As a role composition,
we get control over any name collisions.

: if $x.foo { print "$x has property foo" }


: $x.bar = 1; # Or $x = $x but bar

Or maybe the .bar notation is only for rvalues, and to create a
property you have to say:

$x but= bar;

: Which makes meta-properties (eg. C<nothing>) easy to fathom.

That would certainly be easy to do under a role-playing implementation.

: (That one seems a little dangerous from an error checking point of view.


: Is there such thing as a 'method not found' error?)

Certainly, as long as we limit the .bar notation to rvalues or to
lvalues on already-created properties. And in fact, we may be limiting
the creation of properties to predeclared names, so that even

return 0 but ture;

can be caught at compile time.

: To get a hash of out-of-band properties, use either the C<btw> or the


: C<props> method, depending on whether our language designers are feeling
: cute.

The feeling of this language designer at this moment is that
properties aren't kept in a hash. They're indistiguishable from
other attributes/methods except insofar as they are composed into the
singleton class from roles that happen to be marked as property roles.
If we have a .props or .btw method of accessing that set of methods,
it's just syntactic sugar for ordinary method introspection with a
funny selection criterion.

Now it's certainly possible that non-active properties will be
optimized to a hash of non-active values internally, but we shouldn't
really think of them that way. We should think of them as methods
of a singleton class, or more precisely, of a role that cuts across
a number of singleton classes. In that respect it's a bit like
aspect-oriented programming, only it happens conceptually at compile
time, without having to write a bunch of method wrappers.

Larry

P.S. I think we deserve a $rubyometer-- for bypassing mixins.

Simon Cozens

unread,
Nov 27, 2003, 7:01:37 PM11/27/03
to perl6-l...@perl.org
la...@wall.org (Larry Wall) writes:
> P.S. I think we deserve a $rubyometer-- for bypassing mixins.

I think you deserve loud and wild applause for an object model I want
to use Right Now Dammit.

--
Overall there is a smell of fried onions. (fnord)

Paul Hodges

unread,
Nov 27, 2003, 11:08:05 PM11/27/03
to Larry Wall, Language List

--- Larry Wall <la...@wall.org> wrote:
> ... in fact, we may be limiting the creation of properties

> to predeclared names, so that even
>
> return 0 but ture;
>
> can be caught at compile time.

Excellent, so long as we can define new properties explicitly.
At the moment, I draw a complete blank on how to do that.

Somebody drop me an example?


__________________________________
Do you Yahoo!?
Free Pop-Up Blocker - Get it now
http://companion.yahoo.com/

Larry Wall

unread,
Nov 28, 2003, 12:14:30 AM11/28/03
to Language List
On Thu, Nov 27, 2003 at 08:08:05PM -0800, Paul Hodges wrote:
:
: --- Larry Wall <la...@wall.org> wrote:
: > ... in fact, we may be limiting the creation of properties
: > to predeclared names, so that even
: >
: > return 0 but ture;
: >
: > can be caught at compile time.
:
: Excellent, so long as we can define new properties explicitly.
: At the moment, I draw a complete blank on how to do that.
:
: Somebody drop me an example?

Well, it hasn't been defined yet. Likely there will be some syntax

my property foo;

that is shorthand for something vaguely resembling

my role foo is property {
has $.foo is rw;
}

However, universal properties like "true" and "tainted" are likely to
be declared implicitly everywhere:

property *true;
property *tainted;

Less common properties are likely to be imported into a lexical scope.
So you'd likely only declare properties that you use entirely by
yourself, or that you intend to export. If you really want to mess
everyone up, though, you could certainly declare things like:

property *ture;

Actually, there's something to be said for declaring all property names
as globals, since they cut across object classes, and you wouldn't want
to add two different properties of the same name to a given object.
Or maybe we can tag property names with the scope in which they're
declared somehow.

Larry

Smylers

unread,
Nov 28, 2003, 2:49:15 AM11/28/03
to perl6-l...@perl.org
Larry Wall writes:

> : if $x.foo { print "$x has property foo" }
> : $x.bar = 1; # Or $x = $x but bar
>
> Or maybe the .bar notation is only for rvalues, and to create a
> property you have to say:
>
> $x but= bar;

I think that would be an unPerlish restriction; people who know how to
read a property would also expect to be able to set it in the same way.

> ... as long as we limit the .bar notation to rvalues or to lvalues on


> already-created properties. And in fact, we may be limiting the
> creation of properties to predeclared names,

That sounds like a much better solution.

And thanks for taking the time to answer Luke's questions so fully.

Smylers

Paul Hodges

unread,
Nov 29, 2003, 11:50:57 AM11/29/03
to Larry Wall, Language List

--- Larry Wall <la...@wall.org> wrote:
> On Thu, Nov 27, 2003 at 08:08:05PM -0800, Paul Hodges wrote:
> : --- Larry Wall <la...@wall.org> wrote:
> : > ... in fact, we may be limiting the creation of properties
> : > to predeclared names, so that even
> : >
> : > return 0 but ture;
> : >
> : > can be caught at compile time.
> :
> : Excellent, so long as we can define new properties explicitly.
> : At the moment, I draw a complete blank on how to do that.
> :
> : Somebody drop me an example?
>
> Well, it hasn't been defined yet. Likely there will be some syntax
>
> my property foo;
>
> that is shorthand for something vaguely resembling
>
> my role foo is property {
> has $.foo is rw;
> }

That's cool. You might even consider making declarable properties a
little *less* convenient, though.... Of course, I bet you *have*
considered it, lol.

> However, universal properties like "true" and "tainted" are likely to
> be declared implicitly everywhere:
>
> property *true;
> property *tainted;
>
> Less common properties are likely to be imported into a lexical
> scope.

hmm... lexical properties....I've read the rest of the message, and I
see how this could be a problem. Just to be clear on it, what exactly
would it mean for a property or trait to be lexical? If a value or
container with that aspect gets passed out of that scope, what happens?

Wouldn't an object efectively provide a virtual "scope" of its own?

> So you'd likely only declare properties that you use entirely by
> yourself, or that you intend to export. If you really want to mess
> everyone up, though, you could certainly declare things like:
>
> property *ture;

And I can certainly see someone doing just that.
False laziness, false impatience, false hubris.... :)

> Actually, there's something to be said for declaring all property
> names as globals, since they cut across object classes, and you
> wouldn't want to add two different properties of the same name to
> a given object.

Agreed.
Maybe the syntax looks something like this:

class Foo has Scalar bar is rw = undef; # suplies a default value;

That would allow you to add the property to the class with a default
value at compile time, wouldn't it? Then you could modify objects:

my $o = Foo.new;
$o.foo but= "stuff";

It would also make it inherently class scoped, and would fail to
compile if someone in another module had already declared a property
bar. Right?

> Or maybe we can tag property names with the scope in which they're
> declared somehow.

o. That's hairy, isn't it?
Yes, I think it would be useful...but what's the upshot? The value of
$o.foo is dependent on scope? Hmm.... My first reaction was to frown
and shudder, but maybe that's short-sighted. Any lexical variable's
value is always dependent on scope.

our $foo = 1;
{ my $foo = 2;
print $foo; # 2
}
print $foo; # 1

I'm just not sure how I like the idea of that applying to properties.

our $o = Foo.new();
$o.foo but= "global?";
dostuff::with($o); # module scope, different value?

Wouldn't that utterly mangle the principle of least surprise?

> Larry

Paul Hodges

unread,
Nov 29, 2003, 12:13:32 PM11/29/03
to Smylers, perl6-l...@perl.org

--- Smylers <Smy...@stripey.com> wrote:
> Larry Wall writes:
>
> > : if $x.foo { print "$x has property foo" }
> > : $x.bar = 1; # Or $x = $x but bar
> >
> > Or maybe the .bar notation is only for rvalues, and to create a
> > property you have to say:
> >
> > $x but= bar;
>
> I think that would be an unPerlish restriction; people who know
> how to read a property would also expect to be able to set it in
> the same way.

I'd think that would depend on the current status of strictures.
Assuming no strictures at all, I'd rather expect Perl to autovivify
properties much the way hash elements are created when you assign a
value to a previously nonexistant key, but that's exactly the reason I
*NEVER* leave strictures *or* warnings off, even in short little
one-shot programs. If it's complex enough to save to a file, it's worth
adding a couple of "use" statements to make sure I don't do something
carelessly stupid.

And if I try to set $o.bar when there's no bar property predefined on
class Foo of which $o is a member, does that mean this singular object
gets this new property, or does Perl have to redesign class Foo on the
fly, and suddenly distribute a bar property across all Foo object
extant? Does it imply a scalar type from your supplied value of 1? What
if you later try to "push $o.bar, 2"? Ugh.

Accordingly, I'd expect Perl to stick out it's tongue, cross it's arms,
and refuse to play with me if I tried to set a property of which it was
not previously aware. Personally, I'm a little scared of how this would
work without strictures on. The DWIMmyness we expect from Perl would
beat the dickens out of any possible optimization, though that's going
to happen a lot with unstrictured code anyway....

On the other hand, properties are probably best scoped to a class, and
a class definition is almost always best placed in a class file, which
has strictures on by default. Again, I recommend some syntax
class-scoped and compile-timed to declare properties, such as

class Foo has Array bar is rw = undef;

> > ... as long as we limit the .bar notation to rvalues or to
> > lvalues on already-created properties. And in fact, we may
> > be limiting the creation of properties to predeclared names,
>
> That sounds like a much better solution.

Agreed.

> And thanks for taking the time to answer Luke's questions so fully.
> Smylers

Ditto. :)

Larry Wall

unread,
Nov 29, 2003, 2:06:22 PM11/29/03
to perl6-l...@perl.org
On Sat, Nov 29, 2003 at 09:13:32AM -0800, Paul Hodges wrote:
: --- Smylers <Smy...@stripey.com> wrote:
: > Larry Wall writes:
: >
: > > : if $x.foo { print "$x has property foo" }
: > > : $x.bar = 1; # Or $x = $x but bar
: > >
: > > Or maybe the .bar notation is only for rvalues, and to create a
: > > property you have to say:
: > >
: > > $x but= bar;
: >
: > I think that would be an unPerlish restriction; people who know
: > how to read a property would also expect to be able to set it in
: > the same way.
:
: I'd think that would depend on the current status of strictures.
: Assuming no strictures at all, I'd rather expect Perl to autovivify
: properties much the way hash elements are created when you assign a
: value to a previously nonexistant key, but that's exactly the reason I
: *NEVER* leave strictures *or* warnings off, even in short little
: one-shot programs. If it's complex enough to save to a file, it's worth
: adding a couple of "use" statements to make sure I don't do something
: carelessly stupid.

I don't feel any great need to de-stricture this in non-strict scopes.
I think people who want hash semantics can use hashes. :-)

: And if I try to set $o.bar when there's no bar property predefined on


: class Foo of which $o is a member, does that mean this singular object
: gets this new property,

Yes, in fact it gets a new anonymous class that is derived from its
current class.

: or does Perl have to redesign class Foo on the


: fly, and suddenly distribute a bar property across all Foo object
: extant?

No, the whole point of properties is that they cut across class lines.
It doesn't matter whether you're flying first class or coach, you
might acquire the property "drunk" at run time.

: Does it imply a scalar type from your supplied value of 1? What


: if you later try to "push $o.bar, 2"? Ugh.

If we allowed undeclared properties, it'd have to assume scalars. But
if we require declaration of properties as a kind of role, then the
role declaration could declare whatever data structure it wants. In
fact, a role can declare multiple attributes, which implies that we
could conceivably have complex struct-like properties:

return undef but error(ENOMAKESENSE, "What the heck?", 42);

Under the hash view of properties, that has to be a scalar reference
to an object, but under the role view, it can merely be a set of
components of the undef object without a separate scalar existence.

Q: Mr. Undef, are you an error object?
A: No, but I play one on TV.

: Accordingly, I'd expect Perl to stick out it's tongue, cross it's arms,


: and refuse to play with me if I tried to set a property of which it was
: not previously aware. Personally, I'm a little scared of how this would
: work without strictures on. The DWIMmyness we expect from Perl would
: beat the dickens out of any possible optimization, though that's going
: to happen a lot with unstrictured code anyway....

I think roles are something we don't want to force novices to learn about
until they're ready for it. They can use existing roles without understanding
what they're doing, but they shouldn't go around creating roles, just as
they shouldn't go around creating objects without knowing what they're
doing.

: On the other hand, properties are probably best scoped to a class, and


: a class definition is almost always best placed in a class file, which
: has strictures on by default. Again, I recommend some syntax
: class-scoped and compile-timed to declare properties, such as
:
: class Foo has Array bar is rw = undef;

No, if you're gonna force people to declare properties in association with
a class, then they're no different from attributes. The whole point of
properties is that they're bound to an object independently of class
definition. You *can* incorporate them into a class explicitly, of course,
since they're just roles:

class Foo does bar {...}

For example, any class that wants to cache its boolean value might say

class Fancy is Simple does true {...}

Then it can recalculate its boolean value only when it needs to, rather
than every time the object is used in a boolean context.

I didn't mention it in my previous article, but roles are also a
generalization of interfaces. That is, interfaces are a degenerate
case of roles, when the role doesn't supply any implementation, which
forces the class incorporating the role to supply an implementation.
(Property roles don't fall into this category because the implied

has $.bar is rw;

also implies the .bar accessor to it, which is all the implementation
it needs.)

: > > ... as long as we limit the .bar notation to rvalues or to


: > > lvalues on already-created properties. And in fact, we may
: > > be limiting the creation of properties to predeclared names,
: >
: > That sounds like a much better solution.
:
: Agreed.
:
: > And thanks for taking the time to answer Luke's questions so fully.
: > Smylers
:
: Ditto. :)

You're very welcome.

I'm just grateful that I feel up to it physically. If you ever want to
increase your appreciation for the simple acts of eating and drinking,
try doing without for a couple of months...

Larry

Larry Wall

unread,
Nov 29, 2003, 2:21:06 PM11/29/03
to Language List
On Sat, Nov 29, 2003 at 08:50:57AM -0800, Paul Hodges wrote:
: hmm... lexical properties....I've read the rest of the message, and I

: see how this could be a problem. Just to be clear on it, what exactly
: would it mean for a property or trait to be lexical? If a value or
: container with that aspect gets passed out of that scope, what happens?

It would mean that that aspect becomes unnameable, even if a different
lexical name looks like it. (But note that exportation can cause
two distinct lexical scopes to share the same name.)

: Wouldn't an object efectively provide a virtual "scope" of its own?

Depends on what you mean by effective. There's a sense in which the
object knows nothing about the properties that are going to be bound
to it someday, or whether there might be two conflicting properties
of the same name. There is the danger of ad hoc polymorphism.

: Maybe the syntax looks something like this:


:
: class Foo has Scalar bar is rw = undef; # suplies a default value;

Well, it's "does" to incorporate a role, but again, you generally wouldn't
apply a property to a class at compile time.

: That would allow you to add the property to the class with a default


: value at compile time, wouldn't it? Then you could modify objects:
:
: my $o = Foo.new;
: $o.foo but= "stuff";

That'd be adding an anonymous property to the foo attributes. You want:

$o but= foo("stuff");

: It would also make it inherently class scoped, and would fail to


: compile if someone in another module had already declared a property
: bar. Right?

You don't want properties inherently class scoped. Except when you do.

: > Or maybe we can tag property names with the scope in which they're


: > declared somehow.
:
: o. That's hairy, isn't it?
: Yes, I think it would be useful...but what's the upshot? The value of
: $o.foo is dependent on scope? Hmm.... My first reaction was to frown
: and shudder, but maybe that's short-sighted. Any lexical variable's
: value is always dependent on scope.
:
: our $foo = 1;
: { my $foo = 2;
: print $foo; # 2
: }
: print $foo; # 1
:
: I'm just not sure how I like the idea of that applying to properties.
:
: our $o = Foo.new();
: $o.foo but= "global?";
: dostuff::with($o); # module scope, different value?
:
: Wouldn't that utterly mangle the principle of least surprise?

The principle of least surprise is also utterly mangled by accidental
polymorphism. We can prevent that by complaining when we detect the
attempt to declare or import two different properties of the same name.

Larry

Paul Hodges

unread,
Nov 29, 2003, 3:40:10 PM11/29/03
to Larry Wall, perl6-l...@perl.org

--- Larry Wall <la...@wall.org> wrote:
> On Sat, Nov 29, 2003 at 09:13:32AM -0800, Paul Hodges wrote:
> : --- Smylers <Smy...@stripey.com> wrote:
> : > Larry Wall writes:
> : >
> : > > : if $x.foo { print "$x has property foo" }
> : > > : $x.bar = 1; # Or $x = $x but bar
> : > >
> : > > Or maybe the .bar notation is only for rvalues, and to create a
> : > > property you have to say:
> : > >
> : > > $x but= bar;
> : >
> : > I think that would be an unPerlish restriction; people who know
> : > how to read a property would also expect to be able to set it in
> : > the same way.
> :
> : I'd think that would depend on the current status of strictures.
> : Assuming no strictures at all, I'd rather expect Perl to autovivify
> : properties much the way hash elements are created when you assign a
> : value to a previously nonexistant key, but that's exactly the
> : reason I *NEVER* leave strictures *or* warnings off, even in short
> : little one-shot programs. If it's complex enough to save to a file,
> : it's worth adding a couple of "use" statements to make sure I don't
> : do something carelessly stupid.
>
> I don't feel any great need to de-stricture this in non-strict
> scopes. I think people who want hash semantics can use hashes. :-)

lol -- good. :)
I'm all for there being more than one way to do it, and for not playing
Code Police (God knows I'd do my share of time in the BigHouse...), but
I have to agree with you on this one.

> : And if I try to set $o.bar when there's no bar property predefined
> : on class Foo of which $o is a member, does that mean this singular
> : object gets this new property,
>
> Yes, in fact it gets a new anonymous class that is derived from its
> current class.

Ah -- implicit adoption by the new foster parent. That's kind of neat,
but it confuses me. Does that mean you're leaning more toward allowing
undeclared properties, or just that you're still trying to give both
sides of the argument thorough consideration?

Just for my vote, I want to be able to declare new properties, but
would rather not be able to accidentally set $o.ture.

> : or does Perl have to redesign class Foo on the
> : fly, and suddenly distribute a bar property across all Foo object
> : extant?
>
> No, the whole point of properties is that they cut across class
> lines.
> It doesn't matter whether you're flying first class or coach, you
> might acquire the property "drunk" at run time.

The adoption mentioned above handles this, but even though properties
cut across class lines, I want to avoid those silly boo-boos.
While

if $me.flying {
$me.drunk = "scotch"; # inebriation source
$me.dunk = true; # I do when I can
$scotch.dunk = "fig newton"; # the only acceptable value!
$newton.dunk = true; # only way I eat 'em
$scotch.drunk = true; # oops, it's all gone :(
}

might be all well-and-good, I don't want my $newton to be able to be
set <C>$newton.drunk = true</C> by accident because in all that
pseudo-repetitive code I mistyped and the compiler let me get away with
it. Code bits like this are common enough that I want every bit of
assistance I can get.

I'd rather be able to add the .dunk and .drunk properties to classes in
which they are appropriate, even after the fact of the class
definition, but I definitely don't want that to make it possible to
drink my $newtons, nor get them inebriated.

Am I too far over the edge here?

> : Does it imply a scalar type from your supplied value of 1? What
> : if you later try to "push $o.bar, 2"? Ugh.
>
> If we allowed undeclared properties, it'd have to assume scalars.

Okie.

> But if we require declaration of properties as a kind of role,
> then the role declaration could declare whatever data structure
> it wants. In fact, a role can declare multiple attributes, which
> implies that we could conceivably have complex struct-like
> properties:
>
> return undef but error(ENOMAKESENSE, "What the heck?", 42);
>
> Under the hash view of properties, that has to be a scalar reference
> to an object, but under the role view, it can merely be a set of
> components of the undef object without a separate scalar existence.
>
> Q: Mr. Undef, are you an error object?
> A: No, but I play one on TV.

That's beautiful, and very sensible. Where can I read up on roles a
little more?



> : Accordingly, I'd expect Perl to stick out it's tongue, cross it's
> : arms, and refuse to play with me if I tried to set a property of
> : which it was not previously aware. Personally, I'm a little scared
> : of how this would work without strictures on. The DWIMmyness we
> : expect from Perl would beat the dickens out of any possible
> : optimization, though that's going to happen a lot with unstrictured
> : code anyway....
>
> I think roles are something we don't want to force novices to learn
> about until they're ready for it. They can use existing roles
> without understanding what they're doing, but they shouldn't go
> around creating roles, just as they shouldn't go around creating
> objects without knowing what they're doing.

True, which is why I want to learn more about them, lol.
I need to get started making my mistakes in virtual code now, before I
start writing real P6 code, so I can get over the hump in the learning
curve. :)

> : On the other hand, properties are probably best scoped to a class,
> : and a class definition is almost always best placed in a class
> : file, which has strictures on by default. Again, I recommend some
> : syntax class-scoped and compile-timed to declare properties, such
> : as
> :
> : class Foo has Array bar is rw = undef;
>
> No, if you're gonna force people to declare properties in association
> with a class, then they're no different from attributes. The whole
> point of properties is that they're bound to an object independently
> of class definition. You *can* incorporate them into a class
> explicitly, of course, since they're just roles:
>
> class Foo does bar {...}

"does" rings a bell. :)

But I thought properties *were* attributes, basically....
Hrmm. So properties are "object" attributes unrelated to class?
Ok, floundering again. Lemme think this through.

my $x = undef but true;

undef is a value. $x is just a joe scalar. No class, no "real" object.
I get that. We're just fiddling with the details of $x's value, and
assigning the globally available property of true to it so that

print "foo" is $x;

will print, even though it's value is undef. So far so good.
Now, I want to say

my $y = undef but zippy;

The compiler politely tells me that zippy isn't valid, and that perhaps
I should RTFM. Ok, that's good, but I really want to be able to return
a zippy undef as a response to those impertinent sub calls, so that I
can both refuse to talk to them and still have a zippy response,
effectively having my cake and eating it, too.

Such wittiness requires a little forethought, though.
I have to predeclare what exactly I mean by "zippy", or at least
generally enough that the compiler deems it a valid comeback.
See? I'm catching up.

I'll get back to this in a bit.

> For example, any class that wants to cache its boolean value might
> say
>
> class Fancy is Simple does true {...}
>
> Then it can recalculate its boolean value only when it needs to,
> rather than every time the object is used in a boolean context.

Ok. So

our property *true;

makes sense out of class context, and can be overwritten by explicit
class values for true, but

our property *zippy;

would probably be a bit foolish, since there can be only one such, and
trying to redeclare it by loading two modules with that in them would
crash, but wouldn't storing the context of a property by like
recursively giving the properties some properties of their own? Is that
a can of worms we really want to open?

> I didn't mention it in my previous article, but roles are also a
> generalization of interfaces. That is, interfaces are a degenerate
> case of roles, when the role doesn't supply any implementation, which
> forces the class incorporating the role to supply an implementation.
> (Property roles don't fall into this category because the implied
>
> has $.bar is rw;
>
> also implies the .bar accessor to it, which is all the implementation
> it needs.)

All I've seen on interfaces is a few lines in passing. Anyone got a
reference where I can RTFM and thin the spam to the list? :)

> : > And thanks for taking the time to answer Luke's questions so
> : > fully.
> :

> : Ditto. :)
>
> You're very welcome.
>
> I'm just grateful that I feel up to it physically. If you ever want
> to increase your appreciation for the simple acts of eating and
> drinking, try doing without for a couple of months...
>
> Larry


lol -- I'll keep praying for ya, and I'm sure I'm not alone.

And please, I don't need any *increase* in my appreciation of calorie
intake!!! >:o)

Paul Hodges

unread,
Nov 29, 2003, 3:53:50 PM11/29/03
to Larry Wall, Language List

--- Larry Wall <la...@wall.org> wrote:
> On Sat, Nov 29, 2003 at 08:50:57AM -0800, Paul Hodges wrote:
> : hmm... lexical properties....I've read the rest of the message,
> : and I see how this could be a problem. Just to be clear on it,
> : what exactly would it mean for a property or trait to be lexical?
> : If a value or container with that aspect gets passed out of that
> : scope, what happens?
>
> It would mean that that aspect becomes unnameable, even if a
> different lexical name looks like it. (But note that exportation
> can cause two distinct lexical scopes to share the same name.)

To quote a better man than me, "ow, me noggin."
Do you mean unreference-able by name?
And "exportation"???

> : Wouldn't an object efectively provide a virtual "scope" of its own?
>
> Depends on what you mean by effective. There's a sense in which the
> object knows nothing about the properties that are going to be bound
> to it someday, or whether there might be two conflicting properties
> of the same name. There is the danger of ad hoc polymorphism.

Don't you just love the way the Greek "polymorphism" just comfortably
sidles up to the literal Latin "ad hoc"? :) Almost makes me feel like
I was back in college, staying up way too late talking about the nature
of reality, except that this is both more "concrete", if you will, and
usually more confusing, lol.

What I mean is (I guess) that there should only be one $o.bar, and it
sounds like you're saying that's not the case. Please fix my bleeding
brain on this one?

> : Maybe the syntax looks something like this:
> :
> : class Foo has Scalar bar is rw = undef; # suplies a default
>

> Well, it's "does" to incorporate a role, but again, you generally
> wouldn't apply a property to a class at compile time.

You say "again". :)
As a general apology to anyone besides me who might be inconvenienced
by it, my mail is on a bounce or three before I get it, and may go out
as strangely, so I suspect you recieved my second message before my
first. You certainly responded to that one first.



> : That would allow you to add the property to the class with a
> : default value at compile time, wouldn't it? Then you could modify
> : objects:
> :
> : my $o = Foo.new;
> : $o.foo but= "stuff";
>
> That'd be adding an anonymous property to the foo attributes. You
> want:
>
> $o but= foo("stuff");

Ah! Okie.

> : It would also make it inherently class scoped, and would fail to
> : compile if someone in another module had already declared a
> : property bar. Right?
>
> You don't want properties inherently class scoped. Except when you
> do.

Right. I'm with you.

> : > Or maybe we can tag property names with the scope in which
> : > they're declared somehow.
> :
> : o. That's hairy, isn't it?
> : Yes, I think it would be useful...but what's the upshot? The value
> : of $o.foo is dependent on scope? Hmm.... My first reaction was to
> : frown and shudder, but maybe that's short-sighted. Any lexical
> : variable's value is always dependent on scope.
> :
> : our $foo = 1;
> : { my $foo = 2;
> : print $foo; # 2
> : }
> : print $foo; # 1
> :
> : I'm just not sure how I like the idea of that applying to
> : properties.
> :
> : our $o = Foo.new();
> : $o.foo but= "global?";
> : dostuff::with($o); # module scope, different value?
> :
> : Wouldn't that utterly mangle the principle of least surprise?
>
> The principle of least surprise is also utterly mangled by accidental
> polymorphism. We can prevent that by complaining when we detect the
> attempt to declare or import two different properties of the same
> name.
>
> Larry

Which does make better sense. :)

Paul Hodges

unread,
Nov 29, 2003, 4:07:30 PM11/29/03
to Hod...@writeme.com, Larry Wall, perl6-l...@perl.org

--- Paul Hodges <ydb...@yahoo.com> wrote:
> print "foo" is $x;

With deeply sincere apologies, that should have been

print "foo" if $x;

Larry Wall

unread,
Nov 29, 2003, 6:08:25 PM11/29/03
to perl6-l...@perl.org
On Sat, Nov 29, 2003 at 12:40:10PM -0800, Paul Hodges wrote:
: --- Larry Wall <la...@wall.org> wrote:
: > Yes, in fact it gets a new anonymous class that is derived from its

: > current class.
:
: Ah -- implicit adoption by the new foster parent. That's kind of neat,
: but it confuses me. Does that mean you're leaning more toward allowing
: undeclared properties, or just that you're still trying to give both
: sides of the argument thorough consideration?

I'm not doing either of those things... :-)

: Just for my vote, I want to be able to declare new properties, but


: would rather not be able to accidentally set $o.ture.

That's how it works.

: > : or does Perl have to redesign class Foo on the


: > : fly, and suddenly distribute a bar property across all Foo object
: > : extant?
: >
: > No, the whole point of properties is that they cut across class
: > lines.
: > It doesn't matter whether you're flying first class or coach, you
: > might acquire the property "drunk" at run time.
:
: The adoption mentioned above handles this, but even though properties
: cut across class lines, I want to avoid those silly boo-boos.
: While
:
: if $me.flying {
: $me.drunk = "scotch"; # inebriation source
: $me.dunk = true; # I do when I can
: $scotch.dunk = "fig newton"; # the only acceptable value!
: $newton.dunk = true; # only way I eat 'em
: $scotch.drunk = true; # oops, it's all gone :(
: }
:
: might be all well-and-good, I don't want my $newton to be able to be
: set <C>$newton.drunk = true</C> by accident because in all that
: pseudo-repetitive code I mistyped and the compiler let me get away with
: it. Code bits like this are common enough that I want every bit of
: assistance I can get.

None of those are legal if the object doesn't have the property yet.
Only C<but> has the power to add roles at run time.

: I'd rather be able to add the .dunk and .drunk properties to classes in


: which they are appropriate, even after the fact of the class
: definition, but I definitely don't want that to make it possible to
: drink my $newtons, nor get them inebriated.
:
: Am I too far over the edge here?

Nope.

: > But if we require declaration of properties as a kind of role,


: > then the role declaration could declare whatever data structure
: > it wants. In fact, a role can declare multiple attributes, which
: > implies that we could conceivably have complex struct-like
: > properties:
: >
: > return undef but error(ENOMAKESENSE, "What the heck?", 42);
: >
: > Under the hash view of properties, that has to be a scalar reference
: > to an object, but under the role view, it can merely be a set of
: > components of the undef object without a separate scalar existence.
: >
: > Q: Mr. Undef, are you an error object?
: > A: No, but I play one on TV.
:
: That's beautiful, and very sensible. Where can I read up on roles a
: little more?

Well, it's not nearly as general as we're making it, but the
inspiration for it comes in part from the "Traits" paper:

http://www.cse.ogi.edu/~black/publications/TR_CSE_02-012.pdf

Basically, I'm attempting to take their concept and unify it with
properties, interfaces, generics, aspects, and mixins. Among other
things...

: But I thought properties *were* attributes, basically....

We're using "attributes" to mean instance variables defined by the
class. Properties used to be considered something else, but now this
role-playing I'm talking about makes them more like real attributes
that happen to be added at run time. Except it doesn't modify any
named class to do so, but only the anonymous class associated with
the object in question. (And if there isn't an anonymous class yet,
it generates one.)

: Hrmm. So properties are "object" attributes unrelated to class?

Unrelated to the original named class.

: Ok, floundering again. Lemme think this through.


:
: my $x = undef but true;
:
: undef is a value. $x is just a joe scalar. No class, no "real" object.
: I get that. We're just fiddling with the details of $x's value, and
: assigning the globally available property of true to it so that
:
: print "foo" is $x;
:
: will print, even though it's value is undef. So far so good.
: Now, I want to say
:
: my $y = undef but zippy;
:
: The compiler politely tells me that zippy isn't valid, and that perhaps
: I should RTFM. Ok, that's good, but I really want to be able to return
: a zippy undef as a response to those impertinent sub calls, so that I
: can both refuse to talk to them and still have a zippy response,
: effectively having my cake and eating it, too.
:
: Such wittiness requires a little forethought, though.
: I have to predeclare what exactly I mean by "zippy", or at least
: generally enough that the compiler deems it a valid comeback.
: See? I'm catching up.

Yep.

: I'll get back to this in a bit.


:
: > For example, any class that wants to cache its boolean value might
: > say
: >
: > class Fancy is Simple does true {...}
: >
: > Then it can recalculate its boolean value only when it needs to,
: > rather than every time the object is used in a boolean context.
:
: Ok. So
:
: our property *true;
:
: makes sense out of class context, and can be overwritten by explicit
: class values for true, but
:
: our property *zippy;
:
: would probably be a bit foolish, since there can be only one such, and
: trying to redeclare it by loading two modules with that in them would
: crash, but wouldn't storing the context of a property by like
: recursively giving the properties some properties of their own? Is that
: a can of worms we really want to open?

I don't see what the problem is. Once anyone has declared *zippy, everyone
has a global zippy, and it's the same global zippy everywhere. You only
get separate zippys if in more than one place you say things like:

our property zippy;
my property zippy;

Either of those declarations may be exported, however, in which case
the importing modules shares the zippy, just as it would share an
exported variable.

: > I didn't mention it in my previous article, but roles are also a


: > generalization of interfaces. That is, interfaces are a degenerate
: > case of roles, when the role doesn't supply any implementation, which
: > forces the class incorporating the role to supply an implementation.
: > (Property roles don't fall into this category because the implied
: >
: > has $.bar is rw;
: >
: > also implies the .bar accessor to it, which is all the implementation
: > it needs.)
:
: All I've seen on interfaces is a few lines in passing. Anyone got a
: reference where I can RTFM and thin the spam to the list? :)

Don't have a doc, but see Java for an example. Basically it's a
clunky way of sneaking a little bit of multiple inheritance into a
language that only supports single inheritance.

Larry

Larry Wall

unread,
Nov 29, 2003, 6:23:52 PM11/29/03
to Language List
On Sat, Nov 29, 2003 at 12:53:50PM -0800, Paul Hodges wrote:
:
: --- Larry Wall <la...@wall.org> wrote:
: > On Sat, Nov 29, 2003 at 08:50:57AM -0800, Paul Hodges wrote:
: > : hmm... lexical properties....I've read the rest of the message,
: > : and I see how this could be a problem. Just to be clear on it,
: > : what exactly would it mean for a property or trait to be lexical?
: > : If a value or container with that aspect gets passed out of that
: > : scope, what happens?
: >
: > It would mean that that aspect becomes unnameable, even if a
: > different lexical name looks like it. (But note that exportation
: > can cause two distinct lexical scopes to share the same name.)
:
: To quote a better man than me, "ow, me noggin."
: Do you mean unreference-able by name?
: And "exportation"???

Exportation is just aliasing some name inside a scope to somewhere
outside the scope. Importatation is the same operation from the viewpoint
of the importing scope.

Perl 5 didn't allow exportation of lexicals because typeglobs only dealt
with package variables, not lexical variables. In Perl 6 we'll be able
to alias both lexicals and package variables. That implies that a lexically
scoped name can be exported, whether it refers to a variable or something
else like a property.

: > : Wouldn't an object efectively provide a virtual "scope" of its own?


: >
: > Depends on what you mean by effective. There's a sense in which the
: > object knows nothing about the properties that are going to be bound
: > to it someday, or whether there might be two conflicting properties
: > of the same name. There is the danger of ad hoc polymorphism.
:
: Don't you just love the way the Greek "polymorphism" just comfortably
: sidles up to the literal Latin "ad hoc"? :) Almost makes me feel like
: I was back in college, staying up way too late talking about the nature
: of reality, except that this is both more "concrete", if you will, and
: usually more confusing, lol.

Well, I didn't make up that particular term. It's right out of the OO faq.

: What I mean is (I guess) that there should only be one $o.bar, and it


: sounds like you're saying that's not the case. Please fix my bleeding
: brain on this one?

It means if there are two conflicting definitions of the same name, it's
considered ambiguous where both versions of name are visible. Otherwise,
the name means the property that is in scope, and you can't see the "other"
property that happens to have the same name elsewhere. In other words,
any time you say property "bar", it's really a shorthand for a longer
name that may include a package name or lexical scope. The aliasing of
the short name to the actual name has to be unambiguous or it's illegal.

Larry

Paul Hodges

unread,
Nov 29, 2003, 9:46:23 PM11/29/03
to Larry Wall, perl6-l...@perl.org
> : but it confuses me. Does that mean you're leaning more toward
> : allowing undeclared properties, or just that you're still trying
> : to give both sides of the argument thorough consideration?
>
> I'm not doing either of those things... :-)

Yayy! :)

> : Just for my vote, I want to be able to declare new properties, but
> : would rather not be able to accidentally set $o.ture.
>
> That's how it works.

Ok. So are we sticking with the

our property *foo;

syntax?

And does that mean property is a type? ~smirk~

> : if $me.flying {
> : $me.drunk = "scotch"; # inebriation source
> : $me.dunk = true; # I do when I can
> : $scotch.dunk = "fig newton"; # the only acceptable value!
> : $newton.dunk = true; # only way I eat 'em
> : $scotch.drunk = true; # oops, it's all gone :(
> : }

> : . . . .


>
> None of those are legal if the object doesn't have the property yet.
> Only C<but> has the power to add roles at run time.

Which works as well for objects of class Foo as for undef. Ok.
But it only works if the property/role being added is one the compiler
already knows, in which case it just "promotes" the object to a new
pseudo-class with the new property. Yes?

> . . . .


> : That's beautiful, and very sensible. Where can I read up on roles a
> : little more?
>
> Well, it's not nearly as general as we're making it, but the
> inspiration for it comes in part from the "Traits" paper:
>
> http://www.cse.ogi.edu/~black/publications/TR_CSE_02-012.pdf

This box isn't well configured, so I forwarded this to work. I'll see
it Monday.



> Basically, I'm attempting to take their concept and unify it with
> properties, interfaces, generics, aspects, and mixins. Among other
> things...

You have a talent for designing Swiss Army Knives. :)



> : But I thought properties *were* attributes, basically....
>
> We're using "attributes" to mean instance variables defined by the
> class. Properties used to be considered something else, but now this
> role-playing I'm talking about makes them more like real attributes
> that happen to be added at run time. Except it doesn't modify any
> named class to do so, but only the anonymous class associated with
> the object in question. (And if there isn't an anonymous class yet,
> it generates one.)

Wrapper-classes?



> : Hrmm. So properties are "object" attributes unrelated to class?
>
> Unrelated to the original named class.

On that note, just for curiosity -- does undef have a class?

> . . . .


> : our property *zippy;
> :
> : would probably be a bit foolish, since there can be only one such,
> : and trying to redeclare it by loading two modules with that in them
> : would crash, but wouldn't storing the context of a property by like
> : recursively giving the properties some properties of their own? Is
> : that a can of worms we really want to open?
>
> I don't see what the problem is. Once anyone has declared *zippy,
> everyone has a global zippy, and it's the same global zippy
> everywhere. You only get separate zippys if in more than one place
> you say things like:
>
> our property zippy;
> my property zippy;

I was just saying that the compiler would bail if you said

module Foo { our property *zippy; }
module Bar { our property *zippy; }

( Hmm... I think I need to reread the rule on semicolons. :)



> Either of those declarations may be exported, however, in which case
> the importing modules shares the zippy, just as it would share an
> exported variable.

Ok, exported as in the Exporter module.

> . . . .


> : All I've seen on interfaces is a few lines in passing. Anyone got a
> : reference where I can RTFM and thin the spam to the list? :)
>
> Don't have a doc, but see Java for an example. Basically it's a
> clunky way of sneaking a little bit of multiple inheritance into a
> language that only supports single inheritance.
>
> Larry


Ok, if Java interfaces will do as an example/template, I understand,
and I *LIKE* it. In fact, I like it much better than Java (but then, I
always have. ;o)

Paul Hodges

unread,
Nov 29, 2003, 10:04:51 PM11/29/03
to Larry Wall, Language List
> : And "exportation"???
>
> Exportation is just aliasing some name inside a scope to somewhere
> outside the scope. Importatation is the same operation from the
> viewpoint of the importing scope.

I just wasn't thinking clearly when you said it the first time.

> Perl 5 didn't allow exportation of lexicals because typeglobs only
> dealt with package variables, not lexical variables. In Perl 6
> we'll be able to alias both lexicals and package variables. That
> implies that a lexically scoped name can be exported, whether it
> refers to a variable or something else like a property.

So a role defined in one module can be scoped lexically so as not to
trample another module's namespace, and the use()'er of that module can
elect whether ot not to export that role into his own space for
implicit use on other objects. Accordingly, if Foo implements a zippy
property, and Bar does as well, and both are polite enough about it to
make then the equivelent of EXPORT_OK, then I can say

use Foo 'zippy';
use Bar;
use Baz;

my Baz @ray = ( Baz.new() );
$ray[0] but= zippy;

But just for the sake of clear understanding, suppose I pushed onto
@ray a whole passle of Foos and Bars and Bazzes. All the Foos and
Bazzes could use Foo's zippy. If I say

push @ray, Bar.new();
$ray[-1].zippy = "woohoo!";

then Bar's zippy would be used by default, right?
Now the hard question.

my $tst = Baz.new();

How do I set a zippy property on $tst explicitly using Bar's zippy?
Is that possible? Baz has no zippy, so I'd have to use "but", right?
How about

$tst but= Bar.zippy; # is zippy a class property?
$tst but= Bar::zippy; # is zippy a class method? do I need a & ??

Or is this even possible?

> : . . . .


> : Don't you just love the way the Greek "polymorphism" just
> : comfortably sidles up to the literal Latin "ad hoc"? :)

> : . . . .


>
> Well, I didn't make up that particular term. It's right out of the
> OO faq.

Oh, I know. I didn't mean to imply there was anything wrong with it.
It just struck me as funny. I have a classics degree, and I have to
take it out and walk it every now and the. :)



> : What I mean is (I guess) that there should only be one $o.bar, and
> : it sounds like you're saying that's not the case. Please fix my
> : bleeding brain on this one?
>
> It means if there are two conflicting definitions of the same name,
> it's considered ambiguous where both versions of name are visible.
> Otherwise, the name means the property that is in scope, and you
> can't see the "other" property that happens to have the same name
> elsewhere. In other words, any time you say property "bar", it's
> really a shorthand for a longer name that may include a package name
> or lexical scope. The aliasing of the short name to the actual name
> has to be unambiguous or it's illegal.
>
> Larry

Ok. "it's illegal" was what I was looking for. :)

Paul Hodges

unread,
Nov 29, 2003, 10:08:40 PM11/29/03
to Hod...@writeme.com, Larry Wall, Language List

With apologies, I'm already seeing blunders. *sigh*

> my Baz @ray = ( Baz.new() );

No reason to type that. Should be

my @ray = ( Baz.new() );

Luke Palmer

unread,
Nov 29, 2003, 11:10:45 PM11/29/03
to Hod...@writeme.com, Larry Wall, Language List
Paul Hodges writes:

> Larry Wall writes:
> > Perl 5 didn't allow exportation of lexicals because typeglobs only
> > dealt with package variables, not lexical variables. In Perl 6
> > we'll be able to alias both lexicals and package variables. That
> > implies that a lexically scoped name can be exported, whether it
> > refers to a variable or something else like a property.
>
> So a role defined in one module can be scoped lexically so as not to
> trample another module's namespace, and the use()'er of that module can
> elect whether ot not to export that role into his own space for
> implicit use on other objects. Accordingly, if Foo implements a zippy
> property, and Bar does as well, and both are polite enough about it to
> make then the equivelent of EXPORT_OK, then I can say
>
> use Foo 'zippy';
> use Bar;
> use Baz;
>
> my Baz @ray = ( Baz.new() );
> $ray[0] but= zippy;
>
> But just for the sake of clear understanding, suppose I pushed onto
> @ray a whole passle of Foos and Bars and Bazzes. All the Foos and
> Bazzes could use Foo's zippy. If I say
>
> push @ray, Bar.new();
> $ray[-1].zippy = "woohoo!";
>
> then Bar's zippy would be used by default, right?

I think so. If Bar has a zippy method, then that zippy method is called
instead of setting the property. Which are really the same thing. So,
um, yes.

> Now the hard question.
>
> my $tst = Baz.new();
>
> How do I set a zippy property on $tst explicitly using Bar's zippy?

Probably just

$tst but= Bar::zippy;

I imagine that properties work just like other names, so they can be
stuck in package symbol tables, too.

> Is that possible? Baz has no zippy, so I'd have to use "but", right?
> How about
>
> $tst but= Bar.zippy; # is zippy a class property?
> $tst but= Bar::zippy; # is zippy a class method? do I need a & ??

Yeah, the latter one. Note that class methods are called like:

Bar.zippy;

now, so there's no ambiguity. Hooray.

> Or is this even possible?

Please, we're talking about Perl... :-)

Luke

Gordon Henriksen

unread,
Nov 30, 2003, 3:08:05 AM11/30/03
to Larry Wall, Language List
On Thursday, November 27, 2003, at 04:21 , Larry Wall wrote:

> (Oh, apparently C# 2.0 is thinking along the same lines with its
> "partial classes", though I haven't looked at those in detail.)

My reading was that C# 2's partial classes were merely a mechanism for
placing long method definitions in separate files; i.e. purely a
structural convenience to the compiler's user, with absolutely no effect
at runtime.

http://www.c-sharppro.com/features/2003/10/cs200310bw_f/cs200310bw_f.asp

search for "Partial types are simple"

Gordon Henriksen
mali...@mac.com

Paul Hodges

unread,
Dec 1, 2003, 10:42:09 AM12/1/03
to perl6-l...@perl.org

--- Larry Wall <la...@wall.org> wrote:
> Well, it's not nearly as general as we're making it, but the
> inspiration for it comes in part from the "Traits" paper:
>
> http://www.cse.ogi.edu/~black/publications/TR_CSE_02-012.pdf
>
> Basically, I'm attempting to take their concept and unify it with
> properties, interfaces, generics, aspects, and mixins. Among other
> things...

Ok, having read this now (at least corsorily) and compared it with what I
believe I understand about the way P6 is implementing
traits/properties/roles, I begin to get it, and I am, as usual, suitably
impressed and excited.

So is this a good time to divert this topic into an elaboration of roles?

> : Somebody drop me an example?
>
> Well, it hasn't been defined yet. Likely there will be some syntax
>
> my property foo;
>
> that is shorthand for something vaguely resembling
>
> my role foo is property {
> has $.foo is rw;
> }

So if I want to implement a package of related roles that I commonly use in
our In-House code, such as to specify how verbose an object should be on log
output, and how touchy it should be over whether a problem is screamingly
fatal or just warningly annoying, and maybe toss in a shorthand method that
lets me pass the names of some specific traits I want to be able to use (
like "allow(qw/winkin blinkin nod/)" or some such), it should be pretty
simple....but I'm having a hard time coming up with the syntax that declares
the package and exports the roles.

module IHL::Roles;
@ISA = 'Exporter';
@EXPORT_OK = qw/ fatal verbose allow setvals /;

our role fatal is property {
has $.fatal is rw;
}

our role verbose is property {
has $.verbose is rw;
}

sub allow {
.... # I'd want to make this one too complex to actually do it here
}

sub import {
allow @_[1...];
}

sub setvals ($o, *@t) {
"\$o.$_ = true".eval for @t; # surely there's a better way to do this?
}

then write allow() to build roles for each value passed in, maybe taking an
arg to say whether they should be truly global, or built in the caller's
namespace....
Then I could say

use IHL::Roles qw/ allow setvals fatal verbose /;
use Foo;
my $o = Foo.new();
allow qw/ foo bar baz /;
setvals($o,qw/ verbose baz /);

I'm trying to make sure I don't tumble back into pure P5 here, but I don't
think I'm really awake yet. :)

*****
"The information transmitted is intended only for the person or entity to
which it is addressed and may contain confidential, proprietary, and/or
privileged material. Any review, retransmission, dissemination or other use
of, or taking of any action in reliance upon, this information by persons or
entities other than the intended recipient is prohibited. If you received
this in error, please contact the sender and delete the material from all
computers.60"

Jonathan Scott Duff

unread,
Dec 1, 2003, 1:09:34 PM12/1/03
to Hodges, Paul, perl6-l...@perl.org
On Mon, Dec 01, 2003 at 10:42:09AM -0500, Hodges, Paul wrote:
> So is this a good time to divert this topic into an elaboration of roles?

I can wait for A12, but in the mean time ... :-)

> So if I want to implement a package of related roles that I commonly use in
> our In-House code, such as to specify how verbose an object should be on log
> output, and how touchy it should be over whether a problem is screamingly
> fatal or just warningly annoying, and maybe toss in a shorthand method that
> lets me pass the names of some specific traits I want to be able to use (
> like "allow(qw/winkin blinkin nod/)" or some such), it should be pretty
> simple....but I'm having a hard time coming up with the syntax that declares
> the package and exports the roles.
>
> module IHL::Roles;
> @ISA = 'Exporter';
> @EXPORT_OK = qw/ fatal verbose allow setvals /;
>
> our role fatal is property {
> has $.fatal is rw;
> }
>
> our role verbose is property {
> has $.verbose is rw;
> }
>
> sub allow {
> .... # I'd want to make this one too complex to actually do it here
> }
>
> sub import {
> allow @_[1...];
> }
>

> sub setvals ($o, *@t) {
> "\$o.$_ = true".eval for @t; # surely there's a better way to do this?
> }

Trying to keep up here ... but couldn't you do something like this?

sub setvals ($o, *@t) {
$o but= $_(true);
}

er, wouldn't you *have* to do something like that. If the object in
$o hasn't the property "foo", then C<$o.foo = true;> would be an
error, so you're trying to do 2 things: 1) give the object a property
and 2) assign a value to that property.

I think you're trying to do too much in the above code. If you just
have a common set of roles that you want to use across objects, you
could do this:

module MyRoles;
use Exporter;
@EXPORT_OK = <<verbose fatal>>;

our property verbose is true;
our property fatal is true;
our property notexported;
our property *trulyglobal;

then in other code:

use MyRoles;
use SomeFancyStuff;
my $o = SomeFancyStuff.new() but verbose;
$o but= MyRoles.notexported;
$o but= trulyglobal;

Or am I missing something?

> then write allow() to build roles for each value passed in, maybe taking an
> arg to say whether they should be truly global, or built in the caller's
> namespace....

Isn't that what my, our, Exporter, and the globalifying * are all about?

I look forward with much anticipation to A12.

-Scott
--
Jonathan Scott Duff
du...@lighthouse.tamucc.edu

Paul Hodges

unread,
Dec 1, 2003, 1:56:15 PM12/1/03
to du...@lighthouse.tamucc.edu, perl6-l...@perl.org
> From: Jonathan Scott Duff [mailto:du...@lighthouse.tamucc.edu]

> On Mon, Dec 01, 2003 at 10:42:09AM -0500, Hodges, Paul wrote:
> >
> > module IHL::Roles;
> > @ISA = 'Exporter';
> > @EXPORT_OK = qw/ fatal verbose allow setvals /;
> >
> > our role fatal is property {
> > has $.fatal is rw;
> > }
> >
> > our role verbose is property {
> > has $.verbose is rw;
> > }
> >
> > sub allow {
> > .... # I'd want to make this one too complex to actually do it here
> > }
> >
> > sub import {
> > allow @_[1...];
> > }
> >
>
> > sub setvals ($o, *@t) {
> > "\$o.$_ = true".eval for @t; # surely there's a better way to do this?
> > }
>
> Trying to keep up here ... but couldn't you do something like this?
>
> sub setvals ($o, *@t) {
> $o but= $_(true);
> }
>
> er, wouldn't you *have* to do something like that. If the object in
> $o hasn't the property "foo", then C<$o.foo = true;> would be an
> error, so you're trying to do 2 things: 1) give the object a property
> and 2) assign a value to that property.

A) You're absolutely right. I goofed. :)
B) What exactly does $_(true) mean in "$o but= $_(true);"?

I assume you're setting the the value, so I think I understand it, but how about

sub setvals ($o, *@t) {
$o but= $_;
$o.$_ = true;
}

Though I'm still "iffy" about that $o.$_ business.....
I think $_(true) is better. I'm just fumbling for perspective.

> I think you're trying to do too much in the above code.

lol -- always. :)

> If you just have a common set of roles that you want to use across objects,
> you could do this:
>
> module MyRoles;
> use Exporter;
> @EXPORT_OK = <<verbose fatal>>;
>
> our property verbose is true;
> our property fatal is true;
> our property notexported;
> our property *trulyglobal;
>
> then in other code:
>
> use MyRoles;
> use SomeFancyStuff;
> my $o = SomeFancyStuff.new() but verbose;
> $o but= MyRoles.notexported;
> $o but= trulyglobal;
>
> Or am I missing something?

Should have been

use MyRoles <<verbose>>;

for one, shouldn't it? :)
Nice concise definitions.
But I still would like to be able to write a role generator in the module, so that I can pass it a list of roles I want valid and have it set them all up, so that my program only has to say

use MyRoles <<allow setvals>>;
use Thingy;
my $o = Thingy.new();
allow <<foo bar baz>>;
setvals $o, <<foo baz>>;

instead of

use Thingy;
my $o = Thingy.new();
our property foo is true;
our property bar is true;
our property baz is true;
$o but= foo;
$o but= baz;

Don't get me wrong; there's nothing wrong with this code.
I just foresee certain things that I do commonly enough that I want to factor them out into something tested and consistent.

Likewise, working on the details of such an implementation is always what makes the underlying "stuff" start to make sense to me. :)

One thing, though.... could I do this? >=o}

my property (foo,bar,baz) ^is true;
$thingy ^but= (foo,baz);

I'm pretty sure that syntax is way wonky -- would "is" be a vectorizable operator?
Does it even qualify as an operator at all?

> > then write allow() to build roles for each value passed in,
> > maybe taking an arg to say whether they should be truly global,
> > or built in the caller's namespace....
>
> Isn't that what my, our, Exporter, and the globalifying * are
> all about?

Probably, though I haven't seen anything yet about how the P6 version of the Exporter is going to handle things like specifying exportation of my() vars &co.


*****
"The information transmitted is intended only for the person or entity to which it is addressed and may contain confidential, proprietary, and/or privileged material. Any review, retransmission, dissemination or other use of, or taking of any action in reliance upon, this information by persons or entities other than the intended recipient is prohibited. If you received this in error, please contact the sender and delete the material from all computers." 113

Luke Palmer

unread,
Dec 1, 2003, 3:37:06 PM12/1/03
to Hodges, Paul, du...@lighthouse.tamucc.edu, perl6-l...@perl.org
Hodges, Paul writes:
> I assume you're setting the the value, so I think I understand it, but
> how about
>
> sub setvals ($o, *@t) {
> $o but= $_;
> $o.$_ = true;
> }
>
> Though I'm still "iffy" about that $o.$_ business..... I think
> $_(true) is better. I'm just fumbling for perspective.

Y'all seem to be missing a C<for> somewhere :-)

sub setvals ($o, *@t) {
$o but= $_ for @t;
}

I think that should work, as the right side of C<but> should always be a
property, so a property reference ought be interpreted correctly.

> One thing, though.... could I do this? >=o}
>
> my property (foo,bar,baz) ^is true;
> $thingy ^but= (foo,baz);

No, but you might be able to if you used proper vectorizing syntax ;-)

my property (foo,bar,baz) is sometrait; # is automatically distributes
$thingy »but=« (foo,baz);

C<true> doesn't seem like a trait you would put on a property. C<true>
is a run-time property, and I think it would be awfully confusing to
make it a trait as well. If you're talking about some kind of
initialization, you might use:

my property (foo,bar,baz) is first(1);

Or C<is> might be correct if you're -- somehow -- deriving these
properties from the C<true> property. But I don't think that was the
intent.

> I'm pretty sure that syntax is way wonky -- would "is" be a
> vectorizable operator? Does it even qualify as an operator at all?

C<is> is definitely an operator, much in the same way C<my> is an
operator. Whether it's vectorizable is questionable, because in all
cases I've seen the vectorization is implicit. That is, if it has a
non-vector meaning, the meaning of:

my ($a,$b,$c) is foo;

is a little fuzzy. What's C<is> applying to if it's not applying to all
of $a, $b, and $c?

> > > then write allow() to build roles for each value passed in,
> > > maybe taking an arg to say whether they should be truly global,
> > > or built in the caller's namespace....
> >
> > Isn't that what my, our, Exporter, and the globalifying * are
> > all about?
>
> Probably, though I haven't seen anything yet about how the P6 version
> of the Exporter is going to handle things like specifying exportation
> of my() vars &co.

I'm pretty sure that the interface to Exporter can be cleaned up quite a
bit in Perl 6. For now, though, I think it's fine to assume it works
exactly like Perl 5's.

Luke
à

Paul Hodges

unread,
Dec 1, 2003, 4:05:30 PM12/1/03
to Luke Palmer, du...@lighthouse.tamucc.edu, perl6-l...@perl.org
> From: Luke Palmer [mailto:fibo...@babylonia.flatirons.org]

> Hodges, Paul writes:
> >
> > sub setvals ($o, *@t) {
> > $o but= $_;
> > $o.$_ = true;
> > }
>
> Y'all seem to be missing a C<for> somewhere :-)
>
> sub setvals ($o, *@t) {
> $o but= $_ for @t;
> }

LOL!!! I can't believe I missed that! =o)
You're obviously right, tho.

> I think that should work, as the right side of C<but> should
> always be a property, so a property reference ought be interpreted
correctly.
>
> > One thing, though.... could I do this? >=o}
> >
> > my property (foo,bar,baz) ^is true;
> > $thingy ^but= (foo,baz);
>
> No, but you might be able to if you used proper vectorizing syntax ;-)
>
> my property (foo,bar,baz) is sometrait; # is automatically
distributes
> $thingy »but=« (foo,baz);

Didn't know "is" would do that. Good to know!
And in my meager defense, I did reference MikeL's operator synopsis as of
3/25/03, which said ^[op] might be a synonym for <<>> or >><< (Sorry, no
fancy chars here. :)

> C<true> doesn't seem like a trait you would put on a property. C<true>
> is a run-time property, and I think it would be awfully confusing to
> make it a trait as well. If you're talking about some kind of
> initialization, you might use:
>
> my property (foo,bar,baz) is first(1);
>
> Or C<is> might be correct if you're -- somehow -- deriving these
> properties from the C<true> property. But I don't think that was the
> intent.

Was just initializing. Don't remember "is first(whatever)", though it seems
a bit familiar.



> > I'm pretty sure that syntax is way wonky -- would "is" be a
> > vectorizable operator? Does it even qualify as an operator at all?
>
> C<is> is definitely an operator, much in the same way C<my> is an
> operator. Whether it's vectorizable is questionable, because in all
> cases I've seen the vectorization is implicit. That is, if it has a
> non-vector meaning, the meaning of:
>
> my ($a,$b,$c) is foo;
>
> is a little fuzzy. What's C<is> applying to if it's not
> applying to all of $a, $b, and $c?

I hadn't seen it done that way...at least not recently enough that I
remembered it.
Last I recall, someone was thinking it would be

my ($a is foo, $b is foo, $c is foo);

Which really sux. I'm glad that was cleaned up.

> > > > then write allow() to build roles for each value passed in,
> > > > maybe taking an arg to say whether they should be truly global,
> > > > or built in the caller's namespace....
> > >
> > > Isn't that what my, our, Exporter, and the globalifying * are
> > > all about?
> >
> > Probably, though I haven't seen anything yet about how the
> > P6 version of the Exporter is going to handle things like specifying
> > exportation of my() vars &co.
>
> I'm pretty sure that the interface to Exporter can be cleaned
> up quite a bit in Perl 6. For now, though, I think it's fine to assume it
works
> exactly like Perl 5's.

Which is why I was building an allow(), which would let you specify property
names to create in the use() statement of the module. I have *NO* clue how
you would use the current Exporter to create roles on-the-fly, but I think I
could build something that would do its own exporting to whatever level it
was told. Maybe level 0 is make them but don't export, 1 is export them into
the calling namespace, and 2 is truly global:

use MyRoles export => 0, <<foodiddly podunk
whatever_other_silliness_is_on_the_menu_today>>;
my $whatsit but= MyRoles.foodiddly; # above line made this acceptable
$whatsit.foodiddly = 1;

but could I instead say

my $whatsit but= MyRoles.foodiddly(1);

or something like that?


*****
"The information transmitted is intended only for the person or entity to
which it is addressed and may contain confidential, proprietary, and/or
privileged material. Any review, retransmission, dissemination or other use
of, or taking of any action in reliance upon, this information by persons or
entities other than the intended recipient is prohibited. If you received
this in error, please contact the sender and delete the material from all

computers.61"

Michael Lazzaro

unread,
Dec 2, 2003, 3:30:32 PM12/2/03
to perl6-l...@perl.org

On Monday, December 1, 2003, at 01:05 PM, Hodges, Paul wrote:
> Didn't know "is" would do that. Good to know!
> And in my meager defense, I did reference MikeL's operator synopsis as
> of
> 3/25/03, which said ^[op] might be a synonym for <<>> or >><< (Sorry,
> no
> fancy chars here. :)

Hey, that was *March*! ;-) The fossil records from that time are
fragmentary, at best.

I don't think I ever saw any further reference to the ^[op] syntax
staying alive; I assume that means it's dead. Last I heard, which was
admittedly around the same time frame, we'd have the non-Unicode-using
>>op<<, and a Unicode synonym »op«, and that's it.

There were also vaguely threatening proposals to have <<op>> and >>op<<
do slightly different things. I assume that is also dead, and that
<<op>> is (typically) a syntax error.

If anyone in the know knows otherwise, plz verify for Piers' summary
and the future fossil record.

MikeL

Reply all
Reply to author
Forward
0 new messages