Grokbase
x

AttributeHelpers naming (again)

View TopicPrint | Flat  Thread  Threaded
1) Hans Dieter Pearcey I hate to keep coming back to this, but I'm unsettled and unemployed, so I might as well keep at it...
| +1 vote (Anchor)
[ Profile | Reply to group ] [ Flat  Thread  Threaded ]
I hate to keep coming back to this, but I'm unsettled and unemployed, so I
might as well keep at it until I feel like I've got it right.

We've been talking about the roles that AH provides as being "Perl5" or
"Native", but they're really not -- some of them are (Str) but some of them
aren't (Counter, Bool, ImmutableHash, etc.).  It doesn't even match up exactly
with Moose's builtin types, so "Moose" isn't a good name either.

It's a collection of common, simple data types.  I can't think of a good name
for this.  (And it's not even correct -- Counter is very useful, but isn't
really a "data structure" so much as it is a common code pattern.)

The fact that the underlying data structures are normal Perl hashes, arrays,
scalars, etc. is also not something we really want to draw attention to; after
all, the whole point is that you use $self->push_things instead of push
@{$self->things}, so that consumers of your API don't hardcode that sort of
thing.

In the end of I'm not saying much different than I have before: what is the
most precise way to distinguish these particular attribute traits from other
traits?

I also keep coming back to something Dave said, along the lines of "well, if
these values actually had methods, we'd just delegate to them instead of
special-casing it", and wondering how much work it would take to solve auto- or
manual boxing in a way that people would like.  I don't want to be distracted
by that and end up with nothing to show for the hackathon work that we did on
AH, though.

hdp.
2) Stevan Little I think we have 3 categories of things, at least in my mind ... 1) Low-level immutable data...
| +1 vote (Anchor)
[ Profile | Reply to group ] [ Flat  Thread  Threaded ]
I think we have 3 categories of things, at least in my mind ...

1) Low-level immutable data structures:

   ImmutableHash
   List

These have no mutation operations available and are building blocks  
for the other mutable versions (see below). I doubt people actually  
use these ones directly (at least not often).

2) Basic data-structures and values:

   Array
   Hash
   Bool
   String
   Number
   Bag

Array is an "extension" of List and Hash is an "extension" of  
ImmutableHash, both providing additional mutation operations. Bool,  
String and Number are just your basic values. Bag is just a poorly  
named and badly implemented data structure. Now, these do not really  
map to the Perl Scalar, Array, Hash types. However some of them do map  
to some of the basic Moose types (Bag being the exception).

3) Code Patterns

   Counter

We only have one of these, but I can see other patterns like some kind  
of StringBuffer maybe (sure you could do that with String, but this  
would provide sensible defaults). The key thing about these is that  
they provide sensible types, default values and a subset of  
operations. They have a clarity of purpose which makes them more self  
documenting and therefor very useful.

---

So, not sure this really helps. I wouldn't mind splitting these things  
into 3 different categories or something. I mean, we are breaking back  
compat with MX::AH so we are free to rethink this if we want.

- Stevan



On Jul 2, 2009, at 2:38 PM, Hans Dieter Pearcey wrote:

> I hate to keep coming back to this, but I'm unsettled and
> unemployed, so I
> might as well keep at it until I feel like I've got it right.
>
> We've been talking about the roles that AH provides as being "Perl5"
> or
> "Native", but they're really not -- some of them are (Str) but some
> of them
> aren't (Counter, Bool, ImmutableHash, etc.). It doesn't even match
> up exactly
> with Moose's builtin types, so "Moose" isn't a good name either.
>
> It's a collection of common, simple data types. I can't think of a
> good name
> for this. (And it's not even correct -- Counter is very useful, but
> isn't
> really a "data structure" so much as it is a common code pattern.)
>
> The fact that the underlying data structures are normal Perl hashes,
> arrays,
> scalars, etc. is also not something we really want to draw attention
> to; after
> all, the whole point is that you use $self->push_things instead of
> push
> @{$self->things}, so that consumers of your API don't hardcode that
> sort of
> thing.
>
> In the end of I'm not saying much different than I have before: what
> is the
> most precise way to distinguish these particular attribute traits
> from other
> traits?
>
> I also keep coming back to something Dave said, along the lines of
> "well, if
> these values actually had methods, we'd just delegate to them
> instead of
> special-casing it", and wondering how much work it would take to
> solve auto- or
> manual boxing in a way that people would like. I don't want to be
> distracted
> by that and end up with nothing to show for the hackathon work that
> we did on
> AH, though.
>
> hdp.
3) Chris Prather Damnit, google turned off my Reply to All ---------- Forwarded message ---------- From: Chris...
| +1 vote (Anchor)
[ Profile | Reply to group ] [ Flat  Thread  Threaded ]
Damnit, google turned off my Reply to All


---------- Forwarded message ----------
From: Chris Prather <perigrin@gmail.com>
Date: Thu, Jul 2, 2009 at 3:18 PM
Subject: Re: AttributeHelpers naming (again)
To: Stevan Little <stevan.little@iinteractive.com>


On Thu, Jul 2, 2009 at 2:53 PM, Stevan
Little<stevan.little@iinteractive.com> wrote:
> I think we have 3 categories of things, at least in my mind ...
>
> 1) Low-level immutable data structures:
>
> =A0ImmutableHash
> =A0List
>
> These have no mutation operations available and are building blocks for t=
he
> other mutable versions (see below). I doubt people actually use these one=
s
> directly (at least not often).
>
> 2) Basic data-structures and values:
>
> =A0Array
> =A0Hash
> =A0Bool
> =A0String
> =A0Number
> =A0Bag
>
> Array is an "extension" of List and Hash is an "extension" of ImmutableHa=
sh,
> both providing additional mutation operations. Bool, String and Number ar=
e
> just your basic values. Bag is just a poorly named and badly implemented
> data structure. Now, these do not really map to the Perl Scalar, Array, H=
ash
> types. However some of them do map to some of the basic Moose types (Bag
> being the exception).
>
> 3) Code Patterns
>
> =A0Counter
>
> We only have one of these, but I can see other patterns like some kind of
> StringBuffer maybe (sure you could do that with String, but this would
> provide sensible defaults). The key thing about these is that they provid=
e
> sensible types, default values and a subset of operations. They have a
> clarity of purpose which makes them more self documenting and therefor ve=
ry
> useful.
>
> ---
>
> So, not sure this really helps. I wouldn't mind splitting these things in=
to
> 3 different categories or something. I mean, we are breaking back compat
> with MX::AH so we are free to rethink this if we want.
>

The only thing that really ties these together is that they're
unblessed attribute types, otherwise I think stevan's breakdowns here
are exactly it. Breaking them apart into useful abstractions and
possibly adding things like Queue, and Stack to the Code Patterns set
(which would make Array a List + Stack + Queue) would be possibly the
right idea.

-Chris
4) Stevan Little Yeah, a Stack and Queue would be really useful too. I totally agree. Perhaps we need 2 different...
| +1 vote (Anchor)
[ Profile | Reply to group ] [ Flat  Thread  Threaded ]
On Jul 2, 2009, at 3:24 PM, Chris Prather wrote:

> Damnit, google turned off my Reply to All
>
>
> ---------- Forwarded message ----------
> From: Chris Prather <perigrin@gmail.com>
> Date: Thu, Jul 2, 2009 at 3:18 PM
> Subject: Re: AttributeHelpers naming (again)
> To: Stevan Little <stevan.little@iinteractive.com>
>
>
> On Thu, Jul 2, 2009 at 2:53 PM, Stevan
> Little<stevan.little@iinteractive.com> wrote:
>> I think we have 3 categories of things, at least in my mind ...
>>
>> 1) Low-level immutable data structures:
>>
>>  ImmutableHash
>>  List
>>
>> These have no mutation operations available and are building blocks
>> for the
>> other mutable versions (see below). I doubt people actually use
>> these ones
>> directly (at least not often).
>>
>> 2) Basic data-structures and values:
>>
>>  Array
>>  Hash
>>  Bool
>>  String
>>  Number
>>  Bag
>>
>> Array is an "extension" of List and Hash is an "extension" of
>> ImmutableHash,
>> both providing additional mutation operations. Bool, String and
>> Number are
>> just your basic values. Bag is just a poorly named and badly
>> implemented
>> data structure. Now, these do not really map to the Perl Scalar,
>> Array, Hash
>> types. However some of them do map to some of the basic Moose types
>> (Bag
>> being the exception).
>>
>> 3) Code Patterns
>>
>>  Counter
>>
>> We only have one of these, but I can see other patterns like some
>> kind of
>> StringBuffer maybe (sure you could do that with String, but this
>> would
>> provide sensible defaults). The key thing about these is that they
>> provide
>> sensible types, default values and a subset of operations. They
>> have a
>> clarity of purpose which makes them more self documenting and
>> therefor very
>> useful.
>>
>> ---
>>
>> So, not sure this really helps. I wouldn't mind splitting these
>> things into
>> 3 different categories or something. I mean, we are breaking back
>> compat
>> with MX::AH so we are free to rethink this if we want.
>>
>
> The only thing that really ties these together is that they're
> unblessed attribute types, otherwise I think stevan's breakdowns here
> are exactly it. Breaking them apart into useful abstractions and
> possibly adding things like Queue, and Stack to the Code Patterns set
> (which would make Array a List + Stack + Queue) would be possibly the
> right idea.

Yeah, a Stack and Queue would be really useful too. I totally agree.

Perhaps we need 2 different namespaces:

   Basic::

For the #2 and #1 items.

   Pattern::

For the #3 items.

We can ignore for now that #1 and #2 are different, as doy said on  
#moose "... it's not like there's a particular reason to make  
something an ImmutableHash rather than a Hash". I think the limited  
direct usage of the #1 types means we can just lump them into #2.

The result is that we would have something like this:

   has foo => (traits => [ 'Basic::ArrayRef' ], isa => ArrayRef, ...);

   has web_hits => (traits => [ 'Pattern::Counter' ], ...);

As long as the traits are below the right Moose::*::*:: namespace we  
should be good.

Thoughts? Objections? Calls for my assignation?

(NOTE: I am not sold on these names (Basic, Pattern) they are only  
suggestions of how we cna break things up)

- Stevan
5) autarch I definitely like the distinction, especially since it opens up the Pattern:: space to other...
| +1 vote (Anchor)
[ Profile | Reply to group ] [ Flat  Thread  Threaded ]
On Thu, 2 Jul 2009, Stevan Little wrote:

> has foo => (traits => [ 'Basic::ArrayRef' ], isa => ArrayRef, ...);
>
> has web_hits => (traits => [ 'Pattern::Counter' ], ...);
>
> As long as the traits are below the right Moose::*::*:: namespace we should
> be good.
>
> Thoughts? Objections? Calls for my assignation?
>
> (NOTE: I am not sold on these names (Basic, Pattern) they are only
> suggestions of how we cna break things up)

I definitely like the distinction, especially since it opens up the
Pattern:: space to other interesting extensions.

As far as names, I don't much like Basic. Maybe DataStructure? That's what
it really is, right? I'd not that Queue and Stack would then be data
structures, not patterns.

Pattern works for me, though I could imagine there's something better.


-dave

/*============================================================
http://VegGuide.org http://blog.urth.org
Your guide to all that's veg      House Absolute(ly Pointless)
============================================================*/
6) Hans Dieter Pearcey Do not forget to distinguish between full names It may be reasonable for 'ArrayRef' to be the...
| +1 vote (Anchor)
[ Profile | Reply to group ] [ Flat  Thread  Threaded ]
On Thu, Jul 02, 2009 at 03:32:54PM -0400, Stevan Little wrote:
> The result is that we would have something like this:
>
> has foo => (traits => [ 'Basic::ArrayRef' ], isa => ArrayRef, ...);
>
> has web_hits => (traits => [ 'Pattern::Counter' ], ...);
>
> As long as the traits are below the right Moose::*::*:: namespace we
> should be good.

Do not forget to distinguish between full names
(Moose::Meta::Attribute::Trait::whatever) and short names
(register_implementation).

It may be reasonable for 'ArrayRef' to be the shortname but 'DataType::ArrayRef'
to be the namespace under Moose::Meta::Attribute::Trait.

hdp.
7) Chris Prather rayRef' DataStructure:: is fine if the registerd version doesn't require typing DataStructure::...
| +1 vote (Anchor)
[ Profile | Reply to group ] [ Flat  Thread  Threaded ]
On Thu, Jul 2, 2009 at 3:59 PM, Hans Dieter Pearcey<hdp@pobox.com> wrote:
> On Thu, Jul 02, 2009 at 03:32:54PM -0400, Stevan Little wrote:
>> The result is that we would have something like this:
>>
>> =A0 has foo =3D> (traits =3D> [ 'Basic::ArrayRef' ], isa =3D> ArrayRef, =
...);
>>
>> =A0 has web_hits =3D> (traits =3D> [ 'Pattern::Counter' ], ...);
>>
>> As long as the traits are below the right Moose::*::*:: namespace we
>> should be good.
>
> Do not forget to distinguish between full names
> (Moose::Meta::Attribute::Trait::whatever) and short names
> (register_implementation).
>
> It may be reasonable for 'ArrayRef' to be the shortname but 'DataType::Ar=

rayRef'
> to be the namespace under Moose::Meta::Attribute::Trait.

DataStructure:: is fine if the registerd version doesn't require
typing DataStructure:: every time ... that said Structure:: is I think
enough for Structural things.

Queue / Stack are stuck into DataStructures in CS classes but I don't
see them as being any more or less structural than a Counter which is
really a monotonic variable ... or a snapshot of a vector ... or ....
the fact is that a Queue or a Stack is a List with pre-defined
operations you can perform upon it (push/pop and enqueue/dequeue) this
is why I put them into the pattern category rather than the Data
Structure one ... despite what my CS text books might have claimed.
8) Stevan Little Very good point actually. I think we should split the categories by their intentions ... Structural...
| +1 vote (Anchor)
[ Profile | Reply to group ] [ Flat  Thread  Threaded ]
On Jul 2, 2009, at 4:12 PM, Chris Prather wrote:

> On Thu, Jul 2, 2009 at 3:59 PM, Hans Dieter Pearcey<hdp@pobox.com>
> wrote:
>> On Thu, Jul 02, 2009 at 03:32:54PM -0400, Stevan Little wrote:
>>> The result is that we would have something like this:
>>>
>>> has foo => (traits => [ 'Basic::ArrayRef' ], isa =>
>>> ArrayRef, ...);
>>>
>>> has web_hits => (traits => [ 'Pattern::Counter' ], ...);
>>>
>>> As long as the traits are below the right Moose::*::*:: namespace we
>>> should be good.
>>
>> Do not forget to distinguish between full names
>> (Moose::Meta::Attribute::Trait::whatever) and short names
>> (register_implementation).
>>
>> It may be reasonable for 'ArrayRef' to be the shortname but
>> 'DataType::ArrayRef'
>> to be the namespace under Moose::Meta::Attribute::Trait.
>
> DataStructure:: is fine if the registerd version doesn't require
> typing DataStructure:: every time ... that said Structure:: is I think
> enough for Structural things.
>
> Queue / Stack are stuck into DataStructures in CS classes but I don't
> see them as being any more or less structural than a Counter which is
> really a monotonic variable ... or a snapshot of a vector ... or ....
> the fact is that a Queue or a Stack is a List with pre-defined
> operations you can perform upon it (push/pop and enqueue/dequeue) this
> is why I put them into the pattern category rather than the Data
> Structure one ... despite what my CS text books might have claimed.

Very good point actually.

I think we should split the categories by their intentions ...

   Structural - ArrayRef, HashRef, Number, etc ...

   Behavioral - Counter, Queue, Stack, Buffer, etc ...

Now, you could easily argue all around this and blah blah blah (I WANT  
TO PAINT THE BIKESHED RED!). But what I am proposing is that we draw  
*our own* distinctions, complete with reasoning to support. And let me  
start the first wave of bullshit here ...

Structural items are ones for whom the underlying value type is the  
key focus. ArrayRef describes the actual data structure used and  
Number the actual value type used. The operations supplied for these  
Structural items are basically the core operations that perl supports  
out of the box (with maybe a few additions for convenience).

Behavioral items are one for whom the behavior of the item is the key  
focus. Counter is obvious. The Stack item is less obvious unless you  
look at it as an ADT (Abstract Data Type) and realize that it really  
describes a data structure whose internal implementation is irrelevant  
as long as it provides an expected set of behaviors.

Yes, these lines are blurry. Yes, you could easily argue that ArrayRef  
fits the Behavioral definition and Stack fits the Structural. But who  
cares, I think we can make our own distinctions and as long as we  
remain consistent then all the haters can just f*ck off ;)

/me throws the mic down and walks off stage ...

- Stevan
9) Jesse Luehrs So... why stop there? Since we're redoing API anyway, what about this idea: the Structural items...
| +1 vote (Anchor)
[ Profile | Reply to group ] [ Flat  Thread  Threaded ]
On Thu, Jul 02, 2009 at 04:36:37PM -0400, Stevan Little wrote:
> Very good point actually.
>
> I think we should split the categories by their intentions ...
>
>   Structural - ArrayRef, HashRef, Number, etc ...
>
> Behavioral - Counter, Queue, Stack, Buffer, etc ...
>
> Now, you could easily argue all around this and blah blah blah (I WANT
> TO PAINT THE BIKESHED RED!). But what I am proposing is that we draw
> *our own* distinctions, complete with reasoning to support. And let me
> start the first wave of bullshit here ...
>
> Structural items are ones for whom the underlying value type is the key
> focus. ArrayRef describes the actual data structure used and Number the
> actual value type used. The operations supplied for these Structural
> items are basically the core operations that perl supports out of the box
> (with maybe a few additions for convenience).
>
> Behavioral items are one for whom the behavior of the item is the key
> focus. Counter is obvious. The Stack item is less obvious unless you
> look at it as an ADT (Abstract Data Type) and realize that it really
> describes a data structure whose internal implementation is irrelevant
> as long as it provides an expected set of behaviors.
>
> Yes, these lines are blurry. Yes, you could easily argue that ArrayRef
> fits the Behavioral definition and Stack fits the Structural. But who
> cares, I think we can make our own distinctions and as long as we remain
> consistent then all the haters can just f*ck off ;)

So... why stop there? Since we're redoing API anyway, what about this
idea: the Structural items described here get their methods stored
directly on the associated TypeConstraint object, and handles just looks
things up from there. This would make extending quite easy, doing
something like

subtype 'Matrix', as 'ArrayRef[ArrayRef]',
                  where { ... },
                  with { lookup => sub {
                             my ($mat, $i, $j) = @_;
                             $mat->[$i][$j]
                         } };

which would make this valid:

has matrix => (
    isa => 'Matrix',
    handles => ['lookup'],
);

This would simplify the interface too, since users wouldn't have to
think about including traits and whatnot, things would just work.

Thoughts?
-doy
10) Stevan Little Well, seems like taking it too far to me, at least for core. Because while interesting, it really...
| +1 vote (Anchor)
[ Profile | Reply to group ] [ Flat  Thread  Threaded ]
On Jul 2, 2009, at 8:11 PM, Jesse Luehrs wrote:

> On Thu, Jul 02, 2009 at 04:36:37PM -0400, Stevan Little wrote:
>> Very good point actually.
>>
>> I think we should split the categories by their intentions ...
>>
>> Structural - ArrayRef, HashRef, Number, etc ...
>>
>> Behavioral - Counter, Queue, Stack, Buffer, etc ...
>>
>> Now, you could easily argue all around this and blah blah blah (I
>> WANT
>> TO PAINT THE BIKESHED RED!). But what I am proposing is that we draw
>> *our own* distinctions, complete with reasoning to support. And let
>> me
>> start the first wave of bullshit here ...
>>
>> Structural items are ones for whom the underlying value type is the
>> key
>> focus. ArrayRef describes the actual data structure used and Number
>> the
>> actual value type used. The operations supplied for these Structural
>> items are basically the core operations that perl supports out of
>> the box
>> (with maybe a few additions for convenience).
>>
>> Behavioral items are one for whom the behavior of the item is the key
>> focus. Counter is obvious. The Stack item is less obvious unless you
>> look at it as an ADT (Abstract Data Type) and realize that it really
>> describes a data structure whose internal implementation is
>> irrelevant
>> as long as it provides an expected set of behaviors.
>>
>> Yes, these lines are blurry. Yes, you could easily argue that
>> ArrayRef
>> fits the Behavioral definition and Stack fits the Structural. But who
>> cares, I think we can make our own distinctions and as long as we
>> remain
>> consistent then all the haters can just f*ck off ;)
>
> So... why stop there? Since we're redoing API anyway, what about this
> idea: the Structural items described here get their methods stored
> directly on the associated TypeConstraint object, and handles just
> looks
> things up from there. This would make extending quite easy, doing
> something like
>
> subtype 'Matrix', as 'ArrayRef[ArrayRef]',
>                  where { ... },
>                  with { lookup => sub {
> my ($mat, $i, $j) = @_;
>                             $mat->[$i][$j]
>                         } };
>
> which would make this valid:
>
> has matrix => (
>    isa => 'Matrix',
>    handles => ['lookup'],
> );
>
> This would simplify the interface too, since users wouldn't have to
> think about including traits and whatnot, things would just work.
>
> Thoughts?
> -doy

Well, seems like taking it too far to me, at least for core. Because  
while interesting, it really blurs the lines between types and  
classes. What would this do?

subtype MyMatrix as Matrix where { ... };

Would it "inherit" the methods? Could I override them if I wanted?  
Could I call the "super" method? At some point you end up with an  
object system within an object system.

The other thing being that you could do all this if you simply made  
Matrix an object in the first place.

Now, this all said, I have always thought that some kind of Haskell-
typeclass-ish type thing would be an interesting extension of the  
Moose type system. Something that would pretty much work as you  
described above.

In short, interesting MooseX:: project I think, but too much for core.

- Stevan
spacer
View TopicPrint | Flat  Thread  Threaded
Home > Groups > Moose > AttributeHelpers naming (again) (10 posts)