I still can't see how it can be "mature" if it offers an iterable returnable type like in the article example yet doesn't indicate the type of the object it is returning!
It has type hints for function parameters and return types but not for arrays. This makes it useless to me.
I know everybody will say "just add comments so an IDE can interpret it" but this should be a feature of the language. Just adding comments to hint to an IDE is not a real solution.
It's still just a vector<void* > in C++ parlance. Nobody would take you seriously if you said "just add comments to indicate what your void* might be" in a large codebase.
I still can't see how C++ can be "mature" if you have to indicate the type of object it is returning!
I know everybody will say "just add a type declaration so the compiler can interpret it" but this should be a feature of the language. Just adding type declarations to hint to a compiler is not a real solution.
But it's not a hint to the compiler. It's stating a fact to the compiler. It'll stop compilation.
If I have a basket of fruit, all the items in that basket container are fruit. I can't put anything other than fruit in it. It's a basket of fruit. I know how to interact with the fruit due to its type.
If I am able to put dung into my basket, my fruit is spoiled and I cannot assume how to interact with the objects in the basket.
This is a PHP array without types at the array level. I can put dung into it and have no idea how to interact with it.
Or are you saying that a container of any type is perfectly acceptable? Did the other languages (C++, C#, Java) get it wrong?
eg. on this line can you tell me what the array holds and how I interact with it? What does array $operations hold?
> But it's not a hint to the compiler. It's stating a fact to the compiler. It'll stop compilation.
So, if I type out that something's a Banana, and the compiler stops and tells me it's actually an Apple, why did I need to type anything?
> Did the other languages (C++, C#, Java) get it wrong?
I can only speak for Java, but here goes. Here's something that compiles without warning and crashes at runtime:
Fruit[] basket = new Apple[] { new Apple(), new Apple() };
basket[0] = new Apple();
basket[1] = new Banana(); // Crash here
You and I know Dung doesn't belong in a basket, but Java sure doesn't. It will not warn about me comparing Fruit to Dung, nor is there a way to ask the compiler to warn me that I forgot to handle Banana:
void handleFruit(Fruit fruit) {
if (fruit instanceof Apple) {
System.out.println("Apple");
} else if (fruit instanceof Dung) {
System.out.println("Dung");
}
}
Here's another one:
void foo() {
Fruit[] basket = new Apple[] { new Apple(), new Apple() };
handleFruit(basket[0]);
handleFruit(new Apple();
}
void handleFruit(Fruit fruit) {
System.out.println("Do I get called?";
}
void handleFruit(Apple apple) {
System.out.println("Or do I?";
}
In the first code sample we established that the basket could only contain Apples, but now when you handle something from the basket, it's apparently any Fruit.
And when you handleFruit an Apple, there's no warning that the compiler is making a choice between the two acceptable handleFruit functions.
Anyway, just like me, this Bucket<Dung> is full of shit. Time to dump it all out. I could put it in the compost, or in the veggie garden. Anywhere that contains Dung. Likewise, the Fruit could go in a Bowl, or a Cupboard.
Here's a first pass at it:
interface Transfer<F, T> {
void dump(F from, T to);
}
class FertiliseGarden implements Transfer<Bucket, Garden> {
public void dump(Bucket from, Garden to) {
}
}
class PutAwayFruit implements Transfer<Basket, Cupboard> {
public void dump(Basket from, Cupboard to) {
}
}
It compiles, but it's missing the only safety check I really cared about - the contents must match (even if the containers vary!) Let's introduce another type variable X to assert this:
Now it asserts what I want it to assert, but it doesn't compile.
I can't call how Java handles the above stuff as 'wrong', since that's stating it too objectively. I can only say I disagree with the above design decisions (if they were deliberate) or I find fault with them (if they just turned out that way).
Yes that Java example is bad and terrible. I'm honestly amazed you can do Fruit[] basket = new Apple[]. That's terrible.
You can't do that in C++. You can slice objects but you'll get a warning in any good compiler.
I would like to know the type of the object I am working with else it'd be "auto everything" in C++ and it makes the code unreadable.
That's basically what I am finding objectionable about PHP because you've got types added as return types from functions, and also types for parameters and you can enable strict checks for the types but none of it makes any sense when you can just get an array of unknown/any type.
It's like a C++ vector of void pointers that you can cast to whatever you'd like it to be and that's really bad. It's also not very maintainable, particularly in large codebases.
It's a strange oversight in PHP given the type "safety" enforced elsewhere. I suspect they just aren't doing it because so much code would break.
I would like to see this typed array introduced so you can look at horrible codebases like the Magento example (there's loads of it) and see at a glance what you're dealing within instead of "an array of unknown type".
I will use your FertiliseGarden function shortly, thanks.
It has type hints for function parameters and return types but not for arrays. This makes it useless to me.
I know everybody will say "just add comments so an IDE can interpret it" but this should be a feature of the language. Just adding comments to hint to an IDE is not a real solution.
It's still just a vector<void* > in C++ parlance. Nobody would take you seriously if you said "just add comments to indicate what your void* might be" in a large codebase.