Hi internals,
After the RFC to add IntlDatePatternGenerator () was accepted, it was brought up that the duplication of
procedural and OO style was not necessarily/useful anymore.
This already has some (old) precedent - in 2012, UConverter was added to ext/intl
(https://wiki.php.net/rfc/uconverter) and in 2014 IntlChar
(https://wiki.php.net/rfc/intl.char) - both of which only provide a class, but not the
procedural API.
This was also shortly discussed on the mailing list for IntlChar:
https://externals.io/message/79146#79167 after which the procedural API
was dropped without much ado.
When I wrote the IntlDatePatternGenerator RFC, I was not aware that the
procedural API was viewed as deprecated, nor that there had been additions to
ext/intl that were purely OO.
In the thread after its vote, it was also suggested that we add a policy that
forbids new additions from adding duplicated APIs, and that OO style should
be preferred if possible. I am not sure if I am the best person to write such an RFC,
but I wanted to bring this to its own thread and provide the context I have dug up so
far.
The duplication of the OO and procedural API dates back to the addition of the intl
extension to core. There is some discussion about it in this thread from 2008:
https://externals.io/message/36775
(ignore the unrelated discussion about PHP6)
The main argument at this point was that OO in PHP is a new thing, and that while
the OO API is objectively better, the procedural API should also be there to
lessen the learning curve for existing PHP users that are not yet familiar with OOP.
I would argue that 13 years later, this argument no longer holds - anyone who
has used PHP at some point since then most likely has encountered classes.
One open question that still remains is what we do with the already existing
procedural API.
Should it be deprecated? Should it only be soft-deprecated, in that we mention in the
documentation that the OO style is preferred, but that the procedural API is
not planned to be removed?
Should we just leave the procedural API as-is and live with the fact that some
classes have procedural counterparts
and some don't?
I would personally lean towards (at least soft-) deprecation just for consistency,
but I would like to hear what you would have to say.
Regards,
Mel
Hi Mel,
I love this idea. We should definitely make it official that procedural
style API is unfavourable and should not be added to new classes.
On top of that, I would be in favor of deprecating all existing procedural
APIs.
- It's making it more difficult to maintain code in two variants
- It's making it difficult to maintain documentation
- It's confusing for users
- Procedural API is usually much more verbose than OO style
- The return values often do not match
OO style allows method chaining vs function nesting with procedural. The
only time when I ever saw any advantage to procedural style is when using
date_create()
. Depending on what one is used to, procedural style can be
cleaner and more understandable.
echo date_diff(date_create('2000-01-01'),
date_create('2000-01-05'))->format('%R%a days');
vs
echo (new DateTime('2000-01-01'))->diff(new
DateTime('2000-01-05'))->format('%R%a days');
However, above examples are not apples to apples. When using date_create
with variable input, you must employ manual error checking as it won't
throw any errors like OO does. When you factor this in, the first example
becomes a nightmare and a gun to shoot yourself in the foot. It happened to
me.
So, maybe what we could do is slowly deprecate all procedural APIs, but
leave some exceptions as handy shortcut functions. If that's not possible,
then I wouldn't mind seeing all procedural APIs go away.
Regards,
Kamil
Am 03.06.2021 um 22:47 schrieb Kamil Tekiela tekiela246@gmail.com:I love this idea. We should definitely make it official that procedural
style API is unfavourable and should not be added to new classes.
On top of that, I would be in favor of deprecating all existing procedural
APIs.
- It's making it more difficult to maintain code in two variants
- It's making it difficult to maintain documentation
- It's confusing for users
- Procedural API is usually much more verbose than OO style
- The return values often do not match
While I understand your points and especially see the benefit for maintainers, I'm not a fan of make-everything-OO-with-exceptions.
This leads to more exceptions creeping into otherwise exception-free code. I assume that some people don't see a problem with that but it can end up using exceptions for flow control which is frowned upon even by some exception enthusiasts.
As soon as you start mixing ifs and exceptions it tends to get messy because you might even end up converting ifs to exceptions like
try {
$date = new DateTime($datestring);
if ($limit > $maxlimit)
throw new Exception(...);
...
} catch (Exception $e) {}
as opposed to
if ($date = date_create($datestring) and $limit <= $maxlimit)
...
I'm fine with new OO style APIs not providing a procedural equivalent but I'm wary about deprecating/removing existing ones.
Final remark: I think neither procedural nor OO style is the right choice for everything. I believe it should be decided individually.
- Chris
After the RFC to add IntlDatePatternGenerator () was accepted, it was brought up that the duplication of
procedural and OO style was not necessarily/useful anymore.
This already has some (old) precedent - in 2012, UConverter was added to ext/intl
(https://wiki.php.net/rfc/uconverter) and in 2014 IntlChar
(https://wiki.php.net/rfc/intl.char) - both of which only provide a class, but not the
procedural API.
This was also shortly discussed on the mailing list for IntlChar:
https://externals.io/message/79146#79167 after which the procedural API
was dropped without much ado.When I wrote the IntlDatePatternGenerator RFC, I was not aware that the
procedural API was viewed as deprecated, nor that there had been additions to
ext/intl that were purely OO.
In the thread after its vote, it was also suggested that we add a policy that
forbids new additions from adding duplicated APIs, and that OO style should
be preferred if possible. I am not sure if I am the best person to write such an RFC,
but I wanted to bring this to its own thread and provide the context I have dug up so
far.The duplication of the OO and procedural API dates back to the addition of the intl
extension to core. There is some discussion about it in this thread from 2008:
https://externals.io/message/36775
(ignore the unrelated discussion about PHP6)
The main argument at this point was that OO in PHP is a new thing, and that while
the OO API is objectively better, the procedural API should also be there to
lessen the learning curve for existing PHP users that are not yet familiar with OOP.
I would argue that 13 years later, this argument no longer holds - anyone who
has used PHP at some point since then most likely has encountered classes.One open question that still remains is what we do with the already existing
procedural API.
Should it be deprecated? Should it only be soft-deprecated, in that we mention in the
documentation that the OO style is preferred, but that the procedural API is
not planned to be removed?
Should we just leave the procedural API as-is and live with the fact that some
classes have procedural counterparts
and some don't?
I would personally lean towards (at least soft-) deprecation just for consistency,
but I would like to hear what you would have to say.
I'd take a step at a time, and start with "prohibit introduction of new
dual APIs" only. (Soft-)deprecation can follow in own RFCs, maybe for
single extensions, or even single (groups of) functions.
--
Christoph M. Becker
I'd take a step at a time, and start with "prohibit introduction of new
dual APIs" only.
That sort of RFC doesn't really buy anything. It'd take a 2/3 vote to
override it which is the same as what it'd take to introduce a dual
API in the first place. Drop the ceremony and just add a note to the
wiki.
Hi internals,
After the RFC to add IntlDatePatternGenerator () was accepted, it was
brought up that the duplication of
procedural and OO style was not necessarily/useful anymore.
This already has some (old) precedent - in 2012, UConverter was added to
ext/intl
(https://wiki.php.net/rfc/uconverter) and in 2014 IntlChar
(https://wiki.php.net/rfc/intl.char) - both of which only provide a
class, but not the
procedural API.
This was also shortly discussed on the mailing list for IntlChar:
https://externals.io/message/79146#79167 after which the procedural API
was dropped without much ado.When I wrote the IntlDatePatternGenerator RFC, I was not aware that the
procedural API was viewed as deprecated, nor that there had been additions
to
ext/intl that were purely OO.
In the thread after its vote, it was also suggested that we add a policy
that
forbids new additions from adding duplicated APIs, and that OO style should
be preferred if possible. I am not sure if I am the best person to write
such an RFC,
but I wanted to bring this to its own thread and provide the context I
have dug up so
far.The duplication of the OO and procedural API dates back to the addition of
the intl
extension to core. There is some discussion about it in this thread from
2008:
https://externals.io/message/36775
(ignore the unrelated discussion about PHP6)
The main argument at this point was that OO in PHP is a new thing, and
that while
the OO API is objectively better, the procedural API should also be there
to
lessen the learning curve for existing PHP users that are not yet familiar
with OOP.
I would argue that 13 years later, this argument no longer holds - anyone
who
has used PHP at some point since then most likely has encountered classes.One open question that still remains is what we do with the already
existing
procedural API.
Should it be deprecated? Should it only be soft-deprecated, in that we
mention in the
documentation that the OO style is preferred, but that the procedural API
is
not planned to be removed?
Should we just leave the procedural API as-is and live with the fact that
some
classes have procedural counterparts
and some don't?
I would personally lean towards (at least soft-) deprecation just for
consistency,
but I would like to hear what you would have to say.
I think that not adding new procedural mirror APIs is pretty
uncontroversial at this point. I think one open question is regarding API
additions to existing classes with a mirror API -- should we keep adding
procedural functions in that case?
The more interesting question here is whether we want to deprecate existing
APIs. From a quick look, these are the extensions that provide procedural
mirror APIs:
date
finfo
intl
mysqli
oci8 (only partially)
xmlwriter
I don't think I'd want to blanket deprecate all of these. I do see value in
some of the procedural APIs (okay, only date really) or at least historical
importance (mysqli is a migration target for mysql, which was only
procedural). I think if we want to deprecate these, it should be on a
case-by-case basis. For example, I see very little value in the procedural
intl APIs.
One annoying factor here is that these mirror APIs were often added
thoughtlessly and have design issues as a result. For example,
xmlwriter_open_uri()
makes sense, but XMLWriter::openUri() should clearly
have been a static method, not an instance method. Similarly, mysqli_init()
makes some sense, but mysqli::init() is entirely useless.
Regards,
Nikita
I think that not adding new procedural mirror APIs is pretty
uncontroversial at this point. I think one open question is regarding API
additions to existing classes with a mirror API -- should we keep adding
procedural functions in that case?
I guess maintaining consistency between the mirror APIs makes sense for
as long as we still have those mirror APIs.
The more interesting question here is whether we want to deprecate existing
APIs. From a quick look, these are the extensions that provide procedural
mirror APIs:date
finfo
intl
mysqli
oci8 (only partially)
xmlwriterI don't think I'd want to blanket deprecate all of these. I do see value in
some of the procedural APIs (okay, only date really) or at least historical
importance (mysqli is a migration target for mysql, which was only
procedural). I think if we want to deprecate these, it should be on a
case-by-case basis. For example, I see very little value in the procedural
intl APIs.One annoying factor here is that these mirror APIs were often added
thoughtlessly and have design issues as a result. For example,
xmlwriter_open_uri()
makes sense, but XMLWriter::openUri() should clearly
have been a static method, not an instance method. Similarly,mysqli_init()
makes some sense, but mysqli::init() is entirely useless.
Deprecating the procedural APIs where it makes sense sounds like a great
step into the right direction. Historical oddities in the OO APIs could
be dealt with later.
Regards,
Dik Takken