To the authors: Please try to bit a more consistent

I find myself repeatedly frustrated by ambiguous wording in the specification. I know the specification practically by heart,
but even that doesn’t help at times when the terms are becoming just too chaotic.

Given that I don’t expect anyone to do my bidding and spend the next two weaks correcting the plenthora of inconsistencies,
but would rather have this considered a plea for future revisions, I will save myself the effort and not publish an endless list
of issues.

Also, I know that certain terminology has become a de-facto standard despite its inconsitency, however, that shouldn’t stop
anyone from bringing it back to a consistent level.

On top of that, I’m aware that the specification is written by people who are close to, if not directly involved in
implementation. This certainly forges a specific perspective on the way things are conveyed to the “end-user” of the GL,
nonetheless I’d also ask those who’ve assumed that perspective to recall that the perspective from which an API should
be written is that of the user of the interface. And by itsself an API has in no sort of way, whatsoever, to reflect the
underlying implementation.

That said, even if the same entity can equally adequately be described by multiple terms depending on the vantage point, it
is best to choose one perspective to be held regardless of the context, because we bear the user in mind, for whom the
optimal specification (in the very meaning of the word) is minimal, unifying as much as possible into as few as possible
different concepts. No matter whether the technical realization is far from unified.

As two trivial examples of how wording can affect the understandability of the spec consider the redundant use of something
being “attached” to a binding point or something being “bound”.

Similarly, we have ARRAY_BUFFERs designated to be “Buffers for Vertex Attributes” called “Vertex Buffer Objects”. Furthermore,
we have “Vertex Array Objects” and the spec ocasionally (6.8, for example) refers to “Vertex Array”. Well, damn whomever
doesn’t eventually get confused by that.

These are just two examples of something which has become an unfortunate characteristic of the specification throughout.
The issue is less to absolutely not apparent to the person who wrote the things him- or herself, knowing what they meant by
it, but in light of its original purpose, that is, specifying the concepts cleary and uniquely to strangers, the specifiation
quickly becomes nebulous and unnecessary complex (worst of all: partly ill-defined, if a term such as “Vertex Array” is used
without clear intend).

Please take greater care of the use of terms and definitions. On behalf of all those among us who work primarily with the spec,
I thank you in advance.

Note: the following assumes that you’re talking about GL version 4.3.

Given that I don’t expect anyone to do my bidding and spend the next two weaks correcting the plenthora of inconsistencies, but would rather have this considered a plea for future revisions, I will save myself the effort and not publish an endless list of issues.

… why not? A list of issues is more likely to get fixed than a rambling generalized suggestion to “do better”. That’ll simply be dismissed.

Granted, they may dismiss a list of issues, but it’s more likely to get fixed than a general complaint. Even moreso when some of the things you complain about are demonstrably false, as seen below.

As two trivial examples of how wording can affect the understandability of the spec consider the redundant use of something being “attached” to a binding point or something being “bound”.

I did a scan through GL 4.3 for the word “attach”. I noticed one use of “attach” that should have been “bind”. That was in the section on image load/store. Every other time, the word “attach” is never used in reference to directly binding an object to the context. This is a simple specification bug, and you should file a bug report on it.

You’re probably thinking about section 5.3 of GL 4.3, where it defines the term “directly attached” and “indirectly attached” objects. That’s a temporary definition that makes the specification of section 5.3 much easier. That’s all it’s for. And those terms are used consistently within that section.

Similarly, we have ARRAY_BUFFERs designated to be “Buffers for Vertex Attributes” called “Vertex Buffer Objects”.

That only happens in section 10.3.6. That’s an inconsistency, and again, you should file a bug on it.

And the spec never called them “Buffers for Vertex Attributes”. Indeed, I searched the spec and that phrase never appears. Nor does anything like it. You shouldn’t quote something that isn’t exactly what it was where you found it.

Furthermore, we have “Vertex Array Objects” and the spec ocasionally (6.8, for example) refers to “Vertex Array”. Well, damn whomever doesn’t eventually get confused by that.

I fail to see the inconsistency. Arrays are sequences of values. Vertex arrays are sequences of values used for vertex data. Buffer objects can hold arrays that will be used for vertex data.

The term “vertex array” is very well defined in section 10.3, cleverly titled “Vertex Arrays”. It is quite literally the very first sentence of that section: “Vertex data are placed into arrays that are stored in the server’s address space (described in section 10.3.8).

So I fail to see anything that is “partly ill-defined” about the use of this term.

Also, please stop pressing ENTER at the end of lines (or adding <br> or whatever it is you’re doing). It completely messes up the formatting of your posts, making them hard to read. The forum word-wraps automatically; you don’t need to help it. Just add two lines between paragraphs.

To save myself the effort. If I were to analyze the hundreds (yes) of inconsistencies, redundancies and generally ill-worded parts of the spec, I might aswell rewrite it. Also, as is vividly illustrated by your response, it will but entail endless discussion with people like you (no offense) who’ve grown accustomed to both the perspective and the wording of the specification, eventually leading to no definite outcome, because the issue is 90% subjective.

I respond to your arguments exempli gratia. I do not wish a continued discussion about issues which I’ve provided to merely serve as an illustration of what is wrong.

I’m certain of my point. I don’t have the time nor the ambition to detail it to the last of its occurrences. That, again, is why I only ask you to keep what I say in mind.

I did a scan through GL 4.3 for the word “attach”. I noticed one use of “attach” that should have been “bind”. That was in the section on image load/store. Every other time, the word “attach” is never used in reference to directly binding an object to the context. This is a simple specification bug, and you should file a bug report on it.

You’re probably thinking about section 5.3 of GL 4.3, where it defines the term “directly attached” and “indirectly attached” objects. That’s a temporary definition that makes the specification of section 5.3 much easier. That’s all it’s for. And those terms are used consistently within that section.

In the sections other than 5.3, it’s no definition at all. As generally, few is properly defined. Terms are being used casually - the exact meaning wants to be inferred from context. But you’re spot on the issue here: We have many occurrences of “attach”, “attachment” or the-like plus we have occurrences of “bind”, “bound”, “binding point”, etc.

Why do we not call it “binding” in any case? What is the difference between “binding” something and “attaching” it, other than it being different per definitionem? Why use two different words? The answer is: Because you’ve assumed the wrong perspective. You are trying to honour a difference where to the user of the GL, there is none. Attaching a shader to a program. Why do we not bind it? Binding a RB to a FB. Why do we not bind it?

Bottom line: For the end-user who is concerned with how to employ the API to achieve a specific goal, the way these terms are used seems arbitrary at best, often contradictory.

That only happens in section 10.3.6. That’s an inconsistency, and again, you should file a bug on it.

No, I will not, because of the reasons I’ve presented. This is my “bug-report”. I’m telling of a general flaw which I assume to be because of a certain “mentality” under which the specification is often written. The subject is a matter of perspective. I will not try to argue against those who 1) have assumed a different perspective 2) are the ones making the decision, because it will be a waste of my time trying to convince them of how “my perspective” is more eligible than “theirs”. That’s why I’m sticking to what you denigrate as a “rambling generalized suggestion” and can only hope that it makes 1 out of 10 authors just slightly reconsider the wording which they put into the specifcation in the future.

And the spec never called them “Buffers for Vertex Attributes”. Indeed, I searched the spec and that phrase never appears. Nor does anything like it. You shouldn’t quote something that isn’t exactly what it was where you found it.

Table 6.1 states “Purpose of ARRAY_BUFFER: Vertex attributes”.

I fail to see the inconsistency. Arrays are sequences of values. Vertex arrays are sequences of values used for vertex data. Buffer objects can hold arrays that will be used for vertex data.

And you’re missing the point again. This is not about contradiction, this is about being confusing. Using unnecessarily many different terms, introducing new concepts where concepts are not needed. The idea of “Vertex Buffer Objects” and “Vertex Array Objects” are referred to many different times, and each time we have a slightly different wording or perspective. In one chapter the “Vertex Buffer Object” is that, and in another it’s called “Vertex Attributes”, although both refer to the same entity from the programmer’s point of view.

The term “vertex array” is very well defined in section 10.3, cleverly titled “Vertex Arrays”. It is quite literally the very first sentence of that section: “Vertex data are placed into arrays that are stored in the server’s address space (described in section 10.3.8).

So why is it not “cleverly titled” “Vertex Array Objects” but ocasionally referred to as such? Do you think an additional “Object” doesn’t make a difference to reader? It does. Do you think it should be made clear that there is a semantic difference between the entity of an array, holding the data, and an object, associated to the former? No, it should not.

Also, please stop pressing ENTER at the end of lines (or adding <br> or whatever it is you’re doing). It completely messes up the formatting of your posts, making them hard to read. The forum word-wraps automatically; you don’t need to help it. Just add two lines between paragraphs.

I used ENTER to break my lines after a certain width because the forum software visually cuts off text which is longer than that and I’d like to see what I’m writing. I figured that in “WYSIWYG” mode this doesn’t happen, so I could type normally this time.

On the subject itsself:

It’s apparent to me that discussing the issues, like I just did with the two examples I gave and to which you responded, will not lead anywere. Out of respect, I ask you to not further argue against the specific examples I gave, because I will not have part in this.

The power of my point lies in the fact that my view is unbiased and qualified per definitionem: I am the user who accesses the specification without prejudice and a great experience in API documentation.

I do not demand anything. I do not demand any bugs fixed nor any appreciation of my point by people who disagree with it, because they have a different view on things.

I’m merely describing what I consider a problem about the specification and I make the claim that by it, I’m representing all those whose view is qualified and not prejudiced by having lived “in the system” for too long (or by being part of it as an implementor, for that matter).

Out of respect, I ask you to not further argue against the specific examples I gave, because I will not have part in this.

That’s interesting. You post an accusation of the specification being unclear. I point out how your examples don’t hold water. You reply to my specific points. But then you declare that I should “respect” this and not respond to your reply?

Um, no. I’m not going to do that. As for “respect”… I’m not sure how “respectful” it is to ask someone to allow their evidence to stand unchallenged in a discussion forum. Even moreso when those arguments are based on a severe misunderstanding of how OpenGL works, as well as some undeniably erroneous claims (such as claiming the spec says “Binding a RB to a FB”. Check out 9.2.7, the first sentence. Again).

If you’re looking to make claims without having those claims vetted or challenged, I would suggest getting a blog. This is a discussion forum; what you say here will be challenged if others feel the need to do so. You don’t get to decide when that is or is not appropriate.

The power of my point lies in the fact that my view is unbiased and qualified per definitionem: I am the user who accesses the specification without prejudice and a great experience in API documentation.

First, I’m hoping that you don’t expect your gratuitous use of Latin phrases to win you points. Because really, it’s just making your argument look hollow because you feel that you need to dress it up in ostensible finery in order to make it seem more legit.

Second, I contest your claim of being “without prejudice”. Actually, I take that back: [i]you[/i] already contested this claim; you stated that you were “welcomed with quite a lot of ignorance” on other OpenGL fora and discussion places. You clearly have a history of arguing against the OpenGL API. So let us dispense with this pretense of a “per definitionem” “unbiased” perspective.

Third, and most importantly, the fundamental foundation of your problem is your attempt to treat a specification as “API documentation”. Let me be as clear as possible: a specification is not API documentation. A specification is a precise document that explains how something works. Documentation explains how to use something. Similar in concept, but very different in execution.

Your “experience in API documentation,” is not going to prepare you for reading any specification, whether OpenGL, C++, or any other detailed specification. Most C++ users can’t even follow the C++ specification; they’ve learned by route or by general guidelines, not the actual rules of the Specification for Programming Language C++.

Specifications aren’t documentation. Documentation is intended to be used by people who are learning to use something. Specifications are intended to be used by people who are implementing the specified system.

Whether technical or engineering, a specification must be very explicit about things, to a level of pedantry and OCD that mere documentation generally doesn’t care about. So concepts that casual documentation might ignore or blend together cannot be ignored or blended in a specification. A specification must specify and it must be precise.

Think of it as the difference between a mere agreement and a legal document. The latter is a specification. To expect easily digestible language from a legal document is folly; that’s not what it’s for. It’s for precisely spelling out the terms of an agreement.

For example, the terms “Vertex Buffer Object” (which again, is only used in one section of the spec) and “Vertex Attributes” do not refer to the same thing. A user might conceptually conflate the two. Documentation might blur the line between them. Tutorials might ignore the distinction between them. But a specification never can. Why? Because they are two distinct concepts. Since they are two distinct concepts, the OpenGL specification doesn’t have the luxury to pretend that they’re the same. It must specify behavior precisely. And precision requires specificity.

For the record, “Vertex Buffer Objects” are buffer objects that provide storage for vertex arrays. “Vertex Attributes” are vertex shader input variables, who’s data might come from arrays provided by VBOs, but they can also come from other sources.

A user could ignore this distinction. Granted, not a user who’s read my tutorials or my wiki articles (and frankly, I would consider a user to conflates them to be under-educated about OpenGL). But a user in general could ignore this distinction, and in casual conversation you might refer to one of these as the other.

But the specification cannot ignore it, because it needs to be able to talk about things precisely. It can’t say that a in vec4 position; definition in a vertex shader defines a “Vertex Buffer Object”. Because that’s not true; in reality, in the OpenGL graphics system, that definition has no direct connection to any buffer object. The term for that definition is “Vertex Attribute”; to call it a “Vertex Buffer Object” would be confusing to anyone trying to implement OpenGL.

The same goes for “Bind” vs. “Attach”, only this is something that a user cannot ignore (and if you’ve ignored it, you’re not really thinking about it).

For the record, “binding” an object to the context means that the object is now part of the OpenGL context’s state. Functions that modify state from objects of that type can now modify that object’s state. It also means that the given object can now be directly used for rendering purposes. “Bind” is consistently used for this purpose, and every function of the form glBind* does this.

“Attaching” an object always means associating one object with another. The result of this operation never means that you can modify the object; calling glFramebufferTexture doesn’t let you call glTexImage2d like you can after glBindTexture. Objects that are attached to another object can only be used in rendering operations if the container object is itself bound to the context. They’re two different operations, and therefore they have two different names.

These distinctions are not arbitrary. They’re important. They matter to how things are defined. They matter to the expected behavior of the OpenGL graphics system.

Your problem is that you’re asking for lazy wording in a specification. You want different concepts that have some similarities to use the same terms. Well, a specification can’t do that. A specification can’t be lazy, because the entire purpose of a specification is to be precise.

Unless you like your legal documents to be lazy too.

The closest thing to a real point you make is that many terms do not have explicit definitions (though, as previously stated, “vertex array” is not one of them). Many terms are only defined implicitly: by how the term is used, not by an explicit paragraph of text. For example, the bind vs. attach distinction is entirely explicit: it’s based on what operations are called “bind” and what are called “attach”. By consistently using the terms correctly, the definition is created implicitly. But there’s no explicit definition.

Explicit definitions for all terms would be nice.

I do not wish a continued discussion about issues which I’ve provided to merely serve as an illustration of what is wrong.

I’m certain of my point.

I know you’re certain of it and sincerely believe that this problem exists as you have defined it.

That doesn’t mean you’re right. If you want to put forth a proposition that something needs fixing, you must first provide evidence that it’s broken. Otherwise, it’s just pointless noise. It’s no different than saying, “OpenGL needs a way to allow normalized integers to be used in vertex formats.” Yeah, we already have that, thank you.

I’m merely describing what I consider a problem about the specification and I make the claim that by it, I’m representing all those whose view is qualified and not prejudiced by having lived “in the system” for too long (or by being part of it as an implementor, for that matter).

So you’re claiming to speak for everyone who isn’t already familiar with OpenGL. I would be interested to see any proof that might support your claim that this is a problem for people beyond yourself.

I remind you that the OpenGL specification is not documentation and should not be treated like it is.

Oh, and one factual error:

The answer is: Because you’ve assumed the wrong perspective. You are trying to honour a difference where to the user of the GL, there is none. Attaching a shader to a program. Why do we not bind it? Binding a RB to a FB. Why do we not bind it?

That’s wrong and you know it. From the very first sentence of section 9.2.7 of GL 4.3 core: “A renderbuffer can be attached as one of the logical buffers of a currently bound framebuffer object by calling…”

If you’re going to argue that the spec is inconsistent, at least have enough respect for people reading your post to get your facts straight. I shouldn’t be able to nullify your evidence with a spec quote; that’s a sign of laziness and a lack of research on your part.

And people reading your “argument” deserve better than that.

[QUOTE=Alfonse Reinheart;1249633]That’s interesting. You post an accusation of the specification being unclear. I point out how your examples don’t hold water. You reply to my specific points. But then you declare that I should “respect” this and not respond to your reply?

Um, no. I’m not going to do that. As for “respect”… I’m not sure how “respectful” it is to ask someone to allow their evidence to stand unchallenged in a discussion forum.[/QUOTE]

You mistook my intend, which was not to silence you, but to warn you that any further arguments against those very specific examples will go ignored by me (thus, “out of respect”).

Even moreso when those arguments are based on a severe misunderstanding of how OpenGL works, as well as some undeniably erroneous claims (such as claiming the spec says “Binding a RB to a FB”. Check out 9.2.7, the first sentence. Again).

A typo(ish). I meant to write “attach” so “Binding a RB to a FB. Why do we not bind it?” should have been “Attaching a RB to a FB. Why do we not bind it?”.

First, I’m hoping that you don’t expect your gratuitous use of Latin phrases to win you points. Because really, it’s just making your argument look hollow because you feel that you need to dress it up in ostensible finery in order to make it seem more legit.

I’d be tempted to reply in Latin, just to ridicule your much-unneeded ad-hominem. But unfortunally, I don’t speak Latin. And I don’t pretend to. But please allow me to use Latin phrases whereever I deem them adequate without alleging that I had ulterior motives. I’d grant you the same liberty.

Second, I contest your claim of being “without prejudice”. Actually, I take that back: [i]you[/i] already contested this claim; you stated that you were “welcomed with quite a lot of ignorance” on other OpenGL fora and discussion places. You clearly have a history of arguing against the OpenGL API. So let us dispense with this pretense of a “per definitionem” “unbiased” perspective.

The (un)biasedness I was referring to in my reply concerns the bias towards the phrasing of the specification. I don’t harbor any bad feelings towards the specification per-se, why should I? Neither do I think you have any specific feelings in favor of it. The bias comes from 1) your perspective as to which exact information the specification should convey and 2) knowing what is meant even though what is actually said might be unclear.

Third, and most importantly, the fundamental foundation of your problem is your attempt to treat a specification as “API documentation”. Let me be as clear as possible: a specification is not API documentation. A specification is a precise document that explains how something works. Documentation explains how to use something. Similar in concept, but very different in execution.

Our definitions of the respective terms disagree. I equate documentation and specification or even reference and specification (not: “tutorial and specification” or “user manual and specification”). Admitted, “documentation” could be seen as a broader term, but that’s not what I had in mind. The very purpose of a specification, documentation or reference is to non-redundantly and completely specify (document) the behaviour of just anything. I don’t see how in this regard an API documentation (such as one generated by DOXYGEN, published by the W3C, ISO for C99, IETF RFCs or, if absolutely necessary, even C++) is any different from what is supposed to be the specifcation of the GL API.

Your “experience in API documentation,” is not going to prepare you for reading any specification, whether OpenGL, C++, or any other detailed specification. Most C++ users can’t even follow the C++ specification; they’ve learned by route or by general guidelines, not the actual rules of the Specification for Programming Language C++

Specifications aren’t documentation. Documentation is intended to be used by people who are learning to use something. Specifications are intended to be used by people who are implementing the specified system.

Whether technical or engineering, a specification must be very explicit about things, to a level of pedantry and OCD that mere documentation generally doesn’t care about. So concepts that casual documentation might ignore or blend together cannot be ignored or blended in a specification. A specification must specify and it must be precise.

Think of it as the difference between a mere agreement and a legal document. The latter is a specification. To expect easily digestible language from a legal document is folly; that’s not what it’s for. It’s for precisely spelling out the terms of an agreement.

Given what I said above, my experience in what you consider specification is vast and substancial. I’ve made my ways through books of what was an imposition of page-over-page of EBNFs and I hardly ever have used tutorials or guides to become knowledgable of a subject. I know what to expect and I know what I may expect. Also, I recognize the patterns of badly written specifications or parts therein. And I’m sorry to say that while OpenGL does have its glorious parts, it is evident that it was designed and written by implementors with little experience in library design.
Further, I attribute the overall state of the specification to how Khronos works. To how extensions from multiple sources find their way into newly released standards without undergoing any major revision or unification. That, of course, prevents a clean, unified API, as it could be expected if it was designed by “a single mind”, so to speak.

Your problem is that you’re asking for lazy wording in a specification. You want different concepts that have some similarities to use the same terms. Well, a specification can’t do that. A specification can’t be lazy, because the entire purpose of a specification is to be precise.

These are two distinct issues: One the one hand we have the need for the specification to be absolutely precise. On the other hand, we have the freedom to design an API widely independently of the underlying implementation. This might appear like a silly example (I’m deliberately refraining from resorting to examples which can be lengthly discussed) and might not even be true, but it illustrates the point about API design. Perhaps you even agree:

Even though Framebuffers, Renderbuffers, Buffer Objects and any other sort of object are completely different in their purpose, function and capabilities, nothing would stop you from defining an “object orientented like” API in which all objects are created through a glNew( enum object_type ) call. Similarly, nothing prevents us from having a single notion of “binding” something to something else, achieved through glBind( uint source,uint target ) or glBind( enum sourcetype,uint source,enum targettype,uint target). These are just two examples I quickly made up and which - I admit - may not even work out in all of their detail, but the point is: An API is free to unify virtually everything as long as no ambiguities arise.

The closest thing to a real point you make is that many terms do not have explicit definitions (though, as previously stated, “vertex array” is not one of them). Many terms are only defined implicitly: by how the term is used, not by an explicit paragraph of text. For example, the bind vs. attach distinction is entirely explicit: it’s based on what operations are called “bind” and what are called “attach”. By consistently using the terms correctly, the definition is created implicitly. But there’s no explicit definition.

Explicit definitions for all terms would be nice.

Indeed it would. To my impression though, this is just one of a dozen of characteristics which illustrate that there should have gone more rigor into the specification. I did not mean to make the following point in this thread for I meant to only adress a certain lack of consistency, but after the severe contra you give me on the subject, I can’t but mention that the enormous amount of forward-references (speaking of terms which are only defined much later) is another indicator for the illness that resides in the OpenGL specification. Some of these issues are being adressed; very slowly they are. Esp. the 4.x series has received what appears to be a significant overhaul of the structure, but it is not enough. Another thing that I consider typical of immature software APIs is the way the GL tries to anticipate backwards compatibility and in the attempt bloats the API with nonsense such as “function f takes a parameter, that parameter must always be 1” (if you know what I’m referring to).

I don’t reckon this to bear great consequences. I will not turn from OpenGL no matter how horrible I consider the state of the API and specifcation thereof. And neither will other people, I think. But my plea holds the promise that if more effort would be put into writing a clear, consise specifiation, with a deliberate user-centric API in mind, the GL would be much more accessible and efficiently used. Certainly, it’s too late to unify the GL API. But the least thing we can do is unify the concepts in the documentation, even if the actual API (such as function names) remains unnecessarily convoluted.

I know you’re certain of it and sincerely believe that this problem exists as you have defined it.

That doesn’t mean you’re right. If you want to put forth a proposition that something needs fixing, you must first provide evidence that it’s broken.

I don’t have to. “Either you get it or you don’t.” Or, somewhere in between. I repeat: The issue is subjective. The specification is complete and, to my knowledge, not self-contradictory as it stands. My concern is with what I recognize as a weakness in its general style.

My perception of the issue goes unchallenged. The only thing that I want you to believe is that I do qualify for making such a judgement, and, moreover and much more important, that it applies not only to me, but to almost everyone new to the GL and thus, poses an issue in the specification itsself, because latter’s whom it’s supposed to adress. Most people swallow things as they are. I can relate. I spend an hour in this thread (and so did you, I know) without any great hope that it will actually change anything, why should I bother? But I’m willing to try. Not trying to point out “this and that”. All I’m trying to achieve is to make the authors question their perspective, and even if it’s just for a second.

And, for God’s sake, I guess you are right: I should never have started with examples but now I should at least see them through:

10.3 specifies “Vertex Arrays”. So let’s say this is the proper definition of those entities. Then there is notion of “Generic Vertex Attribute Arrays”. Also, we have notion of “Vertex Buffer Objects”, we have mention of “Generic Attribute Arrays” (without the “Vertex”). Furthermore “Generic Vertex Attributes” (mentioned in 10.3.3, but reffering to an array of such attributes as a whole rather than just one single attribute), “Generic Attribute” (10.3.4, this time, however, actually referring to a singular element of an array), shortly followed by “Vertex Array Element” and “Generic Attribute Array Element”. Also, we have “Vertex Data” mentioned, “Vertex Array Data”, and “Vertex Attribute” (without the “Generic”). The plural “Vertex Attributes” can be found in table 6.1 again. The type of the buffer is then indicated by “ARRAY_BUFFER”. This makes 13 terms, and I found them by just a quick glance over the relevant chapters. I bet you can find more if you look closely. 13 terms for describing a single concept.

And I readily believe you’re able to justify how every one of them is a bit subtly different from the other. A matter of perspective.
And I can admit that this might not be a huge deal by itsself.
The huge deal comes from that this pattern of vague prosa and lack of concise, straight-forward defintion is predominant throughout every single chapter of the specification and even spans the specification as a whole. And Vertex Arrays is just the unlucky subject I happend to pick in my first post, it’s not even the worst.

Our definitions of the respective terms disagree. I equate documentation and specification or even reference and specification (not: “tutorial and specification” or “user manual and specification”).

Here’s the part you don’t seem to understand: the term “specification” is not something you get to define; it already has a definition. Your argument basically boils down to “specifications should be different from how they’re currently written.” It’s not “me” you’re disagreeing with. It’s the world.

If you reject a commonly-agreed-upon definition, you can’t complain when everyone else ignores what you have to say. The OpenGL specification could use some further reworking. And it does have some terminology issues here and there. But the specification does not conform to what you want because it is not supposed to.

I don’t have to. “Either you get it or you don’t.” Or, somewhere in between. I repeat: The issue is subjective. The specification is complete and, to my knowledge, not self-contradictory as it stands. My concern is with what I recognize as a weakness in its general style.

My perception of the issue goes unchallenged.

You are not Humpty Dumpty, and the world is not Wonderland. You cannot make words mean what you want them to. Your “perception” requires language to mean something other than its widely agreed upon meaning. Therefore, your “perception” is wrong.

That’s not subjective; that’s objective.

Admitted, “documentation” could be seen as a broader term, but that’s not what I had in mind. The very purpose of a specification, documentation or reference is to non-redundantly and completely specify (document) the behaviour of just anything.

No it is not.

The purpose of documentation, especially reference documentation, is to convey information, such that the reader understands something. The purpose of a specification is to exactly specify the behavior of something.

Reference documentation is best broken down into units based on how the user wants to absorb information. That is why they’re generally based around function calls and so forth. Specifications are not.

For example, the C++11 specification’s discussion of the functioning of braced-init-lists in section 8.5.4 says how they work. But they don’t say where they can be used. This is poor organization for reference documentation, because the first question a user who is interested in braced-init-lists will ask is “where can I use them?” The answer to that question is scattered through the entire specification (collated in the full grammar in appendix A). That is makes for a poor reference, but a good specification.

All the implementer of C++11 needs to know is how a construct is expected to work and the full grammar. Where it can be used is part and parcel of implementing those features where braced-init-lists can be used. It’s good specification also because, if you collated all of the places where braced-init-lists could be used in 8.5.4, you’d still have to talk about using them in the places where they are used. So you’d have copies of information. Duplicate information is bad specification, if for no other reason than the fact that they can get out of sync.

Or look at it this way. On the OpenGL Wiki, the article for Vertex Shaders has a section describing how to associate shader inputs with attribute indices. But so does the article on Vertex Attributes. Why? Because that’s good reference documentation; it answers the user’s questions, thus providing comprehensive information to the user. But the specification only explains this once. That’s good specification, but relatively poor documentation, since a description of what an attribute is (section 11.1.1) comes after talking about how you feed them (section 10).

Reference documentation is meant to be absorbed piecemeal. Specifications are not.

I can’t but mention that the enormous amount of forward-references (speaking of terms which are only defined much later) is another indicator for the illness that resides in the OpenGL specification

Let’s consider this. If you’re correct that forward referencing material is wrong for the OpenGL specification, then I should be able to find many other technical specifications that don’t forward reference.

What about C++11(PDF)? Nope; it forward references 20x more than OpenGL despite only being twice as long. What about the XML 1.1 standard? Nope, it forward references a lot too.

If these other big, important standard specifications, written by two separate organizations mind you, use forward referencing a lot… maybe that’s just how standard specifications are written. If every specification has this “illness”, then you need to consider that the “illness” is not a disease.

These are two distinct issues: One the one hand we have the need for the specification to be absolutely precise. On the other hand, we have the freedom to design an API widely independently of the underlying implementation. This might appear like a silly example (I’m deliberately refraining from resorting to examples which can be lengthly discussed) and might not even be true, but it illustrates the point about API design. Perhaps you even agree:

Even though Framebuffers, Renderbuffers, Buffer Objects and any other sort of object are completely different in their purpose, function and capabilities, nothing would stop you from defining an “object orientented like” API in which all objects are created through a glNew( enum object_type ) call. Similarly, nothing prevents us from having a single notion of “binding” something to something else, achieved through glBind( uint source,uint target ) or glBind( enum sourcetype,uint source,enum targettype,uint target). These are just two examples I quickly made up and which - I admit - may not even work out in all of their detail, but the point is: An API is free to unify virtually everything as long as no ambiguities arise.

… now I’m confused. How did we get from “the specification is poorly worded” to “the API needs to be rewritten”? These are completely different conversations.

How do you get that far off-topic of your own topic? Or is this really just a way to back-door a discussion of how the API is bad?

And I readily believe you’re able to justify how every one of them is a bit subtly different from the other. A matter of perspective.

No it isn’t; it’s a matter of facts. The facts in question being “what the specification says.”

Some of what you suggested are legitimate grievances. For example, “generic vertex attribute arrays” is a synonym for “generic attribute arrays”; there’s no point in using both terms. So that’s an editorial issue that should be ironed out. But there are differences between other terms that you choose not to recognize.

For a specification, “different” is all that matters, no matter how “subtle” that difference may be. If two concepts are different (such as “vertex attribute” being a superset of “generic vertex attribute”. They are related but by definition different) then they need distinct terms which must be used consistently. Those differences exist, and therefore the specification must recognize them.

To ask for the specification to ignore those differences is to ask for the specification to be broken.

[QUOTE=Alfonse Reinheart;1249641]Here’s the part you don’t seem to understand: the term “specification” is not something you get to define; it already has a definition. Your argument basically boils down to “specifications should be different from how they’re currently written.” It’s not “me” you’re disagreeing with. It’s the world.

If you reject a commonly-agreed-upon definition, you can’t complain when everyone else ignores what you have to say. The OpenGL specification could use some further reworking. And it does have some terminology issues here and there. But the specification does not conform to what you want because it is not supposed to.

You are not Humpty Dumpty, and the world is not Wonderland. You cannot make words mean what you want them to. Your “perception” requires language to mean something other than its widely agreed upon meaning. Therefore, your “perception” is wrong.

[…][/QUOTE]

You keep excusing poor wording and incomprehensibility by the need for being exact. By your own words, something which is understandably written cannot possibly be a specification because “a specification has to be exact”.

You know what I think this is? Elitism.

You’re so on terms with the spec that you are no longer able to spot the poor wording, the ambiguities, the lack of clarity, because you already know how every sentence ends before you’ve finished and. And then comes the pride: “This is no ordinary documentation! No, by far not! A documentation… Pfft… A Spe-ci-fi-ca-tion, however - that has to be exact! A specification doesn’t allow lazy wording! Oh no! A specification has to […]”.

For christ’s sake, drop it. I said that a specification is to non-redundantly and precisely define something. And you allege I was defining the term “specification” to my liking like “Humpty Dumpty”? Really?! Do you even read what you (I) say? If anything, I was disagreeing on the use of the term “documentation”. And that’s completely irrelevant to our discussion.

A specification can as well be criticized with regard to its clarity as any other documentation. So if you happen to intent to drag this argument of yours out further and make it the foundation of your reasoning (which you currently seem to do): Don’t. It won’t deserve any response.

… now I’m confused. How did we get from “the specification is poorly worded” to “the API needs to be rewritten”? These are completely different conversations.

How do you get that far off-topic of your own topic? Or is this really just a way to back-door a discussion of how the API is bad?

You might aswell drop these poor polemics. I know it’s off-topic and (if you had read, which I assume you did) you know it’s not that far off-topic, because the “implementor’s perspective” is naturally reflected in both: The API itsself and the documentation for it.

Some of what you suggested are legitimate grievances. For example, “generic vertex attribute arrays” is a synonym for “generic attribute arrays”; there’s no point in using both terms.

You bet there isn’t. And this was one example of hundreds I don’t consider worth finding and listing, because it would be too much effort. But here, let me just open the reference and pick the first best sentence that I can spot on that page, to show you how easily one finds these “legitimate grievances”:

7.8 Shader Buffer Variables and Shader Storage Blocks: The second sentence (the first one seems all right to me):

“Sets of buffer variables are grouped into interface blocks called shader storage blocks”.

Now let us dissect that seemingly all-right sentence:

“Sets of buffer variables”: Okay. No complaint here. This is the non-ambiguous subject of the sentence.

“are grouped into”: You may not notice it, but that statement (as is the whole sentence) is pointless. What does “grouped” actually mean? Is it something like “they are considered to be part of”? Grouping is not defined anywhere.

Well, whatever it is: I don’t care. No one does. When I read a specification, I care about clear definition of actual behaviour and terms describing the latter. I don’t care if the author considers a set of entities a “bunch”, a “group” or a “horde”.
It’s an additional sentence without information the sole purpose of which is to convey a certain “feeling” of the situation. When I read a specification, I give every sentence the same weight. 100% relevance. I can’t be bothered to figure out how important a certain statement is. I consider it a definition. And when I read something like “Sets of buffer variables are grouped into interface blocks called shader storage blocks” I will memorize the useless information that the term “grouping of sets of buffer variables” is defined to mean that, althought I will never find use for applying that information again.

The problem is, if this happens ten times on each page, in almost every second sentence, the “specification” becomes a book of endless prose, with a minimal information-to-text ratio.

But let’s not stop here. Although we’ve determined that the sentence is either useless because the lack of technical definition of the term “grouped” or it is to be the definition of “grouped” itsself, we have more work to do:

“interface blocks called shader storage blocks”: Now isn’t that lovely. So we have established three terms for the same entity (sets of buffer variables) within one sentence. Even better: Instead of calling those “groups” “buffer variable blocks” or even “buffer variable groups”, we’ve extended our vocabulary by a completely different word. And a huge vocabulary is good, right? It makes you elloquent!

No it isn’t. The point of a specification is not to be elloquent nor to immerge the reader into its fictional world (latter of which the GL spec is extremely guilty of). A specification is supposed to use a minimum of defined terms to achieve a maximum of clarity and non-ambiguity.

So that’s an editorial issue that should be ironed out.

I’m glad we’re clear on that. And now consider the fact that this (as the one above), was just the first best thing that came to notice when I opened the spec and picked a random sentence. What does that tell you about the probability of the number of “editorial issues” throughout the specification as a whole? You don’t have to be a genius to realize the specification is cluttered by issues of this kind, which together are worse than their sum.

Also, consider that redundant terms are likely just the tip of the iceberg - the most obvious issue. One, even someone like you easily recongizes (again, no offense) as such, and there’s a hidden fields of much more subtle problems which greatly affect the clarify of the specification for someone who doesn’t already know what it says.

PS: W.r.t. “forward references”: I’ve worked with W3C specs for years and I’ve never found them to have such an extensive use of forward references I find in the GL spec - let alone as unclear as the GL spec.

There is yet another thing I’d like to add with regard to foward references. It is not occurence of forward references alone, that takes from clarity. It is particularly the way they are made: Casually, mentioning the term has if it had been properly defined or the reader, at this point had already encountered it, where in fact, the first mention of it comes much later. This is in stark contrast to the clean, comprehensible style of the XML specification or even the C++ specification where references are explicit and clearly denoted as such.

This goes in line with the general, casual “prose” style of the GL specification and it conceals recursive definition or at least does not clearly distinguish between informative and normative content. If a forward reference is made in a normative manner, the document should be restructured. If it’s made in an informative manner, it should be marked as such. The GL spec remains casual in its formulation and indecisive in what it considers normative defintions and what is only supplementary (background) information.

All together, the specification fails to deliver exactly those features which are expected of a specification. As I said repeatedly now, it may be complete and non-contradictory (two objective criteria) but there is more to a good specification than that. Namely, clarity, which it lacks.

ManDay, your knew so you’re probably not aware that Alfonse is well known on these forums for being a useless cunt. While he is very negative his opinions do not actually affect OpenGL in any form, even though he may give the impression that they do.

ManDay if you have particular specification bugs to report, you have the link. otherwise i don’t get the point of sitting and bitching here. Alfonse Reinheart - really? you could just write “If found a specification bug, you may file a bug report on it. If you just have vague complaints - no one will pay attenton.” but i guess you like arguing on the internet and writing gigantic posts no one will probably read.

Although he can definitely speak for himself, Alfonse at least doesn’t go around calling fellow board members useless ****s. You should actually be banned for such remarks. Not to mention, that the majority of the official OpenGL.org Wiki is Alfonse’s work. glLoadGen is another one which is actually pretty awesome. But hey, Mr. 27-posts surely has much more merit to be recognized by the community…

You may disagree with his strong opinions and coming on pretty strongly on pretty every controversial topic, but your insults don’t do any good.

[QUOTE=thokra;1249738]. But hey, Mr. 27-posts surely has much more merit to be recognized by the community…
.[/QUOTE]

I don’t post here very often, specifically to avoid getting responses from Alfonse.

Edit: Did I give the impression I have more merit?

Foobarbazqux, I’ve deleted your post. Knock off the vulgar language and name calling. You’re free and encouraged to cite your own opinions, but please keep it civil. Cite facts or experience as backup for your opinions, or no one will pay any attention to your posts.

now it looks like thokra responded to me because you removed citation frame from his post.

Edit your post and insult Alfonse, then it will fit again! :smiley:

You keep excusing poor wording and incomprehensibility by the need for being exact. By your own words, something which is understandably written cannot possibly be a specification because “a specification has to be exact”.

You know what I think this is? Elitism.

A specification can as well be criticized with regard to its clarity as any other documentation.

An ad hominem and a strawman. That’s a double-fallacy score :wink:

I never said that a specification can’t be criticized for clarity. I said that your criticisms are generally invalid. I’m arguing against your argument, not that everything is A-OK in the spec.

Your criticisms are not all criticisms. Your criticism is that the specification is systemically unclear and poorly specified. I don’t agree. What evidence you graciously provide generally appears less than solid, as I’ve picked apart most of it. A few misuses of terminology here and there do not constitute the kinds of systemic issues you claim exist.

And this was one example of hundreds I don’t consider worth finding and listing, because it would be too much effort.

If you don’t actually want to find the “hundreds” of examples you claim that exist, then you don’t want the problem to be fixed. You want to complain. You’re like the person who calls tech support because he’s having a problem with his computer, but the only information he provides is “it doesn’t work.”

So my question for you is this: do you just want to complain and get stuff off your chest? Or do you want to actually get something substantive changed in the spec? Because complaining won’t actually do that; years watching this forum prove that. If you have specific grievances, file bugs on them (not that this guarantees anything of course). If you refuse to find specific grievances and just want to say, “rewrite the whole spec. Again,” then you’re not being part of the solution.

But here, let me just open the reference and pick the first best sentence that I can spot on that page, to show you how easily one finds these “legitimate grievances”:

7.8 Shader Buffer Variables and Shader Storage Blocks: The second sentence (the first one seems all right to me):

“Sets of buffer variables are grouped into interface blocks called shader storage blocks”.

Now let us dissect that seemingly all-right sentence:

“Sets of buffer variables”: Okay. No complaint here. This is the non-ambiguous subject of the sentence.

“are grouped into”: You may not notice it, but that statement (as is the whole sentence) is pointless. What does “grouped” actually mean? Is it something like “they are considered to be part of”? Grouping is not defined anywhere.

… I just want to be clear on this. You are now claiming confusion about the meaning of a plain English word, yes?

Let’s compare this with a sentence from C++11 by analogy:

“tuples are heterogeneous, fixed-size collections of values.”

The terms “heterogeneous”, “fixed-size”, and “collection” are never defined anywhere. However, all of them are in the dictionary (save fixed-size, which is a compound term made from two dictionary terms). So… that’s where you find their definitions. If you don’t know what they mean, you look them up.

“Grouped” is not a “technical term”; it is a word in the English language: “to place or associate together in a group, as with others.” It doesn’t need a definition, just like “sets”, “are”, and “into” don’t. Indeed, you could make the exact same argument against “Sets of buffer variables” by declaring that the word “sets” hasn’t been defined yet. So your singling out of the word “grouped” doesn’t really make sense here.

So let’s substitute the definition into the sentence: “Sets of buffer variables are associated together in a group in interface blocks called shader storage blocks.”

Sadly, failing to use a dictionary does not constitute a “legitimate grievance”.

I’m guessing that your next argument will be that some dictionary words are technical terms (like “bind” and “attach”), while others have their obvious meaning (like “sets” and “grouped”). So let me just head that off.

The specification is quite clear on the meaning of the binding of objects; it has a whole section that introduces the concept (section 2.4). So “bind” is clearly defined and consistently used. While “attach” is used as a technical term, the dictionary definition for the term is sufficient since it is consistently and only used when describing object-to-object linking.

The specification explicitly says that “bind” means “to context”, and it is never used in its dictionary definition. And it never uses “attach” to mean “to context”. So it never needs to come out and explicitly say that “attach” only involves object-to-object linking.

And thus there is no confusion. Well, save for what you make for yourself by asking why it isn’t always called “bind”, even though it’s clearly two different kinds of operations. If you take the spec at face value, there’s nothing to be confused about.

“interface blocks called shader storage blocks”: Now isn’t that lovely. So we have established three terms for the same entity (sets of buffer variables) within one sentence. Even better: Instead of calling those “groups” “buffer variable blocks” or even “buffer variable groups”, we’ve extended our vocabulary by a completely different word. And a huge vocabulary is good, right? It makes you elloquent!

No it isn’t. The point of a specification is not to be elloquent nor to immerge the reader into its fictional world (latter of which the GL spec is extremely guilty of). A specification is supposed to use a minimum of defined terms to achieve a maximum of clarity and non-ambiguity.

Let’s look at this sentence, but instead we’ll replace all of the technical terms with placeholders:

Sets of X are grouped into Ys called Z.

What this sentences says is obvious, regardless of what X, Y, and Z are: it defines a relationship between the three terms. It tells us that there are component parts X, sets of which can be grouped into things called Y. The specific name for such things are called Z.

The relationship between these terms is quite simple: Z is a specialized form of Y. Specifically, it is a Y that is made up of X’s; Y could theoretically be made of other things, but when Y’s are made of X’s, they are called Z’s.

In order for this relationship to exist and be discussed effectively, we must have three terms. We need a term for X, the atomic unit that can be grouped. We need a term for Y, the generalized grouping of things, which could be X’s or something else. We need Y, because we need to be able to talk about all groupings of this kind, whether they contain X’s or not. And we need a term for Z, which is a specialized form of Y that groups only X’s; thus allowing us to talk about this specific kind of grouping.

Therefore, we need a minimum of three terms to talk about this stuff. The specification is therefore using “a minimum of defined terms.” Therefore, by your own definition, the spec is fine on this point.

Now, you can argue that the specification could call “shader storage blocks” by a name more closely related to “buffer variables”. And to be honest, I wouldn’t disagree. However, even if they were called “buffer variable blocks”, that would still be a different defined term from “buffer variable”. It would be more obviously related to “buffer variable blocks”, but it’d still be a different term with a different meaning.

So you wouldn’t be changing the number of defined terms in the specification. You’re just picking different words for them.

And quite frankly… it’s too late for that. Even if the ARB wanted to use the name “buffer variable block”, there are already a half-dozen enumerators called “SHADER_STORAGE_…”. They’re not going to break existing code… well for any reason, but especially not just because someone might have come up with a better name for something.

Also, there is an actual reason why it’s not called “buffer variable block.” Because then you would have to call the buffer object storage for them “buffer variable buffer object.” This is a very odd name, what with the double reuse of “buffer” with two different meanings. Now maybe they should have called “buffer variables” something else, like “shader storage variable”. But then, how do you declare them in GLSL? With the “shader_storage” qualifier? “buffer” is much simpler and shorter.

But ultimately, this is all semantics and irrelevant. It’s just a term. You could argue that one would be easier to learn than the other. But the specification doesn’t pick terminology based on how easy they are to learn. Nor is it wrong for not doing so. As long as the specification consistently uses the same terms for the same concepts, and does not use different terms for the same concept, it’s fine.

There is yet another thing I’d like to add with regard to foward references. It is not occurence of forward references alone, that takes from clarity. It is particularly the way they are made: Casually, mentioning the term has if it had been properly defined or the reader, at this point had already encountered it, where in fact, the first mention of it comes much later. This is in stark contrast to the clean, comprehensible style of the XML specification or even the C++ specification where references are explicit and clearly denoted as such.

Let’s test this theory.

The first use of the term “braced-init-list” in N3337 for C++11 (PDF) is in section 5.2, folio page 93. It states, “A braced-init-list shall not be used with the built-in subscript operator.” The actual definition of this term is in section 8.5.4, folio page 199. The first use of the term “template” is at the start of section 3; it is not actually defined until section 14.

In neither place is there an “explicit” or “clearly denoted” reference to where these terms are defined. Sometimes the C++ specification will provide a section number when referencing a term, and sometimes it won’t.

The only difference is the fact that the C++11 specification italicizes all of its terminology, whereas OpenGL reserves italics almost exclusively for function argument names. If you want to claim that the specification should have some special formatting for all of its technical terms, I wouldn’t disagree. Obviously it can’t be italics, but it could be something else.

And why is that? Why are vague complaints which are supposed to provoke - even if just a little - reconsideration not worth paying attention to? I find this attitude unworthy of any critically thinking being.

“Either it has a Bug-Number, or I ignore whatever it has to say!”

Well, suit yourself, if that’s the case. Because a “vague comment” is exactly what this is and what I mean it to be.

PS: Thanks for the impartial moderation.

[QUOTE=ManDay;1249771]And why is that? Why are vague complaints which are supposed to provoke - even if just a little - reconsideration not worth paying attention to? I find this attitude unworthy of any critically thinking being.

“Either it has a Bug-Number, or I ignore whatever it has to say!”

Well, suit yourself, if that’s the case. Because a “vague comment” is exactly what this is and what I mean it to be.

PS: Thanks for the impartial moderation.[/QUOTE]

this forum is for suggestions. if you want to just ramble without any purpose - that’s the wrong place. if someone doesn’t make an effort to produce consistent, clear criticism or too stupid to appreciate and do that, then yes, it’s logical to ignore him. why would i listen to you if you refuse to properly describe your point in consistent, organized manner? you won’t provoke any results like that. especially in combination with that ignorant attitude, where you assume your statements are undeniable. although they are really questionable for most of community(which defines the way API is).

if you are not satisfied with bug reports and you think specification should be changed substantially, you should come up with organized, consistent explanation of your point with sufficient examples covering all of the issues and how do you think it should be implemented. then you might get attention, reasonable criticism and corrections from community. and if there’s really something objectively wrong with specification, it may be fixed. no one want’s to interpret inconsistent rambling and no one will take it seriously, including people responsible for API and specification.

It sure is. Why would anyone want to do that? Luckily, I don’t want to ramble and I do pursue a purpose (if, for just a second you had thought that this wasn’t so, you clearly should not have replied in the first place).

if someone doesn’t make an effort to produce consistent, clear criticism or too stupid to appreciate and do that, then yes, it’s logical to ignore him. why would i listen to you if you refuse to properly describe your point in consistent, organized manner?

You keep talking in questions and general statements. Make a point. If you consider my opening post not clear or call me stupid, then call it so instead of elevating your opinions into some pseudo-meta generalizations. If you think I actively refuse to properly describe my point in question, then you’re just blatantly ignorant, for my very point is to describe my perception of the specification which I attested to be formally complete and non-contradictory. And if, even in that light, you still think what I say is unclear with respect to what I want to say, I must assume you’re generally incapable of understanding descriptions which disagree with your very own perspective.

you won’t provoke any results like that.

Excellent observation. If you’re speaking for yourself, that is. You’re obviously not interested in questioning your own take of the specificiation in the first place. What you fail to realize is that my comment adresses only those who are receptive to other people’s opinions at all. And thus, taken any foundation to attack me upon, you try dragging out an argument by your own, self-made logic, alleging I had certain intentions (such as pointing out factual mistakes in the specification) which you were allowed to prove false. You’re wrong.
As I’ve said a couple of times now, and will not repeat, the issue is subjective and therefore not suitable for being discussed of being right or wrong. And as long as you fail to understand that, your debate will just turn in circles.

especially in combination with that ignorant attitude, where you assume your statements are undeniable.

In fact, they are - at least some. And it is only due to your very own arrogance that you refuse to see that. Given all that, don’t expect any further response to attempts to discredit the subject itsself, rather than elaborating your personal opinion on the matter.

i think, i have a friendfor you :smiley: