News for hackers. Stuff that matters.
Re:Brian Kernighan adds Unicode support to Awk by bombcar on Saturday August 20, 2022 @02:46PM (#32534279)
Is UTF-32 fixed size per char? Because then it allows simple math that you can’t do on UTF-8.
Re:Brian Kernighan adds Unicode support to Awk by valleyer on Saturday August 20, 2022 @02:51PM (#32534310)
It's a fixed size per codepoint. Many clusters that appear atomic in a text editor are made up of multiple codepoints. The flag emojis are among the many examples.
Re:Brian Kernighan adds Unicode support to Awk by thrown_22 on Saturday August 20, 2022 @09:19PM (#32536578)
UTF-8 is this magic ball of mud that somehow managed to convince people overstrikes were stupid and then implemented them so exuberantly that you can have a single glyph represented by half a dozen of them.
Re:Brian Kernighan adds Unicode support to Awk by ekimekim on Saturday August 20, 2022 @11:22PM (#32537128)
To nitpick: Overstrikes/other combining characters and the multiple possible ways to represent the same glyph are aspects of Unicode, the character set which deals with code points from 0 to 0x10ffff. Whereas UTF-8 is a way of encoding that character set into a sequence of bytes. The things you describe are present in all unicode encodings.
Re:Brian Kernighan adds Unicode support to Awk by masklinn on Saturday August 20, 2022 @03:33PM (#32534598)
> Because then it allows simple math that you can’t do on UTF-8.

That's not actually useful, because unicode itself is a variable length encoding.

So it mostly blows up the size of your data.

Though it might have been selected for implementation simplicity and / or backwards compatibility (e.g. same reason why Python did it, then had to invent "flexible string representation" because strings had become way too big to be acceptable).

Re:Brian Kernighan adds Unicode support to Awk by moefh on Saturday August 20, 2022 @06:16PM (#32535635)
UTF-32 is a fixed-length encoding of Unicode[1], so it does simplify things a lot for a regex engine.

[1] At least when talking about code points, which is what matters for regular expressions (unless you want stuff like \X with is not universally supported).

Re:Brian Kernighan adds Unicode support to Awk by kqr on Sunday August 21, 2022 @01:36AM (#32537677)
Wait, does Unicode not have multiple representations even of simple things like the letter "ä"? Then you definitely need to handle actual characters/glyphs in regexes.
Re:Brian Kernighan adds Unicode support to Awk by moefh on Sunday August 21, 2022 @01:50AM (#32537738)
Sure, but that's up to whoever is writing the regular expression.

The standard '.' (match any character) in a regexp matches an Unicode code point, not a grapheme cluster. To match a grapheme cluster, you have to use "\X", which is not universally supported.

For example, in Python 3, the builtin module module "re" doesn't support "\X", you have to install the "regex" module for it:

    # text is 'e' followed by U+0301 (combining acute accent):
    text = b'e\xcc\x81'.decode('utf8') 
    print(f'text: "{text}"')

    import re
    print(re.match('^(.)(.)$', text).groups())   # prints "('e', '´')"

    import regex  # must be installed
    print(regex.match('^(\X)$', text).groups())  # prints "('é',)"
Re:Brian Kernighan adds Unicode support to Awk by bmn__ on Sunday August 21, 2022 @05:17AM (#32538560)
> To match a grapheme cluster, you have to use "\X", which is not universally supported.

You have the words "supported" and "implemented" mixed up. Kernighan claims Unicode support, so he is required by the standard the implement \X.

If a software does not implement \X, then it is not compliant, and it would be very wrong to say it supports Unicode. Does anyone have a deeplink showing the evidence for awk?

Re:Brian Kernighan adds Unicode support to Awk by burntsushi on Sunday August 21, 2022 @12:45PM (#32541921)
This is just false. UTS#18 specifies multiple levels of Unicode support. \X is part of level 2. It is perfectly valid to generally say "has Unicode support" even if it's just Level 1, assuming you document somewhere what precisely is supported.

For example, I regularly say that Rust's regex crate has Unicode support. But it does not support \X. It's more precisely documented here: https://github.com/rust-lang/regex/blob/master/UNICODE.md

Re:Brian Kernighan adds Unicode support to Awk by moefh on Sunday August 21, 2022 @05:47AM (#32538679)
> so he is required by the standard the implement \X.

Which standard is that?

If you're talking about Unicode, the "standard" for regular expressions[1] is an "Unicode Technical Standard", which according to itself isn't required for Unicode conformance:

> A Unicode Technical Standard (UTS) is an independent specification. Conformance to the Unicode Standard does not imply conformance to any UTS.

So awk can claim Unicode support without supporting "\X" (like many regex engines).

If you're talking about POSIX, its regex chapter[2] doesn't mention "\X". In any case I don't think awk claims to conform to POSIX.

[1] https://unicode.org/reports/tr18/

[2] https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1...

Re:Brian Kernighan adds Unicode support to Awk by Pelam on Sunday August 21, 2022 @03:29AM (#32538098)
At the end of this comment there is what I believe is a single grapheme cluster. On disk this single "letter" occupies 73 bytes. Surprisingly large number of tools and editors know how to work with things like these and render them at least somehow

I think I once created one that was about a kilobyte. Is there an upper limit?

I created it using this page https://glitchtextgenerator.com/

The 73 byte X:

x̧̡̬̘͓̖̲̻̻̲̠̪̻͓͙̜̂̓̊̔̀̀͗̑̀̅̀̂̚͘̕̚͘͢͜͠

Re:Brian Kernighan adds Unicode support to Awk by dotancohen on Saturday August 20, 2022 @04:22PM (#32534900)
Unicode is not an encoding, despite MS Notepad calling some encoding "Unicode".
Re:Brian Kernighan adds Unicode support to Awk by tialaramex on Saturday August 20, 2022 @05:48PM (#32535431)
Unicode isn't a storage encoding and so yeah, Notepad shouldn't do that. However Unicode does encode essentially all extant human writing systems into integers called "code points" between zero and 0x10FFFF. The Latin "capital A" is 65 for example.

However you'd probably like to store something more compact than, say, JSON arrays of integers. So there are also a bunch of encodings which turn the integers into bytes. These encodings would work for any integers, but they make most sense to encode Unicode's code points. UTF-8 turns each code point into 1-4 bytes, a pair of UTF-16 encodings turns them into one or two "code units" each of 2 bytes either little or big endian. And UTF-32 just encodes them as native 32-bit integers but again either little or big endian.

Re:Brian Kernighan adds Unicode support to Awk by formerly_proven on Saturday August 20, 2022 @05:13PM (#32535179)
> Q: What is Unicode?

> A: Unicode is the universal character encoding, maintained by the Unicode Consortium. This encoding standard provides the basis for processing, storage and interchange of text data in any language in all modern software and information technology protocols.

https://home.unicode.org/basic-info/faq/

Re:Brian Kernighan adds Unicode support to Awk by jll29 on Saturday August 20, 2022 @06:27PM (#32535695)
Regardless of official terminology, there are two levels:

1. Map a character to a unique number in a character set (in Unicode: called codepoint)

2. Map a number that represents a character in a character set to a bit pattern for storage (transiently or persistently, internally or externally). Unicode code points can be bit-encoded in various ways: UTF8, UCS2 and UCS4/UTF32.

The original code points permit the same character to be represented in various ways, which makes equality checks non-trivial: for instance a character like "ä" can be represented as a single character or alternatively as a composition of "a" + umlaut accent (2 characters).

So far, this is all about plain text, so we are not talking about font families or character properties (bold, italics, underlined) or orientation (super-script, sup-script).

Ken Lunde's opus magnum is the standard book on representing text in various languages other than English, with a focus on Asian languages: https://www.oreilly.com/library/view/cjkv-information-proces...

Re:Brian Kernighan adds Unicode support to Awk by brewmarche on Saturday August 20, 2022 @06:14PM (#32535618)
In your quote encoding refers to assigning numbers (code points in Unicode parlance) to characters (I am simplifying here, I know the definition of character in Unicode is not that easy).

It’s like a catalogue of scripts. We have to extend it when we encounter new scripts that are not catalogued yet (or when we create new emojis)

Converting a byte sequence to a Unicode code point sequence and vice-versa is called transformation format (or more generally an encoding form, but then might not be deterministic) by Unicode (see <https://www.unicode.org/faq/utf_bom.html#gen2>). Unicode specifies UTF-8, -16 and -32. We do not have to change these formats unless the catalogue hit the limits of 32 bits (not a big problem for UTF-8 but for the other two formats). These formats are already able to encode code points that are not assigned yet.

And the confusion now is that a lot of people call what Unicode calls transformation format (i.e. the byte to code point mapping) encoding as well. The term charset is also used sometimes.

PS: Note that a goal of Unicode is to be able to accommodate legacy encoding/charsets by having a broad enough catalogue. This is so that these legacy encoding which may come with their own catalogue can be mapped to the Unicode catalogue. So we have control codes (even though not part of any “proper” human script), precomposed letters (there is a code point for à although it could be represented by a + combining `), things like the Greek terminal form of sigma separately encoded, although that could be done in font-rendering (like generally done for Arabic), and a lot more to aid with mapping and roundtrips.

Re:Brian Kernighan adds Unicode support to Awk by tzot on Monday August 22, 2022 @07:45AM (#32550082)
Just a note about the Greek terminal form of sigma: when dealing with Greek numerals, ςʹ (the final form of sigma) is 6 while σʹ (the non-final form of sigma) is 200; they need to be differentiated whatever the font engine decides to render.
Re:Brian Kernighan adds Unicode support to Awk by brewmarche on Monday August 22, 2022 @03:23PM (#32555988)
Thanks, good to know. I’ve also realised that determining which form to use in mathematical formulas is maybe not that straightforward.

Edit: by which I mean that I’ve only seen the non terminal form so far in maths but it’s hard to write an algorithm that distinguishes between a word ending in sigma and some juxtaposition of Greek variables.

Re:Brian Kernighan adds Unicode support to Awk by layer8 on Saturday August 20, 2022 @05:59PM (#32535512)
Unicode uses the term “character encoding form” or “character encoding scheme” for what is normally referred to or abbreviated as “character encoding” or “charset” (see e.g. RFC 8187), and uses “character encoding” or “coded character set” for the abstract assignment of natural numbers to the abstract characters in a character repertoire, which is more usually referred to as just “[coded] character set” (cf. also UCS = Unicode Character Set). This different use of terminology can cause confusion. The GP is correct that Unicode as a whole is not what is colloquially meant by “encoding”.
Re:Brian Kernighan adds Unicode support to Awk by bzxcvbn on Sunday August 21, 2022 @02:34AM (#32537900)
MS has taken the approach of calling UTF-16 "Unicode" as it's what's used in most of their systems.
Re:Brian Kernighan adds Unicode support to Awk by simias on Saturday August 20, 2022 @02:51PM (#32534313)
It's always the tradeoff, some operations are simpler on UTF-32 but they have additional memory (and therefore cache) footprint and since you typically don't want to use UTF-32 externally you have to convert back and forth which is not free.

I think these days people don't bother with UTF-32 too much because it's not even like you have a clean "one 32bit int, one character" relation anyway since some characters can be built from multiple codepoints. Since generally most code manipulating character strings are interested in characters and not codepoints, UTF-32 is effectively a variable-length encoding too...

Re:Brian Kernighan adds Unicode support to Awk by tialaramex on Saturday August 20, 2022 @03:09PM (#32534424)
Right, somebody else might have actual metrics but I'd have guessed actual regular expression patterns are split something like:

90% Only care about ASCII, thus individual bytes in UTF-8, and so UTF-32 just wastes memory

1% Care about individual code points, but spread over multiple bytes (e.g. the double dagger ‡), UTF-32 is perfect

9% Care about multiple code points (to form e.g. a Flag, or é written in combining form, or two women kissing) and so UTF-32 doesn't really help again

Re:Brian Kernighan adds Unicode support to Awk by bmn__ on Sunday August 21, 2022 @05:26AM (#32538590)
Applications and text-processing libraries are free use an internal text encoding or data structure, if you will, which does not suffer from the drawbacks. Conversions to encodings suitable for data exchange (e.g. UTF-8) are performed at the I/O boundaries.
Re:Brian Kernighan adds Unicode support to Awk by tialaramex on Sunday August 21, 2022 @04:11PM (#32543935)
Sure, and if stuff lives inside your "application and text-processing library" for long enough and performs enough of the thusly optimised actions without leaving, you might even amortize the cost of the work you did at the edges.

But probably not.

Re:Brian Kernighan adds Unicode support to Awk by layer8 on Saturday August 20, 2022 @06:03PM (#32535554)
Another factor is that nowadays machine code execution is much faster than memory accesses, so the trade-off of requiring more program logic to process a more compact format makes a lot of sense.
Re:Brian Kernighan adds Unicode support to Awk by moomin on Saturday August 20, 2022 @02:49PM (#32534289)
A “character” can be of fairly arbitrary length in Unicode, so no.
Re:Brian Kernighan adds Unicode support to Awk by fooster on Saturday August 20, 2022 @04:29PM (#32534947)
Not to be contradictory, but unicode is not a specific encoding. ufc-8 is an encoding (with a non specific length) and utf-32 is an encoding of a Unicode code point with a specific length.
Re:Brian Kernighan adds Unicode support to Awk by happytoexplain on Saturday August 20, 2022 @09:25PM (#32536603)
Most people talking about characters in Unicode are referring to grapheme clusters, and I assume the parent is too, since they are in fact defined by Unicode and vary in length in all encodings, hence their answer of "no" to the GP.
Re:Brian Kernighan adds Unicode support to Awk by happytoexplain on Saturday August 20, 2022 @02:55PM (#32534333)
It is fixed size per code point, which are what developers (and programming languages) sometimes casually call a character, but in practice a character is a grapheme, which can be multiple code points once you're outside the ASCII range. But it can still be useful to count code points, which would be faster in UTF-32.

Edit: Mixed up code units and code points.

Re:Brian Kernighan adds Unicode support to Awk by thayne on Saturday August 20, 2022 @03:17PM (#32534481)
And even then, in some languages at least, what constitutes a grapheme isn't always well defined.
Re:Brian Kernighan adds Unicode support to Awk by a1369209993 on Saturday August 20, 2022 @04:12PM (#32534840)
> in some languages at least, what constitutes a grapheme isn't always well defined.

Can you provide some examples? People say this a lot, but the cases I've been able to find tend to be things like U+01F1 LATIN CAPITAL LETTER DZ, which is only not well defined in the sense that Unicode defines it wrong (as one character rather than two) presumably-on-purpose, for compatibility with one or more older character encodings.

Re:Brian Kernighan adds Unicode support to Awk by kergonath on Sunday August 21, 2022 @12:38AM (#32537454)
I don’t know about DZ, but things that are two letters in one language can be one in another (famously ij in Dutch, but there are others).

Also, things like æ and œ are much easier to deal with if they are a single glyphs. Their upper-case versions are respectively Æ and Œ even in languages where they are two letters. I suppose that now we would do it with something like ZWJs to make sure that both letters are transformed consistently but there are technical reasons behind the current situation.

[edit] here you go: dz is the 7th letter of the Hungarian alphabet, but the capital version (in a normal sentence) of dz is Dz and not DZ. Yeah, languages are weird: https://en.m.wikipedia.org/wiki/Hungarian_alphabet

Re:Brian Kernighan adds Unicode support to Awk by hvdijk on Sunday August 21, 2022 @12:36PM (#32541816)
> famously ij in Dutch

ij is considered two letters in Dutch, although they go by special rules: https://onzetaal.nl/taalloket/ij-plaats-in-alfabet

Re:Brian Kernighan adds Unicode support to Awk by happytoexplain on Saturday August 20, 2022 @04:27PM (#32534932)
Is DZ "wrong" because it's not considered a digraph by professionals, or because people don't agree that digraphs should be considered single characters?
Re:Brian Kernighan adds Unicode support to Awk by a1369209993 on Saturday August 20, 2022 @05:03PM (#32535125)
"DZ" isn't 'wrong', it's a perfectly valid two-character string consisting of "D" followed by "Z". Assigning to a multi-character string a encoded representation that isn't the concatenation of representations of each character in the string (especially while insisting that that makes it a distinct character in its own right) is what's wrong.
Re:Brian Kernighan adds Unicode support to Awk by bzxcvbn on Sunday August 21, 2022 @02:41AM (#32537928)
But the letter DZ is not the same thing as the letter D followed by the letter Z. It's a standalone letter in e.g. Hungarian or Slovak, much like æ isn't "ae".
Re:Brian Kernighan adds Unicode support to Awk by happytoexplain on Saturday August 20, 2022 @03:27PM (#32534555)
True - I was thinking of Unicode's definition ("[extended] grapheme clusters").
Re:Brian Kernighan adds Unicode support to Awk by Ericson2314 on Saturday August 20, 2022 @07:16PM (#32535986)
It is fixed size...for now ;)
Re:Brian Kernighan adds Unicode support to Awk by sargstuff on Sunday August 21, 2022 @10:08PM (#32546541)
But what order are the bytes being chomped?
[dead]
Re:Brian Kernighan adds Unicode support to Awk by jamiek88 on Saturday August 20, 2022 @07:26PM (#32536045)
This adds nothing to an interesting discussion. Can you leave this Facebook nonsense there please?
Re:Brian Kernighan adds Unicode support to Awk by alganet on Saturday August 20, 2022 @05:57PM (#32535499)
You are right.

Unicode in UTF-8 will have variable char length. Plain ASCII will be one byte for each char, but others might have up to 4 bytes. Anything dealing with it will have to be aware of leading bytes.

UTF-32 in other hand will encode all chars, even plain ASCII ones, using 4 bytes.

Take the "length of a string" function, for example. Porting that from ASCII to UTF-32 is just dividing the length in bytes by 4. For UTF-8, you'd have to iterate over each character and figure out if there is a combination of bytes that collapse into a single character.

Re:Brian Kernighan adds Unicode support to Awk by jsjohnst on Saturday August 20, 2022 @08:28PM (#32536322)
> Porting that from ASCII to UTF-32 is just dividing the length in bytes by 4. For UTF-8, you'd have to iterate over each character and figure out if there is a combination of bytes that collapse into a single character.

You have to do that with UTF-32 as well. Yes, every codepoint is 32 bits, but every character can be made up of one or more codepoints.

Re:Brian Kernighan adds Unicode support to Awk by alganet on Sunday August 21, 2022 @01:21AM (#32537618)
What?

U+004D in UTF-8 is 4D, in UTF-32 is 0000004D

U+0430 in UTF-8 is D0 B0, in UTF-32 is 00000430

I took this examples from page 102 of The Unicode Standard Version 5.0.

These leading zeros on the UTF-32 are what is omitted from UTF-8. One of the encodings is optimized for space, the other for processing speed.

I am no expert on unicode though, there might be something I'm missing (ligatures, this kind of stuff). I would gladly accept a more in depth expalanation on why I am wrong on this.

Re:Brian Kernighan adds Unicode support to Awk by bzxcvbn on Sunday August 21, 2022 @02:51AM (#32537963)
The letter à can be represented in two different ways in Unicode:

* As the single code point U+00E0, which encodes 'à'.

* Or as the sequence of two code points U+0061 U+0300, which respectively encode the Latin letter 'a' and the combining acute accent (it's hard to display as a standalone character, so go e.g. here: https://www.compart.com/fr/unicode/U+0300). These two code points get combined into a single grapheme cluster, the technical name for what most people consider to be a character, that displays as 'à'.

As you can see, there is no difference in the visual representation of à and à. But if you inspect the string (in python or whatever) then you'll see that one of them has one code point (one "char"), while the second has two. If you're on Windows, an easy way is to type it into pwsh:

    PS> 'à'.EnumerateRunes() | % { "U+{0:X4}" -f $_.Value }
    U+0061
    U+0300
    PS> 'à'.EnumerateRunes() | % { "U+{0:X4}" -f $_.Value }
    U+00E0
Re:Brian Kernighan adds Unicode support to Awk by alganet on Sunday August 21, 2022 @03:28AM (#32538095)
The character "à" as a single byte E0, as far as I know, is not UTF-8. This is the 224th character of the extended ASCII table (also ISO 8859). It's another system: https://en.wikipedia.org/wiki/Extended_ASCII

This representation is incompatible with UTF-8, which marks the octet series Cx, Dx, Ex and Fx as leading bytes. You can see the table here: https://en.wikipedia.org/wiki/UTF-8#Codepage_layout

What I believe Kernighan _wants_, is to reuse a lot of code that was designed for ASCII. Code that treats 1 char as 1 byte. In order to do that, he is going to encode each unicode character using 4 of whatever type he was previously using before, zeroing the "pad" bytes, which is exactly what UTF-32 does. This way, he doesn't have to fundamentally change all the types he is already working with. (ps: I looked at the commit after I wrote this, he doesn't seem to be doing what I suggested).

Your PS snippet failed for me "Method invocation failed because [System.String] does not contain a method named 'EnumerateRunes'."

Dit it in bash, which supports UTF-8 and lets you explicitly set the encoding:

    $ LC_ALL=C bash -c 'x=à; echo ${#x}'
    2
    $ LC_ALL=en_US.UTF-8 bash -c 'x=à; echo ${#x}'
    1
These snippets count the number of chars according to the selected encoding.

If I had UTF-32 locales in my machine, "à" would appear as 4. Unfortunatelly I don't know any system that implements UTF-32 to display its behavior.

Let's now reconstruct "à" in UTF-8, telling bash to use only ASCII:

    $ LC_ALL=C bash -c 'printf %b \\xC3\\xA0'
    à
I've tunneled UTF-8 through an ASCII program, and because my terminal accepts UTF-8, everything is fine. Didn't even had to use \u escapes. This backwards compatibility is by design, and chosing between UTF-8, 16 and 32 plays a role in how you're going to deal with these byte sequences.
Re:Brian Kernighan adds Unicode support to Awk by bzxcvbn on Sunday August 21, 2022 @04:35AM (#32538370)
> The character "à" as a single byte E0, as far as I know, is not UTF-8.

It's not, but I wrote "Unicode" and "code point", not "UTF-8" and "code unit". It sounds like you don't know the difference, which makes this whole discussion a bit silly and probably a bit pointless. One of the best explanations I've read is this one: https://docs.microsoft.com/en-us/dotnet/standard/base-types/... and especially the section on grapheme clusters.

> Your PS snippet failed for me "Method invocation failed because [System.String] does not contain a method named 'EnumerateRunes'."

Sounds like you're using the outdated windows powershell, not pwsh.

Re:Brian Kernighan adds Unicode support to Awk by alganet on Sunday August 21, 2022 @08:07AM (#32539352)
I'm talking about how many bytes it takes to store characters in these encodings, and how the lengh of these sequences changes according to each standard.

You are talking about another level of abstraction. These UTF-16 builtins are first-class citizens in .NET, and you never have to deal with the raw structure behind all of it unless you want to. C does not have these primitives, a string there is composed of smokes and mirrors using byte arrays.

In summary, you are talking about using a complete, black box Unicode implementation. I'm talking about the tradeoffs one might encounter when crafting stuff that goes inside one of these black boxes, and it's different from the black box you know.

Re:Brian Kernighan adds Unicode support to Awk by bzxcvbn on Sunday August 21, 2022 @10:14AM (#32540393)
Okay, let's back up a little. You were replying about a comment that said:

> Yes, every codepoint is 32 bits, but every character can be made up of one or more codepoints.

And you expressed surprise and incredulity at the idea. I explained that a "character" (which, given the context, is to be taken as a "grapheme") can, indeed, take up more than one code point. This has nothing to do with UTF-32, UTF-8, or .NET's implementation. It's inherent to how Unicode works.

As an even more obvious example, try to figure out how many bytes are in the character ȃ encoded as UTF-32, using whatever method you'd like. (I say "more obvious" because you'll be forced to copy-paste the character I've used in your code editor.) Other examples include emojis such as this one: https://emojipedia.org/woman-golfing/ (that I can't use in the comment box for some reason).

Then for some reason you felt compelled to offer a rebuttal that showed you didn't understand the difference between a grapheme and a code point. So I just linked some doc. I'm not attacking you.

Re:Brian Kernighan adds Unicode support to Awk by alganet on Sunday August 21, 2022 @11:15AM (#32540990)
That reply is not my first interaction on the thread. I guess you didn't see the previous one, so perhaps you are missing context. Here's the link: https://news.ycombinator.com/item?id=32535499

"ȃ" uses two bytes in UTF-8, 2 bytes in UTF-16 and 4 bytes in UTF-32. The woman golfing uses 4 bytes in UTF-8, UTF-16 and UTF-32.

My surprise was at the idea of having to look up a variable length sequence of bytes in a string stored as UTF-32. To me, UTF-32 exists exactly for the use case of "I don't want to calculate variable length" (optimizing for speed), and UTF-8 exists for "I don't want to use more bytes than I need" (optimizing for space).

I never used the term "codepoint" in this entire thread until now. I was originally talking about storing bytes, hence my little discomfort of not being able to communicate what I'm trying to say. Not feeling attacked, just incapable of expressing, which might have come off wrong. Sorry about that.

BTW, there are many things that I don't understand about Unicode. I never read the full standard. I don't know enough about a grapheme to tell whether it is something that impacts or not the number of bytes when storing in UTF-32.

Why we are talking about UTF-8 versus UTF-32 and not Unicode as a whole? Because there is a code comment about these two in the commit linked by the OP, which sparked this particular subthread.

Re:Brian Kernighan adds Unicode support to Awk by tzot on Monday August 22, 2022 @07:57AM (#32550157)
> "ȃ" uses two bytes in UTF-8

"â" uses two bytes when encoded in UTF-8, while "ȃ" (which was what bzxcvbn supplied as an example and you pasted in the quoted section) uses three bytes when encoded in UTF-8.

  >>> s="ȃ"
  >>> len(s)
  2
  >>> s.encode('utf8')
  b'a\xcc\x91'
  >>> import unicodedata as ud
  >>> [ud.name(c) for c in s]
  ['LATIN SMALL LETTER A', 'COMBINING INVERTED BREVE']
Re:Brian Kernighan adds Unicode support to Awk by bzxcvbn on Sunday August 21, 2022 @03:36PM (#32543624)
> The woman golfing uses 4 bytes in UTF-8, UTF-16 and UTF-32.

No. It's made up of 5 code points. Each of these takes 32 bits, or 4 bytes, in UTF32. So that emoji, which is a single grapheme, uses 20 bytes in UTF32. Once again, just try it yourself, encode a string containing that single emoji in UTF32 using your favorite programming language and count the bytes!

Re:Brian Kernighan adds Unicode support to Awk by alganet on Sunday August 21, 2022 @06:09PM (#32544978)
Let's go to the source:

https://www.unicode.org/faq/utf_bom.html

> Q: Should I use UTF-32 (or UCS-4) for storing Unicode strings in memory? > > This depends. It may seem compelling to use UTF-32 as your internal string format because it uses one code unit per code point. (...)

It also confirms what I said about implementation vs interface (or storage vs access, whatever):

> Q: How about using UTF-32 interfaces in my APIs? > > Except in some environments that store text as UTF-32 in memory, most Unicode APIs are using UTF-16. (...) While a UTF-32 representation does make the programming model somewhat simpler, the increased average storage size has real drawbacks, making a complete transition to UTF-32 less compelling

Finally:

> Q: What is UTF-32? > > Any Unicode character can be represented as a single 32-bit unit in UTF-32. This single 4 code unit corresponds to the Unicode scalar value, which is the abstract number associated with a Unicode character.

So, it does in fact reduce the complexity of implementing it _for storage_, as I suspected. And there is a tradeoff, as I mentioned. And the Unicode documentation explicitly separates the interface from the storage side of things.

That's good enough for me. I mentioned before there might be some edge cases like ligatures, and you came up with a zero-width joiner example. None of this changes these fundamental properties of UTF-32 though.

Re:Brian Kernighan adds Unicode support to Awk by jsjohnst on Monday August 22, 2022 @09:04AM (#32550754)
Reading this thread, I feel bad for the person you’re arguing with. It’s clear you are in the “knowledgeable enough to be dangerous” stage and no amount of trying to guide you will sway you from your mistaken belief that you are right.

Now to try one last time, you are misreading the spec and not understanding important concepts. Take the “woman golfing” emoji as an example. That emoji is not a Unicode “character” and is part of why it can’t be represented by a single UTF32. That emoji is a grapheme which combines multiple “characters” together with a zero width joiner, “person golfing” and “female” in this case. Rather than have a single “character” for every supported representation of gender and skin color, modern emoji use ZWJ sequences instead, which means yes, something you incorrectly think is a “character” can in fact take up more than 4 bytes in UTF32.

Re:Brian Kernighan adds Unicode support to Awk by alganet on Monday August 22, 2022 @09:10PM (#32559373)
I am reading the spec, discussing online and trying to understand the subject better, what is wrong with that?

I said I might be wrong _multiple times_, and its genuine. I'm glad you appeared with an in-depth explanation that proves me wrong. I asked exactly for that.

The first examples in this thread are not zero-width-joiners (á, â) or complex graphemes. They all could be stored in 4 bytes. It took some time to come up with the woman golfing example.

By the way, one can still implement reading "character" by "character" in sequences of 4 UTF-32 bytes, and decide to abstract the grapheme units on top of that. It still saves a lot of leading byte checks.

Maybe someone else learned a little bit reading through the whole thing as well. If you are afraid I'm framing the subject with the wrong facts, this is me assuming, once again, that I never claimed to be a Unicode expert. I don't regret a single thing, I love being actually proven wrong.

Re:Brian Kernighan adds Unicode support to Awk by jsjohnst on Monday August 22, 2022 @09:51PM (#32559633)
> I am reading the spec, discussing online and trying to understand the subject better, what is wrong with that? I said I might be wrong _multiple times_, and its genuine.

I encourage you to reread the comment I replied to again and see if it has the tone of someone “trying to learn” or rather something different.

> I don't regret a single thing, I love being actually proven wrong.

Me too!

Re:Brian Kernighan adds Unicode support to Awk by alganet on Monday August 22, 2022 @10:36PM (#32559931)
> I encourage you to reread the comment I replied to again and see if it has the tone of someone “trying to learn” or rather something different.

To me it sounds ok. I'm not an english native speaker though, so there is a handicap on my side on tone, vocabulary and phrasing.

My intent was to admit I had wrong assumptions. At some point before this whole thread, I _really_ believed all graphemes (which, in my mind, were "character combinations") could be stored in just 4 bytes. I was aware of combining characters, I just assumed all of them could fit in 32bit. You folks taught me that it can't.

However, there's another subject we're dealing with here as well. Storing these characters at a lower level, whether they form graphemes or not at a higher level of abstraction.

The fact that I was wrong about graphemes, directly impacts the _example_ that I gave about the length of a string, but not the _fundamental principle_ of UTF-32 I was trying to convey (that you don't need to count lead bytes at the character level). Can we agree on that? If we can't, I need a more in-depth explanation on _why_ regarding this as well, and if given, that would mean I am wrong once again, and if that happens, I am fine, but it hasn't yet.

Re:Brian Kernighan adds Unicode support to Awk by jsjohnst on Tuesday August 23, 2022 @08:53AM (#32564180)
> The fact that I was wrong about graphemes, directly impacts the _example_ that I gave about the length of a string, but not the _fundamental principle_ of UTF-32 I was trying to convey (that you don't need to count lead bytes at the character level). Can we agree on that? If we can't, I need a more in-depth explanation on _why_ regarding this as well, and if given, that would mean I am wrong once again, and if that happens, I am fine, but it hasn't yet.

As I said in the other thread, to try to minimize confusion, consider Character and Grapheme as synonymous. They are made up of one or more codepoints. The world you’ve made up that everything is characters and they all take exactly four bytes in UTF32 is just wrong. Yes, many graphemes are a single codepoint, so yes, they are 4 bytes in UTF32, but not ALL (and it’s not just emoji’s to blame).

If what you’re on about is the leading zeros, yes, they don’t matter individually. Unicode by rule is limited to 21bits to represent all codepoints so the 11 bits left as leading zeros are wasted, which is why folks don’t use UTF32 typically as it’s the least efficient storage wise and doesn’t have really any advantage over UTF-16 outside easy counting of codepoints (but again, codepoints aren’t characters).

Re:Brian Kernighan adds Unicode support to Awk by alganet on Tuesday August 23, 2022 @04:21PM (#32570939)
I'm talking more about C (or any low level stuff) than Unicode now. The world I'm using as a reference has only byte arrays, smokes and mirrors.

I'm constantly pointing you _to the awk codebase_. It's a relevant context, the title of the post and it matters. Can you please stop ignoring this? There's no Unicode library there, it's an implementation from scratch.

If you are doing it from scratch, there's a part of the code that will deal with raw bytes, way before they are recognized as Unicode things (whatever they might be).

Ever since this entire post was created, the main context was always this: an implementation from scratch, in an environment that does not have unicode primitives as a first-class citizens. Your string functions don't have \u escapes, YOU are doing the string functions that support \u.

Re:Brian Kernighan adds Unicode support to Awk by jsjohnst on Tuesday August 23, 2022 @07:27PM (#32572952)
Ok, now I know you’re just trolling. Enjoy and goodbye!
Re:Brian Kernighan adds Unicode support to Awk by alganet on Tuesday August 23, 2022 @10:14PM (#32574232)
I'm not kidding. Just look at the code:

https://github.com/onetrueawk/awk/commit/d322b2b5fc16484affb...

I am talking about that environment. You are not.

Re:Brian Kernighan adds Unicode support to Awk by jsjohnst on Monday August 22, 2022 @09:44PM (#32559585)
To make the point more clear, the female golfing Unicode “character” is encoded as follows in various UTFs:

UTF16 (12 bytes total):

\ud83c\udfcc\ufe0f\u200d\u2640\ufe0f

UTF32 (20 bytes total):

u+0001f3ccu+0000fe0fu+0000200du+00002640u+0000fe0f

UTF8 (16 bytes total):

\xf0\x9f\x8f\x8c\xef\xb8\x8f\xe2\x80\x8d\xe2\x99\x80\xef\xb8\x8f

Re:Brian Kernighan adds Unicode support to Awk by alganet on Monday August 22, 2022 @11:00PM (#32560052)
You are still presenting me with abstractly encoded data. \u and u+ are in a higher level of abstraction. The only raw bytes I am seeing here are in the UTF-8 string, which you decided to serialize as hexadecimals (did you had a choice? why?).

If you had all of these expressed as pure hexadecimals (or octals, or any single-byte unit), how would they be serialized?

Then, once all of them are just hexadecimals, how would you go about parsing one of these sequences of hexadecimals into _characters_? (each hexa representing a raw byte, just like in the awk codebase we are talking about)

Another question: do you need first to parse the raw bytes into characters before recognizing graphemes, or can you do it all at once for both variable-length and fixed-length encodings?

Re:Brian Kernighan adds Unicode support to Awk by jsjohnst on Tuesday August 23, 2022 @08:47AM (#32564091)
> You are still presenting me with abstractly encoded data.

That’s the actual encoding for that grapheme as specified by the spec for UTF8, UTF16, and UTF32.

> \u and u+ are in a higher level of abstraction.

No, it’s not, it’s how you write escaped 16bit and 32bit hexadecimal strings for UTF-16 and UTF-32 respectively. Notice there’s 4 hex characters after \u and 8 hex after u+. Those are the “raw bytes” in hex.

> The only raw bytes I am seeing here are in the UTF-8 string, which you decided to serialize as hexadecimals

All three forms are “raw bytes” in hex form. \x is how you represent an escaped 8 bit UTF-8 byte in hex.

> Another question: do you need first to parse the raw bytes into characters before recognizing graphemes, or can you do it all at once for both variable-length and fixed-length encodings?

You need to “parse” (more like read for UTF16 and UTF32, as there’s not much actual parsing outside byte order handling) the raw bytes into codepoints. To try to minimize confusion, consider Character and Grapheme as synonymous. They are made up of one or more codepoints. It really doesn’t matter if it’s variable length or fixed length, you still have to get the codepoints before you can determine character/graphemes.

Re:Brian Kernighan adds Unicode support to Awk by alganet on Tuesday August 23, 2022 @03:31PM (#32570158)
I am asking you "how do you purify water"? And you're holding a bottle of Fiji and telling me "look, it's simple".

You're absolutely right about what is a character and what is a grapheme. I already said that, this subject is done. You're right, no need to come back to it. You win, I already yielded several comments ago.

Now, to the other subject: I would very much prefer if we talked only about bytes. Yes, talking only about bytes makes things harder. Somewhere down the line, there must be an implementation that deals with the byte sequence. I'm talking about these, just above the assembler (for awk). There IS confusion at this level, no way to avoid it except abstracting it by yourself, byte by byte (or, 4 bytes by 4 bytes in UTF-32).

Re:Brian Kernighan adds Unicode support to Awk by adambatkin on Sunday August 21, 2022 @12:28PM (#32541727)
Take a step back and ask "why do I need to know the length of this thing?" If it's so you know how much storage to allocate, then the process/time is the same for both (the answer is: however many bytes you happen to have). If your array is bigger than the number of valid characters (code points) and you need to search through it to find the "end" (last valid character), you can do that with almost identical complexity (you don't actually need to iterate over ever byte and Code Point with UTF-8 because of how elegantly the encoding was designed).

Why else might you need to know the length? If it's to know how much space to allocate in a GUI (or even on a console) then neither encoding is going to help.

Maybe it's because of some arbitrary limitation like "your name must be less than 50 characters" and I'll just say that if that's the case, you are doing it wrong (if you need to limit it for storage/efficiency purposes, fine, but you will probably be better off limiting by bytes and using UTF-8 since most people will be able to squeeze in more of their names).

I'm not saying there aren't reasons for needing to know the "length" (number of Code Points) of a string, and certainly many existing algorithms are written in a way that they assume that calculating string length and being able index arbitrarily into the middle of a string are fast (O( 1 ) for indexing) but in reality, for almost any real world problem beyond "how much storage do I need" almost everything you need to do actually requires iterating over a string one Code Point at a time (which is O( n ) for both, with the biggest difference being that UTF-8 may require more branching, but also it's common enough that in many cases between vectorization and just generally better optimizations because of it's popularity, UTF-8 will do just fine while usually using less storage, which can significantly benefit CPU cache locality).

Re:Brian Kernighan adds Unicode support to Awk by alganet on Sunday August 21, 2022 @06:38PM (#32545213)
It needs the length for operations such as substring, or to apply length modifiers on regular expressions (such as \w{3,5}), which is a common thing in awk programs.

In fact, the return value of the u8_rune as implemented in the branch we are discussing (https://github.com/onetrueawk/awk/compare/unicode-support) returns a length to be used as an offset later.

This is not me saying, it's the author. There is a code comment there:

> For most of Awk, utf-8 strings just "work", since they look like null-terminated sequences of 8-bit bytes. Functions like length(), index(), and substr() have to operate in units of utf-8 characters. The u8_* functions in run.c handle this.

I know there might be different ways of doing it, but we're talking about a specific implementation.

I was wrong to assume he is storing stuff in UTF-32. He could have, but there was already code in place there to make the UTF-8 storage easier to implement.