Re: packages vs. classes

2006-05-26 Thread Stevan Little

On 5/23/06, Sam Vilain [EMAIL PROTECTED] wrote:

Right, but we should really ship with at least a set of Meta Object
Protocol Roles, that covers the core requirements that we will need for
expressing the core types in terms of themselves;

- classes and roles
- attributes and methods
- subsets (ie constraints/subtypes)
- generics (including, by induction, nested generics)

I *think*, at this point, that's all that are necessary.


I would maybe add a protocol for instance creation. We have recently
added that to Moose, and found it very useful in terms of abstracting
out the kind of instance storage used (ARRAY based storage currently
Just Works given the right Instance sub(meta)class).

I see the instance protocol as being an important component of cross
language runtime thing. If all instances conform to, or can be made to
conform to, an base instance protocol, making Perl 6 objects which
inherit from Python objects should be fairly easy.


People can instantiate the roles that cover all that to an actual
metaclass in whatever way they like (eg,
Moose::Meta::Class-isa(Class::MOP::Class)), but not having to detect
the type and then figure out how to talk to it for at least the core of
the object system would be good.


I think the roles can serve as the core interface nessecary to
function with the base object system. As long as my metaclass .does()
the correct role, it should be able to function in the object system.
Of course the old garbage-in garbage-out rule applies, we should give
you enough meta-rope to shoot your meta-self in your meta-foot.


People can diverge completely with completely incompatible metaclasses
that don't .do those roles, the only side effect of which being that
people who write code for the standard Perl 6 metamodel will be
incompatible, and maybe some ways of setting up the class won't work
without another layer of trickery. I *think* that's what you're getting
at. Of course, it shouldn't be prohibited just because it smells.


I am not sure I like this, incompatible metaclass issues are really
really tricky and hard to debug (aka - smells *really* bad). And the
system needed to support them really can bloat the metamodel internals
in a nasty way. There are several papers out there on the subject,
none of which IMO provide a satisfactory solution. The problem then
becomes compounded by introducing the Python and Ruby metamodels into
the fray. Having a single compatability level made out of roles is not
that much of a restriction really, and keeps much of the system
interals clean and orderly. It also makes it much easier for use to
add new metamodels from other languages by just by writing a layer to
map to the core metamodel roles.

- Stevan


Re: packages vs. classes

2006-05-26 Thread Paul Hodges


--- Stevan Little [EMAIL PROTECTED] wrote:

 On 5/23/06, Sam Vilain [EMAIL PROTECTED] wrote:
  People can diverge completely with completely incompatible
  metaclasses that don't .do those roles, the only side effect
  of which being that people who write code for the standard
  Perl 6 metamodel will be incompatible, and maybe some ways
  of setting up the class won't work without another layer of
  trickery. I *think* that's what you're getting at. Of course,
  it shouldn't be prohibited just because it smells.
 
 I am not sure I like this, incompatible metaclass issues are really
 really tricky and hard to debug (aka - smells *really* bad). And the
 system needed to support them really can bloat the metamodel
 internals in a nasty way. There are several papers out there on the
 subject, none of which IMO provide a satisfactory solution. The 
 problem then becomes compounded by introducing the Python and Ruby
 metamodels into the fray. Having a single compatability level made
 out of roles is not that much of a restriction really, and keeps
 much of the system interals clean and orderly. It also makes it
 much easier for use to add new metamodels from other languages by
 just by writing a layer to map to the core metamodel roles.

my $.02
I'd say a more standard system is much better, so long as we leave a
standard set of hooks by which someone can insert a nonstandard setup.
A small API isn't a huge bloat, and is worth it, though I agree that a
full system might actually be counterproductive.

And by all that I've seen lately, the whole language is pretty
malleable that way; those who really want the nonstandard model can
take the small overhead hit of whatever internal shenanigans they need
to implement, and just about anything like that can be stuffed into a
module now, can't it?

So the upshot is, a standardized metamodel seems like the way to go to
me
/my $.02

ot
And Congrats again, gramps. May your new little one be as loved as the
language you've also labored so much to guide to maturity. ;o]
/ot

Paul

on est aisément dupé par ce qu'on aime -- Molière (one is easily fooled by 
that which one loves)
Increase in wisdom can be measured accurately by the corresponding decrease in 
anger. -- Friedrich Nietzsche
There are trivial truths and there are great Truths. The opposite of a trival 
truth is obviously false.
 The opposite of a great Truth is also true.  -- Neils Bohr

Real friends are those whom, when you must inconvenience them, are bothered 
less by it than you are. -- me. =o) 
Hodges' Rule of Thumb: Don't expect reasonable behavior from anything with a 
thumb.

__
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com 


Re: packages vs. classes

2006-05-22 Thread Sam Vilain
Larry Wall wrote:

'Course, I left out everything about prototype objects there...

The name Foo also (in context) represents an uninitialized object of
the class in question.  Any object, initialized or not, can get at
its type handlers by saying

Foo.meta
$foo.meta

and, in fact, the Foo.^bar syntax is just short for Foo.meta.bar.
  


Perhaps saying it is like:

Foo.meta.get_attribute(bar)

Would be safer. Don't want to stomp on the meta-objects.

[...]
of the actual magic being defined elsewhere.  It would be possible
to access classes et al. only via the mechanisms supplied by the
metaobject protocols, but that would be kind of like the bad old
[...]
  


Right, but we should really ship with at least a set of Meta Object
Protocol Roles, that covers the core requirements that we will need for
expressing the core types in terms of themselves;

- classes and roles
- attributes and methods
- subsets (ie constraints/subtypes)
- generics (including, by induction, nested generics)

I *think*, at this point, that's all that are necessary. They are
actually quite a useful set for the concerns I raised earlier about
automatically inferring relational information from the metamodel (if
only I knew these terms back then... ;))
http://groups.google.com/groups?threadm=200303042358.56560.sam%40vilain.net

People can instantiate the roles that cover all that to an actual
metaclass in whatever way they like (eg,
Moose::Meta::Class-isa(Class::MOP::Class)), but not having to detect
the type and then figure out how to talk to it for at least the core of
the object system would be good.

People can diverge completely with completely incompatible metaclasses
that don't .do those roles, the only side effect of which being that
people who write code for the standard Perl 6 metamodel will be
incompatible, and maybe some ways of setting up the class won't work
without another layer of trickery. I *think* that's what you're getting
at. Of course, it shouldn't be prohibited just because it smells.

On different note, there should be nice, per-class ways to make type
constraints not simply code blocks - otherwise too much reverse
engineering will be required to do the final stage of compiling typesafe
code, where you close the classes and discard all the runtime type checks.

An easy example of this is generics. With where, this is what you
write (ignore the syntax errors for now):

class Array of Str is Array where { $_.isa(Str) for @$_ }

But that sucks, because that information about the type of the container
is buried deep within the code reference, is slow, and we can't build
our methods with the right signatures. So, we write;

role Array[::T] { ... }
class Array of Str does Array[Str];

Great. Now that information is available to Array in a structured manner
and the signatures can be built correspondingly. But to represent the
core types like Mapping or Set, we also need, for instance, the unique
constraint to be represented as an object, not a code block:

For instance,

role Mapping[::T1, ::T2] does Coll[::T1, ::T2] where Unique(0);

The where Unique(0) is the important bit. What is Unique, and who
uses it? In my prototypes, I've been considering it being the job of the
composing class or role to handle that, as a meta-object method call.

So, the above might call Coll.meta.Unique(0) (look, I'm stomping all
over the meta-object now) during the composition of the Mapping role,
and it uses this to affect the methods that it builds until you get
something that behaves not entirely quite unlike a Mapping.

However feel free to continue to handwave for now. Personally I'd like
to see this synoptic before the Perl 6.0 release, to avoid the mistakes
of other (*cough* C# *cough* Java 1.5 *cough*) languages that slipped on
getting the generics in their libraries, to their ultimate detriment.

Sam.


Re: packages vs. classes {long}

2006-05-20 Thread Chip Salzenberg
On Fri, May 19, 2006 at 05:05:02PM -0700, Larry Wall wrote:
 So what's in a name?  One could say that .meta is functioning more like a
 name sigil than like a method, and the Real Name of the metaobject is
 Foo::^Bar or some such, if it needs a name.

Method, I like.  Stealth sigil, I don't like.

Generally, dependence on names for proper functioning of any programming
construct -- variable, classe, whatever -- is in my experience almost
invariably a design flaw, which ends up being rectified eventually (unless
the enclosing system dies first), sometimes at significant cost to the
thematic coherence of the system.  For example, Perl 5 acquired references,
and made anonymous subroutines, arrays, and hashes convenient.  Where the
language did not make something anonymous, modules came to the rescue (e.g.
IO::Handle).  I don't have to tell _you_ how much of Perl 4 became either
vestigial or embarrasing in the transition, and how frustrating a _partial_
adaptation to anonymity became.

Similarly, while it's taken decades, Unix variants are finally coming around
to making most filesystem operations available on file descriptors rather
than only on names.  (fchown, fchmod, flink, etc.)

So, if you want arbitrary_expression.meta to work, I think you should bite
the bullet and admit that it actually *is* a method, or attribute, or
anything else that's value-derived ... as long as it's not name-derived.
You can't sigilize a name that isn't there.

 Then maybe Foo::Bar is just a strange hash.  Or maybe it has its own
 sigil.  But from the viewpoint of Dorothy the programmer, it's the package
 that presents the public interface Oz::Wizard, and it's the metaobject
 that's trying to hide behind the metacurtain.

I think I don't understand you.
However, if I do understand you, I disagree.

Think through the use case of the entirely anonymous class -- the class
which is not only nameless in the end, but which never had a name to begin
with.

(I'm not very familiar with prototype-based programming, but if I have the
right inkling, anonymous prototype objects might even be the norm.  But at
this point I've begun speculating; so if that's wrong, ignore it.)

Such an anonymous class, and objects of such a class, respond to named
methods, to be sure; but the class *itself* has no name, and never did.
Where do its methods live?  Perhaps in a package, but of necessity that
package has no name.  (If the package name was merely obscure as opposed to
nonexistent, it could not be garbage-collected when it was no longer in use,
as its parent would continue to refer to it.)

Furthermore, and perhaps most persuasively, I can easily imagine meta
objects that have no use for a package at all, or that require several
packages to respresent the partitioning of various subfunctions.  Parrot's
classes may be such metaobjects soon, as the HLL developers clamor to have
the names introduced by the Parrot implementation completely segregated from
their own work areas.

Thus, choosing a _package_ as the owner of the primary entry point to a
class's data structures -- that is, in the common case, it's name -- makes
little sense to me.

  -

At the risk of plowing ground that has already been sold to developers:

I would suggest that the type object in Perl 6 might well be the point of
entry for the suite of (type,meta,package).  The relationships would work
like so:

type object  --  meta object {e.g. Class}  --  package {optional}
  \---  more packages? {possible}

Note that the package(s) is (are) optional.  Some metaobjects won't need
them.  For example, in Parrot, the metaobject for namespace doesn't point
to a namespace object, for chicken-and-egg reasons.  OTOH, it's possible
for some metaobjects to need more than one.

Getting back to the common case: the default behavior of Class creation will
include creating names for the type object and the package object, and
perhaps also for the metaobject, e.g.:


  Oz::Wizard::  ---+
 |
  Oz::Wizard   |
   | |
   v v
type object  --  Class  --  package
^
|
  Oz::^Wizard? ---+


Details of this second diagram are for illustration purposes only, to show
that I'm not suggesting that everything be anonymous.  My point is that the
type system should (must!) still work even if no such names are ever assigned.

I don't know the p6 lexical magic required to make it happen, but if the
Wizard type object is anonymous, it should still be possible to say

   my arbitrary_expression_returning_Wizard $gandalf;

and similarly it should be possible to use arbitrary expressions for all
other type/meta operations including introspection, modification,
subclassing, etc.
-- 
Chip Salzenberg [EMAIL PROTECTED]


Re: packages vs. classes

2006-05-19 Thread Larry Wall
On Thu, May 18, 2006 at 03:17:36PM -0700, Chip Salzenberg wrote:
: What's the relationship in perl6 between namespaces and classes?

Hmm, well, that's hard to put one's finger on, but to the first
approximation namespaces are for declarational names, while classes
can really only name things operationally.  So packages, modules,
classes, roles, subsets, enums, etc. all pretend they are packages
for purposes of naming from a global root.  Any extra semantics are
defined by the objects that support each type of declarator.  But
as container objects they all support the Package role, or some such.

The situation is analogous to the filesystem.  We have a /proc
filesystem nowadays because it's convenient to name certain
abstractions in the OS as if they were ordinary files despite most
of the actual magic being defined elsewhere.  It would be possible
to access classes et al. only via the mechanisms supplied by the
metaobject protocols, but that would be kind of like the bad old
days when ps(1) had to rummage around in /dev/kmem to figure out what
to say.

: For example, given:
: 
:   package Foo { sub bar {...} }
:   class Corge { method grault {...} }
: 
: Is the full name of foo Foo::foo?

Yes, assuming that Foo is a top-level package name, and that you meant bar.

: What's the full name of grault?

Just as if the class were a package:

Corge::grault

Though nowadays for clarity we often write these as

Foo::bar
Corge::grault

instead.

: Is there a common role that Foo and Corge both do?  

As bare names they can be taken in context to mean either the package
or the type.  When necessary we can disambiguate these:

Foo.^{$x}   call .{$x} on the type metaobject
Foo::{$x}   call .{$x} on the package object

Contextually, though, a bare package name is generally taken to be a pun on
the type unless followed by ::.  So

my Corge $foo;

is not really saying much about the Corge package except that there has
to be one, and to the extent that the Corge type supports certain methods
at declaration time, those names appear to be in the Corge package.
It's quite possible that the Corge type has metamethods that let us
get at unnameable behavior, but that would generally be construed as
violating encapsulation--hopefully for a good reason--but the public
interface of a type should generally be presented declarationally
via packages and the objects they contain.

A consequence of all this is that when you use any type declarator:

module M ...
class C ...
role R ...
subset S ...
enum E ...

the name is referring to both the package and the type simultaneously,
and the type is allowed to present whatever public interface it likes,
generally via the package.  It also presents an internal declarational
interface to the innards of the declarator, so that metamethods like
has and does and is are given meaning in your class declaration.
The type also presumably controls which traits make sense on various
declarations.

Interestingly, even the tag groups of module exports are done with
the package interface currently.  The is export (:DEFAULT) trait
merely pokes the current name down into the ::DEFAULT subpackage of
the module, and it hopefully can become very efficient to import a
prepackaged set of symbols as a lump.

If this isn't answering what you were asking, please ask s'more,
and I'll try to reply when I'm not busy having a grandbaby.

Larry


Re: packages vs. classes

2006-05-19 Thread Larry Wall
'Course, I left out everything about prototype objects there...

The name Foo also (in context) represents an uninitialized object of
the class in question.  Any object, initialized or not, can get at
its type handlers by saying

Foo.meta
$foo.meta

and, in fact, the Foo.^bar syntax is just short for Foo.meta.bar.

The Foo object maybe therefore be used to reason about objects of
a class, but the Foo object itself is not the class.  Foo.meta is
the real class object.  Foo itself is just a Foo that hasn't been
defined yet.  Foo.isa(Class) is false, because there's no Class
type in Perl 6 as far as Perl 6 is concerned.  The type of metaobject
Foo.meta might be called Class if that's what the metaobject protocol
decides it should be, but Perl the Language doesn't care.  If so,
then Foo.meta.isa(Class) would be true.  But Foo.isa(Class) is still
false.

The purpose of all this is to support prototype-based programming as
well as class-based programming.  Assuming either one or the other
(in the absence of appropriate declaration) is a kind of encapsulation
violation of the .meta interface.

Larry


Re: packages vs. classes

2006-05-19 Thread Chip Salzenberg
On Fri, May 19, 2006 at 12:35:11PM -0700, Larry Wall wrote:
 If this isn't answering what you were asking, please ask s'more,
 and I'll try to reply when I'm not busy having a grandbaby.

adCONGRATULATIONSvance  :-)

 Packages, modules, classes, roles, subsets, enums, etc. all pretend they
 are packages for purposes of naming from a global root.  Any extra
 semantics are defined by the objects that support each type of declarator.
 But as container objects they all support the Package role, or some such.

The above paragraph is about half of what I was asking.  It contains a bit
of bad news: it imples that Parrot can't assume that each HLL only has one
namespace-ish class.  But I think that particular guilletine blade was
already on its way down.

The other half:

Your distinction between the type object and the class object is more than a
little disturbing to the current design issues I'm facing.  You write:

 Foo.^{$x} call .{$x} on the type metaobject
 Foo::{$x} call .{$x} on the package object

Two and a half questions and a proposal on that.

Q1: How do you disambiguate type from package in the Perl 6 namespace?
Given a class Foo::Bar, is Foo::Bar:: the package and Foo::Bar the
type? Or what?

Q1.5: If I asked why the circumflex is in there, would I regret it?

Q2: What is the object reference relationship among Foo::, Foo::Bar the
type, and Foo::Bar:: ?  (Where are the object reference arrows?)

Proposal:

In Parrotland, it seems at the moment that Parrot type objects might be best
implemented as specializations of Parrot namespace objects.  Consider:

  Defining a new class creates exactly one named object.
  Aliasing (e.g. importing) a class requires exactly one namespace operation.
  Removing a class requires deleting exactly one namespace entry.
  There is no confusion as to which object is the class object.
  There is no confusion as to what should be looked up where.

As something of a probing attack -- to provoke informative rebuttal -- I'd
like to propose that type objects should do Package.  What say?
-- 
Chip Salzenberg [EMAIL PROTECTED]


Re: packages vs. classes

2006-05-19 Thread Chip Salzenberg
On Fri, May 19, 2006 at 12:53:29PM -0700, Larry Wall wrote:
 and, in fact, the Foo.^bar syntax is just short for Foo.meta.bar.

So, you anticipated my half-question.

 The type of metaobject Foo.meta might be called Class if that's what the
 metaobject protocol decides it should be, but Perl the Language doesn't
 care.  If so, then Foo.meta.isa(Class) would be true.  But Foo.isa(Class)
 is still false.

OK, in my previous message, you should apparently read metaobject for
type object.  But I think the questions still apply, as does the proposal
that all _metaobjects_ that currently are correlated with packages should
instead just _do_ Package.
-- 
Chip Salzenberg [EMAIL PROTECTED]


Re: packages vs. classes

2006-05-19 Thread Chip Salzenberg
On Fri, May 19, 2006 at 02:51:55PM -0700, Chip Salzenberg wrote:
 On Fri, May 19, 2006 at 12:53:29PM -0700, Larry Wall wrote:
  The type of metaobject Foo.meta might be called Class if that's what the
  metaobject protocol decides it should be, but Perl the Language doesn't
  care.  If so, then Foo.meta.isa(Class) would be true.  But Foo.isa(Class)
  is still false.
 
 OK, in my previous message, you should apparently read metaobject for
 type object.  But I think the questions still apply, as does the proposal
 that all _metaobjects_ that currently are correlated with packages should
 instead just _do_ Package.

And again I must correct myself, the above doesn't make sense.

Based on what I'm seeing, the Perl 6 type object is the thing that claims
the primary name associated with a class.  Foo::Bar is the type object.
The metaobject seems to be anonymous.  And the package seems to be fairly
questionable... given how generic you want to be, the Perl 6 implmentation
probably can't assume that there is exactly one package associated with a
given type object, either directly or indirectly.
-- 
Chip Salzenberg [EMAIL PROTECTED]


Re: packages vs. classes

2006-05-19 Thread Larry Wall
On Fri, May 19, 2006 at 03:25:43PM -0700, Chip Salzenberg wrote:
: Based on what I'm seeing, the Perl 6 type object is the thing that claims
: the primary name associated with a class.  Foo::Bar is the type object.
: The metaobject seems to be anonymous.  And the package seems to be fairly
: questionable... given how generic you want to be, the Perl 6 implmentation
: probably can't assume that there is exactly one package associated with a
: given type object, either directly or indirectly.

I think the only constraint on it is that Foo::Bar.meta can't
point to two different objects.  But .meta isn't a real method--it's
more like a notation representing the blessing, in P5 terms.
Certainly different packages could share the same .meta object if
the particular kind of metaobject it points to chooses to store all
the state in the package rather than the metaobject.  In that sense
the package is just a handy place to put publicly named class state.

Going the other way, $object.meta makes no guarantees that the
metaobject it points to has any name.  Could be completely anonymous,
or an eigenclass, or whatever.  Presumably metaobjects that are
associated with a package can tell you that name somehow, perhaps
even by stringification.  But which operations can succeed through
.meta will depend on what .meta.isa, as it were.  In this, Perl is so
OO that it even encapsulates the OO, so Perl is agnostic even about
the extent to which Perl is an OO language.

In Perl 6, all objects are blessed equally, but some objects are
blessed more equally than others...

So what's in a name?  One could say that .meta is functioning more like
a name sigil than like a method, and the Real Name of the metaobject is
Foo::^Bar or some such, if it needs a name.  Then maybe Foo::Bar
is just a strange hash.  Or maybe it has its own sigil.  But from the
viewpoint of Dorothy the programmer, it's the package that presents the
public interface Oz::Wizard, and it's the metaobject that's trying
to hide behind the metacurtain.  And as in the original, sometimes the
official story needs a bit of tweaking.  But for now the Package of Oz
is great and glorious, and doubtless you should be quaking in fear.  :)

All that and several bucks'll get you a Starbucks...

Larry


packages vs. classes

2006-05-18 Thread Chip Salzenberg
On Thu, May 18, 2006 at 02:52:53PM -0700, Chip Salzenberg wrote:
 { copied to P6L for the use case question below }
Well, that message wasn't, but this one is...

What's the relationship in perl6 between namespaces and classes?
For example, given:

  package Foo { sub bar {...} }
  class Corge { method grault {...} }

Is the full name of foo Foo::foo?  What's the full name of grault?
Is there a common role that Foo and Corge both do?  
-- 
Chip Salzenberg [EMAIL PROTECTED]