# PHP Annotations RFC + Patch

- Thread: https://externals.io/message/49733
- Original archive: https://news-web.php.net/php.internals/49733
- Started by Matthew Weier O'Phinney on 2010-09-16T20:51:05+00:00
- Messages: 79
- Page 1 of 4: messages 1 to 25 (25 per page, add `?page=N` to the URL)
- Next page: https://externals.io/message/49733.md?page=2
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · RFCs at https://externals.io/rfc.md · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #49580 — Dmitry Stogov — 2010-09-08T07:32:31+00:00

URL: https://externals.io/message/49733#49580

Hi Pierrick,

I've taken just a quick look into concept and patch. It looks 
interesting and might be useful in some areas, but I see several 
significant problems:

1) Have you thought about compatibility with opcode caches? In case I 
understood properly, you store annotation as a HashTable of object. But 
life-time of objects is restricted by request time, so they won't 
persist in opcode cache and will have to be recreated on each request. 
It's a huge overhead. I don't have a good solution for this problem 
except for using arrays instead of objects.

2) I suppose that usage of annotation would be quite rare case. I don't 
think it make sense to extend each op_array, property and class with 
additional "annotations" field. I think it's possible to have a separate 
CG(annotaions_map) where the keys might be the addresses of 
corresponding classesm, methods and properties.

3) I think the annotaton syntax must follow PHP syntax as close as possible
- allow leading \ in QualifiedName
- use '=>' in arrays

4) I didn't understand why do we need nested annotations.

The first and second problems are the most important.
I don't like to lose performance of existing applications which don't 
use annotations at all. I think the concept must be redesigned a bit.
Also I would like to see an APC patch to check if the implementation 
works and doesn't lose performance.

Thanks. Dmitry.

Pierrick Charron wrote:
> Hi Dmitry,
> 
> As discussed on IRC, here are the RFC and the patch to add Annotation
> support in PHP :
> 
> - RFC : http://wiki.php.net/rfc/annotations
> - Patch : http://www.adoy.net/php/Annotations.diff
> 
> All your feedback and suggestions will be more than welcome.
> 
> Thanks again.
> 
> Pierrick (or adoy on irc)

---

## #49582 — Pierrick Charron — 2010-09-08T13:05:09+00:00

URL: https://externals.io/message/49733#49582 · In reply to: #49580

Hi Dmitry,

First thanks for having a look at the patch and taking some time to
give your feedback ! It's much appreciated

2010/9/8 Dmitry Stogov <dmitry@zend.com>:
> Hi Pierrick,
>
> I've taken just a quick look into concept and patch. It looks interesting
> and might be useful in some areas, but I see several significant problems:
>
> 1) Have you thought about compatibility with opcode caches? In case I
> understood properly, you store annotation as a HashTable of object. But
> life-time of objects is restricted by request time, so they won't persist in
> opcode cache and will have to be recreated on each request. It's a huge
> overhead. I don't have a good solution for this problem except for using
> arrays instead of objects.

You're right annotations are stored in an HashTable. But this
HashTable doesn't store zval objects directly but zend_annotations.
This is the reflection getAnnotation and getAnnotations method which
are in charge of reading the zend_annotation structures and
instantiating the proper annotation object when needed. The zval named
instance in the zend_annotation structure is there only to point to
the annotation instance at runtime so that the state of the annotation
is kept between two calls to the getAnnotation and getAnnotations on a
same code element (I added this directly into the zend_annotation
structure to make it faster but I can imagine a HashTable like you
mentioned earlier where keys are addresses). I'm not yet quite
familiar with the APC source code but since (and correct me if i'm
wrong) APC save zend_class_entry, etc.. in memory we could modify it
to also save the new HashTable *annotations of those structures (like
you already do for doc_comment) excluding the zval *instance.

> 2) I suppose that usage of annotation would be quite rare case. I don't
> think it make sense to extend each op_array, property and class with
> additional "annotations" field. I think it's possible to have a separate
> CG(annotaions_map) where the keys might be the addresses of corresponding
> classesm, methods and properties.

Annotations are metadata related to a code element. IMHO it make sense
to add them in the appropriate code element structures (even
doc_comment is in those structures) so that APC and other cache will
know that this is something part of the code element and it needs to
be cached and so on.

> 3) I think the annotaton syntax must follow PHP syntax as close as possible
> - allow leading \ in QualifiedName
> - use '=>' in arrays

The actual patch already implement those two points. You can right now
already do

[\My\Own\Annotation(array('foo' => 'bar', 'baz'))]
class FooBar {}

Sorry about that, I just noticed that the EBNF in the RFC was not
updated correctly to reflect those two points. I just made the
modification to replace "=" by "=>" in arrays and allow the optional
leading \ in the QualidifedName

> 4) I didn't understand why do we need nested annotations.

Nested annotations could be use for many cases. Doctrine for example
use them a lot to do things like :
[JoinTable(
    name="users_phonenumbers",
    joinColumns=array(
        [JoinColumn(name="user_id", referencedColumnName="id")]
    ),
    inverseJoinColumns=array(
        [JoinColumn(name="phonenumber_id", referencedColumnName="id",
unique=true)]
    )
)]

> The first and second problems are the most important.
> I don't like to lose performance of existing applications which don't use
> annotations at all. I think the concept must be redesigned a bit.

Right now the only performance decrease is at compile time since the
annotations HashTable are filled by the parser. At runtime you don't
have any performance decrease if you're not using annotations. If you
use them, you'll lose some time when you do getAnnotation() to
instantiate the object, but this instantiation is just done once for
each annotation on a single code element so it make it a little bit
faster if you use them intensively.

> Also I would like to see an APC patch to check if the implementation works
> and doesn't lose performance.

I will try to work on an APC patch to store the Annotations HashTable
of every code element structure.

> Thanks. Dmitry.

Thanks again for your time :)

Pierrick

>
> Pierrick Charron wrote:
> > […]

---

## #49583 — Dmitry Stogov — 2010-09-08T13:56:35+00:00

URL: https://externals.io/message/49733#49583 · In reply to: #49582

Pierrick Charron wrote:
> Hi Dmitry,
> 
> First thanks for having a look at the patch and taking some time to
> give your feedback ! It's much appreciated
> 
> 2010/9/8 Dmitry Stogov <dmitry@zend.com>:
> > […]
> 
> You're right annotations are stored in an HashTable. But this
> HashTable doesn't store zval objects directly but zend_annotations.

Then it's not a problem. my mistake.

> This is the reflection getAnnotation and getAnnotations method which
> are in charge of reading the zend_annotation structures and
> instantiating the proper annotation object when needed. The zval named
> instance in the zend_annotation structure is there only to point to
> the annotation instance at runtime so that the state of the annotation
> is kept between two calls to the getAnnotation and getAnnotations on a
> same code element (I added this directly into the zend_annotation
> structure to make it faster but I can imagine a HashTable like you
> mentioned earlier where keys are addresses). I'm not yet quite
> familiar with the APC source code but since (and correct me if i'm
> wrong) APC save zend_class_entry, etc.. in memory we could modify it
> to also save the new HashTable *annotations of those structures (like
> you already do for doc_comment) excluding the zval *instance.
> 
> > […]
> 
> Annotations are metadata related to a code element. IMHO it make sense
> to add them in the appropriate code element structures (even
> doc_comment is in those structures) so that APC and other cache will
> know that this is something part of the code element and it needs to
> be cached and so on.

It's easier to keep it in appropriate places, but it's a waste of 
memory, because only a few classes will use it. According to doc 
comments, in case we accept annotations, I would represent it as a 
special kind of annotation.

Separate map(enity -> anotations) would require memory only for defined 
annotations. Of course it would be a bit more expensive to read it and 
would require special handling in opcode hashes.

> > […]
> 
> The actual patch already implement those two points. You can right now
> already do
> 
> [\My\Own\Annotation(array('foo' => 'bar', 'baz'))]
> class FooBar {}
> 
> Sorry about that, I just noticed that the EBNF in the RFC was not
> updated correctly to reflect those two points. I just made the
> modification to replace "=" by "=>" in arrays and allow the optional
> leading \ in the QualidifedName

great.

> > […]
> 
> Nested annotations could be use for many cases. Doctrine for example
> use them a lot to do things like :
> [JoinTable(
>     name="users_phonenumbers",
>     joinColumns=array(
>         [JoinColumn(name="user_id", referencedColumnName="id")]
>     ),
>     inverseJoinColumns=array(
>         [JoinColumn(name="phonenumber_id", referencedColumnName="id",
> unique=true)]
>     )
> )]
> 
> > […]
> 
> Right now the only performance decrease is at compile time since the
> annotations HashTable are filled by the parser.

I assume parser works with near the same speed without annotations. right?

> At runtime you don't
> have any performance decrease if you're not using annotations. If you
> use them, you'll lose some time when you do getAnnotation() to
> instantiate the object, but this instantiation is just done once for
> each annotation on a single code element so it make it a little bit
> faster if you use them intensively.

I see, but assumptions are not always right, often memory consumption 
affects performance directly, it's better to check.

> > […]
> 
> I will try to work on an APC patch to store the Annotations HashTable
> of every code element structure.

In case you have plain C structures (without objects) it shouldn't be a 
big problem. I'm more interested to store annotation separately. In this 
case APC support would be a bit more difficult.

I could help you with implementation in case the idea accepted in general.

Thanks. Dmitry.

> > […]
> 
> Thanks again for your time :)
> 
> Pierrick
> 
> > […]

---

## #49584 — Guilherme Blanco — 2010-09-08T16:44:44+00:00

URL: https://externals.io/message/49733#49584 · In reply to: #49583

Hi Dmitry,

Comments goes inline.


>
>
> Pierrick Charron wrote:
> > […]
>
> Then it's not a problem. my mistake.
>
> > […]
>
> It's easier to keep it in appropriate places, but it's a waste of memory,
> because only a few classes will use it. According to doc comments, in case
> we accept annotations, I would represent it as a special kind of annotation.
>
> Separate map(enity -> anotations) would require memory only for defined
> annotations. Of course it would be a bit more expensive to read it and would
> require special handling in opcode hashes.

Argument is not reasonable IMHO.
You may know that most code around web lack of documentation,
specially docblock, so why not separate the docblocks on a separate
structure too?
Sorry, but your argument is not reasonable.
Each class/property/method should contain all relevant information it
can get, whatever it needs (docblock, annotations, visibility
information, etc). Of course you have a bit of memory overhead, but
it's a pointer, isn't it? So at the end, we will only have overhead
when we have annotations defined.
Also, decomposing the annotation definition and storage adds a level
of dependency and indirection that may get things harder to comprehend
by newer contributors.

>
> > […]
>
> great.
>
> > […]

I see many use cases of nested annotations. Pierrick gave one, that is
exactly related to the project I contribute for.
Another good example is the implementation of JSR-303 (Bean
Validation) on Symfony 2, that adds automatic validation to POPOs.
Example:

class User {
    ...

    [Validation([Email(checkMX = true)])]
    public $email;
}

> > […]
>
> I assume parser works with near the same speed without annotations. right?

Yes. It is as complex as the addiction of any new feature that
includes new grammar rules, like type hinting checks on method
prototypes.

>
> > […]
>
> I see, but assumptions are not always right, often memory consumption
> affects performance directly, it's better to check.

The impact is minimum because it only adds pointers to structs.
The instantiation is done on demand, so only when user asks for
Annotations they are instantiated.

>
> > […]
>
> In case you have plain C structures (without objects) it shouldn't be a big
> problem. I'm more interested to store annotation separately. In this case
> APC support would be a bit more difficult.
>
> I could help you with implementation in case the idea accepted in general.

Thanks a lot for the offered help. Without help from core developers
it would be very difficult to reach a performant proposed patch.
>
> Thanks. Dmitry.
>
> > […]
>
> --
> 
> 
>
>



-- 
Guilherme Blanco
Mobile: +55 (16) 9215-8480
MSN: guilhermeblanco@hotmail.com
São Paulo - SP/Brazil

---

## #49585 — johannes@schlueters.de — 2010-09-08T17:29:09+00:00

URL: https://externals.io/message/49733#49585 · In reply to: #49584

Hi,


> > […]
> 
> Argument is not reasonable IMHO.
> You may know that most code around web lack of documentation,
> specially docblock, so why not separate the docblocks on a separate
> structure too?
> Sorry, but your argument is not reasonable.
> Each class/property/method should contain all relevant information it
> can get, whatever it needs (docblock, annotations, visibility
> information, etc). Of course you have a bit of memory overhead, but
> it's a pointer, isn't it? So at the end, we will only have overhead
> when we have annotations defined.
> Also, decomposing the annotation definition and storage adds a level
> of dependency and indirection that may get things harder to comprehend
> by newer contributors.

Let's do some math:

A pointer on a 64bit architecture is 8 bytes. A random PHP binary of
mine has 1226 functions. And 133 classes. Each of them has, let's say 10
methods (i guess average is higher, but well).

Then I'm running an application, which has maybe 100 classes with 10
methods each.

This gives 8 * (1226 + 133 + 100 + (133 * 10) + (100 * 10)) bytes =
30.31 kilobytes.

Now I have 100 server children, so this are 3.021 megabytes on the
server.

Oh and that's only for the pointer which _could_ point to annotations
but will most likely point to NULL.

With the approach proposed by Dmitry this memory won't be used but
whenever annotations are accessed a lookup more will be needed.

This calculation is of course completely wrong to many wild guesses and
simplifications in there.

Of course that's not much but your statement shows what will happen
next:

    "specially docblock, so why not separate the docblocks"

First of all I claim that there are more docblocks than annotations.

Secondly what about the next pointer, and the next and the next somebody
wants to add, not only in the op array but other global structures, one
pointer in the zval, one in the hash bucket, one ...?

We can still move this over later when annotations are adopted and the
equation memory vs. CPU for this feature is valued differently.

johannes

---

## #49586 — Guilherme Blanco — 2010-09-08T17:59:45+00:00

URL: https://externals.io/message/49733#49586 · In reply to: #49585

Hi Johannes,

Comments inline.

2010/9/8 Johannes Schlüter <johannes@schlueters.de>:
> Hi,
>
> 
> > […]
>
> Let's do some math:
>
> A pointer on a 64bit architecture is 8 bytes. A random PHP binary of
> mine has 1226 functions. And 133 classes. Each of them has, let's say 10
> methods (i guess average is higher, but well).
>
> Then I'm running an application, which has maybe 100 classes with 10
> methods each.
>
> This gives 8 * (1226 + 133 + 100 + (133 * 10) + (100 * 10)) bytes =
> 30.31 kilobytes.
>
> Now I have 100 server children, so this are 3.021 megabytes on the
> server.
>
> Oh and that's only for the pointer which _could_ point to annotations
> but will most likely point to NULL.
>
> With the approach proposed by Dmitry this memory won't be used but
> whenever annotations are accessed a lookup more will be needed.
>
> This calculation is of course completely wrong to many wild guesses and
> simplifications in there.
>
> Of course that's not much but your statement shows what will happen
> next:
>
>    "specially docblock, so why not separate the docblocks"
>
> First of all I claim that there are more docblocks than annotations.
>
> Secondly what about the next pointer, and the next and the next somebody
> wants to add, not only in the op array but other global structures, one
> pointer in the zval, one in the hash bucket, one ...?
>

You are right. I was thinking strictly to code coupling and containers
by responsability.
I have implemented the support under docblock parsing for Doctrine 2,
and we cache the parsed pieces under the name of ClassMetadata. That's
why I don't feel too much about having it standalone or coupled per
associated piece. I think related to this argument I missed a little
the "eat your own dog food", mainly because I've never done too much
PHP internals.
Anyway, I feel a little uncomfortable when I see localized code using
global resources, it sounds a little like bad architecturing. But I
completely understand the performance reasons. =)

> We can still move this over later when annotations are adopted and the
> equation memory vs. CPU for this feature is valued differently.
>

I didn't mean to be rude. I've re-read my email and it really sounded
like harsh... sorry!
I'm just very anxious to see this merged on core... I've bothered
people 2+ years ago to see this alive on 5.3 and now it's back to
discussion and more close to become reality... I just wanna get things
right and "in". =)

> johannes
>
>



-- 
Guilherme Blanco
Mobile: +55 (16) 9215-8480
MSN: guilhermeblanco@hotmail.com
São Paulo - SP/Brazil

---

## #49588 — Stas Malyshev — 2010-09-08T18:16:53+00:00

URL: https://externals.io/message/49733#49588 · In reply to: #49584

Hi!

> > […]
>      [Validation([Email(checkMX = true)])]

I'm getting a feeling we are developing language inside language here. 
We rejected [] syntax for arrays because it makes the intent unclear. 
I'd say if that's unclear [Validation([Email(checkMX = true)])] is 
super-unclear - what exactly is supposed to happen there? It is very 
non-obvious. I think it needs to be radically simplified.
I understand that people that write ORMs etc. want their work to be 
easier, but I don't think turning PHP into a mesh of random brackets and 
words worth it. If we can't find a model that is easy to comprehend, 
ORMs would have to use XML or other outside-of-syntax means.

-- 
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227

---

## #49589 — Benjamin Eberlei — 2010-09-08T18:58:24+00:00

URL: https://externals.io/message/49733#49589 · In reply to: #49588

Hello Stas,

I agree, using an array like syntax would make the intent much clearer
in the context of PHP, the syntax is just slightly more verbose:

[JoinTable(array(
  "name" => "users_phonenumbers",
  "joinColumns" => array(
    array("name" => "user_id", "referendedColumnName" => "id"),
  ),
  "inverseJoinColumns" => array(
    array("name => "phonenumber_id", "referendColumnName" => "id",
"unique" => true),
  ),
)]

[Validation(array("type" => "EMail", "options" => array("checkMX" =>
true))]

I think that is even possible with the current patch, it just allows
additional [] blocks inside that convert into an object instead of an
array.

Annotations is hardly a feature relevant for ORMs only, its just a very
obvious one to pick. I can find bazzilions of other good examples:

* SOAP/XML-RPC - Hint your service/functions for that WSDL generator you
want to use (instead of writing it by hand)
* ACLs - Configure an access control layer that wraps around your
service-calls (is Foo allowed to do this?)
* Testing - Allow nicer configuration of test-setup, fixtures,
pre-conditions.
* Validation - Explain to a validation component what the fields of your
classes are.
* Hooks/Event-Systems - Explicit mechanisms to register
classes/methods/functions as plugins, event listener or hooks. No more
writing FrameworkHookListener::add('myMagicCallback')
* Frameworks - Leave INI, YAML, XML behind, configuration visible at the
applied context inside PHP is very valuable, instead of having to browse
the source to the configuration directories, see the Routing, Action and
View configuration examples Fabien has posted on Symfony 2 yesterday.
* Dependency Injection - Configuring how dependencies should be wired
between objects, so that a DI container can help you bootstrap your
application.
* Forms - Tell a form generator how an object property should be
rendered, validated and such.

greetings,
Benjamin


Hi!
> 
> > […]
referencedColumnName="id",
> > […]
> 
> I'm getting a feeling we are developing language inside language
here. 
> We rejected [] syntax for arrays because it makes the intent unclear. 
> I'd say if that's unclear [Validation([Email(checkMX = true)])] is 
> super-unclear - what exactly is supposed to happen there? It is very 
> non-obvious. I think it needs to be radically simplified.
> I understand that people that write ORMs etc. want their work to be 
> easier, but I don't think turning PHP into a mesh of random brackets
and 
> words worth it. If we can't find a model that is easy to comprehend, 
> ORMs would have to use XML or other outside-of-syntax means.
> 
> -- 
> Stanislav Malyshev, Software Architect
> SugarCRM: http://www.sugarcrm.com/
> (408)454-6900 ext. 227
> 
> 

On Wed, 2010-09-08 at 11:16 -0700, Stas Malyshev wrote: 
> Hi!
> 
> > […]
> 
> I'm getting a feeling we are developing language inside language here. 
> We rejected [] syntax for arrays because it makes the intent unclear. 
> I'd say if that's unclear [Validation([Email(checkMX = true)])] is 
> super-unclear - what exactly is supposed to happen there? It is very 
> non-obvious. I think it needs to be radically simplified.
> I understand that people that write ORMs etc. want their work to be 
> easier, but I don't think turning PHP into a mesh of random brackets and 
> words worth it. If we can't find a model that is easy to comprehend, 
> ORMs would have to use XML or other outside-of-syntax means.
> 
> -- 
> Stanislav Malyshev, Software Architect
> SugarCRM: http://www.sugarcrm.com/
> (408)454-6900 ext. 227

---

## #49590 — Dmitry Stogov — 2010-09-09T06:22:35+00:00

URL: https://externals.io/message/49733#49590 · In reply to: #49584

Hi Guilherme,

Guilherme Blanco wrote:
> Hi Dmitry,
> 
> Comments goes inline.
> 
> 
> > […]
> 
> Argument is not reasonable IMHO.
> You may know that most code around web lack of documentation,
> specially docblock, so why not separate the docblocks on a separate
> structure too?

It would be good to separate it too, as well as different debug 
information e.g opline number, filename etc.

> Sorry, but your argument is not reasonable.
> Each class/property/method should contain all relevant information it
> can get, whatever it needs (docblock, annotations, visibility
> information, etc). Of course you have a bit of memory overhead, but
> it's a pointer, isn't it? So at the end, we will only have overhead
> when we have annotations defined.

he pointer takes memory too.

Anyway, I think it's better to make experiment and see how this patch 
affects memory consumption. Just load most ZF classes and measure peak 
heap usage.

$ USE_ZEND_ALLOC=0 valgrind --tool=massif php zf.php
$ msprintf massif.out.<pid>

Then we may decide if it make sense to separate annotations or not.
(I can do this test and share results when have time).

> Also, decomposing the annotation definition and storage adds a level
> of dependency and indirection that may get things harder to comprehend
> by newer contributors.

Agree.

> > […]
> 
> I see many use cases of nested annotations. Pierrick gave one, that is
> exactly related to the project I contribute for.
> Another good example is the implementation of JSR-303 (Bean
> Validation) on Symfony 2, that adds automatic validation to POPOs.
> Example:
> 
> class User {
>     ...
> 
>     [Validation([Email(checkMX = true)])]
>     public $email;
> }
> 

OK. at least I don't see a reason for nested brackets.

[Validation(Email(checkMX=>true))] looks better.

Thanks. Dmitry.

> > […]
> 
> Yes. It is as complex as the addiction of any new feature that
> includes new grammar rules, like type hinting checks on method
> prototypes.
> 
> > […]
> 
> The impact is minimum because it only adds pointers to structs.
> The instantiation is done on demand, so only when user asks for
> Annotations they are instantiated.
> 
> > […]
> 
> Thanks a lot for the offered help. Without help from core developers
> it would be very difficult to reach a performant proposed patch.
> > […]

---

## #49595 — Pierrick Charron — 2010-09-10T23:05:10+00:00

URL: https://externals.io/message/49733#49595 · In reply to: #49590

>
> [Validation(Email(checkMX=>true))] looks better.
>
> Thanks. Dmitry.
>

Hi Dmitry

The initial syntax proposed in the RFC/Patch is inspired by C#. If you
modify this syntax to remove brackets in nested annotations you will
have some conflicts like this one :

[Validation(Email)]

In this case the parser can't determine if Email is a constant or a
nested annotation. I did a second patch with an other syntax (proposed
by Etienne in the initial thread) which look like this :

%Validation(%Email)

I personally prefer the first one because I like the fact that you
have a start and an end delimiter for each annotations but I can live
with an other one if the majority is more comfortable with it.

Regards,
Pierrick

---

## #49596 — Stas Malyshev — 2010-09-10T23:54:14+00:00

URL: https://externals.io/message/49733#49596 · In reply to: #49590

Hi!

> [Validation(Email(checkMX=>true))] looks better.

Even here it's not clear what is happening. What is "Validation", what 
is "Email", what is "checkMX" (are they all classes? or only some of 
them?), what is happening to them (are these classes being instantiated? 
when? what is passed as parameters? What is the scope of that? etc). Why 
can we have now two ways to instantiate classes, complete with mix of 
[]s and ()s, but having array syntax using [] is still too complex?

-- 
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227

---

## #49597 — Pierrick Charron — 2010-09-11T00:23:01+00:00

URL: https://externals.io/message/49733#49597 · In reply to: #49596

Hi Stas,

Annotations is a new concept in PHP (even if some framework already
use an user space implementation of them) and I think it is normal
that people will have to read a little bit about this eventually new
feature before using it. This is the same thing for traits, if you
don't know what is a trait you will not know how to use them. But once
you know the concept it's really easy to understand what is an
annotation class, parameter etc...

Is it really the [] Syntax that you don't like for annotations ? I was
personally not against the [] array syntax and I understand that this
annotation syntax will make the future implementation of this [] array
syntax impossible. So I could change it to the syntax proposed by
Etienne in the first thread :

%Annotation(%Email(checkMX = true));

I'm not against any other proposal of syntax so if you have one to
proposition do not hesitate.

Regards,
Pierrick



2010/9/10 Stas Malyshev <smalyshev@sugarcrm.com>:
> Hi!
>
> > […]
>
> Even here it's not clear what is happening. What is "Validation", what is
> "Email", what is "checkMX" (are they all classes? or only some of them?),
> what is happening to them (are these classes being instantiated? when? what
> is passed as parameters? What is the scope of that? etc). Why can we have
> now two ways to instantiate classes, complete with mix of []s and ()s, but
> having array syntax using [] is still too complex?
>
> --
> Stanislav Malyshev, Software Architect
> SugarCRM: http://www.sugarcrm.com/
> (408)454-6900 ext. 227

---

## #49598 — Christian Kaps — 2010-09-11T11:00:56+00:00

URL: https://externals.io/message/49733#49598 · In reply to: #49597

Hi,

> > […]

at first I thought what for an ugly syntax. But after a time I think it
is regardless of whether the % or @(from Java, which I prefer over all,
if it were possible) syntax is used. It looks very similar. So I prefer
the % syntax so we can use the [] for defining arrays in annotations. Is
it possible to define objects from type stdClass in the form
%Annotation({key: 'value'})?

An other question. Is it necessary to terminate an annotation with a
semicolon, like in your example?

class Compiler {

    /**
     * Compile a node into plain PHP.
     *
     * @param Node $node The node to compile.
     */
    %Annotation(%Email(checkMX = true))
    %ResourceParameter(['key' => 'name', 'value' => 'annotation'])
    %Inject('\my\name\space\Class')
    %Test
    %Annotation({key: 'value'})
    public function compile(Node $node) {

    }
}

Greetings,
Christian

Am 11.09.2010 02:23, schrieb Pierrick Charron:
> Hi Stas,
>
> Annotations is a new concept in PHP (even if some framework already
> use an user space implementation of them) and I think it is normal
> that people will have to read a little bit about this eventually new
> feature before using it. This is the same thing for traits, if you
> don't know what is a trait you will not know how to use them. But once
> you know the concept it's really easy to understand what is an
> annotation class, parameter etc...
>
> Is it really the [] Syntax that you don't like for annotations ? I was
> personally not against the [] array syntax and I understand that this
> annotation syntax will make the future implementation of this [] array
> syntax impossible. So I could change it to the syntax proposed by
> Etienne in the first thread :
>
> %Annotation(%Email(checkMX = true));
>
> I'm not against any other proposal of syntax so if you have one to
> proposition do not hesitate.
>
> Regards,
> Pierrick
>
>
>
> 2010/9/10 Stas Malyshev <smalyshev@sugarcrm.com>:
> > […]

---

## #49599 — Guilherme Blanco — 2010-09-11T17:46:58+00:00

URL: https://externals.io/message/49733#49599 · In reply to: #49598

Hi Stas and Christian,

The separator never was a problem... but I definately don't want to
see another 6 months just to define what would the separator be.
If we need to drop [] in favor of array support, I vote for ! as separator.

!Author("Guilherme Blanco")
!Validation(!Email(checkMX = true))


@Stas: Explaining the example of class User {
[Validation([Email(checkMX = true)])] public $email; }

class Validation extends \ReflectionAnnotation {}
class Email extends \ReflectionAnnotation {
    protected $checkMX;

    public function getCheckMX() { return $this->checkMX; }
}


$reflClass = new \ReflectionClass('User');
$reflProp = $reflClass->getProperty('email');

$emailAnnot = $reflProp->getAnnotation('Validation')->getValue();
echo $emailAnnot->getCheckMX(); // true


I hope this helps to explain a little bit.


Cheers,

On Sat, Sep 11, 2010 at 8:00 AM, Christian Kaps
<christian.kaps@mohiva.com> wrote:
>  Hi,
>
> > […]
>
> at first I thought what for an ugly syntax. But after a time I think it
> is regardless of whether the % or @(from Java, which I prefer over all,
> if it were possible) syntax is used. It looks very similar. So I prefer
> the % syntax so we can use the [] for defining arrays in annotations. Is
> it possible to define objects from type stdClass in the form
> %Annotation({key: 'value'})?
>
> An other question. Is it necessary to terminate an annotation with a
> semicolon, like in your example?
>
> class Compiler {
>
>    /**
>     * Compile a node into plain PHP.
>     *
>     * @param Node $node The node to compile.
>     */
>    %Annotation(%Email(checkMX = true))
>    %ResourceParameter(['key' => 'name', 'value' => 'annotation'])
>    %Inject('\my\name\space\Class')
>    %Test
>    %Annotation({key: 'value'})
>    public function compile(Node $node) {
>
>    }
> }
>
> Greetings,
> Christian
>
> Am 11.09.2010 02:23, schrieb Pierrick Charron:
> > […]
>
>
> --
> 
> 
>
>



-- 
Guilherme Blanco
Mobile: +55 (16) 9215-8480
MSN: guilhermeblanco@hotmail.com
São Paulo - SP/Brazil

---

## #49600 — Stas Malyshev — 2010-09-11T18:19:10+00:00

URL: https://externals.io/message/49733#49600 · In reply to: #49599

Hi!

> The separator never was a problem... but I definately don't want to
> see another 6 months just to define what would the separator be.
> If we need to drop [] in favor of array support, I vote for ! as separator.

The separator is not a problem (even though 1-char one produces much 
less clutter). The cryptic syntax is. We have rejected much cleaner 
syntax proposals because it was not clean enough, though only thing it 
did was to drop one keyword, and this one rolls a bunch of pretty 
unobvious code into a couple of symbols. I think we should choose either 
never do it or allow it, but not be random about it.
-- 
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227

---

## #49601 — Pierre Joye — 2010-09-11T18:24:49+00:00

URL: https://externals.io/message/49733#49601 · In reply to: #49600

> Hi!
>
> > […]
>
> The separator is not a problem (even though 1-char one produces much less
> clutter). The cryptic syntax is.

It seems that there is a misunderstanding about the goals of the
annotations. They are not meant to be read by human being
(javadoc/phpdoc/etc. are) but to be parsed automatically to be used
for services.

In that sense, to have a syntax closed to one of the best (or less
worst, if you are on the opposed side ;-) syntax out there (c#/.net)
may be a good thing to do, instead of re einventing the php wheel.

Cheers,
-- 
Pierre

@pierrejoye | http://blog.thepimp.net | http://www.libgd.org

---

## #49602 — Benjamin Eberlei — 2010-09-11T20:02:38+00:00

URL: https://externals.io/message/49733#49602 · In reply to: #49601

Hey everyone,

I want to re-drop my proposal onto the table that is just a shortcut
notation for php class instantiation inside that brackets (omiting the
new keyword):

annotation := [className(classArgs*)]
classArgs := array | string | int | float | ...

Re-pasting my examples (this time from simple to complex):

[ExpectedException("InvalidArgumentException")]
[ExpectedException("InvalidArgumentException", "Expected message", 40")]

[Validation(array("type" => "EMail", "options" => array("checkMX" =>
true))]

[JoinTable(array(
  "name" => "users_phonenumbers",
  "joinColumns" => array(
    array("name" => "user_id", "referendedColumnName" => "id"),
  ),
  "inverseJoinColumns" => array(
    array("name => "phonenumber_id", "referendColumnName" => "id",
"unique" => true),
  ),
)]

The only thing new here would be the brackets [] and the implicit class
instantiation through omitting the new keyword.

i.e. [Foo("bar")] would essentially mean new Foo("bar") when
$refl->getAnnotation() is called.

greetings,
Benjamin

On Sat, 2010-09-11 at 20:24 +0200, Pierre Joye wrote: 
> 
> > […]
> 
> It seems that there is a misunderstanding about the goals of the
> annotations. They are not meant to be read by human being
> (javadoc/phpdoc/etc. are) but to be parsed automatically to be used
> for services.
> 
> In that sense, to have a syntax closed to one of the best (or less
> worst, if you are on the opposed side ;-) syntax out there (c#/.net)
> may be a good thing to do, instead of re einventing the php wheel.
> 
> Cheers,
> -- 
> Pierre
> 
> @pierrejoye | http://blog.thepimp.net | http://www.libgd.org

---

## #49603 — Stas Malyshev — 2010-09-11T22:48:31+00:00

URL: https://externals.io/message/49733#49603 · In reply to: #49601

Hi!

> It seems that there is a misunderstanding about the goals of the
> annotations. They are not meant to be read by human being
> (javadoc/phpdoc/etc. are) but to be parsed automatically to be used
> for services.

If it's for services/phpdoc, why can't it be part of phpdoc?

I see here a whole new language syntax being invented, complete with 
nested constructs, new instantiation syntax, new argument parsing rules 
and what not. All that while tiniest attempts on introducing syntax 
sugar were consistently rejected. But here we have sub-section of 
language with totally different rules - PHP has no named parameters, but 
annotations have them, PHP has no array/instantiation shortcut syntax, 
but annotations have it, etc. Please understand, I'm not objecting to a 
particular detail of syntax - I'm objecting to the fact that the design 
of the language appears to be guided by a random whim.
-- 
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227

---

## #49604 — Christian Kaps — 2010-09-12T08:30:52+00:00

URL: https://externals.io/message/49733#49604 · In reply to: #49603

Hi Stas,

this type of annotations cannot be used as PHPDoc annotations due its
different syntax. In other languages like Java, C# or AS3 annotations
are an independent language construct and I think in PHP it should be
the same. I dont know how many non-performant user-land
implementations(hacks), with different syntaxes and concepts, exists in
the meantime. So I think it is time for a consistent syntax in the PHP
core.

I see your concerns about the inconsistency in the syntax, so here are
my thoughts how we can avoid this.

1. In Java annotations are a special type of an interface. But due the
lack of type hinting for scalar values we cannot use this construct,
because we cannot put some validation logic in an interface. My proposal
is to create a new "annotation" type. This type should have the same
rules as a class and should contain all features proposed in the
ReflectionAnnotation class. With this construct it should be possible to
use named or unnamed parameters for an annotation.

annotation URL {

    public $url;
    public $title;
    public $target;

    public function __construct($url, $title, $target = 'self') {

    }
}

[URL('http://www.php.net', <http://www.php.net%27,> 'PHP', 'blank')] or
[URL('http://www.php.net', <http://www.php.net%27,> 'PHP')] or
[URL('url' = 'http://www.php.net', <http://www.php.net%27,> 'name' = 'PHP', 'target' = 'blank')]


With this new type there exists a new language construct which doesn't
overlap with the class construct. So it is possible to use its own
instantiation syntax.

2. The syntax for arrays should be the same as in PHP. So we can use the
[] as annotation separator. When we allow expressions in the form
Annotation(array('value' => 4 %2)) or Annotation(array('value' =>
!MY_CONSTANT)) which I think is a valid construct, then we cannot use
the ! or % as annotation separator.

3. For the consistency with named parameters there exists 2
possibilities. Either we implement named parameters in the PHP core or
named parameters are an exception for annotations.

I think with this changes we have a separate language construct like
traits, which does allow a new syntax.

Greetings,
Christian


Am 12.09.2010 00:48, schrieb Stas Malyshev:
> Hi!
>
> > […]
>
> If it's for services/phpdoc, why can't it be part of phpdoc?
>
> I see here a whole new language syntax being invented, complete with
> nested constructs, new instantiation syntax, new argument parsing
> rules and what not. All that while tiniest attempts on introducing
> syntax sugar were consistently rejected. But here we have sub-section
> of language with totally different rules - PHP has no named
> parameters, but annotations have them, PHP has no array/instantiation
> shortcut syntax, but annotations have it, etc. Please understand, I'm
> not objecting to a particular detail of syntax - I'm objecting to the
> fact that the design of the language appears to be guided by a random
> whim.

---

## #49605 — Sebastian Bergmann — 2010-09-12T12:34:48+00:00

URL: https://externals.io/message/49733#49605 · In reply to: #49601

> It seems that there is a misunderstanding about the goals of the
> annotations. They are not meant to be read by human being
> (javadoc/phpdoc/etc. are) but to be parsed automatically to be used
> for services.

 Annotations are part of the code and code is not only automatically
 parsed but also read by humans.

-- 
Sebastian Bergmann                    Co-Founder and Principal Consultant
http://sebastian-bergmann.de/                           http://thePHP.cc/

---

## #49606 — Pierre Joye — 2010-09-12T12:56:51+00:00

URL: https://externals.io/message/49733#49606 · In reply to: #49605

Hello Sebastian.


> 
> > […]
>
>  Annotations are part of the code and code is not only automatically
>  parsed but also read by humans.

Obviously as they write it. However the primary goal of annotations is
not to be read by human, that's why docs' exist (APIs, inline, etc.).
To make the syntax a pain to parse and make it way too different from
existing annotations syntaxes would not be good.

Cheers,
-- 
Pierre

@pierrejoye | http://blog.thepimp.net | http://www.libgd.org

---

## #49607 — Stas Malyshev — 2010-09-12T18:55:16+00:00

URL: https://externals.io/message/49733#49607 · In reply to: #49604

Hi!

> 1. In Java annotations are a special type of an interface. But due the
> lack of type hinting for scalar values we cannot use this construct,
> because we cannot put some validation logic in an interface. My proposal

I'm not sure I understand - what scalar type hints have to do with it?
Anyway, annotation can't be interface since you'd have to instantiate it 
to get the values. Interface can't have values.

> is to create a new "annotation" type. This type should have the same
> rules as a class and should contain all features proposed in the
> ReflectionAnnotation class. With this construct it should be possible to
> use named or unnamed parameters for an annotation.

I think this is very bad idea - to have language construct that is 
exactly like class but has different set of features. If named 
parameters are needed in PHP, let's add named parameters in PHP. But if 
we decide they are not needed in PHP, they shouldn't be in one 
particular corner of a particular syntax construct and nowhere else. 
This makes the language hard to learn and hard to understand - you never 
know what surprise the next syntax construct will bring you. I'm very 
strongly against only one construct in the language having named 
parameters syntax while other places don't.

> 2. The syntax for arrays should be the same as in PHP. So we can use the
> [] as annotation separator. When we allow expressions in the form
> Annotation(array('value' =>  4 %2)) or Annotation(array('value' =>
> !MY_CONSTANT)) which I think is a valid construct, then we cannot use
> the ! or % as annotation separator.

Where this expression would be evaluated, in which context? Where would 
the variable values be stored? What happens if they change?

> I think with this changes we have a separate language construct like
> traits, which does allow a new syntax.

Separate language construct doesn't mean separate rules. We are still in 
the same language, so we can't just randomly put arbitrary set of 
features together and call it a new construct. There should be some 
commonality between different language constructs within the same language.
-- 
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227

---

## #49609 — Nick Pope — 2010-09-13T10:17:05+00:00

URL: https://externals.io/message/49733#49609 · In reply to: #49604

Hi All,

There seems to be a lot of discussion as to syntax for annotations at 
the moment.  Firstly I'd like to say that I've never delved into PHP 
internals so may not understand some of the reasons why some of my 
suggestions may not work, so please don't give me a hard time about it! 
  I also have no experience with using annotations in any language per 
se.  This is just the viewpoints of an observer of this discussion.

There seem to be the following concerns:

1. Use of ! or % as a an annotation separator would conflict.
2. Use of [] would prevent the use of them as a shorthand for array()
3. Many other languages use @, but that is the PHP silence operator.
4. Annotations need their own construct and phpdoc won't suit.

I had a few options to try and address all of these:

1. Use a comment-like syntax.  phpdoc uses /** */, so perhaps trying 
something like /*! */ or /*@ */ could be answer.  If this special 
comment was parsed and treated differently to a standard comment then 
you could also use any syntax you'd like to define for annotations 
without worrying about conflicts with PHP.  (I realise that PHP does not 
know anything about phpdoc tags.)  The above are suitable if annotations 
will be allowed to span multiple lines.  Otherwise some other single 
line comment syntax could be suitable: //@ or #@.  One complaint about 
this might be the confusion of excess comments.

An advantage is that if annotations are disabled PHP will just skip over 
a comment while parsing, or, if an older version of PHP is in use, this 
is backward-compatible code.  A disadvantage is that people don't think 
of comments as being able to affect code.

class DatabaseObject {
   /**
    * A function that does something to the database object...
    */
   /*!
    * JoinTable(array(
    *   'name' => 'users_phonenumbers',
    *   'joinColumns' => array(
    *   array('name' => 'user_id', 'referencedColumnName' => 'id'),
    * ),
    * 'inverseJoinColumns' => array(
    *   array('name' => 'phonenumber_id', 'referencedColumnName' => 'id',
    *     'unique' => true),
    * ))
    */
   public function something() { ... }
}

class Mailer {
   /**
    * Send e-mail to a single e-mail address.
    *
    * @param  string  $email  An e-mail address.
    */
   #@ EmailValidation(array('options' => array('checkMX' =>  true))
   public function sendEmail($email) { ... }
}

2. If there is a problem with it being a comment, why not just tweak the 
delimiters slightly?  Surely if /* */ can be used for comments something 
like /+ +/ can't be any more awkward?  Same advantage in that you could 
switch to a different parsing context and perhaps we can leave [] in the 
eventuality they get implemented as a shorthand for array(). 
Alternatively why not try /[ ]/?

class Mailer {
   /**
    * Send e-mail to a single e-mail address.
    *
    * @param  string  $email  An e-mail address.
    */
   /+
    + EmailValidation(array('options' => array('checkMX' => true))
    +/
   public function sendEmail($email) { ... }
}

class Mailer {
   /**
    * Send e-mail to a single e-mail address.
    *
    * @param  string  $email  An e-mail address.
    */
   /[ EmailValidation(array('options' => array('checkMX' =>  true)) ]/
   public function sendEmail($email) { ... }
}

Anyway.  Just some thoughts.

Cheers,

Nick



>   Hi Stas,
>
> this type of annotations cannot be used as PHPDoc annotations due its
> different syntax. In other languages like Java, C# or AS3 annotations
> are an independent language construct and I think in PHP it should be
> the same. I dont know how many non-performant user-land
> implementations(hacks), with different syntaxes and concepts, exists in
> the meantime. So I think it is time for a consistent syntax in the PHP
> core.
>
> I see your concerns about the inconsistency in the syntax, so here are
> my thoughts how we can avoid this.
>
> 1. In Java annotations are a special type of an interface. But due the
> lack of type hinting for scalar values we cannot use this construct,
> because we cannot put some validation logic in an interface. My proposal
> is to create a new "annotation" type. This type should have the same
> rules as a class and should contain all features proposed in the
> ReflectionAnnotation class. With this construct it should be possible to
> use named or unnamed parameters for an annotation.
>
> annotation URL {
>
>      public $url;
>      public $title;
>      public $target;
>
>      public function __construct($url, $title, $target = 'self') {
>
>      }
> }
>
> [URL('http://www.php.net',<http://www.php.net%27,>  'PHP', 'blank')] or
> [URL('http://www.php.net',<http://www.php.net%27,>  'PHP')] or
> [URL('url' = 'http://www.php.net',<http://www.php.net%27,>  'name' = 'PHP', 'target' = 'blank')]
>
>
> With this new type there exists a new language construct which doesn't
> overlap with the class construct. So it is possible to use its own
> instantiation syntax.
>
> 2. The syntax for arrays should be the same as in PHP. So we can use the
> [] as annotation separator. When we allow expressions in the form
> Annotation(array('value' =>  4 %2)) or Annotation(array('value' =>
> !MY_CONSTANT)) which I think is a valid construct, then we cannot use
> the ! or % as annotation separator.
>
> 3. For the consistency with named parameters there exists 2
> possibilities. Either we implement named parameters in the PHP core or
> named parameters are an exception for annotations.
>
> I think with this changes we have a separate language construct like
> traits, which does allow a new syntax.
>
> Greetings,
> Christian
>
>
> Am 12.09.2010 00:48, schrieb Stas Malyshev:
> > […]

---

## #49613 — Zeev Suraski — 2010-09-13T13:05:57+00:00

URL: https://externals.io/message/49733#49613 · In reply to: #49601

At 20:24 11/09/2010, Pierre Joye wrote:
>
> > […]
>
>It seems that there is a misunderstanding about the goals of the
>annotations. They are not meant to be read by human being
>(javadoc/phpdoc/etc. are) but to be parsed automatically to be used
>for services.
>
>In that sense, to have a syntax closed to one of the best (or less
>worst, if you are on the opposed side ;-) syntax out there (c#/.net)
>may be a good thing to do, instead of re einventing the php wheel.

I'm not sure we've seen a good reason to add annotations instead of 
using PHPDoc.  Sure, PHPDoc isn't a perfect fit for certain purposes, 
but I think it certainly falls in the good-enough fit for most 
purposes.  It's also both machine and human readable, and best of all 
- it's already there.
There should be overwhelmingly strong reasons to add a whole new 
branch of syntax to PHP, I for one don't see the huge gain 
annotations bring on top of PHPDoc.

Zeev

---

## #49614 — Sebastian Bergmann — 2010-09-13T13:20:20+00:00

URL: https://externals.io/message/49733#49614 · In reply to: #49613

> I for one don't see the huge gain annotations bring on top of PHPDoc.

 Same here, I am satisfied with the way that annotations work, for
 instance, in PHPUnit.

-- 
Sebastian Bergmann                    Co-Founder and Principal Consultant
http://sebastian-bergmann.de/                           http://thePHP.cc/

---

Next page: https://externals.io/message/49733.md?page=2
