Hi Dennis, OK, I understand better :)
> De : Dennis Birkholz [mailto:den...@birkholz.biz] > > Currently, all traits, classes and interfaces share a common symbol > table. So if a trait Foo exists in a namespace bar\, not interface or > class with name Foo can also exist inside that namespace. > > I now would not limit this symbol table to hold only the > class/interface/trait names but hold the names of all possible types. > (Types are classes, traits, interfaces, scalar types, arrays, etc) Arrays ?? > If the integer type is named "int" in namespace \, that means you can > not define a class/trait/interface/whatever in \ that is also named int. The potential name clash is exactly the same. We want to define *today* keywords which won't conflict *tomorrow* with user class names defined *yesterday*. Also, how does the user know which types are currently defined, let alone those that will be in the future ? Sorry, it just moving the problem, not solving it. > Union types where mentioned here several types e.g. for the numeric type > that would be defined somewhat like numeric = int|float but without a > specific syntax so far. What you show is not exactly union types. It is union type + alias, which is different. I intend to support a syntax like 'function str_replace(string|array $search,...', using no alias. That's what I'm asking a syntax for. No problem with type aliases but my primary intent is not to merge both features. > For each new union type that is > required, another name has to be excluded from being a valid class name. > If all these types also would only go into the \ namespace, there would > be nearly no BC break (at least with namespaced code). Everything is in 'at least'. Sorry, but similar to suggesting lowercase-only types. That's conventions only. We cannot base on this. > class MyIncompatibleDateTime { ... } > union DateTime = \DateTime|MyIncompatibleDateTime; Defining a new kind of element in a class is huge work as there are implications everywhere. I'd prefer to stick with existing concepts. > class Whatever { > // Allow \DateTime and \Foo\MyIncompatibleDateTime here > function doWithDate(DateTime $date) { ... } Readability limited to 5 minutes. One year later, of for your colleague, everyone will guess you're referencing the a DateTIme class. > Another case are enum types that I saw on the list some time ago. The > names of the enum types should also go into the same symbol table. Enum is just a kind of specialized type. These will probably exist in the future, but I don't know which form they will take. > From the point of view of a consumer/user of the language, it is kind of > inconsistent to have some type names that are limited in their scope > (class/trait/interface names are only valid inside their namespace) and > some type names that are global (primitive types like string/int/etc.). Probably but where do we stop ? Do you want to change syntax to use \PHP\function, \PHP\for, \PHP\switch everywhere in your code ? It would be useful too as it would allow to redefine language behavior from userland, but I guess we wouldn't have any user more to use the feature. > We could argue now that it would be even better to put all primitive > types inside of \PHP so there would be absolutely no BC break when we > introduce them. We could also make very clean in the docs that users > should never ever define any types inside the \PHP namespace. The same. Doc is just conventions. Cannot base grammar on this. > I understand that scalar types and classes are something different > inside the engine and I do not propose to remove all scalar types in > favor of class based primitive types. No. If we ever do it, both cannot coexist. Way too complex for the user and to implement. But the handling in the engine and > the resolution of a name in the PHP code are two different things. But > if we can allow scalar type names as type hints or return types, we > should also be able to put the names into the same namespaced symbol > table as we put class names. But I do not have a deep inside in the > inner workings of the engine code so this is only guesswork. In terms of internal implementation, adding another type in the symbol table shared by classes, interfaces, and traits is very complex work. The reason is that there is no real symbol type, as it was done incrementally. Engine behavior is based on a set of binary flags attached to each entry : is_interface, is_abstract, is_trait... Sometimes, these are not checked at all, this is for example the case with autoloaders. They don't have specialized behavior for interfacs and traits, so they don't check anything. Sometimes, the code distinguishes traits, sometimes abstract classes... Magic methods don't even have special flags. Most are recognized by strcmp() when needed ! So, adding a new (virtual) type in such a table is very complex because there's no room for it. The only way is to add an additional is_type_hint flag and go modifying the code everything this should cause different behavior, e.g. almost everywhere. And changing this to define 'real' symbol types would be still more complex and would be rejected because it would slow down the interpreter. So, no perfect solution here... Thanks for your suggestions. I'll resume my position by saying that, from all you suggested, the only possible option, IMO, is to force the user to add a specific reserved prefix every time he uses a builtin type hint, or add a use clause at the beginning of each file. This alone would remove the RFC any chance to pass, even if I was strongly in favor of it. If I add the extreme implementation complexity and potential slow performance, I'd be dead 5 min after proposing it :) Don't get me wrong. I appreciate your suggestions, but I don't think it's possible. As I previously said, additional features may be attached to namespaces, but probably as links with classes. But keep sending suggestions, I'm always interested in original ideas. Thanks François -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php