Originally Posted on DevelopmentMatt.com
Recently, I read an interesting article from Andrew Carter entitled Make PHP Great Again [cheap plug: this link was included in my most recent Newsletter]. In it Andrew brought up the topic of scalar objects. If you're not familiar with scalar objects, they represent a single value (integer, boolean, string, etc.) that you can perform operations on*. In PHP this could look something like:
$name = 'Matt';
var_dump($name->length()); // int(4)
* It's important to note that, as far as I've been able to ascertain, the context in which you use the term "scalar" is important. Different languages implement and define scalar differently.
Soon after scalar objects were brought to the forefront of my mind, I came across the following tweet:
To which I replied:
The Case For Scalar Objects in PHP
If you read Andrew's post he discusses how PHP's core functions are inconsistent. This topic isn't new:
PHP 8 is a great opportunity to cleanup these inconsistencies. Introducing scalar objects would provide a consistent API that would be more fluent and much more enjoyable to work with. Which of the following is more intuitive to you?
$hello = str_replace('Matt', 'Bob', 'Hello Matt!');
var_dump($hello); // Hello Bob!
or
$hello = 'Hello Matt!';
var_dump($hello->replace('Matt', 'Bob')); // Hello Bob!
I know this is a silly example, but doesn't the second bit of code just feel better?
Let's get scalar objects in PHP 8! Who's with me?!?
Top comments (33)
"PHP 8 is a great opportunity to cleanup these inconsistencies."
This alone would be reason enough, lol
good stuff, good stuff.
i'd like better and consistent treatment for callables
examples of what we can not do ATM:
also
Just what's in my head ATM :)
You can call
($o->f)("dev.to")
and it will work.In the example you give with the callable, it would create conflict between properties and methods of classes, that are totally separated in PHP.
This will create backward compatibility problems.
There would be a conflict only if no policy is set up.
What seems obvious to me is to check for declared methods first.
Like you cannot "create" a class identifier that has already being declared in class.
There's already a check to prevent from using an name that is declared "private" for example.
That's the "identity" of the class.
Then if someone declares a property with same name a warning should be raised (or another error policy) because after all good practices : that doesnt' make sense to have a property named as an action or a method named as a noun.
So a simple check to put in place when invoking a class member, priority :
This avoids overwriting declared methods while giving the possibility to construct methods dynamically or just use callable as a valid value for a property without aliasing it prior to being able to use it.
Callable as a type must be supported in every part of the language.
Note that example show an anonymous function but it can be any object with magic "__invoke" that is supposedly a valid type for an property.
Valid type but not fully handled ATM.
and for another suggestion since i found a way to declared constant dynamically:
a way to get constants declared in a specific namespace.
something like:
Agree with you on those points. An update can be done on this features.
And of course, it would make sense as you say, because of Closure as a type and __invoke method :)
+1 !
Are you proposing this work similar to Java with auto boxing? I mean something like
Is cool and all, but are we going to assume auto boxing here or are we going with no more primitives at all? I feel if we still want real primitives(which I assume we do), something like
is a better approach than automatically auto boxing all scalars into objects. That way we have both scalar objects and primitives still.
Perhaps instead even better could be having the 'scalar object' not be a real object at all, but instead the access before in the first example I provided instead be a bit of syntactic sugar for
Something like that would be great. Without generics and such I don't think we really want them to be objects cause we wouldn't want something like
Because then there's literally no point to using stdClass as a type hint since everything would be one.
Also I just want a real god damn array. None of this map masquerading as an array bullshit. Sometimes I just need some integers one after the other in memory and not have to worry about if someone used a string as an index by accident.
When using loosely typed programming languages for very large code bases you end up wishing for namespacing and strict types to enforce isolation and contracts between code modules at the language level. Once you have strict types you quickly figure out you need generics to fully type-check all your code. Once you have generics you realize you can have strictly typed generic collection classes and Maybe types (e.g. java's optional). Once you use those you realize that they'd be awesome if they had fluent API's so you could do collection->map(...)->filter(...)->sort(...)->reduce(...), and so all those collection classes and maybe types are extended to support that style (e.g. java's streams). And then when you're writing that kind of code, it would be awfully handy to have pattern matching and macro-like meta-syntax (see: scala).
And that is how all programming languages used for large projects, including PHP, are on a path to become like haskell, scala, etc. which already have all of these features. It is inevitable.
well, i personally dont care, php as not strictly typed language curently is not ready for this. imho.
ps: in last snippet you have syntax error. :P :)
Mind expanding your point here? What does type safety has to do with scalar objects?
I mean, when type is not enforced, scalar object can have different methods depending on current type. Or am I wrong?
Maybe I'm missing something, but isn't how JavaScript does it with
.reduce
,.map
,.split
etc... practically what the suggested improvement wants? And JS doesn't enforce types either, right?Yep, and it would just require an extra step sometimes to explicitly cast to the desired type. We have to do this in PHP/JS sometimes now as it is.
It could be usable tho... i imagine this:
But we are slowly heading in that direction, far too slowly really. Strict types help you code better and stop of lot of issues that can take time to debug.
PHP 7 made some headway here with strict_types, if you don't want it don't set it to true, or just leave out your type hints altogether - very sloppy!
Personaly I'd love to have fixed types for variables:
Or even better without the annoying $ prefix which does nothing IMHO:
Yes, all those Ruby and Smalltalk developers are producing completely unusable garbage because they lack manifest typing. /s
I like PHP's dynamic loose scripting nature. If you want that more verbose kind of thing, there is Java, or Swift, or whatever.
PHP's current nature fulfills a unique niche in my toolkit and I like it the way it is (although I'm all for consistent naming and moving to a more dynamic OO style).
This was already proposed,implemented and rejected a few years ago:
github.com/rossriley/php-scalar-ob...
Looks like now it exists as a PHP extension:
github.com/nikic/scalar_objects
But this would be so much better if it was part of the core and had properly published methods.
PHP needs to grow and keep up with the needs of developers rather than developers continuously getting frustrated with the lack modernity in one of the most popular languages in use. If PHP does not embrace good OOP practices it will loose it's popularity. Given that .NET Core has been available cross platform for some time now, it is becoming a popular draw for those of us who long for something better. If it were not for a host of projects and a large code base I would have moved on already.
Time will tell and for me time is running out with the arcane state PHP is still in, despite the major leap in PHP 7 it's still very old fashioned.
I agree with you 100%, If it wasn't for the large code bases I have to maintain every single day, I would be using .Net Core, but hey, I think the killer feature here would be generics. That is really needed.
The ability to set type_strict globally for a project. Either via php.ini, composer.json or version used 8.y.z-strict || 8.y.z
I
feel
like the more type strictness / checking PHP gets the more it is viewed as aprofessional
language (I know, it s BS but it is what I see in around the web).Function argument order is another one that needs correcting.
Using the dot notation only for these scalar objects would be horrible IMO. Better stick with the
->
operator.Quick edit: I realized that maybe just a typo on your part lol.
It was! I'll fix it. My bad.
The one and only answer to the original tweet I believe is to remove the dollar sign '$' it's hideous
I don't hate the dollar sign per say but I agree it is pretty glaring. But I mean putting a different symbol or the word var or something in front of all the variables wouldn't be much better either. I'm curious about another idea you have for it though!
How about prefixing with a strict type?
dev.to/mattsparks/i-want-scalar-ob...
Some comments may only be visible to logged-in visitors. Sign in to view all comments.