SitePoint Sponsor

User Tag List

Page 2 of 3 FirstFirst 123 LastLast
Results 26 to 50 of 59
  1. #26
    SitePoint Enthusiast
    Join Date
    Feb 2006
    Posts
    68
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I think interfaces and type hinting are tools just like many other features of the language.

    Personally I like writing code like:

    PHP Code:
    function array_something(array $array) { } 
    instead of:

    PHP Code:
    function array_something($array) { 
    if(
    is_array($array)) throw new Exception("first argument should be an array"); 

    The first example has also the advantage of being a little bit self-documenting (You don't have to write the type of the first parameter in doc-block).

  2. #27
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by zYne
    PHP Code:
    function array_something(array $array) { } 
    And thus preventing a programmer from passing an ArrayAccess ?

  3. #28
    SitePoint Guru
    Join Date
    May 2005
    Location
    Finland
    Posts
    608
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by kyberfabrikken
    And thus preventing a programmer from passing an ArrayAccess ?
    Yes. ArrayAccess' behaviour is a subset of array. You can't subject it to the common array manipulation functions, for example. Can you pass an array if the type hint says ArrayAccess, though?

  4. #29
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Ezku
    Yes. ArrayAccess' behaviour is a subset of array. You can't subject it to the common array manipulation functions, for example.
    Let's pretend that in this situation, the function only needs that particular subset behaviour. Otherwise, pretend that I want to pass an object implementing some of the other SPL interfaces, such as Iterator.

    Quote Originally Posted by Ezku
    Can you pass an array if the type hint says ArrayAccess, though?
    No.

  5. #30
    SitePoint Guru BerislavLopac's Avatar
    Join Date
    Sep 2004
    Location
    Zagreb, Croatia
    Posts
    830
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by zYne
    Personally I like writing code like:

    ...snip...

    The first example has also the advantage of being a little bit self-documenting (You don't have to write the type of the first parameter in doc-block).
    So, what is the real difference between this:

    Code:
    Fatal error: Argument 1 passed to foo() must be an array, called in /var/www/_sandbox/index.php on line 8 and defined in /var/www/_sandbox/index.php on line 3
    and this:

    Code:
    Warning: array_reverse() [function.array-reverse]: The argument should be an array in /var/www/_sandbox/index.php on line 5

  6. #31
    SitePoint Enthusiast
    Join Date
    Feb 2006
    Posts
    68
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by kyberfabrikken
    And thus preventing a programmer from passing an ArrayAccess ?
    Well actually yes. In many cases the simplicity that comes with this kind of typing overcomes the flexibility of allowing developer to pass an object that implements ArrayAccess and/or Iterator and maybe even some other interfaces as well.

    PHP Code:
    class {
      
    /**
       * @param $array    - simple array
       */
      
    public function foo(array $array) { }

    instead of:
    PHP Code:
    class {
      
    /**
       * @param mixed $array  -- simple array or an object that implements ArrayAccess and Iterator interfaces
       */
      
    public function foo($array) { 
        
    $interfaces class_implements($array);
        if( ! 
    is_array($array) || 
            ! 
    in_array('ArrayAccess'$interfaces)
            ! 
    in_array('Iterator'$interfaces)
          )
          throw new 
    Exception("first argument should be an array or it should implement ArrayAccess and Iterator interfaces.");
      }

    This becomes just stupid if I want EVERY method that takes an array as parameter to support objects that implement these special interfaces.

  7. #32
    SitePoint Enthusiast
    Join Date
    Feb 2006
    Posts
    68
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by BerislavLopac
    So, what is the real difference between this:

    Code:
    Fatal error: Argument 1 passed to foo() must be an array, called in /var/www/_sandbox/index.php on line 8 and defined in /var/www/_sandbox/index.php on line 3
    and this:

    Code:
    Warning: array_reverse() [function.array-reverse]: The argument should be an array in /var/www/_sandbox/index.php on line 5
    Relying on internal warnings thrown by array_* functions is IMHO a bad coding practice.

    For example think about a framework that takes a config array as a parameter on some method. Then this array is passed from method to method and then some method uses function such as array_reverse. It would be a frustrating task to a developer to figure out why the code threw a warning (propably he would first guess this warning is some bug of the framework itself).

  8. #33
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by zYne
    This becomes just stupid if I want EVERY method that takes an array as parameter to support objects that implement these special interfaces.
    Yes, but only if your premise is that you want to enforce type. If you just take any argument, and use it as if it was an array - then you're fine. This of course relates very closely to your next quote :

    Quote Originally Posted by zYne
    Relying on internal warnings thrown by array_* functions is IMHO a bad coding practice.
    I understand that your argument is that it fails earlier, and thus makes it easier to spot the problem. I won't judge which is more appropriate, but it's important to understand that both styles have pros and cons. Typehinting may help you fail early, but it also imposes some bureaucracy on the developer, and is less flexible.

  9. #34
    SitePoint Guru BerislavLopac's Avatar
    Join Date
    Sep 2004
    Location
    Zagreb, Croatia
    Posts
    830
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Arrays and ArrayAccess are a specific case, because it's mixing apples (data-only arrays operated on with procedural functions) with oranges (objects, which have their own behavior).

  10. #35
    SitePoint Guru 33degrees's Avatar
    Join Date
    May 2005
    Posts
    707
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    This is the one of the problems with PHP's implementations of Interfaces; if you use a type hint, your method becomes locked into that one type of object. In Java, you don't have this problem since you can simply overload the method, making a version that accepts arrays, another that accepts iterators, etc.

    And this is what I find a bit paradoxical about PHP's inclusion of interfaces; in Java they're a way of making your code more agile (and in fact the language would be useless without them), whereas in PHP they actually make your code less agile.

  11. #36
    Web-coding NINJA! silver trophy beetle's Avatar
    Join Date
    Jul 2002
    Location
    Dallas, TX
    Posts
    2,900
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Ok, I much better see the downside of PHP's Interface implementation.

    However, I'm pleased to discover that I still feel I'm using them properly. As I mentioned earlier, I'm the framework developer on a team of four. I author tightly controlled domain objects. I'm responsible for ensuring conformity to our framework's API.

    If one of the other developers needs a feature or change or whatever, they have to come to me for it. So, for my job responsibilities, interfaces (proper) help me enforce the API.
    beetle a.k.a. Peter Bailey
    blogs: php | prophp | security | design | zen | software
    refs: dhtml | gecko | prototype | phpdocs | unicode | charsets
    tools: ide | ftp | regex | ffdev




  12. #37
    SitePoint Guru
    Join Date
    May 2005
    Location
    Finland
    Posts
    608
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by 33degrees
    And this is what I find a bit paradoxical about PHP's inclusion of interfaces; in Java they're a way of making your code more agile (and in fact the language would be useless without them), whereas in PHP they actually make your code less agile.
    Quite obvious, but nevertheless something I hadn't considered before. Damn. I wonder why?

  13. #38
    SitePoint Zealot
    Join Date
    Sep 2005
    Posts
    122
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    How does it makes the code less agile? For the code to work correctly you will still have to implement the methods that will eventually be called. Interfaces in PHP just makes this more verbose and explicit, hence the arguments that interfaces are good for documentation.

    Personally, I don't use them. I think it just introduces unnecessary clutter, however I fail to see how they would make the code less agile.

  14. #39
    SitePoint Guru 33degrees's Avatar
    Join Date
    May 2005
    Posts
    707
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by shea
    How does it makes the code less agile?
    The problem isn't interfaces themselves, but their use in conjunction with type hinting; they add rigidity to your code, making it less agile because changes in one place can lead to changes in other places. This increases the cost of change, and agile methedologies are all about decreasing that cost.

  15. #40
    SitePoint Zealot
    Join Date
    Sep 2005
    Posts
    122
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    So a new method needs to be added to the passed-in object ... regardless of whether you are using an interface, you're still going to have to add that new method to the passed-in object. So where is the increase in cost? That you have to define a function in the interface as well as the class? Barely worth mentioning.

    So changes in one place are going to lead to changes in another place regardless of interfaces. The only difference, which I stated earlier, is that with the verbosity of interfaces, we now have to define, at most, one more method signature.

  16. #41
    SitePoint Guru 33degrees's Avatar
    Join Date
    May 2005
    Posts
    707
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Let's use an example: Your client wants you to model some animals, so you create an IAnimal interface. Your animals need to eat food, so you add an eat(Food $food) method to your interface, and then implement your different animals. One day your client decides he'd like to add some goats, and you realise that your goats don't just eat food, sometimes they eat garbage. So what do you do? You need to change your goats so that they simply eat($stuff), but that means changing your interface, which then means changing every single class that implements IAnimal. Based on your initial requirements, you made the assumption that your animals would only ever eat food; but the requirements changed, and your prediction turned out wrong, so now you have to adapt your code to the new requirements, something that is more complex than it could be because of the typehinting. Hence, type hinting (and static typing in general) increases the cost of changes, decreasing agility.

  17. #42
    SitePoint Enthusiast
    Join Date
    Jul 2004
    Location
    Finland
    Posts
    73
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thats a design problem. Food is bad name for interface, it should be Eatable, CanBeSwallowed or something like that

  18. #43
    SitePoint Guru 33degrees's Avatar
    Join Date
    May 2005
    Posts
    707
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    It's a contrived example; the fact is that there will always be cases where you will need to change the types of arguments your methods should accept, and by locking them in with typehints, you risk needing to make far-reaching changes later.

  19. #44
    SitePoint Addict
    Join Date
    Aug 2003
    Location
    Toronto
    Posts
    300
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    ....lets say your code is designed so that it can only process food and not garbage. Typehinting an interface is in this case therefore specifies the minimum required contract (which without typehinting, you would probably have to check for in your code anyhow -- unless, perhaps, you rely only on test cases to ensure correctness). Changing requirements often DOES require changing and reviewing code in far reaching ways, not?

  20. #45
    simple tester McGruff's Avatar
    Join Date
    Sep 2003
    Location
    Glasgow
    Posts
    1,690
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    ...which surely is an argument to minimise such changes as far as possible.

    Personally I wouldn't use hints unles I was using a DependencyInjection tool which requires them. I can't think of a unit test which would produce a false positive for lack of hints. If it works, it works and hints don't change that. You could get false negatives signalling that the constraints need to be relaxed (ie dump the hints). I think it's best to try to strip away everything that's not absolutely essential since this makes refactoring easier.

  21. #46
    SitePoint Guru 33degrees's Avatar
    Join Date
    May 2005
    Posts
    707
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by jayboots
    ....lets say your code is designed so that it can only process food and not garbage. Typehinting an interface is in this case therefore specifies the minimum required contract (which without typehinting, you would probably have to check for in your code anyhow -- unless, perhaps, you rely only on test cases to ensure correctness).
    The trouble is that the "minimum required contract" may end up changing, and if you're using type hinting that change becomes more far reaching than it would be otherwise. Without the type hint, you can selectively make some of your animals consume things other than food without having to change anything about the rest of the animals.

    Quote Originally Posted by jayboots
    Changing requirements often DOES require changing and reviewing code in far reaching ways, not?
    Yes, of course; agile development is a recognition that change is inevitable, so it should be as easy as possible, and type safety is an impediment to that.

  22. #47
    SitePoint Zealot DerelictMan's Avatar
    Join Date
    Oct 2005
    Posts
    123
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by 33degrees
    Yes, of course; agile development is a recognition that change is inevitable, so it should be as easy as possible, and type safety is an impediment to that.
    I've been with you all along until that last statement, which I feel is more general than it should be. All this time you guys have been discussing using type hints in PHP, which IMHO is a very small subset of what I'd call "type safety". I totally agree that using type hints in a language that is otherwise not anywhere near type-safe makes your code less agile. However, I do not agree that in general type safety results in less agility.

    I really do not want to start a statically vs. dynamically typed debate (we've all been there before), but I do want to point out that the meta-information that types provide in a language like Java makes it possible for many common types of refactorings to be much simpler than they would be otherwise, due to the existence of tools that can analyze that information. Take something as simple as changing the name of a method. Often times you'll pick a name for your method, and after the design or your application is a little more fleshed out, you'll realize that the name is not as clear as it could be. Often you don't need to change the implementation at all, it's just that the name is inconsistent with other names, or is slightly confusing. Often when working with PHP I'll find myself debating over whether it's confusing enough to warrant having to manually update it across a dozen or more files. Yes, I'm more than aware that there are editors that will do search and replace, even using regex. However, it still takes time to make sure you're not replacing any false matches. Constrast this with Eclipse, where I select the method, hit ALT-SHIFT-R, type the new name, and hit enter. That's all that's required, and I can do it in less than 4 seconds.

    That may not seem like a big deal, but every little bit adds up. And renaming methods is just the tip of the iceberg. Really, unless you've got experience with a modern refactoring IDE, you should consider whether there is something you're missing. I know, at least for me, that I'm far more merciless with my refactoring when there are tools to automate some of it for me than I am when I have to do it all by hand. If this could be achieved without static typing, I'd be all over it, but I haven't seen or heard of it yet (outside of the Smalltalk community, which I have on my list to check out at some point...)

    Of course I'm sure many would argue that static typing imposes enough other limitations that it results in a net loss in agility, even with automated refactoring tools taken into account. That has not been my experience, but I accept that others may differ. Just wanted to present a different view on the matter...

  23. #48
    SitePoint Addict
    Join Date
    Aug 2003
    Location
    Toronto
    Posts
    300
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I still don't see how typehinting impinges on the idea that changing requirements require changing code. If anything, it quickly points out where code will need to be changed. Whether you typehint or not, your methods will need to be aware if suddenly an incompatible (ie: an unexpected) object is passed-in. Typehinting merely states at the outset that a given piece of code has certain expectations. Personally, I don't subscribe to the view of absolute generality -- all concrete solutions have limitations; what is the problem in explicitly declaring them? If you need to refactor and modify code at some point to add more sophistication -- aren't tools (and hints or features at any rate) to flag where issues will arise beneficial in those cases? FWIW, I don't advocate typehinting everything in PHP -- just those cases where minimum conditions need be met unconditionally to prevent code breakage. ...or maybe this is my view because I write a lot of library type code and can't trust what people would do with it

  24. #49
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by jayboots
    I still don't see how typehinting impinges on the idea that changing requirements require changing code. If anything, it quickly points out where code will need to be changed. Whether you typehint or not, your methods will need to be aware if suddenly an incompatible (ie: an unexpected) object is passed-in.
    Well, not really. You will get in error if an object of a different type than the programmer specified, is passed in - not if it's incompatible. There's a slight difference.

  25. #50
    SitePoint Addict
    Join Date
    Aug 2003
    Location
    Toronto
    Posts
    300
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by kyberfabrikken
    Well, not really. You will get in error if an object of a different type than the programmer specified, is passed in - not if it's incompatible. There's a slight difference.
    It will be incompatible if it doesn't adhere to the typehint that was specified -- and thus will generate an error -- so no difference.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •