Hello!
There are at least three of the RFC for native work with annotations.
https://wiki.php.net/rfc/reflection_doccomment_annotations
https://wiki.php.net/rfc/annotations-in-docblock
https://wiki.php.net/rfc/annotations
I would like to know how plans in PHP 7 support annotations in the code?
Hello!
There are at least three of the RFC for native work with annotations.
https://wiki.php.net/rfc/reflection_doccomment_annotations
https://wiki.php.net/rfc/annotations-in-docblock
https://wiki.php.net/rfc/annotationsI would like to know how plans in PHP 7 support annotations in the code?
There are no current concrete plans and currently nothing being seriously
discussed (at least, not publicly; I don't know if anyone has anything in
pipeline that they haven't announced yet). The three RFCs you linked above
are all basically dead.
You are of course welcome to put together a proposal and/or start up a
discussion on the subject if it is something you would be prepared to put
work into.
Thanks, Chris
There are no current concrete plans and currently nothing being seriously
discussed (at least, not publicly; I don't know if anyone has anything in
pipeline that they haven't announced yet). The three RFCs you linked above
are all basically dead.You are of course welcome to put together a proposal and/or start up a
discussion on the subject if it is something you would be prepared to put
work into.
I, for one, severely dislike annotations. But, that's why there's an RFC
process :)
--
Jonah H. Harris
Blog: http://www.oracle-internals.com/
There are no current concrete plans and currently nothing being
seriously
discussed (at least, not publicly; I don't know if anyone has anything
in
pipeline that they haven't announced yet). The three RFCs you linked
above
are all basically dead.You are of course welcome to put together a proposal and/or start up a
discussion on the subject if it is something you would be prepared to
put
work into.I, for one, severely dislike annotations. But, that's why there's an RFC
process :)
I tend to think it is not a taste matter anymore. Symfony ecosystem
(components, doctrine and co), Zend framework, etc use them. We see
requests to work around user land implementation but we keep us away to get
native support. Maybe it is time to the jump and get rid of our tastes,
like years ago when we discussed which kind of OO we wanted in php. At the
end of the day we do what we did not want back then.
There are no current concrete plans and currently nothing being
seriously
discussed (at least, not publicly; I don't know if anyone has anything
in
pipeline that they haven't announced yet). The three RFCs you linked
above
are all basically dead.You are of course welcome to put together a proposal and/or start up a
discussion on the subject if it is something you would be prepared to
put
work into.I, for one, severely dislike annotations. But, that's why there's an RFC
process :)I tend to think it is not a taste matter anymore. Symfony ecosystem
(components, doctrine and co), Zend framework, etc use them. We see
requests to work around user land implementation but we keep us away to get
native support. Maybe it is time to the jump and get rid of our tastes,
like years ago when we discussed which kind of OO we wanted in php. At the
end of the day we do what we did not want back then.
The TYPO3-family (TYPO3 CMS, Flow, Neos) also use annotations.
So, yes it is used "in the wild" already and is there to stay. We can
imho just make it a bit easier to work with (maybe also performance-wise
in some cases) etc.
Kind regards,
Stefan
There are no current concrete plans and currently nothing being
seriously
discussed (at least, not publicly; I don't know if anyone has anything
in
pipeline that they haven't announced yet). The three RFCs you linked
above
are all basically dead.You are of course welcome to put together a proposal and/or start up a
discussion on the subject if it is something you would be prepared to
put
work into.I, for one, severely dislike annotations. But, that's why there's an RFC
process :)I tend to think it is not a taste matter anymore. Symfony ecosystem
(components, doctrine and co), Zend framework, etc use them. We see
requests to work around user land implementation but we keep us away to get
native support. Maybe it is time to the jump and get rid of our tastes,
like years ago when we discussed which kind of OO we wanted in php. At the
end of the day we do what we did not want back then.The TYPO3-family (TYPO3 CMS, Flow, Neos) also use annotations.
So, yes it is used "in the wild" already and is there to stay. We can
imho just make it a bit easier to work with (maybe also performance-wise
in some cases) etc.Kind regards,
Stefan
Drupal is now using annotations as well; not for the Symfony code we've
inherited, actually, but for some home-grown systems for which we're
using Doctrine's annotation library.
Having first-class language support for metadata on definitions would be
quite helpful, if for no other reason than native syntax checking and
code assistance. (And to help people get over the "it's code in
comments!!!" problem, which is entirely because we have to put
annotations in comments now as a hack due to the lack of native support.)
--Larry Garfield
There are no current concrete plans and currently nothing being
seriously
discussed (at least, not publicly; I don't know if anyone has anything
in
pipeline that they haven't announced yet). The three RFCs you linked
above
are all basically dead.
You are of course welcome to put together a proposal and/or start up a
discussion on the subject if it is something you would be prepared toput
work into.
I, for one, severely dislike annotations. But, that's why there's an RFC
process :)I tend to think it is not a taste matter anymore. Symfony ecosystem
(components, doctrine and co), Zend framework, etc use them. We see
requests to work around user land implementation but we keep us away to
get
native support. Maybe it is time to the jump and get rid of our tastes,
like years ago when we discussed which kind of OO we wanted in php. At
the
end of the day we do what we did not want back then.The TYPO3-family (TYPO3 CMS, Flow, Neos) also use annotations.
So, yes it is used "in the wild" already and is there to stay. We can
imho just make it a bit easier to work with (maybe also performance-wise
in some cases) etc.Kind regards,
StefanDrupal is now using annotations as well; not for the Symfony code we've
inherited, actually, but for some home-grown systems for which we're using
Doctrine's annotation library.Having first-class language support for metadata on definitions would be
quite helpful, if for no other reason than native syntax checking and code
assistance. (And to help people get over the "it's code in comments!!!"
problem, which is entirely because we have to put annotations in comments
now as a hack due to the lack of native support.)
Whether the annotation is in a comment or not, the idea of changing
behavior at runtime based on the annotation is pretty magical. I
highly discourage using this type of feature whether it's in a comment
or not.
I will certainly vote no on any RFC on this subject, as I see it as
being significantly more harmful than helpful.
Nothing magical in the annotations no, they very obvious.
It gives you the to declare logic and meta data.
I do not like annotated in comments, I like the implementation of
annotation in C#
2014-11-04 0:49 GMT+02:00 Levi Morrison levim@php.net:
On Mon, Nov 3, 2014 at 10:39 AM, Larry Garfield larry@garfieldtech.com
wrote:On Nov 4, 2014 1:24 AM, "Jonah H. Harris" jonah.harris@gmail.com
wrote:On Mon, Nov 3, 2014 at 9:11 AM, Chris Wright cw@daverandom.com
wrote:There are no current concrete plans and currently nothing being
seriously
discussed (at least, not publicly; I don't know if anyone has
anythingin
pipeline that they haven't announced yet). The three RFCs you linked
above
are all basically dead.
You are of course welcome to put together a proposal and/or start up
a
discussion on the subject if it is something you would be prepared toput
work into.
I, for one, severely dislike annotations. But, that's why there's an
RFC
process :)I tend to think it is not a taste matter anymore. Symfony ecosystem
(components, doctrine and co), Zend framework, etc use them. We see
requests to work around user land implementation but we keep us away to
get
native support. Maybe it is time to the jump and get rid of our tastes,
like years ago when we discussed which kind of OO we wanted in php. At
the
end of the day we do what we did not want back then.The TYPO3-family (TYPO3 CMS, Flow, Neos) also use annotations.
So, yes it is used "in the wild" already and is there to stay. We can
imho just make it a bit easier to work with (maybe also performance-wise
in some cases) etc.Kind regards,
StefanDrupal is now using annotations as well; not for the Symfony code we've
inherited, actually, but for some home-grown systems for which we're
using
Doctrine's annotation library.Having first-class language support for metadata on definitions would be
quite helpful, if for no other reason than native syntax checking and
code
assistance. (And to help people get over the "it's code in comments!!!"
problem, which is entirely because we have to put annotations in comments
now as a hack due to the lack of native support.)Whether the annotation is in a comment or not, the idea of changing
behavior at runtime based on the annotation is pretty magical. I
highly discourage using this type of feature whether it's in a comment
or not.I will certainly vote no on any RFC on this subject, as I see it as
being significantly more harmful than helpful.
Whether the annotation is in a comment or not, the idea of changing
behavior at runtime based on the annotation is pretty magical. I
highly discourage using this type of feature whether it's in a comment
or not.I will certainly vote no on any RFC on this subject, as I see it as
being significantly more harmful than helpful.
This is exactly what I meant. We have almost all major projects using them
but we may consider not adding them natively because we find it magic,
ugly, whatever.
As I do consider personal tastes important, there are times where we should
listen to our users.
Hi!
As I do consider personal tastes important, there are times where we should
listen to our users.
It would be nice to take "paving the walkways" approach, but last time
we tried, IIRC we've got into something very over-engineered. Maybe if
we try again with more restricted scope (i.e. not trying to put a DSL
for describing arbitrarily complex data structures into it :) it would
be more successful this time.
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
Hi!
As I do consider personal tastes important, there are times where we should
listen to our users.It would be nice to take "paving the walkways" approach, but last time
we tried, IIRC we've got into something very over-engineered. Maybe if
we try again with more restricted scope (i.e. not trying to put a DSL
for describing arbitrarily complex data structures into it :) it would
be more successful this time.
All projects mentioned in this thread use:
http://doctrine-common.readthedocs.org/en/latest/reference/annotations.html
That makes a pretty good base spec.
--
Pierre
@pierrejoye | http://www.libgd.org
On Tue, Nov 4, 2014 at 4:21 PM, Stas Malyshev smalyshev@sugarcrm.com
wrote:Hi!
As I do consider personal tastes important, there are times where we
should
listen to our users.It would be nice to take "paving the walkways" approach, but last time
we tried, IIRC we've got into something very over-engineered. Maybe if
we try again with more restricted scope (i.e. not trying to put a DSL
for describing arbitrarily complex data structures into it :) it would
be more successful this time.All projects mentioned in this thread use:
http://doctrine-common.readthedocs.org/en/latest/reference/annotations.html
That makes a pretty good base spec.
Being the author I can say, the doctrine annotations project is way too
over-engineered/special-purpose to land in core.
I agree with Stas that a much simpler approach is probably realistic.
beginning pure speculation here, i see a short array like syntax like:
[foo="bar", bar="baz", baz=["key": "value"]]
function annotated_fn() {}
Maybe even exactly short array syntax:
["foo"="bar", "bar"="baz", "baz"=["key": "value"]]
function annotated_fn() {}
Then $reflectionFunction->getAnnotations() returns an array. Various
PHP/Userland libraries and frameworks can then stick whatever symantic on
top that they want.
greetings
Benjamin
--
Pierre@pierrejoye | http://www.libgd.org
On Tue, Nov 4, 2014 at 4:21 PM, Stas Malyshev smalyshev@sugarcrm.com
wrote:Hi!
As I do consider personal tastes important, there are times where we
should
listen to our users.It would be nice to take "paving the walkways" approach, but last time
we tried, IIRC we've got into something very over-engineered. Maybe if
we try again with more restricted scope (i.e. not trying to put a DSL
for describing arbitrarily complex data structures into it :) it would
be more successful this time.All projects mentioned in this thread use:
http://doctrine-common.readthedocs.org/en/latest/reference/annotations.html
That makes a pretty good base spec.
Being the author I can say, the doctrine annotations project is way too
over-engineered/special-purpose to land in core.I agree with Stas that a much simpler approach is probably realistic.
beginning pure speculation here, i see a short array like syntax like:
[foo="bar", bar="baz", baz=["key": "value"]]
function annotated_fn() {}Maybe even exactly short array syntax:
["foo"="bar", "bar"="baz", "baz"=["key": "value"]]
function annotated_fn() {}Then $reflectionFunction->getAnnotations() returns an array. Various
PHP/Userland libraries and frameworks can then stick whatever symantic on
top that they want.
Yes, that was what discussed last time too and makes perfectly sense.
I only not sure about the syntax. I do not like that one f.e. not really in
phase with what exists (doctrine or other languages).
Cheers,
Pierre
On Tue, Nov 4, 2014 at 11:28 AM, Pierre Joye pierre.php@gmail.com
wrote:On Tue, Nov 4, 2014 at 4:21 PM, Stas Malyshev smalyshev@sugarcrm.com
wrote:Hi!
As I do consider personal tastes important, there are times where we
should
listen to our users.It would be nice to take "paving the walkways" approach, but last time
we tried, IIRC we've got into something very over-engineered. Maybe if
we try again with more restricted scope (i.e. not trying to put a DSL
for describing arbitrarily complex data structures into it :) it would
be more successful this time.All projects mentioned in this thread use:
http://doctrine-common.readthedocs.org/en/latest/reference/annotations.html
That makes a pretty good base spec.
Being the author I can say, the doctrine annotations project is way too
over-engineered/special-purpose to land in core.I agree with Stas that a much simpler approach is probably realistic.
beginning pure speculation here, i see a short array like syntax like:
[foo="bar", bar="baz", baz=["key": "value"]]
function annotated_fn() {}Maybe even exactly short array syntax:
["foo"="bar", "bar"="baz", "baz"=["key": "value"]]
function annotated_fn() {}Then $reflectionFunction->getAnnotations() returns an array. Various
PHP/Userland libraries and frameworks can then stick whatever symantic on
top that they want.Yes, that was what discussed last time too and makes perfectly sense.
I only not sure about the syntax. I do not like that one f.e. not really
in phase with what exists (doctrine or other languages).
The problem with this simple approach is namespacing to avoid clashes, any
solution to incoperates that introduces lots of complexity like allowing
"new Annotation" inside the array definition.
However I guess now that for example composer provides namespaces for
packages, the community could come up with a convention to namespace by
composer package name to allow something like:
["doctrine/orm": ["entity"]]
class User
{
["doctrine/orm": ["id", "generatedvalue", "column": ["type":
"integer"]]]
public $id;
}
The simplicity here is really key. Validation and mapping of this is much
easier implemented in userland code.
Cheers,
Pierre
I agree with Stas that a much simpler approach is probably realistic.
beginning pure speculation here, i see a short array like syntax like:
[foo="bar", bar="baz", baz=["key": "value"]]
function annotated_fn() {}Maybe even exactly short array syntax:
["foo"="bar", "bar"="baz", "baz"=["key": "value"]]
function annotated_fn() {}Then $reflectionFunction->getAnnotations() returns an array. Various
PHP/Userland libraries and frameworks can then stick whatever symantic on
top that they want.
The approach for annotations that I like best would actually be not annotations, but Python-style decorators. They’re very simple, but very powerful. They would allow you to do annotations, but also add extra functionality to functions.
In Python, a decorator is a function (or callable object), and you use one like this:
@some_decorator(foo, bar)
def myfunc():
# function source code here
This is actually syntactic sugar for the following:
def myfunc():
# function source code here
myfunc = some_decorator(myfunc, foo, bar)
Which would be equivalent to the following PHP code:
$myfunc = function myfunc() {
# function source code here
};
$myfunc = some_decorator($myfunc, foo, bar);
Basically, Python decorators allow you to explicitly have a function modify a new function before it’s declared. This is pretty useful: If your decorator does nothing, it’s just an annotation. But you can also use it to add functionality. For example, you might make a decorator that does something before and after a function runs.
Andrea Faulds
http://ajf.me/
Hi!
The approach for annotations that I like best would actually be not
annotations, but Python-style decorators. They’re very simple, but
very powerful. They would allow you to do annotations, but also add
extra functionality to functions.
For python-style decorators, at least the way they work in Python, we'd
need to organize our function tables differently, as Python just
replaces the function with another one while decorating, and I'm not
sure it'd be as easy to do with PHP.
Which would be equivalent to the following PHP code:
$myfunc = function myfunc() { # function source code here }; $myfunc
= some_decorator($myfunc, foo, bar);
Not really, because functions work differently in Python and in PHP. You
can not just replace a function in class's function table with random
closure in PHP, at least easily.
You'd have to convert all such functions to closures (or something that
can be both, maybe) and have the engine be aware that function table now
can store closures. And, also, inheritance may get a bit weird there. It
would be very powerful, but it may not be very simple to do.
Also, it is a major overkill for what annotations are commonly used -
attaching a piece of data to an entity. In Python, decorators are very
powerful for modifying function behavior (i.e., attaching pre/post
conditions to functions or doing some things phpunit does is really
easy) but it is too much for just attaching data.
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
For python-style decorators, at least the way they work in Python, we'd
need to organize our function tables differently, as Python just
replaces the function with another one while decorating, and I'm not
sure it'd be as easy to do with PHP.
Are you sure this would be difficult? We could create a closure of the class method (trivial to do), pass it to a userland function upon creating the class (the former is easy, the “upon creating the class” is the issue), and use the closure it returns as the class method. There’d be issue with autoloading to iron out, but I don’t think it’d be a problem.
You'd have to convert all such functions to closures (or something that
can be both, maybe) and have the engine be aware that function table now
can store closures. And, also, inheritance may get a bit weird there. It
would be very powerful, but it may not be very simple to do.
A closure is just a normal function, actually. The Closure class just wraps a zend_function and a this pointer. There’s no reason you couldn’t substitute here. I believe you could literally just copy the zend_function across, though there’d obviously be some complications.
Not sure about inheritance.
Also, it is a major overkill for what annotations are commonly used -
attaching a piece of data to an entity. In Python, decorators are very
powerful for modifying function behavior (i.e., attaching pre/post
conditions to functions or doing some things phpunit does is really
easy) but it is too much for just attaching data.
This is useful for merely attaching data as well (just return the function passed), but it also enables manipulating the function. It could replace some cases of merely attaching data, too, by making the function do something itself, rather than having something else do something if a function has a certain annotation, when calling that function (if that makes any sense).
--
Andrea Faulds
http://ajf.me/
Hi,
As one of the original authors of both Doctrine Annotations and previous
RFC of native Annotations in PHP, I can go thoroughly on every specific
detail about challenges of design decisions to make.
Primarily, I do not see docblocks as the right place to store class'
metadata information. Metadata != Comments.
This brings the next piece of the puzzle. We have to update lexical and
semantical understanding of PHP. Taking Java's approach (@) does not work
in PHP, because it conflicts with error supression. Same thing happened for
{}. When Pierrick and I wrote the RFC, [] was not supported, so likely
it'll break parsing too now, but at that point, we got [] to work.
Ultimately, we chose <> to avoid headaches.
After that, we entered on how we could semantically validate arguments. We
could easily create an array declaration (as Benjamin suggested), but that
would become near to impossible for a large system to figure it out where
it was the problem, the small made typo. The solution was to instantiate
classes (or what we folded during development, a special class type,
annotation), because we could validate semantically not only classes, but
also properties. We could also implement annotation targets (something can
only be used in a method or at the class level).
This is a valid thing to consider... more effort to the language means less
efforts from end-users (consumers). Bringing annotation targeting,
semantical validation was a great addiction to the RFC, because it makes
easier to developers find bugs, but it exposed another set of problems (and
their solutions):
1- How to instantiate them?
We dropped "new" necessity under that scope and used <>. Again, it made
more sense to specialize class definition into a new type (annotation), but
we kept same implementation for simplicity.
2- How to consume on Reflection?
We decided to use it by fetching based on class name. This added the
enforcement of only having 1 instance of a class per annotation context.
3- How to partially attribute class properties while others rely on
convention over configuration?
We had to bring named parameters to fix this.
4- How to deal with nested Annotations?
When we dropped "new", it became easy to support them by using <>.
Despite any decision, inheritance is also a problem to solve. Should it
clear everything out if a method is overwritten? Should a class require
redeclaration of everything? This adds complexity and error-prone
situations.
What if everything gets inherited by default? Well, then we need a way to
remove other previously declared items. We came up with the solution to
just clear them until we got into further discussion. We had an Override
patch that would inherit everything by default and with Override it would
clear any previously declared Annotations too based on discussion's result.
I hope that gives a but more insight on how RFC Annotations reached that
level of maturity.
Cheers,
For python-style decorators, at least the way they work in Python, we'd
need to organize our function tables differently, as Python just
replaces the function with another one while decorating, and I'm not
sure it'd be as easy to do with PHP.Are you sure this would be difficult? We could create a closure of the
class method (trivial to do), pass it to a userland function upon creating
the class (the former is easy, the “upon creating the class” is the issue),
and use the closure it returns as the class method. There’d be issue with
autoloading to iron out, but I don’t think it’d be a problem.You'd have to convert all such functions to closures (or something that
can be both, maybe) and have the engine be aware that function table now
can store closures. And, also, inheritance may get a bit weird there. It
would be very powerful, but it may not be very simple to do.A closure is just a normal function, actually. The Closure class just
wraps a zend_function and a this pointer. There’s no reason you couldn’t
substitute here. I believe you could literally just copy the zend_function
across, though there’d obviously be some complications.Not sure about inheritance.
Also, it is a major overkill for what annotations are commonly used -
attaching a piece of data to an entity. In Python, decorators are very
powerful for modifying function behavior (i.e., attaching pre/post
conditions to functions or doing some things phpunit does is really
easy) but it is too much for just attaching data.This is useful for merely attaching data as well (just return the function
passed), but it also enables manipulating the function. It could replace
some cases of merely attaching data, too, by making the function do
something itself, rather than having something else do something if a
function has a certain annotation, when calling that function (if that
makes any sense).--
Andrea Faulds
http://ajf.me/--
--
Guilherme Blanco
MSN: guilhermeblanco@hotmail.com
GTalk: guilhermeblanco
Toronto - ON/Canada
Primarily, I do not see docblocks as the right place to store class'
metadata information. Metadata != Comments.
We use comment wrappers in many places to hide secondary material from
other processes. Just rename docblocks -> metadata ... what is the
problem? Now expand the docblock key words and one does not have to
worry about clashes as it's all ring fenced.
Is the material needed at runtime? In which case 'minimize' can strip it
all. I can even see a case for /** being treated differently to /* and
// blocks if needs be.
--
Lester Caine - G8HFL
Contact - http://lsces.co.uk/wiki/?page=contact
L.S.Caine Electronic Services - http://lsces.co.uk
EnquirySolve - http://enquirysolve.com/
Model Engineers Digital Workshop - http://medw.co.uk
Rainbow Digital Media - http://rainbowdigitalmedia.co.uk
Just as a note: /** and /* are already treated differently by the
parser (T_DOC_COMMENT vs. T_COMMENT, this difference is also present
in opcache).
Anyway, metadata/annotations/whatever you want to call them should be
seperated from comments and verbal descriptions on a
syntax level, not just by some conventions. It's one of the big
advantages of having them in the core. If your project needs to
support php5 you can still use doc-comments to store such data, even
if php7 gets first class annotations you may still parse the comment
in whichever way you want. By having a native way of defining them,
php would also avoid all possiblities of bc-breaks in libraries
consuming doc-comments.
2014-11-04 22:11 GMT+01:00 Lester Caine lester@lsces.co.uk:
Primarily, I do not see docblocks as the right place to store class'
metadata information. Metadata != Comments.We use comment wrappers in many places to hide secondary material from
other processes. Just rename docblocks -> metadata ... what is the
problem? Now expand the docblock key words and one does not have to
worry about clashes as it's all ring fenced.Is the material needed at runtime? In which case 'minimize' can strip it
all. I can even see a case for /** being treated differently to /* and
// blocks if needs be.--
Lester Caine - G8HFLContact - http://lsces.co.uk/wiki/?page=contact
L.S.Caine Electronic Services - http://lsces.co.uk
EnquirySolve - http://enquirysolve.com/
Model Engineers Digital Workshop - http://medw.co.uk
Rainbow Digital Media - http://rainbowdigitalmedia.co.uk
Just as a note: /** and /* are already treated differently by the
parser (T_DOC_COMMENT vs. T_COMMENT, this difference is also present
in opcache).Anyway, metadata/annotations/whatever you want to call them should be
seperated from comments and verbal descriptions on a
syntax level, not just by some conventions. It's one of the big
advantages of having them in the core. If your project needs to
support php5 you can still use doc-comments to store such data, even
if php7 gets first class annotations you may still parse the comment
in whichever way you want. By having a native way of defining them,
php would also avoid all possiblities of bc-breaks in libraries
consuming doc-comments.
I take your point, except the bulk of my code already has this metadata
using the current format. I either have to reformat it to some new
'php7' format ( but that will mess up php5 anyway? ), or I just carry on
using the php5 format to avoid having code which is problematic IN php5?
php5 needs this wrapped in comment blocks to hid it for BC reasons?
2014-11-04 22:11 GMT+01:00 Lester Caine lester@lsces.co.uk:
Primarily, I do not see docblocks as the right place to store class'
metadata information. Metadata != Comments.We use comment wrappers in many places to hide secondary material from
other processes. Just rename docblocks -> metadata ... what is the
problem? Now expand the docblock key words and one does not have to
worry about clashes as it's all ring fenced.Is the material needed at runtime? In which case 'minimize' can strip it
all. I can even see a case for /** being treated differently to /* and
// blocks if needs be.
--
Lester Caine - G8HFL
Contact - http://lsces.co.uk/wiki/?page=contact
L.S.Caine Electronic Services - http://lsces.co.uk
EnquirySolve - http://enquirysolve.com/
Model Engineers Digital Workshop - http://medw.co.uk
Rainbow Digital Media - http://rainbowdigitalmedia.co.uk
Hi!
Primarily, I do not see docblocks as the right place to store class'
metadata information. Metadata != Comments.
I personally regard this as a kind of superstition. There's nothing
wrong with extending what can be in comments. In fact, Javascript was
officially "HTML comment" for years, and it didn't prevent anybody from
using Javascript. There are instances of significant comments in various
environments. Outright refusing comments can be significant is just
arbitrarily limiting our options for no reason. I don't say it
necessarily the best option, but we should not reject it because "oh
noes, significant comments!". It has been done, and it's nothing
special, just one of the possibilities
This brings the next piece of the puzzle. We have to update lexical and
semantical understanding of PHP. Taking Java's approach (@) does not
work in PHP, because it conflicts with error supression. Same thing
Except for the mental context, how @ conflicts with errors? Suppression
is always in runtime context and applied to expressions, annotations are
always outside of it and apply to declarations. Unless of course you
want to annotate variables and closures, but I'm not sure annotating
expressions is such a good idea anyway.
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
This brings the next piece of the puzzle. We have to update lexical and
semantical understanding of PHP. Taking Java's approach (@) does not
work in PHP, because it conflicts with error supression. Same thingExcept for the mental context, how @ conflicts with errors? Suppression
is always in runtime context and applied to expressions, annotations are
always outside of it and apply to declarations. Unless of course you
want to annotate variables and closures, but I'm not sure annotating
expressions is such a good idea anyway
At the top-level, @ is a shift/reduce conflict due to ambiguity between statement annotation and expression.
Though it might be possible to work around that with the AST (ew).
--
Andrea Faulds
http://ajf.me/
Hi,
By dealing with annotations in docblocks will force the Annotations parser
to much smarter than you imagine.
Currently in Doctrine Annotations implementation, @param and @Param are
considered different not only by first character to be uppercased, but
rather because a class also exist in that namespace and also because it's
an @Annotation.
Smarter I mean that you'll have to build a rejection list of
non-standardized annotations, such as phpdoc and phpunit. It also makes
pretty hard to parse emails.
You can see the list of ignored names as part of
https://github.com/doctrine/annotations/blob/master/lib/Doctrine/Common/Annotations/AnnotationReader.php#L48
Regards,
This brings the next piece of the puzzle. We have to update lexical and
semantical understanding of PHP. Taking Java's approach (@) does not
work in PHP, because it conflicts with error supression. Same thingExcept for the mental context, how @ conflicts with errors? Suppression
is always in runtime context and applied to expressions, annotations are
always outside of it and apply to declarations. Unless of course you
want to annotate variables and closures, but I'm not sure annotating
expressions is such a good idea anywayAt the top-level, @ is a shift/reduce conflict due to ambiguity between
statement annotation and expression.Though it might be possible to work around that with the AST (ew).
--
Andrea Faulds
http://ajf.me/
--
Guilherme Blanco
MSN: guilhermeblanco@hotmail.com
GTalk: guilhermeblanco
Toronto - ON/Canada
Sorry, I forgot to add references to how we fixed emails handling. It got
split in 2 places:
-
Initial root level annotation
https://github.com/doctrine/annotations/blob/master/lib/Doctrine/Common/Annotations/DocParser.php#L350 -
Subsequent root level annotations
https://github.com/doctrine/annotations/blob/master/lib/Doctrine/Common/Annotations/DocParser.php#L631
[]s,
On Tue, Nov 4, 2014 at 5:42 PM, guilhermeblanco@gmail.com <
guilhermeblanco@gmail.com> wrote:
Hi,
By dealing with annotations in docblocks will force the Annotations parser
to much smarter than you imagine.Currently in Doctrine Annotations implementation, @param and @Param are
considered different not only by first character to be uppercased, but
rather because a class also exist in that namespace and also because it's
an @Annotation.
Smarter I mean that you'll have to build a rejection list of
non-standardized annotations, such as phpdoc and phpunit. It also makes
pretty hard to parse emails.
You can see the list of ignored names as part of
https://github.com/doctrine/annotations/blob/master/lib/Doctrine/Common/Annotations/AnnotationReader.php#L48Regards,
This brings the next piece of the puzzle. We have to update lexical and
semantical understanding of PHP. Taking Java's approach (@) does not
work in PHP, because it conflicts with error supression. Same thingExcept for the mental context, how @ conflicts with errors? Suppression
is always in runtime context and applied to expressions, annotations are
always outside of it and apply to declarations. Unless of course you
want to annotate variables and closures, but I'm not sure annotating
expressions is such a good idea anywayAt the top-level, @ is a shift/reduce conflict due to ambiguity between
statement annotation and expression.Though it might be possible to work around that with the AST (ew).
--
Andrea Faulds
http://ajf.me/--
Guilherme Blanco
MSN: guilhermeblanco@hotmail.com
GTalk: guilhermeblanco
Toronto - ON/Canada
--
Guilherme Blanco
MSN: guilhermeblanco@hotmail.com
GTalk: guilhermeblanco
Toronto - ON/Canada
Hi Guilherme,
On 4 November 2014 23:47, guilhermeblanco@gmail.com <
guilhermeblanco@gmail.com> wrote:
Sorry, I forgot to add references to how we fixed emails handling. It got
split in 2 places:
- Initial root level annotation
- Subsequent root level annotations
I'm not sure if we need that sort of syntax and opinionated approach: I
like Benjamin's approach better, and it is also simpler and still very easy
to use even in our context (doctrine).
For example, this alternative approach perfectly fits the current
doctrine/annotations use-case:
use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\Table;
use Doctrine\ORM\Mapping\Id;
use Doctrine\ORM\Mapping\GeneratedValue;
use Doctrine\ORM\Mapping\Column;
[Entity::class => []]
[Table::class => ['name' => 'foo_table']]
class Foo
{
[Id::class => []]
[GeneratedValue::class => [GeneratedValue::UUID]]
[Column::class => ['name' => 'bar_column', 'type' => 'string']]
private $bar;
}
I did nothing special here, just using plain old associative arrays and
built-in ::class
pseudo-constants: this leaves space for libraries that
do want to use annotations, but not the way doctrine/annotations does it
(calling the constructor of an annotation), and the annotations themselves
can still decide what to do with nested values.
No autoloading is going on, no code execution, nothing: plain and simple
arrays which may as well be used for phpdocumentor as well, if needed.
Greets,
Marco Pivetta
2014-11-05 17:02 GMT+03:00 Marco Pivetta ocramius@gmail.com:
For example, this alternative approach perfectly fits the current
doctrine/annotations use-case:use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\Table;
use Doctrine\ORM\Mapping\Id;
use Doctrine\ORM\Mapping\GeneratedValue;
use Doctrine\ORM\Mapping\Column;[Entity::class => []]
[Table::class => ['name' => 'foo_table']]
class Foo
{
[Id::class => []]
[GeneratedValue::class => [GeneratedValue::UUID]]
[Column::class => ['name' => 'bar_column', 'type' => 'string']]
private $bar;
}
This looks great indeed for many reasons:
-
it's a simple array
-
it can be parsed with built-in DSL syntax for PHP, so any arbitrary
evaluations with constants can be applied transparently, e.g.
[Loggable::class => ['pointcut' => self::PREFIX . 'test' ]] -
C# uses similar syntax with square brackets for annotations:
public class Foo
{
[Display(Name="Product Number")]
[Range(0, 5000)]
public int ProductID { get; set; }
}
However, I would like to see simple markers without nested associative
arrays, e.g just put single AnnotationName::class into brackets or specify
multiple annotations in one section:
[Entity::class, Table::class => 'foo_table']
class Foo
{
// ...
}
I think keeping this just like an array definition in a property would make
this both simple and flexible.
You can even improve on Marcos example with a class having constants:
namespace Doctrine\ORM\Mapping\Annotations;
class ORM
{
const ENTITY = 'Doctrine\ORM\Mapping\Annotations\Entity';
// more constants here
}
And then use it like:
use Doctrine\ORM\Mapping\Annotations\ORM;
[ORM::ENTITY => ["key" => "value"]]
class Article
{
}
This would allow projects to namespace their annotations without much
hassle. But it also allows people to disregard this and just write simple
strings as keys with the risk of clashes with third parties.
greetings
Benjamin
On Wed, Nov 5, 2014 at 4:15 PM, Alexander Lisachenko <
lisachenko.it@gmail.com> wrote:
2014-11-05 17:02 GMT+03:00 Marco Pivetta ocramius@gmail.com:
For example, this alternative approach perfectly fits the current
doctrine/annotations use-case:use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\Table;
use Doctrine\ORM\Mapping\Id;
use Doctrine\ORM\Mapping\GeneratedValue;
use Doctrine\ORM\Mapping\Column;[Entity::class => []]
[Table::class => ['name' => 'foo_table']]
class Foo
{
[Id::class => []]
[GeneratedValue::class => [GeneratedValue::UUID]]
[Column::class => ['name' => 'bar_column', 'type' => 'string']]
private $bar;
}This looks great indeed for many reasons:
it's a simple array
it can be parsed with built-in DSL syntax for PHP, so any arbitrary
evaluations with constants can be applied transparently, e.g.
[Loggable::class => ['pointcut' => self::PREFIX . 'test' ]]C# uses similar syntax with square brackets for annotations:
public class Foo
{
[Display(Name="Product Number")]
[Range(0, 5000)]
public int ProductID { get; set; }
}However, I would like to see simple markers without nested associative
arrays, e.g just put single AnnotationName::class into brackets or specify
multiple annotations in one section:[Entity::class, Table::class => 'foo_table']
class Foo
{
// ...
}
2014-11-05 17:02 GMT+03:00 Marco Pivetta ocramius@gmail.com:
For example, this alternative approach perfectly fits the current
doctrine/annotations use-case:use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\Table;
use Doctrine\ORM\Mapping\Id;
use Doctrine\ORM\Mapping\GeneratedValue;
use Doctrine\ORM\Mapping\Column;[Entity::class => []]
[Table::class => ['name' => 'foo_table']]
class Foo
{
[Id::class => []]
[GeneratedValue::class => [GeneratedValue::UUID]]
[Column::class => ['name' => 'bar_column', 'type' => 'string']]
private $bar;
}This looks great indeed for many reasons:
it's a simple array
it can be parsed with built-in DSL syntax for PHP, so any arbitrary
evaluations with constants can be applied transparently, e.g.
[Loggable::class => ['pointcut' => self::PREFIX . 'test' ]]C# uses similar syntax with square brackets for annotations:
public class Foo
{
[Display(Name="Product Number")]
[Range(0, 5000)]
public int ProductID { get; set; }
}However, I would like to see simple markers without nested associative
arrays, e.g just put single AnnotationName::class into brackets or specify
multiple annotations in one section:[Entity::class, Table::class => 'foo_table']
class Foo
{
// ...
}
One other concern to think about:
In Drupal's case, we have a lot of class annotations. We use them for
discovery. That is, "find me all classes that are a Thingie, and
relevant metadata about them". (Where "is a Thingie" is more than just
"has this interface" in some cases.) The catch is we need the metadata
at very different times than we need the code itself; that's why we're
not just making it a method on the class.
One issue we ran into with the Doctrine parser was that it used
reflection to get the docblock to parse. That meant loading an awful
lot of code that was never actually used in that request, which had a
not-small performance impact.
In the end, we ended up modifying the parser to tokenize the file rather
than just loading it; that way we could free the memory used after each
file rather than holding it around forever, which had a huge memory
savings for us.
I don't know that's possible if done in the engine itself, nor if the
always-available opcode cache obviates that concern or to what degree; I
suppose I am more cautioning to be mindful of the impact of lots of
annotation use at scale, not just on CPU but on memory. There are
plenty of use cases for being interested in the annotations and NOT the
code itself, and we should make sure that's a supported use case that
won't blow up at large scale.
--Larry Garfield
Marco Pivetta wrote on 05/11/2014 14:02:
For example, this alternative approach perfectly fits the current
doctrine/annotations use-case:use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\Table;
use Doctrine\ORM\Mapping\Id;
use Doctrine\ORM\Mapping\GeneratedValue;
use Doctrine\ORM\Mapping\Column;[Entity::class => []]
[Table::class => ['name' => 'foo_table']]
class Foo
{
[Id::class => []]
[GeneratedValue::class => [GeneratedValue::UUID]]
[Column::class => ['name' => 'bar_column', 'type' => 'string']]
private $bar;
}I did nothing special here, just using plain old associative arrays and
built-in::class
pseudo-constants: this leaves space for libraries that
do want to use annotations, but not the way doctrine/annotations does it
(calling the constructor of an annotation), and the annotations themselves
can still decide what to do with nested values.No autoloading is going on, no code execution, nothing: plain and simple
arrays which may as well be used for phpdocumentor as well, if needed.
One problem with using just array syntax, without any new keyword or
symbols, is that it is extremely close to being existing valid syntax.
This may well cause problems in the parser, and would certainly be
confusing to users.
Specifically, a class annotation might look like this:
['Blah\Annotation\Table' => ['name' => 'foo_table']]
class Foo {
}
But add a single semi-colon, and you have valid PHP code
[http://3v4l.org/inkul]:
['Blah\Annotation\Table' => ['name' => 'foo_table']];
class Foo {
}
This works because an expression, by itself, is a valid statement, as
long as it's terminated with a semi-colon, and before the "class"
keyword, you are just in global execution scope (a problem many other
languages don't have to worry about, because statements can't exist
outside blocks).
The same reasoning rules out simple uses of @ as the prefix, because
this is also valid code [http://3v4l.org/TCBbC]:
@Blah\Annotation\Table( ['name' => 'foo_table'] );
class Foo {
}
Amusingly, the @ suppresses the non-existent function error, making this
look almost like it "worked".
Having a single semi-colon change an annotation into a silent statement
seems like an extremely bad idea. The "inside" of an annotation can look
like an array or constructor call, but we need something distinct to
introduce (or wrap) it, assuming we want it positioned before the
"class" keyword, as in other languages.
Regards,
Rowan Collins
[IMSoP]
One problem with using just array syntax, without any new keyword or symbols,
is that it is extremely close to being existing valid syntax. This may well cause problems in the parser,
and would certainly be confusing to users.
Not sure how sacred is $
, but it could be a good candidate for the
annotation identifier since it denotes "something that carries a
value":
$['package.annotation' => ['name' => 'foo']];
class Foo {
}
That might just work, but it's still close to currently possible code.
Why don't we use something that would currently produce a parse error
and is not as close to valid code
as the examples above?
<<< Annotation('abc'), foo >>> // Used <<< as it's different from
T_SL, but it works for hack, so maybe drop a <>
class DEF {}
comes to mind.
2014-11-12 18:23 GMT+01:00 Marcio Almada marcio.web2@gmail.com:
One problem with using just array syntax, without any new keyword or symbols,
is that it is extremely close to being existing valid syntax. This may well cause problems in the parser,
and would certainly be confusing to users.Not sure how sacred is
$
, but it could be a good candidate for the
annotation identifier since it denotes "something that carries a
value":$['package.annotation' => ['name' => 'foo']]; class Foo { }
Hi!
Primarily, I do not see docblocks as the right place to store class'
metadata information. Metadata != Comments.I personally regard this as a kind of superstition. There's nothing
wrong with extending what can be in comments. In fact, Javascript was
officially "HTML comment" for years, and it didn't prevent anybody from
using Javascript. There are instances of significant comments in various
environments. Outright refusing comments can be significant is just
arbitrarily limiting our options for no reason. I don't say it
necessarily the best option, but we should not reject it because "oh
noes, significant comments!". It has been done, and it's nothing
special, just one of the possibilities
Javascript is a good analogy, actually. It started off as something you
stuck in comments to hide it, just in case. But really, no one does
that anymore and hasn't for years. Once it became obvious that it was
useful, here to say, and any browser anyone cared about supported it
directly it became a first-class citizen, without any comment hacks.
Annotations have been a comment hack in PHP for a long time now. They've
proven their usefulness. Many large projects use them. They've been
proven to work. It's time for them to also become first-class citizens
where we can all benefit from them in more robust ways, including
simplifying the de facto workflow and toolchain.
--Larry Garfield
If this is difficult, you can do in PHP 7.0 simple realization
annotation/facades, in versions 7.x to develop and refine.
Most importantly, define the syntax and semantics annotation/facades, for a
version of PHP 7.0
Demand in annotation/facades is very high, ~80% of all popular frameworks
their use, it is really what you need PHP developers.
2014-11-04 20:27 GMT+02:00 Stas Malyshev smalyshev@sugarcrm.com:
Hi!
The approach for annotations that I like best would actually be not
annotations, but Python-style decorators. They’re very simple, but
very powerful. They would allow you to do annotations, but also add
extra functionality to functions.For python-style decorators, at least the way they work in Python, we'd
need to organize our function tables differently, as Python just
replaces the function with another one while decorating, and I'm not
sure it'd be as easy to do with PHP.Which would be equivalent to the following PHP code:
$myfunc = function myfunc() { # function source code here }; $myfunc
= some_decorator($myfunc, foo, bar);Not really, because functions work differently in Python and in PHP. You
can not just replace a function in class's function table with random
closure in PHP, at least easily.
You'd have to convert all such functions to closures (or something that
can be both, maybe) and have the engine be aware that function table now
can store closures. And, also, inheritance may get a bit weird there. It
would be very powerful, but it may not be very simple to do.Also, it is a major overkill for what annotations are commonly used -
attaching a piece of data to an entity. In Python, decorators are very
powerful for modifying function behavior (i.e., attaching pre/post
conditions to functions or doing some things phpunit does is really
easy) but it is too much for just attaching data.Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
In Python, decorators are very
powerful for modifying function behavior (i.e., attaching pre/post
conditions to functions or doing some things phpunit does is really
easy) but it is too much for just attaching data.
FWIW (and I apologize if this is just adding to the noise), one of the most powerful things about decorators in Python is that the decorator can do different things in different contexts.
For example, in the web-app context @app.task
might cause a function’s execution be deferred, and return quickly so the actual work can be carried out by another process.
In a worker context, @app.task
could be used to define the work that should actually be carried out by the current worker.
Reference for those interested in a practical example: http://celery.readthedocs.org/en/latest/userguide/tasks.html
S
In Python, a decorator is a function (or callable object), and you use one like this:
@some_decorator(foo, bar) def myfunc(): # function source code here
I wonder how feasible it would be to add something like this and allow
everything that's allowed in a php function/method call as parameters
inside the annotation call - kind of like python does it, which seems to
be one of the simplest (in usage, not implementation) forms possible.
/**
- @ORM\Entity
- @Table(name="message")
*/
class User {}
becomes something like
@ORM\Entity
@Table(['name' => 'message'])
class User {}
with Entity and Table being callables, obviously. Maybe classes, with
User being the first argument, but I haven't thought that through.
~Florian
Hi!
All projects mentioned in this thread use:
http://doctrine-common.readthedocs.org/en/latest/reference/annotations.html
That makes a pretty good base spec.
Reading it, it looks pretty big - strictly typed values, named
parameters, default constructors linked to properties, support for enum
types, support for typed arrays, separate constant syntax within
annotations. These are all features not supported in PHP, and it seems a
bit weird to me to have mini-language inside PHP that would support
these. And, of course, arbitrary depth recursive annotations, and for
some reason separate array syntax using {} and not [].
Moreover, there's extensive checking for annotations with exceptions
thrown if any of the above doesn't typecheck - I'm not even sure where
that would fit in PHP parser.
Reading it - http://doctrine-common.readthedocs.org/en/latest/reference/annotations.html -
it looks pretty big - strictly typed values, named
parameters, default constructors linked to properties, support for enum
types, support for typed arrays, separate constant syntax within
annotations. These are all features not supported in PHP, and it seems a
bit weird to me to have mini-language inside PHP that would support
these. And, of course, arbitrary depth recursive annotations, and for
some reason separate array syntax using {} and not [].
From my point of view, most of this complexity is accidental.
This happened mostly because, of course, we couldn't have parser /
runtime errors
inside doc comments. Once we have core annotations, oustide of doc comments,
mostly of the DSL described in
http://doctrine-common.readthedocs.org/en/latest/reference/annotations.html
becomes unnecessary.
2014-11-04 15:17 GMT-03:00 Stas Malyshev smalyshev@gmail.com:
Hi!
All projects mentioned in this thread use:
http://doctrine-common.readthedocs.org/en/latest/reference/annotations.html
That makes a pretty good base spec.
Reading it, it looks pretty big - strictly typed values, named
parameters, default constructors linked to properties, support for enum
types, support for typed arrays, separate constant syntax within
annotations. These are all features not supported in PHP, and it seems a
bit weird to me to have mini-language inside PHP that would support
these. And, of course, arbitrary depth recursive annotations, and for
some reason separate array syntax using {} and not [].
Moreover, there's extensive checking for annotations with exceptions
thrown if any of the above doesn't typecheck - I'm not even sure where
that would fit in PHP parser.
Hi!
It would be nice to take "paving the walkways" approach, but last time
we tried, IIRC we've got into something very over-engineered. Maybe if
we try again with more restricted scope (i.e. not trying to put a DSL
for describing arbitrarily complex data structures into it :) it would
be more successful this time.
PHP7 has a wonderful parser, maybe it's possible to provide a general
syntax for annotations with userland hooks for arbitrary data. This
approach can give a tool for framework developers to define a node visitor
for annotations. Alternative way is to define simple key-value storage and
access it via Reflector->getAnnotations().
I want to put my huge +1 vote on annotations support in the core, because
Go! AOP uses annotations a lot for defining metadata and markers in the
code and provides an engine for advanced programming patterns and method
interception. Doctrine is good library, but this can be better on core
level.