Re: Do I need has $.foo; for accessor-only virtual attributes?

2005-07-24 Thread Sam Vilain

Stevan Little wrote:
Yes, we have. One thing to consider is that it is much easier to get the 
Role order doesn't matter thing when they are composed. Once you start 
keeping the roles around, you run into the possiblity for such things as 
next METHOD being executed in Role context. I wont even speculate on 
what that should/could/would do, because I think we just shouldn't go 
there.


We talked briefly about considering this flattening as being a
run-time state thing rather than necessarily taking place in the
Meta-objects.  Is this still tenable?

Side effects like what happens if you do higher level stuff like 
run-time modification of Roles after they have been composed into 
classes can be addressed seperately.



No, that's correct.  We've just basically said that $.x is now a method
call, and as long as you stick to that invocation syntax it just has
to be declared as a method somewhere in the parentage/role-age of
this object.  But collisions in $.x declaration will be treated as
collisions in method declaration.
So we really are looking at closure based access to attributes. This 
also means that the idea behind P6Opaque as a storage format is very 
different. In theory, we could implement these style classes in a very 
Inside-Out manner. In a way, we could look at:

has $.x is rw;
as being sugar for this (pseudo) Perl 6:
{
my %x;
$?CLASS.meta.add_method('x' = method ($self: ?$value) {
%x{$self.id} = $value if $value.defined;
%x{$self.id};
 });
}


Yes, precisely ... except the method returns a Proxy object.
The proxy object responds differently depending on its context.

This is why I wanted the accessors to be traits hanging off the
code object itself, as described in http://xrl.us/guyx, as it makes
this not suck - a null accessor can be quickly optimised away to
direct variable access.  There is a pugs test for these in 
t/oo/attributes/mutators.t


Of course, this interface will need to be extended to support the full 
TIE-like interface that proxy objects support.  Thankfully as we're a 
lot more object oriented these days, I think we might be able to get 
away with:


  my $hash = %object.hash_property;
   :FETCH = should return a Hash object (or Facade), ie .does(Hash)

  my $array = %object.array_property;
   :FETCH = should return a Array object (or Facade), ie .does(Array)

As everything else is just a method call on the returned object.

Exactly which methods are uppercased into is accessor-provided entry
points is then a matter of style; though perhaps for a little sugar
a few should be provided where the function names are awkward to type, 
in particular .(post_circumfix:{}) and .(post_circumfix:[])


To summarise with code for those who are lost;

  has $.foo;

would be sugar for:

  has $foo;
  method foo is accessor( :FETCH { $foo },
  :STORE - $x { $foo = $x },
);

If you use \( $object.foo ) - that is, create a reference to the .foo 
property, you get a Proxy object;  the above should be considered 
functionally equivalent to;


  has $foo;
  method foo is rw {
  return Proxy.new(:FETCH { $foo },
   :STORE - $x { $foo = $x },
  );
  }

This is extended into the other sigil types;

  has %.foo;

is sugar for this:

  has Hash $foo;   # or has %foo, but really, the point is it's
   # an implementation detail, right?
  method foo is rw {
  return Proxy.new( :FETCH{ $foo },  # or a facade
:STORE - Hash $x { $foo = $x },
  )
but {
method post_circumfix:{}($key) is rw {
return Proxy.new( :FETCH{ $foo{$key} },
  :STORE - $x { $foo{$key} = $x },
);
}
};
  }

Doesn't that look nice and ugly!  :-D

Note that this means that taking a reference to a hash slot is actually 
returning you a proxy object that will access the hash when you call it. 
 Sneaky, huh?  This means that this doesn't have to auto-vivify the 
slot any more, closing the caveat found in

t/builtins/arrays_and_hashes/exists.t by Darren Duncan:

  my $slot_ref = \( %foobar );

This looks much tidier with Luke's nomenclature of is accessor;

has Hash $foo;   # or has %foo, but really, whatever
method foo is accessor
:FETCH { $foo },
:STORE - Hash $x { $foo = $x },
:HASHENT - $key is accessor
   :FETCH { $foo{$key} },
   :STORE - $x { $foo{$key} = $x };

Add brackets to suit.  The HASHENT is an early idea for an optional
shortcut; to avoid creating a facade when all you wanna do is define
what happens when you treat the object property as a Hash/Array via
$object.property{key}.  But it's still sugar for the above but { }
clause (or any other way of returning a Facade object that .does(Hash)).

Well, if we ditch the P6Opague type (as we currently 

Re: Do I need has $.foo; for accessor-only virtual attributes?

2005-07-24 Thread Stevan Little


On Jul 24, 2005, at 2:40 AM, Sam Vilain wrote:

Stevan Little wrote:
Yes, we have. One thing to consider is that it is much easier to get 
the Role order doesn't matter thing when they are composed. Once 
you start keeping the roles around, you run into the possiblity for 
such things as next METHOD being executed in Role context. I wont 
even speculate on what that should/could/would do, because I think we 
just shouldn't go there.


We talked briefly about considering this flattening as being a
run-time state thing rather than necessarily taking place in the
Meta-objects.  Is this still tenable?


Well if the MetaClass is where all methods are stored, then it will 
need to be meta in some way. As for run-time vs. compile-time, that 
makes no difference. It happens at class composition time, which can 
take place at any (run|compile)time.


The strength of the role flattening is in the fact that, given it's 
rules of composition, it makes the order in which the roles are 
composed irrelevant. So as long as we flatten the same way, it does not 
matter.


My point was more that we need to keep the same flattening rules, and 
not let


Side effects like what happens if you do higher level stuff like 
run-time modification of Roles after they have been composed into 
classes can be addressed seperately.


Well, this was something I think we talked about. Basically my position 
is that once you compose a role into a class, the connection the class 
retains to that role is only minimal. Basically enough to handle does 
and nothing more. If you modify the Role at runtime, it will not affect 
and previous classes it was composed into.


Personally I don't like the idea of runtime class modification, I think 
it is a dangerous thing to do. But I understand that it is a useful 
feature in certain cases. But runtime Role modification I think is just 
insane, especially since roles can be used by multiple classes, and 
combined with multiple other roles. The combinations of conflicts and 
issues that can arise are endless. Not to mention the fact that given a 
widely enough used role, it would be practically impossible to reason 
about the affect of changing that role.


I think if you find that you need to modify your role at runtime, then 
you have actually found that you need a class, and not a role.


No, that's correct.  We've just basically said that $.x is now a 
method

call, and as long as you stick to that invocation syntax it just has
to be declared as a method somewhere in the parentage/role-age of
this object.  But collisions in $.x declaration will be treated as
collisions in method declaration.
So we really are looking at closure based access to attributes. This 
also means that the idea behind P6Opaque as a storage format is very 
different. In theory, we could implement these style classes in a 
very Inside-Out manner. In a way, we could look at:

has $.x is rw;
as being sugar for this (pseudo) Perl 6:
{
my %x;
$?CLASS.meta.add_method('x' = method ($self: ?$value) {
%x{$self.id} = $value if $value.defined;
%x{$self.id};
 });
}


Yes, precisely ... except the method returns a Proxy object.
The proxy object responds differently depending on its context.


Sure, that makes sense.


To summarise with code for those who are lost;

  has $.foo;

would be sugar for:

  has $foo;
  method foo is accessor( :FETCH { $foo },
  :STORE - $x { $foo = $x },
);

If you use \( $object.foo ) - that is, create a reference to the .foo 
property, you get a Proxy object;  the above should be considered 
functionally equivalent to;


  has $foo;
  method foo is rw {
  return Proxy.new(:FETCH { $foo },
   :STORE - $x { $foo = $x },
  );
  }


This is looking a lot like properties in C#. Which look something like 
this:


private String node;
public String Node {
get { return this.node; }
# NOTE: the 'value' variable is created for you
set { this.node = value; }
};

I think that is a good thing, I know I liked having properties when I 
did some C3 work a little while back.




This is extended into the other sigil types;

  has %.foo;

is sugar for this:

  has Hash $foo;   # or has %foo, but really, the point is it's
   # an implementation detail, right?
  method foo is rw {
  return Proxy.new( :FETCH{ $foo },  # or a facade
:STORE - Hash $x { $foo = $x },
  )
but {
method post_circumfix:{}($key) is rw {
return Proxy.new( :FETCH{ $foo{$key} },
  :STORE - $x { $foo{$key} = $x },
);
}
};
  }


I am not sure if it makes sense to handle whats inside the hash with 
the accessor. I think that is the responsibility of either the hash 
container type itself, or what you really need here is some kind of 

Re: Do I need has $.foo; for accessor-only virtual attributes?

2005-07-24 Thread Sam Vilain

Stevan Little wrote:

This is extended into the other sigil types;
  has %.foo;
is sugar for this:
  has Hash $foo;   # or has %foo, but really, the point is it's
   # an implementation detail, right?
  method foo is rw {
  return Proxy.new( :FETCH{ $foo },  # or a facade
:STORE - Hash $x { $foo = $x },
  )
but {
method post_circumfix:{}($key) is rw {
return Proxy.new( :FETCH{ $foo{$key} },
  :STORE - $x { $foo{$key} = $x },
);
}
};
  }
I am not sure if it makes sense to handle whats inside the hash with the 
accessor. I think that is the responsibility of either the hash 
container type itself, or what you really need here is some kind of 
object to wrap your hash and get such fine grained control. But that is 
just my gut reaction.


This is what the monkey-but syntax is about.  The returned Proxy object
must behave like a Hash for the property to behave like a hash, which
(minimally) means implementing the post_circumfix:{}($key) method.

Quite what that looks like in the metamodel is another question; the above
makes it look like monkey-but can make anonymous sub-classes that derive
new methods, which I inducted as being potentially legal syntax from the
examples of monkey-but I've seen so far.  Ideally this wouldn't have to
happen every time the attribute is accessed ;).


So, if you want a visitor pattern, you grab a visitor iterator
via the Meta-Objects, right?  Which could also solve the 
STORABLE_freeze/STORABLE_thaw / Pixie::Complicity / etc problem by 
unifying the way that foreign objects can marshall themselves to 
Perl objects when required.
You mean for persistence operations? Where you need to thoroughly 
inspect the object to save it to disk/DB/etc.


Yes, that sort of thing.  Sending objects between processes in some
marshalled format, like YAML, XML, binary/Storable, etc.  But there
are plenty of other applications of the visitor pattern; I think a
nice tidy split would be to either allow walking at the public attribute
or the private attribute level.

In the face of AUTOMETH, the public attibutes of a Class might not be
trivial to find, or indeed be infinite.  So the class needs to have a way
to tell the visitor iterator which public attributes are considered to
represent the entire state of the object.

Of course, the same problem doesn't apply for visiting private attributes,
which are either there or not.  I can see arguments for walking at both
levels for certain tasks.

I think the ideal way to write something like that would be to write is 
as a metaobject. Meaning using the Persistent metaclass. As opposed to 
using something on the user side of things to interogate the meta 
side of things. But this may be because I am too deep into the meta side 
if things right now.


Yes, I imagine that the iterator will be returned from a metaobject
method, with gratuitous use of callbacks to make the simple uses really
simple; including the logical equivalent of $File::Find::prune = 1.

Sam.

ps. Monkey-but Monkey-but Monkey-but


Re: Do I need has $.foo; for accessor-only virtual attributes?

2005-07-22 Thread Brent 'Dax' Royal-Gordon
Larry Wall [EMAIL PROTECTED] wrote:
 $x is visible only in the rest of the lexical scope.  In contrast,
 $_y would presumably still be visible if the class were reopened.

This strikes me as an exceedingly bad idea.

Encapsulation is a very good thing, and I'm glad it's being added to
Perl 6.  But once in a while, you really *do* need to break
encapsulation.  Maybe a shortsighted module author didn't add an
accessor you need, or maybe you're doing something highly magical for
(e.g.) debugging.  In any case, though, you'll need an escape hatch,
and I really think extending a class should be it.  By extending a
class, you're explicitly saying I'm going to butt into your affairs;
at this point, if you're not sure what you're doing, you're probably
going to mess things up *anyway*.

(If not this, I at least would like to see a way to make roles and/or
class extensions optionally merge their namespace with the class
they're being composed into; a simple 'is merged' on the
role/extension's definition might do.)

Also note how subtle this point is (it's about the only point I didn't
get from the original message); the degree to which it requires the
class's programmer to predict how others might want to extend his
class; and the syntactic kludge required to specify it (namely, the
sometimes-magical underscore).  I really think this is a very fine
distinction, which programmers will get wrong half the time, and which
you don't even have enough syntax to cope with *anyway*.

-- 
Brent 'Dax' Royal-Gordon [EMAIL PROTECTED]
Perl and Parrot hacker


Re: Do I need has $.foo; for accessor-only virtual attributes?

2005-07-22 Thread Stevan Little

Larry,

On Jul 21, 2005, at 8:07 PM, Larry Wall wrote:

On Thu, Jul 21, 2005 at 05:15:34PM -0400, Stevan Little wrote:
: This means that Roles are now first-class-ish things. Meaning they
: cannot just simply be composed into classes since now we have to 
keep a

: table of elements which are private to a Role.

Well, we've kinda been squinting at that issue from both ends for a
while now, and there's something in both views.


Yes, we have. One thing to consider is that it is much easier to get 
the Role order doesn't matter thing when they are composed. Once you 
start keeping the roles around, you run into the possiblity for such 
things as next METHOD being executed in Role context. I wont even 
speculate on what that should/could/would do, because I think we just 
shouldn't go there.



: On Jul 21, 2005, at 2:48 PM, Larry Wall wrote:
: * All roles can write their shared attributes as $.x and not 
worry

:   about whether the class declares them or not.
:
: I assume they need not worry because we can rely on conflict 
resolution

: to deal with most issues? Or are you thinking something different?

No, that's correct.  We've just basically said that $.x is now a method
call, and as long as you stick to that invocation syntax it just has
to be declared as a method somewhere in the parentage/role-age of
this object.  But collisions in $.x declaration will be treated as
collisions in method declaration.


So we really are looking at closure based access to attributes. This 
also means that the idea behind P6Opaque as a storage format is very 
different. In theory, we could implement these style classes in a very 
Inside-Out manner. In a way, we could look at:


has $.x is rw;

as being sugar for this (pseudo) Perl 6:

{
my %x;
$?CLASS.meta.add_method('x' = method ($self: ?$value) {
%x{$self.id} = $value if $value.defined;
%x{$self.id};
 });
}

Hmmm, it's a good thing I just got a book on CLOS metaobjects :)

: * All roles can write completely private $x attributes that are 
not

:   visible outside their lexical scope but are nevertheless
:   per-instance.
:
: So the Role's scope is preserved here, as opposed to pushing $x into
: the classes scope. Correct?

My notion is that $x (the name proxy) is stored in the lexical scope
of the closure that just happens to be the closure for the role,
rather than keeping a name proxy in the package.  In either case,
$x or $.x is not a real variable, but a placeholder for a particular
slot in the object.  The actual proxy could be stored in the role's
package if that makes it easier to keep track of, but I'd like the
scoping of the name to be lexical like an our in that case.  But if
we can figure out how to store it more like a my variable but still
figure out which slot it maps to when instantiated, that might be cool.
Unfortunately, it could map to different slots in different objects,
so the class in question would have to keep track of where 
MyRole::('$x')

actually maps to.

It's certainly possible that this notion doesn't really map terribly
well onto roles.


Well, if we ditch the P6Opague type (as we currently know it) and use 
the Inside-Out method I show above. Then we just don't actually have 
class/instance attributes anymore at all. We really just have methods, 
some of which happen to be closures around per-instance values. Of 
course this means there is no direct access to attributes at all (which 
I think it not a bad thing, but I am into BD like that).


Hmmm, I kind of like the smell of this.


: This would
: make it difficult to compose role methods into the method table 
without

: bringing along a lot of meta-info about from whence they came. It is
: doable I think, but adds some complexity for which I am not sure the
: cost outweighs the benefits.


Ok, I will respond to myself here:

No Stevan, that is silly, if it is closure-based Inside-Out 
thinga-mah-bobs, then we don't have to keep meta-context-info around, 
the closure does that for us. Duh!



But I like the $x/$.x distinction for classes, since it encourages
people to write completely private attributes to begin with, and
then maybe take the step of adding a dot when the want to provide
an accessor.


I agree, private should be encouraged.

*sniff* *sniff* this is smelling better and better :)

Stevan



Re: Do I need has $.foo; for accessor-only virtual attributes?

2005-07-22 Thread Collin Winter
 I'm not married to the colon.  Speaking of traits and adverbs, why not use
 one of those in the has declaration instead?  That'd certainly be a lot
 more explicit than the magic leading underscore (although I'm at a loss as
 to what the trait would be named...)

I'd like to see an is private trait used for this purpose. This
could be used in the has declaration alongside the existing is rw
and company, possibly in method declarations as well, like so:

method foo() is private {...}

I may have missed a previous debate over this in the past, but this
seems a lot more natural to me than a magical leading underscore.

Collin Winter


Re: Do I need has $.foo; for accessor-only virtual attributes?

2005-07-22 Thread Stevan Little

Brent,

On Jul 22, 2005, at 3:53 AM, Brent 'Dax' Royal-Gordon wrote:

(If not this, I at least would like to see a way to make roles and/or
class extensions optionally merge their namespace with the class
they're being composed into; a simple 'is merged' on the
role/extension's definition might do.)


Actually Roles actually do merge into the class's namespace. This is 
the key to the flattening aspect of Roles. Although how much of their 
namespace they bring along with them is still undetermined (sorta).


Stevan



Re: Do I need has $.foo; for accessor-only virtual attributes?

2005-07-22 Thread Larry Wall
On Fri, Jul 22, 2005 at 07:35:30AM -0500, Collin Winter wrote:
:  I'm not married to the colon.  Speaking of traits and adverbs, why not use
:  one of those in the has declaration instead?  That'd certainly be a lot
:  more explicit than the magic leading underscore (although I'm at a loss as
:  to what the trait would be named...)
: 
: I'd like to see an is private trait used for this purpose. This
: could be used in the has declaration alongside the existing is rw
: and company, possibly in method declarations as well, like so:
: 
: method foo() is private {...}
: 
: I may have missed a previous debate over this in the past, but this
: seems a lot more natural to me than a magical leading underscore.

Well, yes, most people missed that debate, because it was mostly done
on whiteboards in secret meetings of the cabal.  (There is no cabal.)

The problem I have with is private is that, while there may very
well be a trait of that name that you can interrogate, I really
want people to think of the private methods as being in a different
namespace so that there's no confusion about the fact that you can
have a private method and a public method of the same name.  And the
reason I want that is because I strongly believe that private methods
must be absolutely invisible to the public interface, and confusing
the namespaces puts you in a situation where adding a private method
can clobber public inheritance of the same name.

Even worse, it clobbers your private interface.  As soon as you say

method foo() is private {...}

then you can't call $?SELF.foo() and expect to get the public .foo method.
Putting the difference as part of the name forces people to distinguish

$?SELF.foo()
$?SELF._foo()

on the call end.  And the _ has the advantage of being *perceived* as
part of the name.  The problem with

$?SELF.:foo()

is that people see that as a .: operator on the foo method.

Larry


Re: Do I need has $.foo; for accessor-only virtual attributes?

2005-07-22 Thread John Siracusa
On 7/22/05 11:37 AM, Larry Wall wrote:
 The problem I have with is private is that, while there may very
 well be a trait of that name that you can interrogate, I really
 want people to think of the private methods as being in a different
 namespace so that there's no confusion about the fact that you can
 have a private method and a public method of the same name.

Er, but can you ever have a public method that begins with an underscore
under your new system?  If not, then there'd never be any of the overlap
that you want people not to be confused about.  See, now I'm confused...

I get this part:

 The problem with
 
 $?SELF.:foo()
 
 is that people see that as a .: operator on the foo method.

and like I said, I'm not insistent on using the colon.  But I would like to
find a way to remove the proposed contextual magic of the leading underscore
and replace it with something a bit more explicit and obvious--in both the
calling syntax and the declaration syntax.

So, the problem looks like this.  We want to find a way to:

* Define a private rw attribute named foo with an auto-generated
  non-virtual accessor.

* Define a public rw attribute named foo with an auto-generated
  virtual accessor.

* Call both of the accessors above with no ambiguity between the calls,
  even though both attributes have the same name.

The proposed solution:

# Define a private rw attribute named foo with an auto-generated
# non-virtual accessor.
has $_foo;

# Define a private rw attribute named foo with an auto-generated
# non-virtual accessor.
has $.foo is rw;

# Call both of the accessors above with no ambiguity between the calls,
# even though both attributes have the same name.
$?SELF._foo(); # private accessor
$?SELF.foo();  # public accessor

kind of sidesteps the same name issue by, well, not giving both the
attributes the same name.  Instead of two attributes both named foo, the
private one is now named _foo.  This makes the accessor calls unambiguous,
but it doesn't really succeed in emphasizing the separateness of the private
and public namespaces.

Since my goal is to remove the _ magic, I first have to find a way to
differentiate a private rw attribute with an auto-generated non-virtual
accessor from a private rw attribute with no auto-generated accessor.  I
proposed some sort of trait for that earlier:

  # private rw, no accessors, not virtual, name lexically scoped
  has $foo;

  # private rw, rw accessor, not virtual, name class scoped
  has $foo is private;

where the private name is up for grabs.  Or it could be turned around:

  has private $foo;

The next problem to solve is how to differentiate the calls.  The colon is
out because it looks like an operator.  The attribute names are really both
foo, so we can't use the accessor name itself to differentiate.

But both those two foos are in separate namespaces, right?  That's why we
can have both of them in the same class.  So how do we indicate the
namespace separation in the call?  In the spirit of the (now dead?) SUPER::
from Perl 5, this immediately springs to mind:

$?SELF.foo();  # public
$?SELF.PRIVATE::foo(); # private

That's ugly and long, but at least it's clear.  And it doesn't look like an
operator, that's for sure.  How about some shorter alternatives:

$?SELF.OWN::foo();
$?SELF.MY::foo();

The bottom line, I think, is that if you really want private and public
accessors to live in totally different namespaces, you need to explicitly
namespace one or both of the calls.  Name mangling isn't enough.  For
example, imagine this:

  # private rw, no accessors, not virtual, name lexically scoped
  has $foo;

  # private rw, rw _foo accessor, not virtual, name class scoped
  has $foo is private;

  $?SELF.foo();  # public
  $?SELF._foo(); # private

A silly example, perhaps, but it does make two attributes both named foo,
one public and one private.  The calls are disambiguated because the
auto-generated non-virtual accessor for the private attribute has a leading
underscore added to the actual attribute name--IOW, name mangling.  But now
look at this:

  # private rw, no accessors, not virtual, name lexically scoped
  has $foo;

  # private rw, rw _foo accessor, not virtual, name class scoped
  has $foo is private;

  has $._foo; # BOOM - compile-time error: method _foo() already exists

  method _foo { ... } # ditto

Ah ha! you say.  Isn't that an example of the private interface
interfering with the public interface?  Exactly--but AFAICT, the original
proposal suffers from the same problem!

  # private rw, no accessors, not virtual, name lexically scoped
  has $foo;

  # private rw, rw _foo accessor, not virtual, name class scoped
  has $_foo;

  has $._foo; # BOOM - compile-time error: method _foo() already exists

  method _foo { ... } # ditto

The point is, if you really want to the namespaces of the public and private
attribute accessors to be entirely isolated from each 

Re: Do I need has $.foo; for accessor-only virtual attributes?

2005-07-22 Thread John Siracusa
Ack, I screwed up that last email with some bad copy and paste.  Ignore it
in favor of this one please :)

---

On 7/22/05 11:37 AM, Larry Wall wrote:
 The problem I have with is private is that, while there may very
 well be a trait of that name that you can interrogate, I really
 want people to think of the private methods as being in a different
 namespace so that there's no confusion about the fact that you can
 have a private method and a public method of the same name.

Er, but can you ever have a public method that begins with an underscore
under your new system?  If not, then there'd never be any of the overlap
that you want people not to be confused about.  See, now I'm confused...

I get this part:

 The problem with
 
 $?SELF.:foo()
 
 is that people see that as a .: operator on the foo method.

and like I said, I'm not insistent on using the colon.  But I would like to
find a way to remove the proposed contextual magic of the leading underscore
and replace it with something a bit more explicit and obvious--in both the
calling syntax and the declaration syntax.

So, the problem looks like this.  We want to find a way to:

* Define a private rw attribute named foo with an auto-generated
  non-virtual accessor.

* Define a public rw attribute named foo with an auto-generated
  virtual accessor.

* Call both of the accessors above with no ambiguity between the calls,
  even though both attributes have the same name.

The proposed solution:

  # Define a private rw attribute with an auto-generated
  # non-virtual accessor.
  has $_foo;

  # Define a private rw attribute with an auto-generated
  # non-virtual accessor.
  has $.foo is rw;

  # Call both of the accessors above with no ambiguity between the calls,
  # even though both attributes have the same name.
  $?SELF._foo(); # private accessor
  $?SELF.foo();  # public accessor

kind of sidesteps the same name issue by, well, not giving both the
attributes the same name.  Instead of two attributes both named foo, the
private one is now named _foo.  This makes the accessor calls unambiguous,
but it doesn't really succeed in emphasizing the separateness of the private
and public namespaces.

Since my goal is to remove the _ magic, I first have to find a way to
differentiate a private rw attribute with an auto-generated non-virtual
accessor from a private rw attribute with no auto-generated accessor.  I
proposed some sort of trait for that earlier:

  # Define a private rw attribute named foo with an auto-generated
  # non-virtual accessor.
  has $.foo is rw;

  # Define a private rw attribute named foo with an auto-generated
  # non-virtual accessor.
  has $foo is private rw;

where the private name is up for grabs.  Or it could be turned around:

  has private $foo;

The next problem to solve is how to differentiate the calls.  The colon is
out because it looks like an operator.  The attribute names are really both
foo, so we can't use the accessor name itself to differentiate.

But both those two foos are in separate namespaces, right?  That's why we
can have both of them in the same class.  So how do we indicate the
namespace separation in the call?  In the spirit of the (now dead?) SUPER::
from Perl 5, this immediately springs to mind:

$?SELF.foo();  # public
$?SELF.PRIVATE::foo(); # private

That's ugly and long, but at least it's clear.  And it doesn't look like an
operator, that's for sure.  How about some shorter alternatives:

$?SELF.OWN::foo();
$?SELF.MY::foo();

The bottom line, I think, is that if you really want private and public
accessors to live in totally different namespaces, you need to explicitly
namespace one or both of the calls.  Name mangling isn't enough.  For
example, imagine this:

  # Define a private rw attribute named foo with an auto-generated
  # non-virtual accessor named _foo
  has $foo is private rw;

  # Define a private rw attribute named foo with an auto-generated
  # non-virtual accessor named foo
  has $.foo is rw;

  $?SELF.foo();  # public
  $?SELF._foo(); # private

A silly example, perhaps, but it does make two attributes both named foo,
one public and one private.  The calls are disambiguated because the
auto-generated non-virtual accessor for the private attribute has a leading
underscore added to the actual attribute name--IOW, name mangling.  But now
look at this:

  # Define a private rw attribute named foo with an auto-generated
  # non-virtual accessor named _foo
  has $foo is private rw;

  # Define a private rw attribute named foo with an auto-generated
  # non-virtual accessor named foo
  has $.foo is rw;

  has $._foo; # BOOM - compile-time error: method _foo() already exists

  method _foo { ... } # ditto

Ah ha! you say.  Isn't that an example of the private interface
interfering with the public interface?  Exactly--but AFAICT, the original
proposal suffers from the same problem!

  # Define a private rw attribute with an auto-generated
  # non-virtual accessor.
 

Re: Do I need has $.foo; for accessor-only virtual attributes?

2005-07-22 Thread Larry Wall
On Fri, Jul 22, 2005 at 12:53:45AM -0700, Brent 'Dax' Royal-Gordon wrote:
: Larry Wall [EMAIL PROTECTED] wrote:
:  $x is visible only in the rest of the lexical scope.  In contrast,
:  $_y would presumably still be visible if the class were reopened.
: 
: This strikes me as an exceedingly bad idea.
: 
: Encapsulation is a very good thing, and I'm glad it's being added to
: Perl 6.  But once in a while, you really *do* need to break
: encapsulation.  Maybe a shortsighted module author didn't add an
: accessor you need, or maybe you're doing something highly magical for
: (e.g.) debugging.  In any case, though, you'll need an escape hatch,
: and I really think extending a class should be it.  By extending a
: class, you're explicitly saying I'm going to butt into your affairs;
: at this point, if you're not sure what you're doing, you're probably
: going to mess things up *anyway*.

With sufficient work it will almost certainly be possible to excavate
the lexical scope of the class and get back to the $x proxy somehow.
We are under no obligation to make that easy, however.

: Also note how subtle this point is (it's about the only point I didn't
: get from the original message); the degree to which it requires the
: class's programmer to predict how others might want to extend his
: class; and the syntactic kludge required to specify it (namely, the
: sometimes-magical underscore).  I really think this is a very fine
: distinction, which programmers will get wrong half the time, and which
: you don't even have enough syntax to cope with *anyway*.

It's almost certainly the case that ordinary programs will ignore the
$_x option in most cases.  The default submethods will manage $_x as
the backing store for $.x transparently.  Only if you want to write
your own BUILD or want to trust other classes will you have to deal
much with the $_x form, and neither of those are exactly newbie pursuits.

In any event, the fact that reopened class scopes can see $_x is just
sort of an accident of being associated with $.x, since the $.x name
(or at least the .x name) has to be stored in the class's package.
Even reopened classes should probably prefer $.x over $_x except in
those cases where explicit de-virtualization is necessary.

But as usual, I'm seeing these issues sideways to everyone else, which
means I could certainly be blind to something that's obvious to others.

Hmm, would it help if the devirtualized form were $._x instead
of $_x?  Perhaps that shows the relationship better.  (It would
still imply that _x is the corresponding private method, of course).
But it would further discourage people from by default declaring all
their private variables as $._foo, which is probably a good thing.
It would also make _ no longer a kind of pseudo-twigil, and create
a symmetry between $._foo and $obj._foo.  Then then . twigil is *the*
mark of a self-call.

Larry


Re: Do I need has $.foo; for accessor-only virtual attributes?

2005-07-22 Thread John Siracusa
Third time's the charm...really.  Please ignore the last two messages from
me in favor of this one please.  Sigh**2.

---

On 7/22/05 11:37 AM, Larry Wall wrote:
 The problem I have with is private is that, while there may very
 well be a trait of that name that you can interrogate, I really
 want people to think of the private methods as being in a different
 namespace so that there's no confusion about the fact that you can
 have a private method and a public method of the same name.

Er, but can you ever have a public method that begins with an underscore
under your new system?  If not, then there'd never be any of the overlap
that you want people not to be confused about.  See, now I'm confused...

I get this part:

 The problem with
 
 $?SELF.:foo()
 
 is that people see that as a .: operator on the foo method.

and like I said, I'm not insistent on using the colon.  But I would like to
find a way to remove the proposed contextual magic of the leading underscore
and replace it with something a bit more explicit and obvious--in both the
calling syntax and the declaration syntax.

So, the problem looks like this.  We want to find a way to:

* Define a private rw attribute named foo with an auto-generated
  non-virtual accessor.

* Define a public rw attribute named foo with an auto-generated
  virtual accessor.

* Call both of the accessors above with no ambiguity between the calls,
  even though both attributes have the same name.

The proposed solution:

  # Define a private rw attribute with an auto-generated
  # non-virtual accessor.
  has $_foo;

  # Define a public rw attribute with an auto-generated
  # virtual accessor.
  has $.foo is rw;

  # Call both of the accessors above with no ambiguity between the calls,
  # even though both attributes have the same name.
  $?SELF._foo(); # private accessor
  $?SELF.foo();  # public accessor

kind of sidesteps the same name issue by, well, not giving both the
attributes the same name.  Instead of two attributes both named foo, the
private one is now named _foo.  This makes the accessor calls unambiguous,
but it doesn't really succeed in emphasizing the separateness of the private
and public namespaces.

Since my goal is to remove the _ magic, I first have to find a way to
differentiate a private rw attribute with an auto-generated non-virtual
accessor from a private rw attribute with no auto-generated accessor.  I
proposed some sort of trait for that earlier:

  # Define a public rw attribute with an auto-generated
  # virtual accessor.
  has $.foo is rw;

  # Define a private rw attribute named foo with an auto-generated
  # non-virtual accessor.
  has $foo is private rw;

where the private name is up for grabs.  Or it could be turned around:

  has private $foo;

The next problem to solve is how to differentiate the calls.  The colon is
out because it looks like an operator.  The attribute names are really both
foo, so we can't use the accessor name itself to differentiate.

But both those two foos are in separate namespaces, right?  That's why we
can have both of them in the same class.  So how do we indicate the
namespace separation in the call?  In the spirit of the (now dead?) SUPER::
from Perl 5, this immediately springs to mind:

$?SELF.foo();  # public
$?SELF.PRIVATE::foo(); # private

That's ugly and long, but at least it's clear.  And it doesn't look like an
operator, that's for sure.  How about some shorter alternatives:

$?SELF.OWN::foo();
$?SELF.MY::foo();

The bottom line, I think, is that if you really want private and public
accessors to live in totally different namespaces, you need to explicitly
namespace one or both of the calls.  Name mangling isn't enough.  For
example, imagine this:

  # Define a private rw attribute named foo with an auto-generated
  # non-virtual accessor named _foo
  has $foo is private rw;

  # Define a public rw attribute named foo with an auto-generated
  # virtual accessor also named foo
  has $.foo is rw;

  $?SELF.foo();  # public
  $?SELF._foo(); # private

A silly example, perhaps, but it does make two attributes both named foo,
one public and one private.  The calls are disambiguated because the
auto-generated non-virtual accessor for the private attribute has a leading
underscore added to the actual attribute name--IOW, name mangling.  But now
look at this:

  # Define a private rw attribute named foo with an auto-generated
  # non-virtual accessor named _foo
  has $foo is private rw;

  # Define a public rw attribute named foo with an auto-generated
  # virtual accessor also named foo
  has $.foo is rw;

  has $._foo; # BOOM - compile-time error: method _foo() already exists

  method _foo { ... } # ditto

Ah ha! you say.  Isn't that an example of the private interface
interfering with the public interface?  Exactly--but AFAICT, the original
proposal suffers from the same problem!

  # Define a private rw attribute with an auto-generated
  # non-virtual accessor.
  has 

Re: Do I need has $.foo; for accessor-only virtual attributes?

2005-07-22 Thread TSa (Thomas Sandlaß)

Larry Wall wrote:

The problem I have with is private is that, while there may very
well be a trait of that name that you can interrogate, I really
want people to think of the private methods as being in a different
namespace so that there's no confusion about the fact that you can
have a private method and a public method of the same name.  And the
reason I want that is because I strongly believe that private methods
must be absolutely invisible to the public interface, and confusing
the namespaces puts you in a situation where adding a private method
can clobber public inheritance of the same name.

Even worse, it clobbers your private interface.  As soon as you say

method foo() is private {...}

then you can't call $?SELF.foo() and expect to get the public .foo method.
Putting the difference as part of the name forces people to distinguish

$?SELF.foo()
$?SELF._foo()

on the call end.  And the _ has the advantage of being *perceived* as
part of the name.


I start to understand the problem I have with perceiving this.

You think of the name ::foo beeing looked up somehow *in* the object
you want to call on, while I always assumed that the name ::foo is
looked up first. In a method invocation expression this lookup has
to yield a method implementation that has got an invocant type that
is compatible with the one the caller wants to put in.

If ::foo shall not be visible why not arrange for the lookup to fail?
Failing *look*up and invisibility are---linguistically spoken---very
related concepts, or not?

This method-first approach has the added benefit that anyone can place
a compatible method into a lexically closer scope than the one they want
to overwrite. If the closeness still prevents the call because of lacking
specificity a simple

  temp $object does MyStuff;

and a method in scope that is specialized on .does(MyStuff) hardly leaves
outsiders a chance to prevent the dispatch! The same thing without temp
might be construed as anti-social by whomever gave you $object ;)

The otherway round should look more like $?SELFfoo() or SELF::foo().
Hmm, and nullary .foo performs the lookup on $_ or some such. Honestly
I don't understand why the vtbl implementation detail of e.g. C++ is
taken as template for Perl6 SMD OO.

Private methods of an object come into play because the dispatch of
a publicly visible method is called. The private method must be in
scope there. The only requirement on the name is to not leak out into
public namespace.



 The problem with

$?SELF.:foo()

is that people see that as a .: operator on the foo method.


Which is a *BIG* problem in an Operator Oriented Language!
--
TSa (Thomas Sandlaß)




Re: Do I need has $.foo; for accessor-only virtual attributes?

2005-07-22 Thread TSa (Thomas Sandlaß)

Larry Wall wrote:

$x is visible only in the rest of the lexical scope.  In contrast,
$_y would presumably still be visible if the class were reopened.


Which brings me to the question how the name information is told
to a prospective user if the source code of the the first definition
shall not be disclosed. I mean of course there is the documentation
but I thought more of a machine readable form. Some kind of a interface
definition of a package.



:   # or does class scope mean shared by all instances
:   # and lexically scopes per instance?

Class scope is basically package scope.  For instance attributes and
methods the package contains proxies representing the slots in the
actual instance.


Sorry, this proxy is the invocant, right? And the type system ensures
compatibility to the methods expectations. This is to me the whole point
in the method call procedure: to bind the invocant to the variables of
the method with respect to the invocant. Since variables in Perl6 code
bear one of the four sigils Code, $Item, @Array and %Hash this binding
to the invocant is simply indicated by the . twigil and supervised by
the type system.



Sure, if you want to declare an attribute containing a code reference.
But  doesn't have much to do with the call syntax in any event,
whether you're calling subs or methods.  You can declare an attribute
as .foo and call it as $.foo without a problem, since it's just
$?SELF.foo() either way, and the accessor methods are not associated
with sigils.  I think $.foo and .foo are synonymous as attributes,
except insofar as we can probably deduce that .foo is dealing with
a sub ref and not just any old scalar value.


Sorry, I meant the  sigil as generic Code type markup which includes
in particular methods on behalf of the invocant. Actually I see no
point in assuming sub ref for . but a ref to a method with the
invocant type as specializer. The type information for an object that
is blessed into a type comes of course from just the artifact from
the blessing, however it is retrieved from the invocant.

So with these two things at hand a method invocation can be spawned:
1) the invocant ref
2) a method ref
All referential expressions in the code block of the method are
bound according to the runtime representation of the object in that
moment.



: * All roles can write completely private $x attributes that are not
: 	visible outside their lexical scope but are nevertheless 
: 	per-instance.
: 
: I understand that correctly, that $x in
: 
:role Foo { has $x = 7; method foo { $x++ } }
: 
: denotes a reference to an Item from the data environment of the object

: that foo is invoked on.

I don't know what you mean by data environment.  The second
occurrence of $x denotes the generic proxy declared by the has
that represents an eventual slot in the actual instance.  This slot
presumably has no other obvious name to any other role or to the
class that composes this role, though presumably there's an internal
way to get back from a particular slot to the slot's metadata, which
presumably knows which role supplied the definition.


With data environment I mean the stuff reachable through the invocant.
The actual type of the invocant and the method's formal invocant type
specify what is available through the link as long as the invocation
persists.



: The type of the $?SELF that Foo is composed into
: obviously is a subtype of Foo. What happens with this hidden payload if
: the object changes its type such that it is no Foo anymore? E.g. by
: undefining the slot .Foo::foo?

Um, people who undefine functions that are going to be called later get
what they deserve.  As for what happens to $x's slot in the absence
of the lexical reference from Foo::foo, I expect the metadata would
still have pointers to it so it wouldn't necessarily be reclaimed
unless you told the object that is undoes Foo.  Or to look at it
another way, all the objects that do Foo have a closure over that
$x proxy, so it's not going to go away until everyone forgets about
the Foo role itself.


Ups, I hoped that the type system would find out mismatches of the
objects actual structure and the methods expectations of it. Essentially
rendering the method in question not applicable to the object anymore.
BTW, what is the inverse operation of bless? Expel?
--
TSa (Thomas Sandlaß)




Re: Do I need has $.foo; for accessor-only virtual attributes?

2005-07-22 Thread chromatic
On Fri, 2005-07-22 at 20:35 +0200, TSa (Thomas Sandlaß) wrote:

 Ups, I hoped that the type system would find out mismatches of the
 objects actual structure and the methods expectations of it. Essentially
 rendering the method in question not applicable to the object anymore.

I'm not sure that scanning every active object at every sequence point
is feasable in the face of rand() and AUTOMETH().  At some point I'm
willing to say that if you lie about what your classes can do and
someone catches you, you'll suffer the consequences.

-- c



Re: Do I need has $.foo; for accessor-only virtual attributes?

2005-07-22 Thread Matt Diephouse
Larry Wall [EMAIL PROTECTED] wrote:
 On Thu, Jul 21, 2005 at 03:25:17PM -0400, John Siracusa wrote:
 : Damian may not like the colon, but I couldn't help thinking that the _
 : could be replaced with : and things would be cleaner.  Example:
 
 Well, but the _ really is part of the name, insofar as it's trying to
 isolate the namespace.  Even with : we had to say that it would probably
 be stored in the symbol table with the leading colon.  Plus history is
 on the side of leading _ meaning private implementation detail, and
 the : is awfully confusing in the neighborhood of adverb pairs.  If it
 were just sigiled variables, the : would probably be fine, but
 
 method :foo() {...}
 
 just has a strangeness to it that won't go away.  Arguably that's a feature,
 but I'm mostly worried with visual confusion with all the other colons
 in Perl 6.

Just wanted to chip in here and say that I *do* think that its
strangeness is a feature. History may be on the side of _, but
consider that : wasn't valid syntax.

I haven't written enough Perl 6 to say whether or not this is
confusing with adverb pairs, but I love the colon for private
methods/attributes and it's the one thing separating your new thinking
from my ideal Perl 6 OO.

-- 
matt diephouse
http://matt.diephouse.com


Re: Do I need has $.foo; for accessor-only virtual attributes?

2005-07-21 Thread Larry Wall
On Thu, Jul 21, 2005 at 05:16:39PM +1200, Sam Vilain wrote:
: Making $.foo =:= $?SELF.foo, and getting to the raw attribute $.SUPER::foo
: seems like the better solution to me.  But of course, it would, because 
: that's
: how *I* program, and $?SELF != all(@coders).
: 
: Then we could even sneak in making $.foo(bar) a not-so-offensive ./foo(bar),
: with ($.foo)(bar) meaning what $.foo(bar) currently means.  But that really
: is a seperate issue, and speculation of it meaningless if we retain the
: current specified behaviour.

That's kind of the direction I've been thinking while I was driving,
but there are many ramifications.  Of course, the nice thing about
ramifications is that it presents an opportunity to possibly clean
up some other infelicities, such as getting rid of the privacy colon,
which doesn't play well with the rest of the language, and which Damian
has been wanting to get rid of.  It also lets us do some unification
of the private variables with the internal representation of public
variables, something Luke has been asking about for ages.  It solves
the virtual redefinition problem posed by Sam, and it unifies the
concept of attribute and method slots under a single syntax.  Oh,
it also is a solution to the self-call problem.

At the moment I'm thinking of something along these lines:

has $x; # private rw, no accessors, not virtual, name lexically scoped

has $_x;# private rw, rw _x accessor, not virtual, name class scoped

has $.x;# has read-only method
# $.x always virtual
# implies existence of real $_x internal variable
# $.x is itself read-only even in this class
# $_x may be set in methods or submethods
# both names are class scoped

has $.x is rw;
# has rw virtual method
# $.x is also always virtual
# implies existence of real $_x internal variable
# $.x is virtually rw in this class
# $_x is non-virtually rw in this class
# setting $_x limited to submethods
# warning if you set $_x in ordinary method

method x () {...}
# as before

method _x () {...}
# an explicitly private method

and possibly

has method x () {...}
# implicitly private method, not callable by trustees
# lexically scoped name like has $x
# could be my method instead

Other thinkings:

* Any self method can be called via $.x(@args) syntax, short for
$?SELF.x(@args).

* Any private method can be called via $_x(@args) syntax, short for
$?SELF._x(@args), assuming the private call is allowed at all.

* Trusted classes can use the $other._x(@args) syntax to call your private
accessors, but only on $_x attributes and _x methods, not on completely
private $x attributes.

* @.x(@args) is short for $?SELF.x(@args)[]

* %.x(@args) is short for $?SELF.x(@args){}

* .x(@args) is short for $?SELF.x(@args).

* Extra parens are required when using this syntax to return a function
pointer that you then want to call, either $.x()() or ($.x)().  (Or
maybe we make .x(@args) imply one set of parens.)

* All roles can write their shared attributes as $.x and not worry
about whether the class declares them or not.

* All roles can write completely private $x attributes that are not
visible outside their lexical scope but are nevertheless per-instance.

* All roles can write explicitly shared $_x attributes that are private
to the class but visible to other roles and trusted classes.

* You may not declare both $_x and $.x because a declaring of $.x is
actually declaring $_x underneath.

* You *may* declare both $x and $.x because they are invisible to each 
other.
* has $x has no effect on method dispatch, either public or private.

* has $_x has no effect on public method dispatch.

* Don't need to topicalize self any more.

* .foo can (again) always be the topic without warnings.

Have at it...

Larry


Re: Do I need has $.foo; for accessor-only virtual attributes?

2005-07-21 Thread TSa (Thomas Sandlaß)

HaloO Sam,

you wrote:

This in turn implies that the $.foo syntax is, in general, bad
practice!


Yup.


I claim the opposit. But I might have a very different meaning in mind
when I say that. So it's opposit in an orthogonal direction :)



Not very huffmanised, is it?


The syntax is just right for the statefull, imperative programming style.
If that is not your thing, so be it.


Making $.foo =:= $?SELF.foo, and getting to the raw attribute 
$.SUPER::foo


Hmm? Isn't a $ sigil expression a single scalar typed, referential
expression anymore? The secondary . sigil is in my eyes just perfect
to express self reference! If I use %.armleft to scratch %.legright
it is pretty much clear which particular parts of my body are involved.
And if I give a rw reference to $.guts to a surgeon method it is just one
possible result that some parts have become undefined or look funny ;)

And yes, this means a *dynamic* change of self type! E.g. a changing
$.belly_circumference could change a man from .does(LeightWeight) to
.does(HeavyWeight).

What I do *not* understand is what or where $.SUPER::brain should
refer to. If Perl6 avoids the problem of 'schizophrenic self reference'
where some methods make false assumptions about the object layout
or have access to hidden parts then all methods which shall be applicable 
to the object's referential environment must be type sound. This means for
example that the type system prevents dispatches to base class methods 
even though the invocant is instanciated from a derived class. This is a

typical example where Rotweiler instances are *not* a subtype of Dog
instances---at least not as far as playing is concerned.

The example with the $.collar in the Rotweiler class could be
solved by forcing the slot into outside constness which has
the side-effects that the Pet::loose_collar method is not applicable
and thus the $?SELF.lose_collar() call in Dog::play has to dispatch 
elsewhere or fail! In other words: Rotweiler.does(Dog::play) is false!

A strong type system can find that out, a weaker one let's the code
die in Pet::loose_collar on const assignment.


Then we could even sneak in making $.foo(bar) a not-so-offensive 
./foo(bar),

with ($.foo)(bar) meaning what $.foo(bar) currently means.  But that really
is a seperate issue, and speculation of it meaningless if we retain the
current specified behaviour.


I'm seeking a solution along the ideas of homogenious self reference
as outlined above. This would e.g. allow the .foo code ref to mean
a ref to the most specific method applicable to the self type unless
the programmer has arranged that something else is stored there.
As long as the method requires arguments there is just the one char
inconvenience of typing .foo(1,2) instead of .foo(1,2) or whatever
syntax implicitly derefs and calls .foo with $?SELF as the invocant.

Then there is also room for some dwimmery for dispatching .foo through
$?SELF when the type of $_ would fail the dispatch. So from a certain
point of view I like $Larry's ruling that the compiler has to statically
insure that the self type puts the invocant into a fair position for the
dispatch at hand. Perl6 is (type)strong in the source ;)


Another thing I do not understand from a typing point of view is how
perlkind expects a simple .foo expression in the lexical scope of a
class which defines a method foo to be usefull on a random $_ with a
type that is incompatible with the $?SELF type of the invocant of the
method that this .foo call happens to be written. An example:

   class FooDefiner
   {
  has $.text = 'FooDefiner hit';

  method foo { say $.text }

  method foocaller
  {
 for 1..3 { .foo } # 1
 for 1..3 {  foo } # 2
  }
   }

I think compile time name lookup in both lines resolves to
FooDefiner::foo which requires a self type of ::FooDefiner
and I think that Int.does(FooDefiner::foo) is false. So an
invocation of FooDefiner::foocaller would simply produce
a type error or six warnings and no printout if the foo calls
are dispatched over $_, right?


Regards,
--
TSa (Thomas Sandlaß)




Re: Do I need has $.foo; for accessor-only virtual attributes?

2005-07-21 Thread John Siracusa
On 7/21/05, Larry Wall [EMAIL PROTECTED] wrote:
 Have at it...

The only thing I immediately don't like is the use of the normal identifier
character _ to indicate the specialness of a particular variable (or
attribute or whatever we're calling them these days).  IMO, a _ should
just be a _ no matter where it occurs.  Making a leading _ mean
something special (triggering a slew of new semantics) in a particular
context seems a bit hacky to me.

Damian may not like the colon, but I couldn't help thinking that the _
could be replaced with : and things would be cleaner.  Example:

has $x; # private rw, no accessors, not virtual, name lexically scoped

has $:x;# private rw, rw _x accessor, not virtual, name class scoped

has $.x;# has read-only method
# $.x always virtual
# implies existence of real $:x internal variable
# $.x is itself read-only even in this class
# $:x may be set in methods or submethods
# both names are class scoped

...and so on.

Other than that, I like where it's going.  I would like to see some example
scenarios to convince myself that it really does address the concerns
indicated at the start of the explanation, however.  Maybe Luke and Sam can
whip some up? :)

-John




Re: Do I need has $.foo; for accessor-only virtual attributes?

2005-07-21 Thread TSa (Thomas Sandlaß)

Larry Wall wrote:

has $x; # private rw, no accessors, not virtual, name lexically scoped

has $_x;# private rw, rw _x accessor, not virtual, name class scoped


Even if I come across as intellectually handicapped but could
someone help me over this mental bridge: What is the difference
between these two scopes?

class Foo
{
#class scope starts here

  has $x;  # where does this go if not Foo::x

  has $_y; # this goes into Foo::_y

  # both $x and $_y can be used in code from here on
  # and refer to the same two things respectively, right?

  # or does class scope mean shared by all instances
  # and lexically scopes per instance?

#class scope ends here
}




Other thinkings:

* Any self method can be called via $.x(@args) syntax, short for
$?SELF.x(@args).


Isn't  the code sigil?




* All roles can write completely private $x attributes that are not
visible outside their lexical scope but are nevertheless per-instance.


I understand that correctly, that $x in

   role Foo { has $x = 7; method foo { $x++ } }

denotes a reference to an Item from the data environment of the object
that foo is invoked on. The type of the $?SELF that Foo is composed into
obviously is a subtype of Foo. What happens with this hidden payload if
the object changes its type such that it is no Foo anymore? E.g. by
undefining the slot .Foo::foo?


Regards,
--
TSa (Thomas Sandlaß)




Re: Do I need has $.foo; for accessor-only virtual attributes?

2005-07-21 Thread Paul Seamons
On Thursday 21 July 2005 12:48 pm, Larry Wall wrote:
     * Don't need to topicalize self any more.

     * .foo can (again) always be the topic without warnings.

Thank you.

Do the following exist then:

   has @x;  # private, lexically scoped

   has @_x; # private, class scoped, rw _x accessor

   has @.x; # read only, implies @_x for storage, is virtual ($obj.x)

   has @.x is rw; # implies @_x for storage, is virtual

   has %y;  # private, lexically scoped

   has %_y; # private, class scoped, rw _y accessor

   has %.y; # read only, implies %_y for storage, is virtual ($obj.y)

   has %.y is rw; # implies %_y for storage, is virtual

Paul


Re: Do I need has $.foo; for accessor-only virtual attributes?

2005-07-21 Thread Larry Wall
On Thu, Jul 21, 2005 at 02:29:33PM -0600, Paul Seamons wrote:
: On Thursday 21 July 2005 12:48 pm, Larry Wall wrote:
:      * Don't need to topicalize self any more.
: 
:      * .foo can (again) always be the topic without warnings.
: 
: Thank you.
: 
: Do the following exist then:
: 
:has @x;  # private, lexically scoped
: 
:has @_x; # private, class scoped, rw _x accessor
: 
:has @.x; # read only, implies @_x for storage, is virtual ($obj.x)
: 
:has @.x is rw; # implies @_x for storage, is virtual
: 
:has %y;  # private, lexically scoped
: 
:has %_y; # private, class scoped, rw _y accessor
: 
:has %.y; # read only, implies %_y for storage, is virtual ($obj.y)
: 
:has %.y is rw; # implies %_y for storage, is virtual

Yes, the sigil is fairly orthogonal to all this, hopefully.

Larry


Re: Do I need has $.foo; for accessor-only virtual attributes?

2005-07-21 Thread Stevan Little

Larry,

This means that Roles are now first-class-ish things. Meaning they 
cannot just simply be composed into classes since now we have to keep a 
table of elements which are private to a Role.


I personally don't like this, I think it brings us back to Mix-ins and 
(possibly) looses some of the benefits of Roles. But that is just my 
initial gut reaction. I am going to have to let is sink in a little 
more to know for sure. In the meantime I have some questions:


On Jul 21, 2005, at 2:48 PM, Larry Wall wrote:

* All roles can write their shared attributes as $.x and not worry
about whether the class declares them or not.


I assume they need not worry because we can rely on conflict resolution 
to deal with most issues? Or are you thinking something different?



* All roles can write completely private $x attributes that are not
visible outside their lexical scope but are nevertheless per-instance.


So the Role's scope is preserved here, as opposed to pushing $x into 
the classes scope. Correct?


* All roles can write explicitly shared $_x attributes that are 
private

to the class but visible to other roles and trusted classes.


What other roles? the other roles that the class does()? This would 
make it difficult to compose role methods into the method table without 
bringing along a lot of meta-info about from whence they came. It is 
doable I think, but adds some complexity for which I am not sure the 
cost outweighs the benefits.




Have at it...


Stevan



Re: Do I need has $.foo; for accessor-only virtual attributes?

2005-07-21 Thread Larry Wall
On Thu, Jul 21, 2005 at 05:15:34PM -0400, Stevan Little wrote:
: Larry,
: 
: This means that Roles are now first-class-ish things. Meaning they 
: cannot just simply be composed into classes since now we have to keep a 
: table of elements which are private to a Role.

Well, we've kinda been squinting at that issue from both ends for a
while now, and there's something in both views.

: I personally don't like this, I think it brings us back to Mix-ins and 
: (possibly) looses some of the benefits of Roles. But that is just my 
: initial gut reaction. I am going to have to let is sink in a little 
: more to know for sure. In the meantime I have some questions:
: 
: On Jul 21, 2005, at 2:48 PM, Larry Wall wrote:
: * All roles can write their shared attributes as $.x and not worry
:  about whether the class declares them or not.
: 
: I assume they need not worry because we can rely on conflict resolution 
: to deal with most issues? Or are you thinking something different?

No, that's correct.  We've just basically said that $.x is now a method
call, and as long as you stick to that invocation syntax it just has
to be declared as a method somewhere in the parentage/role-age of
this object.  But collisions in $.x declaration will be treated as
collisions in method declaration.

: * All roles can write completely private $x attributes that are not
:  visible outside their lexical scope but are nevertheless 
:  per-instance.
: 
: So the Role's scope is preserved here, as opposed to pushing $x into 
: the classes scope. Correct?

My notion is that $x (the name proxy) is stored in the lexical scope
of the closure that just happens to be the closure for the role,
rather than keeping a name proxy in the package.  In either case,
$x or $.x is not a real variable, but a placeholder for a particular
slot in the object.  The actual proxy could be stored in the role's
package if that makes it easier to keep track of, but I'd like the
scoping of the name to be lexical like an our in that case.  But if
we can figure out how to store it more like a my variable but still
figure out which slot it maps to when instantiated, that might be cool.
Unfortunately, it could map to different slots in different objects,
so the class in question would have to keep track of where MyRole::('$x')
actually maps to.

It's certainly possible that this notion doesn't really map terribly
well onto roles.  I was just hoping for a way to encourage people
to write private attributes, and shortening $.x to $x for that seemed
like good huffmanization in the class, as long as $x actually scopes
to being very private and doesn't interfere in any way with the
class's public interface.  So basically if the role can carry the
same idea through and allow local attributes that have guaranteed
zero influence on the interface, that'd be cool too.

: * All roles can write explicitly shared $_x attributes that are 
: private
:  to the class but visible to other roles and trusted classes.
: 
: What other roles? the other roles that the class does()?

That's what I meant.  $_x variables are the old $:x, basically, and
while they have some kind of proxy in the class's package space, the
leading character is examined to enforce namespace distinction and
some amount of privacy.  Like the old $:x they also imply private
accessors that are really little more than subs you can call with
method syntax.

: This would 
: make it difficult to compose role methods into the method table without 
: bringing along a lot of meta-info about from whence they came. It is 
: doable I think, but adds some complexity for which I am not sure the 
: cost outweighs the benefits.

It's possible that roles should only do the class-based $_x and $.x,
and leave the lexically named $x to the class, unless we can figure
out how the class can keep track of the role's lexical scope and/or
package.

But I like the $x/$.x distinction for classes, since it encourages
people to write completely private attributes to begin with, and
then maybe take the step of adding a dot when the want to provide
an accessor.

One other implementation downside I didn't mention is that it makes
it a little harder to decide that

submethod BUILD ($x) {...}

wants to set the private $x attribute.  Though in theory we can see the $x
declaration from the BUILD declaration.  However, we still get

submethod BUILD ($_x) {...}

pretty much for free.

Larry


Re: Do I need has $.foo; for accessor-only virtual attributes?

2005-07-21 Thread Larry Wall
On Thu, Jul 21, 2005 at 03:25:17PM -0400, John Siracusa wrote:
: On 7/21/05, Larry Wall [EMAIL PROTECTED] wrote:
:  Have at it...
: 
: The only thing I immediately don't like is the use of the normal identifier
: character _ to indicate the specialness of a particular variable (or
: attribute or whatever we're calling them these days).  IMO, a _ should
: just be a _ no matter where it occurs.  Making a leading _ mean
: something special (triggering a slew of new semantics) in a particular
: context seems a bit hacky to me.
: 
: Damian may not like the colon, but I couldn't help thinking that the _
: could be replaced with : and things would be cleaner.  Example:

Well, but the _ really is part of the name, insofar as it's trying to
isolate the namespace.  Even with : we had to say that it would probably
be stored in the symbol table with the leading colon.  Plus history is
on the side of leading _ meaning private implementation detail, and
the : is awfully confusing in the neighborhood of adverb pairs.  If it
were just sigiled variables, the : would probably be fine, but

method :foo() {...}

just has a strangeness to it that won't go away.  Arguably that's a feature,
but I'm mostly worried with visual confusion with all the other colons
in Perl 6.

Plus, the leading underscore would only be magical on attributes and
methods, I suspect.

Larry


Re: Do I need has $.foo; for accessor-only virtual attributes?

2005-07-21 Thread Larry Wall
On Thu, Jul 21, 2005 at 10:17:13PM +0200, TSa (Thomas Sandlaß) wrote:
: Larry Wall wrote:
: has $x;  # private rw, no accessors, not virtual, name lexically 
: scoped
: 
: has $_x; # private rw, rw _x accessor, not virtual, name class scoped
: 
: Even if I come across as intellectually handicapped but could
: someone help me over this mental bridge: What is the difference
: between these two scopes?
: 
: class Foo
: {
: #class scope starts here
: 
:   has $x;  # where does this go if not Foo::x

The name goes into the lexical scope, but it generically represents
a slot in the instance.

:   has $_y; # this goes into Foo::_y
: 
:   # both $x and $_y can be used in code from here on
:   # and refer to the same two things respectively, right?

$x is visible only in the rest of the lexical scope.  In contrast,
$_y would presumably still be visible if the class were reopened.

:   # or does class scope mean shared by all instances
:   # and lexically scopes per instance?

Class scope is basically package scope.  For instance attributes and
methods the package contains proxies representing the slots in the
actual instance.

: #class scope ends here
: }
: 
: 
: 
: Other thinkings:
: 
: * Any self method can be called via $.x(@args) syntax, short for
:  $?SELF.x(@args).
: 
: Isn't  the code sigil?

Sure, if you want to declare an attribute containing a code reference.
But  doesn't have much to do with the call syntax in any event,
whether you're calling subs or methods.  You can declare an attribute
as .foo and call it as $.foo without a problem, since it's just
$?SELF.foo() either way, and the accessor methods are not associated
with sigils.  I think $.foo and .foo are synonymous as attributes,
except insofar as we can probably deduce that .foo is dealing with
a sub ref and not just any old scalar value.

: * All roles can write completely private $x attributes that are not
:  visible outside their lexical scope but are nevertheless 
:  per-instance.
: 
: I understand that correctly, that $x in
: 
:role Foo { has $x = 7; method foo { $x++ } }
: 
: denotes a reference to an Item from the data environment of the object
: that foo is invoked on.

I don't know what you mean by data environment.  The second
occurrence of $x denotes the generic proxy declared by the has
that represents an eventual slot in the actual instance.  This slot
presumably has no other obvious name to any other role or to the
class that composes this role, though presumably there's an internal
way to get back from a particular slot to the slot's metadata, which
presumably knows which role supplied the definition.

: The type of the $?SELF that Foo is composed into
: obviously is a subtype of Foo. What happens with this hidden payload if
: the object changes its type such that it is no Foo anymore? E.g. by
: undefining the slot .Foo::foo?

Um, people who undefine functions that are going to be called later get
what they deserve.  As for what happens to $x's slot in the absence
of the lexical reference from Foo::foo, I expect the metadata would
still have pointers to it so it wouldn't necessarily be reclaimed
unless you told the object that is undoes Foo.  Or to look at it
another way, all the objects that do Foo have a closure over that
$x proxy, so it's not going to go away until everyone forgets about
the Foo role itself.

Larry


Re: Do I need has $.foo; for accessor-only virtual attributes?

2005-07-21 Thread John Siracusa
On 7/21/05 8:14 PM, Larry Wall wrote:
 On Thu, Jul 21, 2005 at 03:25:17PM -0400, John Siracusa wrote:
 The only thing I immediately don't like is the use of the normal identifier
 character _ to indicate the specialness of a particular variable (or
 attribute or whatever we're calling them these days).  IMO, a _ should
 just be a _ no matter where it occurs.  Making a leading _ mean
 something special (triggering a slew of new semantics) in a particular
 context seems a bit hacky to me.
 
 Damian may not like the colon, but I couldn't help thinking that the _
 could be replaced with : and things would be cleaner.
 
 Well, but the _ really is part of the name, insofar as it's trying to
 isolate the namespace.  Even with : we had to say that it would probably
 be stored in the symbol table with the leading colon.

Eh, an implementation detail (or, arguably, syntactic sugar for symbol table
lookups, depending on how it was really implemented in Parrot).

 Plus history is on the side of leading _ meaning private implementation
 detail

Sure, by *convention*, not as imperative magic :)

 and the : is awfully confusing in the neighborhood of adverb pairs.  If it
 were just sigiled variables, the : would probably be fine, but
 
 method :foo() {...}
 
 just has a strangeness to it that won't go away.  Arguably that's a feature,
 but I'm mostly worried with visual confusion with all the other colons
 in Perl 6.

I'm not married to the colon.  Speaking of traits and adverbs, why not use
one of those in the has declaration instead?  That'd certainly be a lot
more explicit than the magic leading underscore (although I'm at a loss as
to what the trait would be named...)

-John




Re: Do I need has $.foo; for accessor-only virtual attributes?

2005-07-21 Thread Sam Vilain

Larry Wall wrote:

: Do the following exist then:
:has @x;  # private, lexically scoped

[...]

:has %y;  # private, lexically scoped

[...]

Yes, the sigil is fairly orthogonal to all this, hopefully.


Yes, for isn't the sigil just a compact form of saying does Hash or
does Array ?  (as well as being part of the unique name, of course)

Sam.


Re: Do I need has $.foo; for accessor-only virtual attributes?

2005-07-20 Thread Piers Cawley
Sam Vilain [EMAIL PROTECTED] writes:

 Larry Wall wrote:
Users of the class includes people subclassing the class, so to them
they need to be able to use $.month_0 and $.month, even though there
is no has $.month_0 declared in the Class implementation, only
has $.month.
 We thought about defining the attribute variables that way,
 but decided that it would be clearer if they only ever refer to
 real attributes declared in the current class.

 Clearer in what way?

 This implies that you cannot;

- refactor classes into class heirarchies without performing
  code review of all methods in the class and included roles.

That's why it's generally a bad idea to use the C$.whatever forms outside
your basic accessor methods.

- wrap internal attribute access of a superclass in a subclass

Which is why it's generally a bad idea to use the C$.whatever forms outside
your basic accessor methods.

 This in turn implies that the $.foo syntax is, in general, bad
 practice!

Yup.


Re: Do I need has $.foo; for accessor-only virtual attributes?

2005-07-20 Thread Sam Vilain

Piers Cawley wrote:

  Users of the class includes people subclassing the class, so to them
  they need to be able to use $.month_0 and $.month, even though there
  is no has $.month_0 declared in the Class implementation, only
  has $.month.

We thought about defining the attribute variables that way,
but decided that it would be clearer if they only ever refer to
real attributes declared in the current class.

Clearer in what way?
This implies that you cannot;

[

  - refactor classes into class heirarchies without performing
code review of all methods in the class and included roles.

,
   - wrap internal attribute access of a superclass in a subclass
].map:{$_ ~

That's why it's generally a bad idea to use the C$.whatever forms outside
your basic accessor methods.

}

This in turn implies that the $.foo syntax is, in general, bad
practice!

Yup.


Not very huffmanised, is it?

Making $.foo =:= $?SELF.foo, and getting to the raw attribute $.SUPER::foo
seems like the better solution to me.  But of course, it would, because that's
how *I* program, and $?SELF != all(@coders).

Then we could even sneak in making $.foo(bar) a not-so-offensive ./foo(bar),
with ($.foo)(bar) meaning what $.foo(bar) currently means.  But that really
is a seperate issue, and speculation of it meaningless if we retain the
current specified behaviour.

Sam.


Re: Do I need has $.foo; for accessor-only virtual attributes?

2005-07-19 Thread Larry Wall
On Tue, Jul 19, 2005 at 02:21:44PM +1200, Sam Vilain wrote:
: Larry Wall wrote:
:   Users of the class includes people subclassing the class, so to them
:   they need to be able to use $.month_0 and $.month, even though there
:   is no has $.month_0 declared in the Class implementation, only
:   has $.month.
: We thought about defining the attribute variables that way,
: but decided that it would be clearer if they only ever refer to
: real attributes declared in the current class.
: 
: Clearer in what way?
: 
: This implies that you cannot;
: 
:   - refactor classes into class heirarchies without performing
: code review of all methods in the class and included roles.
: 
:   - wrap internal attribute access of a superclass in a subclass
: 
: This in turn implies that the $.foo syntax is, in general, bad
: practice!

Well, maybe it's bad outside of submethods, where we must have a way
to devirtualize.  I see what you're saying, but I'll have to think
about it a little.  It does seem a bit inconsistent that we're forcing
virtualization of class names within methods but not attributes.
Perhaps $.foo should be used to refer to the actual attribute
storage only within submethods, and when you declare has $.foo
you're not declaring an accessor method but rather a submethod that
wraps the actual attribute.  The question is then whether normal
methods should treat $.foo as an error or as $?SELF.foo().

Yes, I know your preference.  :-)

Anyway, I have to do a bit of driving the next two days, so hopefully
I'll have a chance to think about it s'more.  But my gut feeling here
is that we both oughta be right on some level, so it probably just
means the current design is drawing some border in the wrong place.
The right place might or might not be the method/submethod boundary.

Larry


Re: Do I need has $.foo; for accessor-only virtual attributes?

2005-07-18 Thread Larry Wall
On Mon, Jul 18, 2005 at 03:34:36PM +1200, Sam Vilain wrote:
: Say I make an accessor method for an attribute that doesn't really
: 'exist'.
: 
: For instance, a good example of this is the month_0 vs month
: properties on a date object; I want to make both look equivalent as
: real properties, but without the users of the class knowing which
: one is the real one.
: 
: Users of the class includes people subclassing the class, so to them
: they need to be able to use $.month_0 and $.month, even though there
: is no has $.month_0 declared in the Class implementation, only
: has $.month.

We thought about defining the attribute variables that way,
but decided that it would be clearer if they only ever refer to
real attributes declared in the current class.  Outside the class,
including in subclasses, you have to use the accessors, so it's always
$self.month_0 and $self.month, however you end up spelling $self...

: So, is $.month just shorthand for $?SELF.month, which happens to be
: optimised away to a variable access in the common case where the
: method month isn't defined, or has a sufficiently simple is
: accessor trait in its declaration?

Nope.  $.month is actually a primitive form that can't be expressed in
terms of method calls in the absence of knowledge about the internals
of the object's representation, which is (by default) opaque in Perl 6.
Another difference is that $.month is never virtual, while $?SELF.month
is always virtual.

: And that, in turn, $:month is actually $?SELF.(:month), where
: :month is an alias for the submethod called month.

That seems divergent in several different ways.  Like $.month, $:month
is also a primitive form that is never virtual.  Unlike $.month,
it does not actually generate a virtual accessor method at all.
It essentially generates a private subroutine accessor that you
can call as as $?SELF.:foo(), which is syntactic sugar for $:foo
only within the class and trusted classes.  Apart from that there
is *no* access to the attribute from outside the class whatsoever.
This private accessor is not at all related to submethods, which have
restricted inheritance but are otherwise callable from anywhere.
There is no aliasing from :month to month.  That colon is very
much a part of the name of the private method, so you can have

method :foo {...}   # private foo method
method foo {...}# public foo method

and there is no conflict at all.  That's because we don't want the
existence or non-existence of :foo to ever change the external
interface.

In contrast, this is illegal:

method foo {...}# public method foo
submethod foo {...} # public submethod foo

because you're trying to define two methods of the same name.

: After all, we want Roles used by Classes to have access to this virtual
: attribute coolness, too.

Roles have exactly the same virtual attribute access as classes, via
methods.  A role that is trying to access both the physical attribute
and the virtual attribute is likely to be mixing two different roles
as one role, and should probably be split.  Keeping the distinction
between $.foo and $self.foo helps enforce that.  But I suspect most of
the coolness you want to do can be just as easily expressed in the
$self.foo form.  And the part you can't is probably not so cool.

: These simple definitions should make all sorts of OO tricks possible,
: and reduces the definition of Classes to one that is purely
: functional (ie, state is just a set of functions too).

One can certainly rewrite $.foo and $:foo in terms of lower level
functional primitives, but we must be careful not to confuse those
with higher-level virtual method calls.  Otherwise we are mixing OO
interface with OO implementation, and we've already discovered in
Perl 5 that that's a Bad Idea.  Interfaces between organisms are
cleaner when their innards stay in and their outtards stay out.

Larry


Do I need has $.foo; for accessor-only virtual attributes?

2005-07-17 Thread Sam Vilain

Say I make an accessor method for an attribute that doesn't really
'exist'.

For instance, a good example of this is the month_0 vs month
properties on a date object; I want to make both look equivalent as
real properties, but without the users of the class knowing which
one is the real one.

Users of the class includes people subclassing the class, so to them
they need to be able to use $.month_0 and $.month, even though there
is no has $.month_0 declared in the Class implementation, only
has $.month.

So, is $.month just shorthand for $?SELF.month, which happens to be
optimised away to a variable access in the common case where the
method month isn't defined, or has a sufficiently simple is
accessor trait in its declaration?

And that, in turn, $:month is actually $?SELF.(:month), where
:month is an alias for the submethod called month.  After all, we
want Roles used by Classes to have access to this virtual attribute
coolness, too.

These simple definitions should make all sorts of OO tricks possible,
and reduces the definition of Classes to one that is purely
functional (ie, state is just a set of functions too).

Sam.