Properties -- distributive, predeclared, post-applied....??

0 views
Skip to first unread message

Paul Hodges

unread,
Dec 4, 2003, 2:35:57 PM12/4/03
to perl6-l...@perl.org, ydb...@yahoo.com
How about

use Baz; # assume object type
my property foo;
my @bar of Baz is false but foo; # maybe not what you meant?

If you apply a trait like false to an array, I expect it to apply to the
"array instance object" itself and not the content, so that
push @bar, Baz.new();
if @bar { print "stuff"; } else { print "empty"; } # oops! false!
if @bar[0] { print " oops"; } else { print " ok"; } # oops! not false!
would print "empty oops" instead of "stuff ok".

I'd *like* to be able to predeclare a trait or property to be distributed
across any values placed in this array, but only this array. For example, it
would be nice if I could have the default aspects of false and foo be
applied to any Baz that gets stuck into @bar, but obviously this isn't the
syntax to do it. I could make Baz's new() do it, but I don't want *ALL* Baz
objects to be false and foo...just the ones in @bar. So, what I need is
something more like

my @bar of Baz;
@bar.STORE.wrap { my $r = call; return $r >>but=<< (false,foo); }

But I'm not sure C<$r >>but=<< (false,foo)> works, and I really wanted to
figure out a way to do it all in the declaration. Maybe it could be

my @bar of Baz will do STORE.wrap { call >>but=<< (false,foo); }

but I'm not sure call will behave as an lvalue and still set up the
appropriate return, I don't expect @bar to accept "will do", and I don't
think "will do" is where the wrap should go. I'm just trying to wrap my
brain around this brick and I can't find all the references that tell me all
the little pieces so that I can compare them for a closer approximation,
lol....


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

Luke Palmer

unread,
Dec 4, 2003, 7:57:52 PM12/4/03
to Hodges, Paul, perl6-l...@perl.org, ydb...@yahoo.com
Hodges, Paul writes:
> How about
>
> use Baz; # assume object type
> my property foo;
> my @bar of Baz is false but foo; # maybe not what you meant?

Definitely not what you meant. Fortunately, the compiler will teach you
a thing or two about it: C<false> is not a trait.

But indeed foo would apply to @bar itself, rather then to any element
that goes into @bar later.

> If you apply a trait like false to an array, I expect it to apply to the
> "array instance object" itself and not the content, so that
> push @bar, Baz.new();
> if @bar { print "stuff"; } else { print "empty"; } # oops! false!
> if @bar[0] { print " oops"; } else { print " ok"; } # oops! not false!
> would print "empty oops" instead of "stuff ok".
>
> I'd *like* to be able to predeclare a trait or property to be distributed
> across any values placed in this array, but only this array. For example, it
> would be nice if I could have the default aspects of false and foo be
> applied to any Baz that gets stuck into @bar, but obviously this isn't the
> syntax to do it. I could make Baz's new() do it, but I don't want *ALL* Baz
> objects to be false and foo...just the ones in @bar. So, what I need is
> something more like
>
> my @bar of Baz;
> @bar.STORE.wrap { my $r = call; return $r >>but=<< (false,foo); }

Something likely more like:

my role property_wrap[Property *@props] {
method STORE($newval) { SUPER::STORE($newval but *@props) }
}
@bar but= property_wrap[false, foo];

With emphasis on "something". (Extrapolating wildly the little bit I
know about roles and making up some semantics, such as C<but *@stuff>).

As for just declaring it, um... why would you want to do that? I could
see making the array default to some value with a trait, which is
trivially:

my @bar is default(undef but foo);

But automatically marking every value that ever goes into the array... I
don't see the utility.

> But I'm not sure C<$r >>but=<< (false,foo)> works, and I really wanted to
> figure out a way to do it all in the declaration. Maybe it could be
>
> my @bar of Baz will do STORE.wrap { call >>but=<< (false,foo); }

Yeah, that's definitely not right. C<will> works as follows:

:w <declaration> will <identifier> <block>

It's really just a shorthand for C<is>, so you don't have to put parens
around the block.

> but I'm not sure call will behave as an lvalue and still set up the
> appropriate return, I don't expect @bar to accept "will do", and I don't
> think "will do" is where the wrap should go. I'm just trying to wrap my
> brain around this brick and I can't find all the references that tell me all
> the little pieces so that I can compare them for a closer approximation,
> lol....

Luke

Paul Hodges

unread,
Dec 4, 2003, 11:08:27 PM12/4/03
to Luke Palmer, Hodges, Paul, perl6-l...@perl.org

--- Luke Palmer <fibo...@babylonia.flatirons.org> wrote:
> Hodges, Paul writes:
> > How about
> >
> > use Baz; # assume object type
> > my property foo;
> > my @bar of Baz is false but foo; # maybe not what you meant?
>
> Definitely not what you meant. Fortunately, the compiler will teach
> you a thing or two about it: C<false> is not a trait.

Duh. I knew I'd do something simple/stupid like that. :)
But you get the idea.

> But indeed foo would apply to @bar itself, rather then to any element
> that goes into @bar later.
>
> > If you apply a trait like false to an array, I expect it to apply
> to the
> > "array instance object" itself and not the content, so that
> > push @bar, Baz.new();
> > if @bar { print "stuff"; } else { print "empty"; }

> > if @bar[0] { print " oops"; } else { print " ok"; }

> > would print "empty oops" instead of "stuff ok".
> >
> > I'd *like* to be able to predeclare a trait or property to be
> distributed
> > across any values placed in this array, but only this array.
> > For example, it would be nice if I could have the default
> > aspects of false and foo be applied to any Baz that gets stuck
> > into @bar, but obviously this isn't the syntax to do it. I could
> > make Baz's new() do it, but I don't want *ALL* Baz objects to be
> > false and foo...just the ones in @bar. So, what I need is
> > something more like
> >
> > my @bar of Baz;
> > @bar.STORE.wrap { my $r = call; return $r >>but=<< (false,foo); }
>
> Something likely more like:
>
> my role property_wrap[Property *@props] {
> method STORE($newval) { SUPER::STORE($newval but *@props) }
> }
> @bar but= property_wrap[false, foo];

...square brackets?
...roles can have methods? duh, they'd have to....ok....
...but, *square* brackets???

And C< but *@props > looks like "but" is distributive.
I think that's good, but not what I inferred from your last note on the
topic.

> With emphasis on "something". (Extrapolating wildly the little bit I
> know about roles and making up some semantics, such as C<but
> *@stuff>).

lol -- oh, ok. :)
But it's *good* BS.

> As for just declaring it, um... why would you want to do that?
> I could see making the array default to some value with a trait,
> which is trivially:
>
> my @bar is default(undef but foo);
>
> But automatically marking every value that ever goes into the
> array... I don't see the utility.

Nothing that couldn't be done in a dozen other ways, but this is one
way that I like. It's perhaps a slightly contrived situation, but one I
hope might shed some light on the semantics so that I can learn to use
them when they're a better solution that the kludges I so often end up
with.

In other words, there's always the possibility of doing it another way.
Any object-oriented code functionality could be replicated by purely
functional code, but sometimes you'd end up having to design entire
paradigms to replace some of the functionalities. It's just a mindset
issue, though I will readily confess that my mind is usually set at
wierd angles.

Usually I end up keeping track of some feature by putting all things
with this feature into THIS array and all things like that into THAT
array or some such parallel silliness. It works, and is faster than
practically any object code on our poor old nag of a workhorse server,
but then if I have to know which stack something came from when I send
it to a sub I have to include another argument. There are LOTS of
alternate ways to mark things, but I like this one.

> > But I'm not sure C<$r >>but=<< (false,foo)> works, and I really
> > wanted to figure out a way to do it all in the declaration. Maybe
> > it could be
> >
> > my @bar of Baz will do STORE.wrap { call >>but=<< (false,foo); }
>
> Yeah, that's definitely not right. C<will> works as follows:
>
> :w <declaration> will <identifier> <block>
>
> It's really just a shorthand for C<is>, so you don't have to put
> parens around the block.

But subs in A6 have a "will do", though I presume the do is optional?

Hmm....still aware that this isn't a sub declaration,

my @bar of Baz will init {
.STORE.wrap { call >>but=<< (false,foo); }
}

I still like the idea that call could set itself up as an lvalue.
~smirk~

So is it possible that this is a valid way to declare a container with
modified methods all at once?

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

Luke Palmer

unread,
Dec 5, 2003, 1:01:12 AM12/5/03
to Hod...@writeme.com, Hodges, Paul, perl6-l...@perl.org
Paul Hodges writes:
> Luke Palmer:

> > Something likely more like:
> >
> > my role property_wrap[Property *@props] {
> > method STORE($newval) { SUPER::STORE($newval but *@props) }
> > }
> > @bar but= property_wrap[false, foo];
>
> ...square brackets?
> ...roles can have methods? duh, they'd have to....ok....
> ...but, *square* brackets???

Yeah. Classes use square brackets when they're parametric, so I could
only assume roles do, too. That is, if you haven't seen this before:

class RingBuffer[$size, Class ?$of = Any] {
has @.buffer of $of is dim($size);
has ($.front, $.back, $.fill);

method push($elem of $of) returns Void {
@.buffer[$.back++] = $elem;
$.back %= $size;
$.fill++;
}

method shift() returns $of {
if $.fill <= 0 { throw X::BufferEmpty } # predeclared
return @.buffer[$.front++];
LAST { $.front %= $size }
}
}

I do have one question for the almighty gods, however. Can you
explicitly use the :: sigil to make a lexical parametric class, as in:

class RingBuffer[$size, ?::of = Any] {
has of @.buffer;
}

Well, modulo the possible ambiguity of the keyword of. Perhaps ::of
would have to be there, too...?

> And C< but *@props > looks like "but" is distributive.
> I think that's good, but not what I inferred from your last note on the
> topic.

I didn't say anything about C<but> not distributing over its I<right>
argument :-) It does, after all, make sense, as you'd probably not be
allowed to mark a property with the @ sigil.

> > As for just declaring it, um... why would you want to do that?
> > I could see making the array default to some value with a trait,
> > which is trivially:
> >
> > my @bar is default(undef but foo);
> >
> > But automatically marking every value that ever goes into the
> > array... I don't see the utility.

[snip]

> Usually I end up keeping track of some feature by putting all things
> with this feature into THIS array and all things like that into THAT
> array or some such parallel silliness. It works, and is faster than
> practically any object code on our poor old nag of a workhorse server,
> but then if I have to know which stack something came from when I send
> it to a sub I have to include another argument. There are LOTS of
> alternate ways to mark things, but I like this one.

Oh, okay.

And declarative is usually much nicer to read than procedural, so that
makes sense.

As far as I can tell, it's not possible without building some machinery
yourself, like we did above. That's okay though: we should be expected
to program generic solutions every once in awhile.

> > > But I'm not sure C<$r >>but=<< (false,foo)> works, and I really
> > > wanted to figure out a way to do it all in the declaration. Maybe
> > > it could be
> > >
> > > my @bar of Baz will do STORE.wrap { call >>but=<< (false,foo); }
> >
> > Yeah, that's definitely not right. C<will> works as follows:
> >
> > :w <declaration> will <identifier> <block>
> >
> > It's really just a shorthand for C<is>, so you don't have to put
> > parens around the block.
>
> But subs in A6 have a "will do", though I presume the do is optional?

You can leave out the C<do> if you like, but you also have to leave out
the C<will> in that case. For instance:

sub foo() { ... }

Is short for:

sub foo() will do { ... }

Which is in turn short for:

sub foo() is do({ ... })

Er, for some definition of 'short' :-)

> Hmm....still aware that this isn't a sub declaration,
>
> my @bar of Baz will init {
> .STORE.wrap { call >>but=<< (false,foo); }
> }
>
> I still like the idea that call could set itself up as an lvalue.
> ~smirk~
>
> So is it possible that this is a valid way to declare a container with
> modified methods all at once?

It would seem so. It's not a particularly clean one (even though it may
be clean *looking*). You might be able to do some jazz like this:

my Baz @bar but property {
method STORE($elem) { call($elem but (false, foo)) }
}

Where you're applying an anonymous property.

Luke

Jonathan Scott Duff

unread,
Dec 5, 2003, 11:40:15 AM12/5/03
to Luke Palmer, Hodges, Paul, perl6-l...@perl.org, ydb...@yahoo.com
On Thu, Dec 04, 2003 at 05:57:52PM -0700, Luke Palmer wrote:
> Hodges, Paul writes:
> > I'd *like* to be able to predeclare a trait or property to be distributed
> > across any values placed in this array, but only this array. For example, it
> > would be nice if I could have the default aspects of false and foo be
> > applied to any Baz that gets stuck into @bar, but obviously this isn't the
> > syntax to do it. I could make Baz's new() do it, but I don't want *ALL* Baz
> > objects to be false and foo...just the ones in @bar. So, what I need is
> > something more like
> >
> > my @bar of Baz;
> > @bar.STORE.wrap { my $r = call; return $r >>but=<< (false,foo); }
>
> Something likely more like:
>
> my role property_wrap[Property *@props] {
> method STORE($newval) { SUPER::STORE($newval but *@props) }
> }
> @bar but= property_wrap[false, foo];
>
> With emphasis on "something". (Extrapolating wildly the little bit I
> know about roles and making up some semantics, such as C<but *@stuff>).

What's the difference between what you have above and this:

my property property_wrap (Property *@props) {


method STORE($newval) { SUPER::STORE($newval but *@props) }
}

@bar but= property_wrap(false, foo);

? The examples I remember from the As and Es all have round brackets
around trait parameters (Hmm. And I can only remember is-trait examples
too). Granted, the universe could have shifted under my feet without my
knowledge.

I discovered after reading this email that I've been assuming that
square-bracket parameterization happened at compile-time while
round-bracket parameterization was, of course, run-time. I don't know
if that's even partially true though. If that isn't the distinction,
then what is? Why the two bracket styles?

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

Luke Palmer

unread,
Dec 5, 2003, 4:56:49 PM12/5/03
to Hodges, Paul, perl6-l...@perl.org, ydb...@yahoo.com

No, it was just a braino on my part. I forgot that I've already seen
parametric properties in a lot of places... :-/

> I discovered after reading this email that I've been assuming that
> square-bracket parameterization happened at compile-time while
> round-bracket parameterization was, of course, run-time. I don't know
> if that's even partially true though. If that isn't the distinction,
> then what is? Why the two bracket styles?

It's a manifestation of "different things should look different". If
classes look too much like subroutines, things would get confusing and
hard to read. I don't think it's necessarily a compile-time thing, as
one would expect this to work:

class Foo[Int $param] {...}
sub make_foo(Int $param) {
Foo[$param].new;
}

I wonder if we'll have C++-like template specialization... I'd like
that, especially since Perl would keep from inventing a new language in
the process.

multi class PrintBasic[Class $of] {
method go() { print "Non-basic"; }
}
multi class PrintBasic[Int|Num|Str] { # Can I do that?
method go() { print "Basic"; }
}

Hmm.

Luke

Reply all
Reply to author
Forward
0 new messages