<div dir="ltr">Thank you Mark for taking care of answering to my concerns — and<br>thanks for the pointers to the previous discussions; but I'm surprised<br>that removing the possibility of specifying that a non-numerical column<br>is made of ascii-only characters does not raise more comments or<br>concerns?… A few more comments embedded below:<br><br>==> On 2026-06-29 à 13:02+0100,<br>      Mark Taylor <<a href="mailto:m.b.taylor@bristol.ac.uk">m.b.taylor@bristol.ac.uk</a>> wrote:<br><br>>François,<br>><br>>On Fri, 19 Jun 2026, Francois Ochsenbein via apps wrote:<br>><br>>> VOTable 1.6 proposes to change the definition of the *char *<br>>> datatype from ascii to utf-8. I really think *it is not a good<br>>> idea*, and a new datatype able to handle utf-8 strings should be<br>>> preferred if the exchange of tables containing non-ascii data is<br>>> required. This is why I introduced the unicodeChar in the first<br>>> version of VOTable: open a possibility of exchanging textual data<br>>> not limited to ascii-only characters. Unicode was in active<br>>> development at that time (2002), and choosing Unicode for the<br>>> expansion of textual data seemed the obvious way, as opposed to a<br>>> choice of a *charset* which enlarges the alphabet to a very limited<br>>> set.<br>>><br>>> Currently virtually 100% of non-numeric data existing in astronomical<br>>> tables consist in a sequence of *restricted ascii characters* as<br>>> defined in FITS (bytes with decimal values between 32 and 126,<br>>> excluding therefore control characters). Considering the importance<br>>> of such non-numerical data, It seems fundamental that  a <FIELD><br>>> made of  *restricted ascii* characters continues to exist in<br>>> VOTable.  <br>><br>>The benefit of repurposing the char datatype to carry Unicode<br>>instead of ASCII is to minimise the change required to software,<br>>and to reduce the impact in the VO where different components<br>>may be updated to VOTable 1.6 on significantly different timescales.<br>><br>>By doing it this way, (a) all VOTable 1.6 software will be able to<br>>read pre-VOTable 1.6 content without any special arrangements in<br>>the code, and (b) most pre-VOTable 1.6 software will be able to read<br>>most VOTable 1.6 content without even noticing the difference. <br>>Admittedly (b) is not 100% true, since ASCII-expecting code<br>>encountering Unicode/UTF-8 bytes may behave strangely, but<br>>(i) in many cases this will result in only slightly garbled output,<br>>or even in output as intended in the case that Unicode rather<br>>than ASCII machinery is in fact used to decode the byte stream; and<br>>(ii) given that most textual content is likely to continue to fall<br>>within the ASCII range, such issues will probably only affect<br>>a small minority of the text encountered.<br><br>Well, if you see the contents as just a text it's ok, but if the<br>contents is something to process it is important to have this<br>information, rather than having to test each byte before performing<br>the field interpretation…<br><br>><br>>If we introduce a new datatype for Unicode, then software writing<br>>character data to VOTable text will need to decide for each<br>>column whether to write a char column which is unable to carry<br>>non-ASCII content but can (probably) be read by all VOTable readers,<br>>or a unicodeString(?) column which can only be read by V1.6-aware<br>>VOTable readers.<br>><br>>Making that decision at write time, i.e. knowing whether string<br>>content is ASCII-only, is typically not easy, since in a<br>>programming environment where strings are natively Unicode<br>>not ASCII, unless output code has additional information about<br>>character data values (for instance that it originated from FITS, <br>>or comprises ISO-8601 timestamps) it can't assume ASCII and can only<br>>safely decide to write it as Unicode.  Alternatively it could make<br>>an additional pass through the data to check for ASCIIness but that<br>>adds expense and inhibits streaming.  If it writes a new<br>>unicodeString type then pre-VOTable1.6 readers have no chance<br>>to make sense of it.  Note also that in the case of BINARY/BINARY2<br>>encoding, a pre-VOTable1.6 reader would not only fail to understand<br>>the content of unicodeString columns, but would be unable to read<br>>any of the data stream for a table containing a unicodeString field,<br>>because it wouldn't know how to count bytes to skip over<br>>the Unicode parts.<br>><br>>For code that reads ASCII or Unicode strings, in most cases it<br>>won't in any case treat the content differently - it's a string.<br>>Admittedly there may be exceptions; for instance software might want<br>>to refuse to write a non-ASCII column to a FITS BINTABLE A-format<br>>column.  But typically for such situations (at least it's what<br>>I'd do) it would be reasonable to make a best-efforts attempt<br>>and just transform non-ASCII characters to a '?' or similar,<br>>in which case knowing that it's ASCII doesn't buy you much.<br>><br><br>Well, the knowledge of ascii or Unicode contents is in principle known<br>by the data producer, i.e. the original VOTable writer — it should not<br>be a decision taken at run-time. So my fundamental question is: how to<br>propagate this knowledge of "pure ascii" contents to the data consumer,<br>if the definition of the "character" datatype is modified ? The<br>proposal of using the "width" attribute can't work with unspecified<br>length, and looks weird since the definition of what is a "width"<br>would differ between character and other datatypes (pull/71).<br><br>>Basically: use of Unicode is normal for text these days, ASCII is<br>>the special case.  The effect of having separate arrangements to<br>>process these formats would be (I claim) more to increase<br>>complication than to allow for simplified processing in some cases.<br>><br>>We have discussed this approach at some length over the last year<br>>or so.  Following an initial email discussion on the apps list<br>><a href="http://mail.ivoa.net/pipermail/apps/2025-June/thread.html">http://mail.ivoa.net/pipermail/apps/2025-June/thread.html</a>,<br>>which included a posting from you voicing concern about it,<br>>I drafted a Pull Request on github setting out my approach in<br>>concrete terms: <a href="https://github.com/ivoa-std/VOTable/pull/71">https://github.com/ivoa-std/VOTable/pull/71</a><br>>This received quite a bit of scrutiny from potential users and<br>>implementers, so I made various changes and presented it at Gorlitz<br>><a href="https://wiki.ivoa.net/internal/IVOA/InterOpNov2025Apps/votable.pdf">https://wiki.ivoa.net/internal/IVOA/InterOpNov2025Apps/votable.pdf</a><br>>I then invited further comments and objections on the mailing list<br>><a href="http://mail.ivoa.net/pipermail/apps/2025-November/001793.html">http://mail.ivoa.net/pipermail/apps/2025-November/001793.html</a><br>>(none forthcoming) prior to merging it in November 2025.<br>>It is now part of the current Working Draft<br>><a href="https://www.ivoa.net/Documents/VOTable/20260413/">https://www.ivoa.net/Documents/VOTable/20260413/</a><br>>and we have at least three prototype/production implementations.<br>><br>>Your suggestion of a new, non-fixed-size unicodeString type is not<br>>absurd, but for the reasons above I don't personally support it,<br>>and it's quite late in the process to back out of the currently<br>>drafted changes.  However if there is broad support for it instead<br>>of repurposing datatype="char", we can consider that.<br><br>You are probably right, the introduction of a new datatype should<br>better be done in a "major" release (VOTable-2.0?)<br><br>><br>>I have made more detailed responses to some of your other points below.<br>><br>>> Notice that Unicode and its UTF-8 serialisation is much more complex<br>>> than just an extension of the basic alphabet used in English to<br>>> "characters" existing in other languages. What a language like Java<br>>> defines as a " *Character*" is in fact a *Unicode code point,* which<br>>> is not necessarily what we could call a "character", a "letter", a<br>>> "symbol" or a "glyph". Unicode code points may be invisible (have a<br>>> zero width), may represent a part of a symbol (e.g. an accent), or<br>>> have a double width. For instance the UTF-8 string &#x2648;&#xFE0E;<br>>> which represents the Aries constellation, is made of 6 bytes<br>>> containing 2 Unicode code points: the first is &#x2648; which has a<br>>> width of 2, and the second is &#xFE0E; which has a width of 0 and<br>>> has just a role of preventing from rendering the Aries symbol as an<br>>> emoji (♈).<br>>><br>>> There are many other traps in Unicode and its UTF-8 serialisation,<br>>> such as several ways of writing a unique symbol like Ω as a 2-byte<br>>> greek letter (&#x3A9;) or as the 3-byte Ohm unit (&#x2126;);<br>>> similarly letters with an accent (e.g. Ô) may be coded with a 2-byte<br>>> code point (&#xD4;),  or with two code points in 3 bytes (O#x302;)<br>>> etc. etc. see e.g. <a href="https://utf8everywhere.org/">https://utf8everywhere.org/</a><br>>> <<a href="https://utf8everywhere.org/">https://utf8everywhere.org/</a>.> . As a consequence, even the<br>>> comparison of 2 UTF-8 strings for equality is *not* an easy<br>>> operation.  <br>><br>>That is all true and well-understood.  But the large majority of<br>>modern programming environments (e.g. Python, JavaScript, Java;<br>>it's an option in Rust) deal with it transparently, since their<br>>native string type is defined as Unicode and not as ASCII.<br>>Knowing that text is ASCII does not therefore convey much benefit<br>>in most programming contexts.<br>>Nearly all software is written these days in an environment in which<br>>strings are assumed Unicode, but that doesn't mean that programmers<br>>spend their time worrying about the fact that Aries is represented<br>>by two code points or that there is no unique way to encode something<br>>that looks like an Omega or accented characters.  Comparison of two<br>>UTF-8 sequences for equality *is* an easy operation, though it will<br>>not necessarily yield true for two strings whose pixel rendering is<br>>identical.<br>><br><br>Sorry to disagree with the "transparency" of Unicode in the various<br>languages: for instance length("άβγ♈︎♉︎😊𝕏") gives 12 in Javascript<br>or Java, while Python3 or awk return 10, which is the correct number of<br>Unicode code-points in this string(*). Similarly extracting a substring<br>out of a string gives different results depending on your programming<br>language when the string contains code-point(s) beyond the BMP.<br>(*) the Unicode contents of this string is<br>\u{3B1}\u{301}\u{3B2}\u{3B3}\u{2648}\u{FE0E}\u{2649}\u{FE0E}\u{1F60A}\u{1D54F}<br><br>>> Rather than a drastic change in the definition of the *char* data<br>>> type, I believe it would be much better to introduce a *String*<br>>> datatype in VOTable, which would be defined as *a UTF-8 sequence of<br>>> Unicode code points, excluding the *&#00;* (null) code point*.  Such<br>>> a datatype would be more flexible, without having to define what is<br>>> a "character" or requiring an *arraysize* attribute; it would<br>>> moreover become possible to define arrays of strings, which is<br>>> currently problematic.  <br>><br>>The current proposal does not need to define what a "character" is.<br>><br>>> In the TABLEDATA serialization, the representation of a *String* is<br>>> straightforward — there is however a possible problem with the<br>>> &-symbols : while the &#-symbols are easily interpretable (numerical<br>>> values like &#x26; or &#60;), what about alphabetic symbols like<br>>> &amp; or &lt; ? If these alphabetic symbols related to ascii<br>>> characters can (and should) be enumerated as it was in VOTable 1.5,<br>>> what about the ever-growing list of Unicode symbols like &llhard;<br>>> (⥫) or &Xopf; (𝕏) ? Should these be explicitely excluded or<br>>> accepted?  <br>><br>>None of these "&-symbols" present VOTable-specific issues.<br>>The Unicode content of elements and attributes in a well-formed<br>>XML document is well-defined, and character entity references<br>>(numeric or one of the five &lt; &gt; &amp; &apos; &quot;) are<br>>generally handled and decoded into a stream of code points by an<br>>XML processing layer before application software sees them.<br>>Entities like &llhard; (defined by HTML5) are not legal in XML<br>>unless specifically defined in an associated DTD (and thus processed<br>>by the XML parser). This is completely standard XML processing,<br>>and no VOTable-specific discussion is required.<br>><br><br>Thank you for the clarification !<br><br>>> The BINARY serialization would not be a problem, since the String<br>>> would just be a stream of bytes ending with a *null*; there would be<br>>> no need to specify a length preceding the stream of bytes, removing<br>>> the requirement of a maximal<br>>> length (number of bytes, or of code points, of glyphs or whatever<br>>> size)  <br>><br>>This would then be unlike any of the existing datatypes in VOTable,<br>>all of which are fixed size, so probably quite a bit of redrafting<br>>would be necessary.  It would mean that you can't skip over<br>>data in a BINARY stream without reading all the bytes.  1-d string<br>>arrays do become easier to encode, though 2+-d string arrays would<br>>require some special arrangements.<br><br>In fact 1-d strings would also require a clarification on how to write<br>these in the <TABLEDATA> serialization: unless quoted strings are a <div>standard in XML?<br><br>>It also means that any VOTable<br>>reader that doesn't know about the new datatype has no chance to read<br>>any of a BINARY stream containing such data.  Is one of these reasons<br>>why strings were not defined this way in the original version<br>>of VOTable?<br><br>The reason was a complete compatibility with FITS, even though the<br>unicodeChar was an attempt to expand the character content beyond the <br>ascii set. But defining a String datatype from the beginning would have<br>been wiser (sorry)…<br><br>><br>>> The FITS serialization would be a problem, since this type does not<br>>> (yet) exist in FITS; there where several discussions about adding<br>>> UTF-8 in FITS, and an obvious possibility would be to save the<br>>> string contents in the heap, while the binary table row would<br>>> contain just a  pointer to the location of the string in the heap.<br>>><br>>> Finally shouldn't the introduction of UTF-8 in VOTable also specify<br>>> whether UTF-8 would be acceptable as attribute values ? Could the<br>>> *name* or value attribute of a <FIELD>, <INFO>, <PARAM> contain<br>>> "characters" outside the restricted-ascii set ?  <br>><br>>The value type of a PARAM is already defined by its datatype attribute<br>>in just the same way as for a FIELD.  INFO is defined in terms of a<br>>PARAM with datatype="char" arraysize="*" (VOTable 1.5 sec 4.8),<br>>so if char is changed to permit Unicode then INFO values will<br>>automatically allow Unicode content as well.  As for FIELD/INFO/PARAM<br>>names, these attributes are defined by the XSD schema as xs:token,<br>>which means (with a few restrictions about control characters)<br>>they can have any Unicode values, which has been the case since the<br>>initial version of VOTable.  Again, this is normal XML business and<br>>I don't think the VOTable standard would be enhanced by including<br>>an XML primer.<br><br>You are right, thank you for the clarification 😊<br><br>><br>>> Sorry for being a bit long, but I think the radical change of<br>>> transforming ascii into UTF-8 is worth thinking about the multiple<br>>> implications involved.  <br>><br>>I agree, we have not got to where we are without thinking about it.<br>><br>>Mark<br>><br><br>Cheers, François<br>-- <br></div></div>