<div dir="ltr"><div><div><div>> In fact, I am still<br>
> a bit confused why an API breakage in these early years of wayland is<br>
> considered such a big deal, compared with a daily struggle of not<br>
> having sufficient typing information.<br><br></div>Same here<br><br></div>To pq:<br><br></div>If
 an request specifies how unknown enum values should be handled, it just
 specifies an error handler. If the request is meant to run with enums, 
then the enums serve no point anyway. <br><br>In such a case, I wouldn't
 even have it say it takes an enum. It should just say it takes a uint, 
and the enum should say its value is uint. Preferably, the element 
wouldn't even be an enum, because all it does is listing meaningless 
values. <br></div><br><div class="gmail_quote">On Mon, 27 Apr 2015 at 15:20 Auke Booij <<a href="mailto:auke@tulcod.com">auke@tulcod.com</a>> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On 27 April 2015 at 14:49, Pekka Paalanen <<a href="mailto:ppaalanen@gmail.com" target="_blank">ppaalanen@gmail.com</a>> wrote:<br>
> On Mon, 27 Apr 2015 13:26:39 +0200<br>
> Auke Booij <<a href="mailto:auke@tulcod.com" target="_blank">auke@tulcod.com</a>> wrote:<br>
><br>
>> Apologies for my lack of responses, I have been abroad for a few days.<br>
>><br>
>> On 23 April 2015 at 10:38, Pekka Paalanen <<a href="mailto:ppaalanen@gmail.com" target="_blank">ppaalanen@gmail.com</a>> wrote:<br>
>> >> This is a sort of sanity condition on being a bitfield: it does not<br>
>> >> require all combinations are valid, but it also distinguishes it from<br>
>> >> a regular enum.<br>
>> ><br>
>> > Is that an important distinction to make? That a bitfield with "too<br>
>> > many" restrictions must not be a bitfield?<br>
>><br>
>> Yes, because what the bitfield flag indicates is that it is useful to<br>
>> think of the values as flags. It means that the values can somehow be<br>
>> combined. If there is no way to validly combine them, then it is not<br>
>> useful to think of them like flags. And if the right way to combine<br>
>> them is not OR'ing, then what you are talking about is not a bitfield.<br>
>> I am not saying it is a kind of value that is unwelcome in the wayland<br>
>> API, merely that it is not in the same category as what is usually<br>
>> considered a bitfield.<br>
>><br>
>> And indeed some things (e.g. wl_shell_surface.resize and<br>
>> xdg_surface.resize_edge) kinda look like a bitfield, but it is up for<br>
>> discussion whether they actually are, since it also looks like all of<br>
>> the options are explicitly listed, so in that sense we do not need to<br>
>> combine values by OR'ing, and it is hence not a bitfield.<br>
>><br>
>> Bill's 23rd of April (pseudo)code is very accurate, and highlights the<br>
>> issues I am trying to address in my bindings. Bill, thanks for that.<br>
>><br>
>> Pekka, you keep suggesting "docenum" only be used for documentation.<br>
>> However, types in richly typed languages *are* documentation (*). They<br>
>> indicate how you should use certain values. The fact that values are<br>
>> packaged as a certain enum type *documents* that you should probably<br>
>> use them in this or that way, without completely blocking use of the<br>
>> raw data (unless Jeroen's plan goes through).<br>
><br>
> Ok, let me clarify: changing documentation alone cannot cause<br>
> failures. That is what I mean by documentation-only here.<br>
><br>
> Sure, you can use language constructs in a documentative way, but the<br>
> main point here is can this cause build or runtime failures if it<br>
> suddenly changes.<br>
><br>
>> (*) In fact, in the case of Haskell, more often than not, you can find<br>
>> functions in an API purely by searching for its type: the type<br>
>> information of functions documents enough to know their behaviour. In<br>
>> some languages, the difference between code and documentation is not<br>
>> so clear-cut.<br>
>><br>
>> The entire reason I am asking for this "enum" attribute is so that the<br>
>> code I generate is more self-documenting. It does not enable the<br>
>> bindings to compute things it otherwise wouldn't be able to: packaged<br>
>> (u)ints are still (u)ints. It's to help the user understand the API,<br>
>> and unless they know better, suggest how they should interact with<br>
>> wayland.<br>
><br>
> Then I didn't understand your intent before. I thought you wanted to use<br>
> the enum types in the API you generate, which in strictly typed<br>
> languages means you get build failures if you try to use a value not in<br>
> the enum.<br>
><br>
> If it cannot cause build or runtime failures, then it's fine.<br>
><br>
>> Jeroen's request, I think, stands separately from this: Jeroen is<br>
>> asking for strict guarantees on what values are and are not allowed in<br>
>> enums. Perhaps this should be moved into a separate thread?<br>
><br>
> I (mistakenly?) took that using the types in the API means that you get<br>
> these strict value guarantees Jeroen is asking for.<br>
><br>
> Can you explain how you will use the enum types in the API without<br>
> hitting the type checks of a strictly typed language? The answer is<br>
> probably language-specific, but that is ok. We only need to answer the<br>
> "can it break?" question, and define the attribute semantics so that it<br>
> cannot break.<br>
><br>
> In fact, that is the definition for the "docenum" attribute: changing,<br>
> adding, or removing it from the XML file cannot cause any new build or<br>
> runtime failures. Otherwise use it any way in a generator you want. It<br>
> is similar to the "summary" attribute and <description> tag.<br>
><br>
>> So in summary:<br>
>><br>
>> - Currently, there is no systematic way to match (u)ints that are<br>
>> passed around with enums that are defined by the protocol. This makes<br>
>> the <enum>s, from a technical point of view, somewhat disconnected<br>
>> from the (u)int arguments.<br>
>><br>
>> - Currently, there is no systematic way to tell if bitwise<br>
>> computations on enum values are supposed to be possible (as per Bill's<br>
>> example code).<br>
>><br>
>> - Currently, there is no guarantee that only certain (u)int values<br>
>> will be exchanged under a given version of a protocol.<br>
>><br>
>> - It would be much welcomed by bindings and documentation generators<br>
>> if there would be a *semantic* correspondence between (u)ints and<br>
>> <enum>s. This correspondence would merely indicate how certain (u)ints<br>
>> are to be interpreted by matching them with an <enum>. This feature<br>
>> alone should not generate an API that is in any sense stronger or<br>
>> weaker than without such information (iow, access to the underlying<br>
>> (u)ints should still be available), but it may look different (e.g.<br>
>> (u)ints packaged in a type that refers to the right <enum>).<br>
><br>
> This is the part I don't get. Either you use the strict types or you<br>
> don't? What is the "maybe" option? Generating parallel APIs, and then<br>
> the user must know which one is actually the right one to use? I see in<br>
> Bill's example there are "forced casts" from arbitrary values to the<br>
> type, but this requires the programmer to write those casts.<br>
><br>
> Note, that "can it break?" also applies to cases where someone is using<br>
> an old XML file without these enum attributes (won't know that he<br>
> should be using forced casts, because the implementations of the casts<br>
> aren't even available) and then switches to a new one with the<br>
> attributes. If you can guarantee such a case cannot break, then it is<br>
> all fine.<br>
><br>
>> - In strongly typed languages, hints on generating the right API shape<br>
>> for bitfield-style arguments would be welcomed (as per Bill's example<br>
>> code). However, details of when something is a "bitfield" need to be<br>
>> discussed.<br>
>><br>
>> - In strongly typed languages, guarantees on which enum values are<br>
>> allowed in the protocol would be welcomed. However, worries about<br>
>> compatibility (both between languages and between versions) need to be<br>
>> worked out in detail. Also, how do such guarantees combine with the<br>
>> "bitfield" flag?<br>
>><br>
>> - Whereas interface names are global, enums are named locally in<br>
>> interfaces. However, there might be a need to refer to another<br>
>> interface's <enum>. However, this is a problem that can be solved<br>
>> later as it comes up (for now the enum attribute would use local<br>
>> names). As far as I am aware, there is no such situation in any common<br>
>> protocol right now.<br>
><br>
> In the end, all I care is about the definition of the new attributes<br>
> related to enum. If you really want to write a generator that can break<br>
> the build of other people, you can.<br>
><br>
> I would just want the definition of the attribute be such, that<br>
> following it literally, nothing can break even if the attribute gets<br>
> added much later than the interface it is used in. Either this, or<br>
> adding/removing the attribute is allowed to break the generated API,<br>
> which means we cannot add it retroactively to stable interfaces. That<br>
> is the difference between documentation-only and not.<br>
><br>
> We have added an attribute before: allow-null for object type <arg>,<br>
> defaulting to "false". It cannot cause failures in cases that weren't<br>
> already failing somehow anyway.<br>
><br>
><br>
> Thanks,<br>
> pq<br>
<br>
Okay, I think we have hit the essence of this part of the debate.<br>
<br>
The way I imagine my code generator in the presence of an "enum"<br>
attribute *would break API* when this attribute is added to an XML<br>
file.<br>
<br>
And yes, the only real way to resolve this breakage is to have<br>
parallel APIs: one based on raw (u)ints, and one with packaged<br>
(u)ints. One cannot interchange them without proper casting. And no,<br>
this is indeed not a road I would like to take.<br>
<br>
However, and I cannot stress this enough, generally speaking, breaking<br>
builds to due added information is preferred to not having the right<br>
type information in the first place. Adding a few casts here and there<br>
when needed is not much work, and the safety it adds has a lot of<br>
value in the context of strongly typed languages. In fact, I am still<br>
a bit confused why an API breakage in these early years of wayland is<br>
considered such a big deal, compared with a daily struggle of not<br>
having sufficient typing information.<br>
<br>
I guess this stems from a mentality difference between languages.<br>
<br>
On 27 April 2015 at 15:13, Pekka Paalanen <<a href="mailto:ppaalanen@gmail.com" target="_blank">ppaalanen@gmail.com</a>> wrote:<br>
> On Mon, 27 Apr 2015 15:49:27 +0300<br>
> Pekka Paalanen <<a href="mailto:ppaalanen@gmail.com" target="_blank">ppaalanen@gmail.com</a>> wrote:<br>
><br>
>> In the end, all I care is about the definition of the new attributes<br>
>> related to enum. If you really want to write a generator that can break<br>
>> the build of other people, you can.<br>
>><br>
>> I would just want the definition of the attribute be such, that<br>
>> following it literally, nothing can break even if the attribute gets<br>
>> added much later than the interface it is used in. Either this, or<br>
>> adding/removing the attribute is allowed to break the generated API,<br>
>> which means we cannot add it retroactively to stable interfaces. That<br>
>> is the difference between documentation-only and not.<br>
><br>
> How about we just define a new attribute for <arg> that points to an<br>
> <enum> for documentary purposes, and warns if the type is not int/uint<br>
> or uint for bitfields; and add an attribute to <enum> to say it's a<br>
> bitfield instead, without any further enforced restrictions.<br>
><br>
> Then, if you want to generate API bindings that have extra<br>
> restrictions not warranted by the above, you can. You also get to keep<br>
> all the pieces if it breaks someone.<br>
><br>
> This would be the "documentation-only, but we can't stop you from<br>
> abusing it" solution.<br>
><br>
> The chances are that it would work just fine for 99% of your<br>
> favourite language's users. We can add the attributes retroactively,<br>
> and you can write software that requires the version of libwayland or<br>
> whatever that has these attributes in the XML.<br>
><br>
> The point is, it will be clear on what protocol writers can and cannot<br>
> do, and with maximum benefits.<br>
><br>
><br>
> Thanks,<br>
> pq<br>
<br>
I am very much in favor of this solution. You will find me in the abuse camp.<br>
</blockquote></div>