Do I *have* to use 'OOP' to use modules?

A

anno4000

Ilya Zakharevich said:
[A complimentary Cc of this posting was sent to

The real problem is that users have to know and take into account
implementation details of a class they're merely using.
The typical case is a hash based class you want to inherit from.

I'm a little bit confused here: do you discuss "users" of the class,
or "developers" of derived classes?

The latter, considering a user everyone who isn't author.
AFAIU, having attributes in the language would bring absolutely no
benefits to the "merely users". The "developers", of course, are in a
very different situation...

You are right, it doesn't make a difference to the end user.

The contrasting situation would be development of a cluster of two or
more classes by a single developer (or team). Essentially this is the
only situation where inheritance among traditional Perl classes can
be handled because the derived class must account for implementation
details of the base class.

Anno
 
T

Ted Zlatanov

Sometimes, you can get where you want to go by only turning left.
In those cases, deciding up front that you're only going to turn
left is not a problem. Other times, you'll want to turn right --
either because that's the most natural route, or because taking
*one* right turn means you get to avoid an extra hour of driving.

There are times when an analogy is healthy and vibrant. At other
times it has been beaten to death, like now :)
TZ> Emacs Lisp comes to mind. It is very useful without using OOP.
TZ> There are many other examples. The problem domain and
TZ> programmer experience should make the
TZ> OOP/procedural/functional/etc. choice.

You can't do OOP in Lisp? This is news to me.

Note I said Emacs Lisp. I'm aware of the other flavors of Lisp and
wasn't discussing them.
You may find that another approach (such as, if you're using Lisp, a
functional approach) is better suited to the problem; but that is
*not* the same thing as deciding, independently of the problem domain,
that object oriented techniques are not to be considered.

Sure. That's what I said, that the problem domain and the programmer
experience (meaning, experience with the methodology and with
programming in general) should make this choice.

Ted
 
I

Ilya Zakharevich

[A complimentary Cc of this posting was sent to

You are right, it doesn't make a difference to the end user.

The contrasting situation would be development of a cluster of two or
more classes by a single developer (or team). Essentially this is the
only situation where inheritance among traditional Perl classes can
be handled because the derived class must account for implementation
details of the base class.

Thinking about it a little bit more, I see absolutely no reason to
have attributes in the language proper. What is lost if all one has
is a module `attr' with methods:

$val = $o->__attr_get($a_name);
$o->__attr_set($a_name, $val);

$val = $o->__attr_get_($superclass_name, $a_name); # Allow "SUPER" as well
$o->__attr_set_($superclass_name, $a_name, $val); # Likewise

$class->__attr__def__($accessor_method, $mutator_method);

??? Then if a module wants to use attributes, just put 'attr' into @ISA...

(Of course, this assumes that attributes are inherited through @ISA -
which is trivial to implement.)

Puzzled,
Ilya
 
I

Ilya Zakharevich

[A complimentary Cc of this posting was NOT [per weedlist] sent to
Ilya Zakharevich
Thinking about it a little bit more, I see absolutely no reason to
have attributes in the language proper. What is lost if all one has
is a module `attr' with methods:

$val = $o->__attr_get($a_name);
$o->__attr_set($a_name, $val);

$val = $o->__attr_get_($superclass_name, $a_name); # Allow "SUPER" as well
$o->__attr_set_($superclass_name, $a_name, $val); # Likewise

$class->__attr__def__($accessor_method, $mutator_method);

Of course, this should have been

$class->__attr__def__($a_name [, $accessor_method, $mutator_method] );

with default $accessor_method, $mutator_method keeping the attribute
in some appropriate out-of-band location ($class-dependent). So one
could even encode this into ->import, thus making

use attr qw(list of attribute names);

work...

Yours,
Ilya
 
A

anno4000

Ilya Zakharevich said:
[A complimentary Cc of this posting was NOT [per weedlist] sent to
Ilya Zakharevich
Thinking about it a little bit more, I see absolutely no reason to
have attributes in the language proper. What is lost if all one has
is a module `attr' with methods:

$val = $o->__attr_get($a_name);
$o->__attr_set($a_name, $val);

$val = $o->__attr_get_($superclass_name, $a_name); # Allow "SUPER" as well
$o->__attr_set_($superclass_name, $a_name, $val); # Likewise

$class->__attr__def__($accessor_method, $mutator_method);

Of course, this should have been

$class->__attr__def__($a_name [, $accessor_method, $mutator_method] );

with default $accessor_method, $mutator_method keeping the attribute
in some appropriate out-of-band location ($class-dependent). So one
could even encode this into ->import, thus making

use attr qw(list of attribute names);

work...

To answer your question from the parent posting, "Why not do it this
way" I'd first have to see how well the scheme works in practice.
That would mean implementation of at least one nontrivial (set of)
class(es) based on your suggestion. I can't answer that out of
hand.

Another question is: It's implemented as a pragma, so people are
free to build their classes that way or not. Does that matter?
This is the problem of many excellent CPAN modules in the Class::
and Object:: spaces: They work well and solve many problems -- in
a world where everybody uses them. How well they interoperate,
among themselves and with other, freely designed classes nobody
knows.

Here lies the objective advantage of inside-out classes: They
are freely inheritable (can be made base classes, without conflict)
by any other class, inside-out or not. This is an interesting
property for developers who want to publish their classes. Any
other class can use them by subclassing. That's what users of
dedicated OO languages miss in Perl.

Anno
 
B

Ben Morrow

Quoth (e-mail address removed)-berlin.de:
Here lies the objective advantage of inside-out classes: They
are freely inheritable (can be made base classes, without conflict)
by any other class, inside-out or not.

And, almost more importantly, can subclass any other class, inside-out
or not. That is, given a random class Foo whose implementation I am not
privy to, I can create an inside-out subclass Bar that definitely
doesn't tread on Foo's internals. Of course, I can only get at Foo's
attributes through Foo's public methods, but I should be doing that
anyway.

Ben
 
A

anno4000

Ben Morrow said:
Quoth (e-mail address removed)-berlin.de:

And, almost more importantly, can subclass any other class, inside-out
or not. That is, given a random class Foo whose implementation I am not
privy to, I can create an inside-out subclass Bar that definitely
doesn't tread on Foo's internals. Of course, I can only get at Foo's
attributes through Foo's public methods, but I should be doing that
anyway.

I believe you mean the technique where one uses the otherwise
unused object proper to hold an actual object of the parent
class?

I don't consider that an essential property of inside-out classes
but rather a (useful) quirk.

For one, it renders your class non-inside-out. It touches, err...
de-references its body (the parent class' accessors do) and is thus
in a state of sin. The result can no longer be used as a base class
by anything that isn't compatible with Foo in the usual sense.

Also, this technique can only be applied once, multiple inheritance
from non-inside-out classes requires other means.

That said, it *is* a useful property and I have been using it
at least once.

Anno
 
I

Ilya Zakharevich

[A complimentary Cc of this posting was sent to

$val = $o->__attr_get($a_name);
$o->__attr_set($a_name, $val);

$val = $o->__attr_get_($superclass_name, $a_name); # Allow "SUPER" as well
$o->__attr_set_($superclass_name, $a_name, $val); # Likewise
$class->__attr__def__($a_name [, $accessor_method, $mutator_method] );

with default $accessor_method, $mutator_method keeping the attribute
in some appropriate out-of-band location ($class-dependent). So one
could even encode this into ->import, thus making

use attr qw(list of attribute names);

work...
To answer your question from the parent posting, "Why not do it this
way" I'd first have to see how well the scheme works in practice.

Hmm, I hoped that somebody *knows* what an attribute *is*, so is able
to see whether the API is sufficient...
Another question is: It's implemented as a pragma, so people are
free to build their classes that way or not. Does that matter?
This is the problem of many excellent CPAN modules in the Class::
and Object:: spaces: They work well and solve many problems -- in
a world where everybody uses them.

I need to think about it more...
Here lies the objective advantage of inside-out classes: They
are freely inheritable (can be made base classes, without conflict)
by any other class, inside-out or not.

Why you think this is not applicable to the scheme above?

Thanks,
Ilya
 
I

Ilya Zakharevich

[A complimentary Cc of this posting was sent to
Abigail
Ilya Zakharevich ([email protected]) wrote on MMMMDCCCXXX September
MCMXCIII in <URL:''
'' Thinking about it a little bit more, I see absolutely no reason to
'' have attributes in the language proper. What is lost if all one has
'' is a module `attr' with methods:

Usability.

Could you be more explicit, please?

Or do you suggest that

$val = $obj--->>>{a_name}; # Or whatever the syntax is

is *undisputably* preferable to

$val = $obj->__get_a_name;

???

Puzzled,
Ilya
 
I

Ilya Zakharevich

[A complimentary Cc of this posting was sent to
Abigail
.. Or do you suggest that
..
.. $val = $obj--->>>{a_name}; # Or whatever the syntax is
..
.. is *undisputably* preferable to
..
.. $val = $obj->__get_a_name;

But I do think that

$val = $.a_name;

(to borrow a Perl6 syntax) is vastly superiour over either

$val = $self -> __get_a_name;

Enough to influence a choice between languages?

Thanks,
Ilya
 
R

Robert 'phaylon' Sedlacek

Abigail said:
Usability.

If Larry had decided that Perl wouldn't have variables, but instead
functions 'set' and 'get', we could do the same in Perl as we can now.

This sounds a lot like you want Perl to behave like some other
languages. Ruby or Java perhaps? Personally, I'd hate if Perl would
introduce one way to handle attributes. I'm rather glad that I can use
Class::BuildMethods, Moose, Class::Accessor::Fast, or my own
implementation easily in my objects. Sure Perl 6 will have attributes in
a fixed design. But without Perl 5's flexibility over 10 years, how
would they have found what's best for most of us?

Nothing in Perl 5's OO is ill-implemented. It can only be ill if you
make a comparison and set an other language in the position of "right."
And in the end, it *is* just a personal opinion.

gr.,
Robert
 
A

anno4000

Abigail said:
(e-mail address removed)-berlin.de ([email protected]) wrote
on MMMMDCCCXXX September MCMXCIII in <URL:"" >
"" > Quoth (e-mail address removed)-berlin.de:
"" > >
"" > > Here lies the objective advantage of inside-out classes: They
"" > > are freely inheritable (can be made base classes, without conflict)
"" > > by any other class, inside-out or not.
"" >
"" > And, almost more importantly, can subclass any other class, inside-out
"" > or not. That is, given a random class Foo whose implementation I am not
"" > privy to, I can create an inside-out subclass Bar that definitely
"" > doesn't tread on Foo's internals. Of course, I can only get at Foo's
"" > attributes through Foo's public methods, but I should be doing that
"" > anyway.
""
"" I believe you mean the technique where one uses the otherwise
"" unused object proper to hold an actual object of the parent
"" class?
""
"" I don't consider that an essential property of inside-out classes
"" but rather a (useful) quirk.

Believe me, the ability of inheriting from any class, regardless of its
implementation was an essential requirement when designing inside-out objects.

"" For one, it renders your class non-inside-out. It touches, err...
"" de-references its body (the parent class' accessors do) and is thus
"" in a state of sin. The result can no longer be used as a base class
"" by anything that isn't compatible with Foo in the usual sense.

Yes, and? Sure, Foo lives in a state of sin from an IOO point of view,
but the assumption is that you don't control Foo. You got Foo from CPAN
or your cow-orker. You control Bar. Now, anyone subclassing Bar (say,
a class Baz) is either an inside-out object, or it isn't. If it is,
it doesn't care how Foo is implemented, so there's no problem. If it
isn't, then Baz itself is living 'in a state of sin'. The restrictions
that are imposed on Baz are done by Foo, not by Bar.

A valid analysis, but I'm thinking not so much in logical but in
psychological or, if you will, marketing terms. Why will IOO
(thanks for the abbreviation) become the standard class implementation
method?

Because the developer of a general purpose class for, say, CPAN (the
market place) wants to avoid everything that might stop a potential
user from using the code. The standard hash implementation allows
other hash-based classes quick-and-dirty inheritance, all others have
to go through contortions to enable full or partial inheritance. Other
implementations tend to be even more restrictive. Only IOO classed are
free of such restrictions, and that makes a *strong* point. Obviously,
I'm only speaking of use by subclassing, other uses of a class are
not impeded by implementation.

On the other hand, a developer who has decided to use IOO is unlikely
to implement the class by subclassing a non-IOO class. That would
spoil the advantage. That's why I consider "upwards inheritablility"
of IOO a more important feature than "downwards inheritablility" for
public classes.

Authors of classes not meant for publication have different criteria,
but they don't decide the race. And even then, I bet most of those
who in fact inherit from a non-IOO class do it "until an IOO-implemen-
tation becomes available".
"" Also, this technique can only be applied once, multiple inheritance
"" from non-inside-out classes requires other means.

As noted in another post, MI is almost impossible in Perl if you don't
control the classes you inherit from. And that has less to do with the
implementation of the classes, but more with the fact that everyone and
his donkey makes the mistake of writing methods that do two unrelated
tasks: constructing an object and initializing an object. Almost all 'new'
methods construct an object, and then stuff the object with attributes.
This is what makes MI almost impossible.

Yes, but that is orthogonal to the type of class. All classes can benefit
from separate creation and initialization (which doesn't mean you can't
have a method that does both).

It is a fundamental fact at least in Perl OO that you need a separate
initializer to do multiple inheritance. You can create an object only
once, but you must initialize it for every class on its @ISA tree.

It is strange that this should have escaped Perl's OO culture for so
long. It must be because inheritance in Perl is (was) cumbersome in
the first place, so it doesn't play the part it could.

Anno
 
A

anno4000

Ilya Zakharevich said:
[A complimentary Cc of this posting was sent to

$val = $o->__attr_get($a_name);
$o->__attr_set($a_name, $val);

$val = $o->__attr_get_($superclass_name, $a_name); # Allow "SUPER" as well
$o->__attr_set_($superclass_name, $a_name, $val); # Likewise

$class->__attr__def__($a_name [, $accessor_method, $mutator_method] );

with default $accessor_method, $mutator_method keeping the attribute
in some appropriate out-of-band location ($class-dependent). So one
could even encode this into ->import, thus making

use attr qw(list of attribute names);

work...
To answer your question from the parent posting, "Why not do it this
way" I'd first have to see how well the scheme works in practice.

Hmm, I hoped that somebody *knows* what an attribute *is*, so is able
to see whether the API is sufficient...

I don't doubt its sufficiency (though an lvalue accessor might be
added). Like Abigail I see potential problems in usability.
I need to think about it more...


Why you think this is not applicable to the scheme above?

For no particular reason except that inside-out is the only scheme I've
seen yet for which it is. It could depend on implementation details
that aren't yet specified.

Anno
 
I

Ilya Zakharevich

[A complimentary Cc of this posting was sent to

I don't doubt its sufficiency (though an lvalue accessor might be
added). Like Abigail I see potential problems in usability.
For no particular reason except that inside-out is the only scheme I've
seen yet for which it is. It could depend on implementation details
that aren't yet specified.

Now I'm completely confused: you say simultaneously that API is
sufficient, and that something depends on implementation details. I
do not see how both can be true...

Thanks,
Ilya
 
A

anno4000

Abigail said:
(e-mail address removed)-berlin.de ([email protected]) wrote
on MMMMDCCCXXXI September MCMXCIII in <URL:** > (e-mail address removed)-berlin.de ([email protected]) wrote
[snip]

** A valid analysis, but I'm thinking not so much in logical but in
** psychological or, if you will, marketing terms. Why will IOO
** (thanks for the abbreviation) become the standard class implementation
** method?

I don't think I implied that IOO will become the standard class
implementation.

I'm not saying you did. I was demonstratively taking an overly
optimistic view to make the point.
In fact, I'm convinced it won't. The vast majority
of the documentation out there telling about objects use hashref based
objects. And that's how people will learn Perl objects, and people don't
have a habit of changing habits.

At least the process would take many years. Perl 6 will make the point
moot whenever it comes.
** Because the developer of a general purpose class for, say, CPAN (the
** market place) wants to avoid everything that might stop a potential
** user from using the code. The standard hash implementation allows
** other hash-based classes quick-and-dirty inheritance, all others have
** to go through contortions to enable full or partial inheritance. Other
** implementations tend to be even more restrictive. Only IOO classed are
** free of such restrictions, and that makes a *strong* point. Obviously,
** I'm only speaking of use by subclassing, other uses of a class are
** not impeded by implementation.
**
** On the other hand, a developer who has decided to use IOO is unlikely
** to implement the class by subclassing a non-IOO class. That would

I beg to differ.

The most important problem that IOO solves is that of subclassing
something of which you don't know the implementation of. Refusing to
subclass a non-IOO class is needlessly restrictive, and you would
have to spend a lot of time rewriting existing code.

I don't consider CPAN to be the "market place". Some people might design
for CPAN, but compared to the number of people that write Perl code,
their numbers are insignificant.

True, but their code is influential, at least potentially.
The majority of the Perl code that gets
written gets written to solve a problem. Code to solve a problem is code
that I (and with me thousands of others) write every day. And I want to
be able to reuse code, without having to worry how something is implemented.
I want to reuse code that I got from CPAN, that was developed by a coworker
(or something that still needs to be developped by him), that I inherited
from my predecessor, or code that I wrote five years ago.

I acknowledged that ...
** Authors of classes not meant for publication have different criteria,
[snip]

** It is a fundamental fact at least in Perl OO that you need a separate
** initializer to do multiple inheritance. You can create an object only
** once, but you must initialize it for every class on its @ISA tree.
**
** It is strange that this should have escaped Perl's OO culture for so
** long. It must be because inheritance in Perl is (was) cumbersome in
** the first place, so it doesn't play the part it could.


I think it is always easily dismissed with "you don't want MI anyway".

But you do, once inheritance works without a hitch. You can then have
small general purpose classes to pick and chose from. Labels, messages,
time stamps, locations (a set of coordinates), all with a well-assorted
supply of methods are just a few examples of capabilities you may want to
add to just about any object. We don't have such a library, but with IOO
it could be implemented.

Anno
 
A

anno4000

Ilya Zakharevich said:
[A complimentary Cc of this posting was sent to

I don't doubt its sufficiency (though an lvalue accessor might be
added). Like Abigail I see potential problems in usability.
For no particular reason except that inside-out is the only scheme I've
seen yet for which it is. It could depend on implementation details
that aren't yet specified.

Now I'm completely confused: you say simultaneously that API is
sufficient, and that something depends on implementation details. I
do not see how both can be true...

I understand sufficiency as "supporting the essential operations". In
that sense even the standard hash-based attributes are sufficient.
That doesn't imply that the implementation has all desirable properties,
like allowing all classes conflict-free inheritance the way IOOs do.

Anno
 
R

Robert 'phaylon' Sedlacek

Abigail said:
Robert 'phaylon' Sedlacek ([email protected]) wrote on MMMMDCCCXXXI
September MCMXCIII in <URL:I fail to understand this argument.

Well, you've snipped an important part away:

| And in the end, it *is* just a personal opinion.
No-one is complaining that Perl takes away flexibility by having regexes
and hashes build in the language, or by not having pointers, but more
restrictive references. Yet people moan that their freedom is taken away
if Perl would have had object instance variables (aka attributes).

Because I see hashes, regexes and references as more low level than
object orientation. One is a paradigm, the others are quite simple
tools.

You might disagree, but see above.

gr.,
Robert
 
I

Ilya Zakharevich

[A complimentary Cc of this posting was sent to

I understand sufficiency as "supporting the essential operations". In
that sense even the standard hash-based attributes are sufficient.

hard to see how they can be sufficient if an object is not a hash ref...
That doesn't imply that the implementation has all desirable properties,
like allowing all classes conflict-free inheritance the way IOOs do.

I still do not see where conflicts can come from. With this API, an
"attribute" is just a pair of methods, setter and getter. So
inheritance is always conflict-free.

Hope this helps,
Ilya
 
I

Ilya Zakharevich

[A complimentary Cc of this posting was sent to
Abigail
But I do think that

$val = $.a_name;

(to borrow a Perl6 syntax) is vastly superiour over either

$val = $self -> __get_a_name;

and

$val = $$self {a_name};

Do I understand correct that you agree on having the same namespace
for attributes and methods? In my example API I put a special
emphasis to have them in separate namespaces... It would be greatly
simplified if the namespaces should be merged:

# Create methods accessing slots in out-of-band storage of the object
use OO::attrib qw(foo bar baz); # In the class' package

$val = $o->baz;
$o->baz = $val; # If lvalue is allowed
$o->baz__set($val); # If performance of getter is tantamount

Then I cannot interpret your objections in other way than saying that
$o.baz is "vastly superiour" to $o->baz...

Puzzled,
Ilya

P.S. Recall that Abigail insisted that attributes should be present
in the core, and I fail to see why this should not be delegated
to a module.

P.P.S. Hmm, an XSUB accessor could easily allow lvalue methods
without a noticable overhead. Probably, some of my old
patches could simplify development a lot, but even without
them, XSUB accessors are possible.
 
I

Ilya Zakharevich

[A complimentary Cc of this posting was sent to
Abigail
__ Do I understand correct that you agree on having the same namespace
__ for attributes and methods?

You understand incorrectly. Attributes should be private to the class;
an object may have more than one attribute with the same name, but no
class could have more than one attribute with the same name.

Sorry, but I have no idea what your "answer" has to do with my
question. E.g., note that an may have more than one method with
the same name, but no class could have more than one method with
the same name.
I may not want to expose the existance (or non-existance) of an attribute
to the world at large.

"Privateness" is indeed not addressed in my API. But neither is it
applicable to methods, so - in context of Perl - this is not a crucial
observation.
Furthermore, if we would have Perl6 style attributes,
we would have compile time checking of typos in attribute names; methods
aren't resolved until runtime.

If one has the same namespace for methods and attributes, how is the
compiler to distinguish what to check, and what not?
I couldn't give a rats ass whether it's core or a module. What I care about
is:

* Encapsulation. How one class is implemented should neither depend
on the implementation of a superclass, nor restrict the implementation
of a subclass.

Is in the discussed API.
* Compile time checking of my attribute names. Full advantage of
'use strict'.

Not there.
* A syntax that isn't convoluted. Attributes are variables - they should
look like variables.

Not there. But neither is it in p6 syntax.
Methods don't look like variables.

I fail to see how $o->method and $o.method are looking differently.

Yours,
Ilya
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,142
Latest member
DewittMill
Top