The SitePoint Forums have moved.

You can now find them here.
This forum is now closed to new posts, but you can browse existing content.
You can find out more information about the move and how to open a new account (if necessary) here.
If you get stuck you can get support by emailing forums@sitepoint.com

If this is your first visit, be sure to
check out the FAQ by clicking the
link above. You may have to register
before you can post: click the register link above to proceed. To start viewing messages,
select the forum that you want to visit from the selection below.

We are, but primitives have (implicit) interfaces too. For example, if a class implements __toString(), then objects of that class has the same interface as a primitive string has. If you restrict the contract of a function to the concrete type "string", then you are preventing the caller from passing an object that otherwise fulfils the contract. This leads to code with a lot of explicit type-juggling.

One would hope that the internals of the language would take care of handling all of this, i.e, if you say a parameter should be a string, and you pass an object that implements __toString(), it would treat it as a string.

Which brings up an interesting point which we can currently test to see if the language handles this with the array typehint and objects that implement ArrayAccess:

And, it appears that it does not. And that, I would say, is a bug in the language, or at the very least that the implementation of ArrayAccess in the internals of the language is incomplete, because there are numerous areas where it works, i.e, where the object functions exactly as an array as expected.... so why not here too?

And, it appears that it does not. And that, I would say, is a bug in the language, or at the very least that the implementation of ArrayAccess in the internals of the language is incomplete, because there are numerous areas where it works, i.e, where the object functions exactly as an array as expected.... so why not here too?

It has been tabled to be fixed...

50. Make it possible to use objects implementing ArrayObject interface anywhere arrays are used.

One would hope that the internals of the language would take care of handling all of this ..

Exactly.

The problem is that typehints to primitives are too restrictive. There is no use-case where what you need is an integer. The only use-cases that exists are those that relate to the parameters interface. For example, that it should be usable as an integer. That's a subtle, but important, distinction. Without it, we get the type-juggling hell that Java and other languages are cursed with.

Originally Posted by dreamscape

And, it appears that it does not. And that, I would say, is a bug in the language, or at the very least that the implementation of ArrayAccess in the internals of the language is incomplete, because there are numerous areas where it works, i.e, where the object functions exactly as an array as expected.... so why not here too?

The array type is a particular good example of the problems this gives. An array has several interfaces; It can be looped over with foreach, it can be accessed through square brackets. By using a typehint to the concrete type array, you are needlessly restricting the contract of your function. What you should have done instead, was to restrict the parameter to the interface that you expect; Eg. ArrayAccess or Iterator. Unfortunately that's not possible because of the static type system that php has inherited from Java.

To summarise - I have no problem with design-by-contract. Making prerequisites explicit can help to strengthen a protocol. But an overly restrictive contract adds bureaucracy. This is not an entirely new problem for php; It's already possible to typehint to concrete classes, rather than interfaces. And even interfaces are needlessly bureaucratic.

Like shea, I'd welcome this even if only for the sake of IDEs. Currently, for the larger part of PHP code, it's impossible for most editors to guess the types of arguments you need to use and warn you about them if they don't match.

Allowing type hinting will let not just PHP, but your IDE to warn you of type mismatches. If type enforcement is in session, it could warn you up front. If it's type casted, there may be separate notices (since if it's casted, it's not as critical of an error).

Personally, I'd use the stricter syntax more than the casting one. Why? Because objects and arrays are already strict (i.e. they present a warning if type mismatch occurs). It already helps me a lot. And there are a lot of times where I miss placing scalar type hints of that kind. If I'm tolerant of the type, I wouldn't need to hint it on the first place - I'd just cast it anyway. I always use type casting, as it helps to keep code more clean, logical and secure. I'm not saying that if you don't use it, your code is not, but if you do it, it helps.

i agree with boen_robot in that having full type hinting support would then allow for full code completion in IDE's which would be a godsend for me. Currently I use the Zend IDE based on Eclipse, which does a great job of reading PHPDoc comments, but it won't raise errors (AFAIK) if you mismatch types.

to be honest, the community seems so torn with this subject, I'd like to see PHP branched to support full static typing of all variables, as opposed to reluctantly adding features here and there to make advocates on both sides of the fence happy. I don't see this happening however, so I would be content with having type hinting.

Originally Posted by arkinstall

Many (misinformed) people believe that PHP IS a toy language used as a bridge between noob and programmer, so that they can move onto better languages.

Sure, people do tend to start with PHP and can learn other languages later (generally of the desktop application variety) but PHP is still the most suitable programming language for web development out there. That it caters for beginners is just another feature, but for it to stay competitive with stronger languages it needs to compensate for programming techniques found in said languages - e.g. namespaces.

i agree completely. All in all, I'm happy with the direction PHP is going. I've been looking forward to 5.3 for longer than I can remember, and the proposed ideas such as this one (type hinting) is just icing on the cake.

I'm personally FOR the addition of type hinting. I'm finding the arguments used by those who are against this feature, are largely invalid. The main argument against, revolves around the fact that PHP is a loosely typed language, and that type hinting would contradict the PHP philosophy, and make it more difficult for beginners to learn the language. Generally speaking, people have thought up worst case scenarios (impractical scenarios) which would never eventuate if type hinting was fully implemented.

Practically all built-in PHP functions already use type hinting, so what possible difference is there between a built-in function with type hinting/restriction, and a user function with the same thing? As long as user function type hinting is implemented in the same way as existing built-in function type hinting, it won't be a problem.

To clarify the behaviour of type hinting for built-in functions, here's generally how they work. If any argument passed to a built-in function, does not match the expected type, PHP will attempt to convert it to that type. So seeing as though all types (I think) can be converted to an integer (0 or 1 at the least), functions expecting an integer, rarely (if ever) generate a warning if something other than an integer is received.

Finally, the two main advantages of type hinting are...

Easier debugging of code; especially when working with someone else's functions/classes/framework.

More efficient coding of functions, as messy, convoluted type checks do not have to be implemented manually by the developer. PHP instead handles this.

I think PHP is long overdue to receive type hinting. It's about the only thing PHP is missing.

Wardrop, how would you see str_replace implemented using type hints? My point is that,
argument type enforcement/coercion may be a good thing, but we need something better
than Java.

kyberfabrikken had a great proposal on the PHP internals list, inspired from some Scheme
feature. Recently I've read about some new feature in Python 3, called function annotations,
which allows Python users to implement custom parameter checking. For them, there's no
reason to have type checking built into the language. They import a library and use some
decorators.

Wardrop, how would you see str_replace implemented using type hints? My point is that,
argument type enforcement/coercion may be a good thing, but we need something better
than Java.

You do know that explicit type enforcement/casting is going to be applied only for user created functions on the arguments the user explicitly specified, and not PHP/extension functions, right?

I think we already have something better than Java's type enforcement and correction in the face of PHP's loose typing nature. Explicit type enforcement/casting is only there if you want it. What can be better than that? You have complete blocking on the one side (JAVA), and a complete tolerance (PHP) on the other.

Oh, and the argument that it will be harder for newbies - Remember that type hinting and explicit type casting will be optional. You can still use loose typing in zero, one, more or all of a function's arguments. Therefore, newbies won't have to learn anything about types until they want to, the same way they don't need to know that arrays can be type hinted, and could just use them.

That's exactly the reason why it's harder. It's called the paradox of choice. Adding choices reduce usability - not the other way around.

Too many options may kill a man. Nonetheless, I think this may make a useful feature to add to the language, although I'd much rather see a few other features implemented, such as traits. I wonder, do you *really* have to enforce that an integer is being passed instead of string "1"? I mean, it *was* validated before you passed it along right? The dynamic nature is one of the benefits of PHP, not one of it's downsides. I use typehinting all the time though, but only for arrays and objects. Scalar values are usually all the same to me, because decent validation and a bit of casting can go a long way.

That's exactly the reason why it's harder. It's called the paradox of choice. Adding choices reduce usability - not the other way around.

If you present them from the get go, yes. But you don't see any tutorials that teach about object and array type hinting, right? They don't have to do that either. Newbies would only learn about type hinting's existence once they encounter a situation where it may seem useful.

In that same fashion, most tutorials don't teach about the clone keyword, object reflection, variable variables and heck, they rarely talk about plain scalar type casting (the "(type) $var" construct) too. Those are all things that newbies learn only once they need them.

Too many options may kill a man. Nonetheless, I think this may make a useful feature to add to the language, although I'd much rather see a few other features implemented, such as traits. I wonder, do you *really* have to enforce that an integer is being passed instead of string "1"? I mean, it *was* validated before you passed it along right? The dynamic nature is one of the benefits of PHP, not one of it's downsides. I use typehinting all the time though, but only for arrays and objects. Scalar values are usually all the same to me, because decent validation and a bit of casting can go a long way.

Scalar values annoy the hell out of me simply because scalars can be anything from a boolean to a string - very different things.

For example, what if you passed a boolean to a function which expects a string?

As for the validating thing, I don't see this as a big use for user-input, but mainly for frameworks and libraries - where some idiot is bound to try and pass 'hello world' to a method which expects a boolean or an integer. Sure, you can cast it with:

PHP Code:

function someFunction($Var){
$Var = (int)$Var;
}

The only difference with that and the new syntax will be that the new syntax will save code and make things more obvious to people reading the code, e.g:

PHP Code:

function someFunction((int)$Var){ }

You know it's going to be an integer without looking any further than the function declaration!

The minute a language BASES itself on being easy to learn, risking functionality and ease-of-coding, is the minute that language loses credibility in the programming world. PHP's been down there before, and it's starting to get a bit of a foothold.

Jake Arkinstall
"Sometimes you don't need to reinvent the wheel;
Sometimes its enough to make that wheel more rounded"-Molona