Page 6 of 10

Re: Namespaces and abstract class names

Posted: Tue Feb 08, 2011 3:58 pm
by John Cartwright
It's an unfortunate by-product of working with PHP. Got to take the good with the bad.

I just want to state for the record, it's important to note I said "If instances where a wide variety of people will use my code", because there is no "right" way to do things in PHP. People have strong preferences, and when it comes to writing open-source code, this solves this issue.

Now, if we had multiple method signatures implemented, then we can just implement this the "right" way.

Re: Namespaces and abstract class names

Posted: Tue Feb 08, 2011 4:11 pm
by Christopher
John Cartwright wrote:I prefer a language to be as strict as possible, or at least be consistent. But there is absolutely no reason to be strict about a method signature that you are overriding in a dynamic language. If the abstract class implemented an interface, sure.. complain. This all stems from the fact that PHP does not recognize method signatures in regard to defining duplicate methods with different signatures. I.e.,
I think one of the nice things about scripting languages is that they are not strict because so often either the intent is clear or it does not matter. However they can be when you want them to be.

Code: Select all

function doFoo($bar=null) {
  if ($bar === null) {
  } elseif ($bar instanceof Some_Class) {
  } elseif ($bar instanceof Some_Other_Class) {
  }
}
You may not like that code ... but except for compiler warnings (less important in scripting languages) you can achieve the same effect and even tailor errors/exceptions thrown to your own likes/needs.

Re: Namespaces and abstract class names

Posted: Tue Feb 08, 2011 4:16 pm
by John Cartwright
Christopher wrote:
John Cartwright wrote:I prefer a language to be as strict as possible, or at least be consistent. But there is absolutely no reason to be strict about a method signature that you are overriding in a dynamic language. If the abstract class implemented an interface, sure.. complain. This all stems from the fact that PHP does not recognize method signatures in regard to defining duplicate methods with different signatures. I.e.,
I think one of the nice things about scripting languages is that they are not strict because so often either the intent is clear or it does not matter. However they can be when you want them to be.

Code: Select all

function doFoo($bar=null) {
  if ($bar === null) {
  } elseif ($bar instanceof Some_Class) {
  } elseif ($bar instanceof Some_Other_Class) {
  }
}
You may not like that code ... but except for compiler warnings (less important in scripting languages) you can achieve the same effect and even tailor errors/exceptions thrown to your own likes/needs.
Indeed. That was a very simplistic example, let me use a real world example in an ACL component collection class.

Code: Select all

/**
  * Add the specified priviledge to the collection
  * 
  * @access public
  * @param string $type
  * @param string $roleId
  * @param string $parentRoleId
  * @param string|array $permissions
  * @param string $assertionClass
  * @throws Insta_Exception If resource was marked locked
  * @throws Insta_Exception Invalid priviledge type specified
  */	
public function addPriviledge($type, $roleId, $parentRoleId, $permissions, $assertionClass = null)
public function addPriviledge($type, Insta_Acl_Role $role, $permissions, $assertionClass = null)
public function addPriviledge(Insta_Acl_Priviledge $priviledge)
That would be a nightmare to implement all the checking.

Maybe we should split this thread if we want to continue with this discussion.

Re: Namespaces and abstract class names

Posted: Tue Feb 08, 2011 4:24 pm
by VladSun
An "Interface" is a particular case of the more general term "Abstract class". An "Interface" is the case when an "Abstract class" has no implementation at all. I.e.

Code: Select all

interface ICount
{
  public function one($param);
  public function two($param);
}
is absolutely the same as:

Code: Select all

abstract class Count_Abstract
{
  abstract public function one($param);
  abstract public function two($param);
}
Both will raise errors if method signatures don't match.

Re: Namespaces and abstract class names

Posted: Tue Feb 08, 2011 4:40 pm
by John Cartwright
Interesting. I didn't know you could use abstract on methods. :banghead:

Which begs the question, why would an abstract class force an implementation. They are meant to be extended, not implemented. Just seems weird.

Re: Namespaces and abstract class names

Posted: Tue Feb 08, 2011 4:41 pm
by VladSun
:mrgreen:

Re: Namespaces and abstract class names

Posted: Tue Feb 08, 2011 4:42 pm
by John Cartwright
VladSun wrote::mrgreen:
I edited my last post after you replied (thought I would be polite and point that out :drunk: ).

Re: Namespaces and abstract class names

Posted: Tue Feb 08, 2011 4:55 pm
by VladSun
John Cartwright wrote:Which begs the question, why would an abstract class force an implementation. They are meant to be extended, not implemented. Just seems weird.
In order to force creation of the *needed/required* implementation. Some of the common implementation may be already done, but some of the specific implementation is still missing and *required* to be done in order to have a "properly working" class. That's why an Abstract class can not be instantiated.

Absolutely the same as using an Interface, though it allows you to put some implementation in it. That's why josh doesn't like it, IMHO :)

PS: BTW John, if you use the abstract keyword for a method you MUST declare the whole class as an abstract one, otherwise an error is reported.

Re: Namespaces and abstract class names

Posted: Tue Feb 08, 2011 6:18 pm
by Christopher
Related to original question (don't stop other dicusssions :)) ... here is Matthew Weier O'Phinney on namespaces (tl;dr Combination of Organization+Readability+Dependency tracking make namespaces great.):

http://weierophinney.net/matthew/archiv ... atter.html

Re: Namespaces and abstract class names

Posted: Tue Feb 08, 2011 6:37 pm
by VladSun
Well, I can't agree that namespaces should be mapped 1:1 to directories. Even in my AnnoLoader project I explicitly define system paths to namespaces (JavaScript). No 1:1 directory mapping.

My class names do follow the Zend/Pear/... class naming and location convention, but I do not feel like it's mandatory for namespaces. In most cases namespaces are used to define a package or a library. I.e. "centralized" location.

Re: Namespaces and abstract class names

Posted: Tue Feb 08, 2011 8:40 pm
by josh
@Vlad
I skipped your post because I was arguing against use of abstract classes, and you asked me if that means I want PHP's handling of abstract classes to be more strict? Your question doesn't make sense. Virtual methods are a feature of abstract classes, which I am arguing against.

@vlad
sure they could remove 'abstract' as soon as they implement prototypical inheritance :-) That would also allow removal of 'public' vs 'private', etc.

@Christopher
4 ways to define a class in javascript? I know of only one, 'function'.

@christopher
What does implementation language mean then? To me it means the language in which you are typing your implementation details, it implies code is what implements your customer's specification. How are the names of methods & classes not implementation details of your program?

@christopher
Regarding parent::foo() I never brought up parent, you did. Not sure what that's about. My argument was that when adding a method to a class, I must navigate it's chain of super classes making sure I'm not choosing a name that will unintentionally override a previously defined method on one of those super classes. Instead of just adding a method I may have to visit several different classes & read over their possibly length method lists. This takes from seconds to minutes or more each time I want to extract out a new method, or add a new method. There's a huge benefit to being able to name a method without it breaking something due to the name you chose.

With composition I can add new methods all day long without worry of my new method nulling out some previously defined behavior. It allows more flexible method naming.

@christopher
robot cannot inherit animal because robots aren't organisms! They shouldn't breathe() and sleep()!!! You're going to print_r() your object and get loads of unrelated information. That's a big code smell.

Inheritance = take it or leave 100% of all defined methods & variables. No in-between.
Composition = take what you need only, no more no less.
Jonah Bron wrote:I'm just reading here, I don't think I'm in a position to jump in, :roll: but...
josh wrote:Here the compiler does nothing to warn you that you're calling a method on Bar instead of Foo, so I'm not sure what your repeated rebuttal about calling "parent::" is about. If a method is overridden, you definitely need to be conscious of that.
If it does something different, wouldn't you just not override it? Or create a new Foo instead?
Yep, which entails the extra steps of reading over the super class' method list, and actually thinking of an alternative name for it once you find out it does conflict with a previously defined method. Its the same as global variables in the sense that w/ globals a variable can overwrite another variable's value if they used the same name. With abstract classes a method can overwrite a previously defined method. The problem is of the same nature but not as insidious as globals.

The only benefit of abstract classes is you type "$this->foo()" instead of "$this->bar->foo()", and a few less delegating methods (which can be good or bad, because it reduces the number of "seams" as defined by Michael Feathers). If we had prototypical inheritance there would be literally no benefit to having abstract classes anymore.

@Christopher
Basically the only reason to use abstract classes is its less verbose, and only in some situations. That's the same argument people give for why global variables, or singletons are a good idea. To me, making my program harder to re-factor doesn't justify a couple less keystrokes anymore than using a singleton would. Since abstract classes DO have limits and composition does not, there is a high likely hood you're going to need to change it from an abstract class to a composite object down the line anyways. That's the same reason we use not to use singletons, because it hinders certain changes (by making refactoring a lot harder). If you find out in a week you did need composition, you will very likely have to go change ALL of the code on ALL of a class' super-classes.

Re: Namespaces and abstract class names

Posted: Tue Feb 08, 2011 10:11 pm
by Jonah Bron
Looks like I've gotten sucked into the conversation :)
josh wrote:robot cannot inherit animal because robots aren't organisms! They shouldn't breathe() and sleep()!!! You're going to print_r() your object and get loads of unrelated information. That's a big code smell.
Right. That's a situation where normal inheritance can't cut it, and composition saves the day.
josh wrote:4 ways to define a class in javascript? I know of only one, 'function'.
I think he means like this:

Code: Select all

var MyClass = function () {
    this.something = function () {
         // ...
    }
}
// or
var MyClass = {};
MyClass.prototype.something = function () {
    // ...
}
josh wrote: Inheritance = take it or leave 100% of all defined methods & variables. No in-between.
Often that's all that's required.
josh wrote:Yep, which entails the extra steps of reading over the super class' method list, and actually thinking of an alternative name for it once you find out it does conflict with a previously defined method. Its the same as global variables in the sense that w/ globals a variable can overwrite another variable's value if they used the same name. With abstract classes a method can overwrite a previously defined method. The problem is of the same nature but not as insidious as globals.
Not sure if I fully see the sense in that. For one, if you want to name a method the same as a parent class's method, it seems likely that you know it, and want to override it. And two, any IDE can tell you if the method names are in conflict pretty much instantly. Netbeans for example puts a green circle with an "I" in it beside any overriding method.
josh wrote:Basically the only reason to use abstract classes is its less verbose, and only in some situations. That's the same argument people give for why global variables, or singletons are a good idea. To me, making my program harder to re-factor doesn't justify a couple less keystrokes anymore than using a singleton would. Since abstract classes DO have limits and composition does not, there is a high likely hood you're going to need to change it from an abstract class to a composite object down the line anyways. That's the same reason we use not to use singletons, because it hinders certain changes (by making refactoring a lot harder). If you find out in a week you did need composition, you will very likely have to go change ALL of the code on ALL of a class' super-classes.
So you're saying that we should use 100% composition because we might need what it provides sometime in the future? Seems like it would be pretty clear cut when a class hierarchy is going to need the functionality that only composition can provide right off the bat. And how do abstract classes make refactoring difficult?

Re: Namespaces and abstract class names

Posted: Wed Feb 09, 2011 6:01 am
by VladSun
josh wrote:@Vlad
I skipped your post because I was arguing against use of abstract classes, and you asked me if that means I want PHP's handling of abstract classes to be more strict? Your question doesn't make sense. Virtual methods are a feature of abstract classes, which I am arguing against.
But many of your arguments you used and you are still using, would be meaningless if PHP was more verbose/strict. I don't see how my question doesn't make sense.

You can not argue against abstract classes, saying some features are missing, and then say that implementing these features sucks because their purpose is to serve abstract classes.

Have you ever tried using Java or C++ like languages josh? I mean strict typed languages. Of course, not Hello-world projects.

Re: Namespaces and abstract class names

Posted: Wed Feb 09, 2011 9:14 am
by Jenk
fwiw, virtual/override (as implemented in .NET) sucks big time. A parent class must know and permit which members are going to be overridden. Completely against the whole point of inheritance in the first place, but lets not get too much into that - it is not something restricted to abstract classes (it applies to everything.)

The argument is: Composition vs Inheritance.

Lets not get stuck on implementation details of compilers, and discuss the benefits/drawbacks of both composition and inheritance.

A quick (but not comprehensive) list of the benefits offered by Composition that are not in inheritance in my eyes are:
  • Easier to separate concerns
  • Can implement more than a single composite, can only inherit one class
  • In the case where multiple inheritance allowed, the Diamond problem is solved.
  • I'm not dependant on a parent class' internal implementation, only on a composites interface - the way it should be in every possible scenario in my opinion.

Re: Namespaces and abstract class names

Posted: Wed Feb 09, 2011 9:36 am
by VladSun
Just read the beginning of the GoF book ... :P