* NUL terminated strings (and now, non UTF-8 encoded strings on input/output)
* Using LF or CR or CRLF as line terminators, and pipe/comma-delimited fields when there were other unambiguous ASCII characters that could have been used (eg, GS, FS, RS) that would have made the encoding/decoding of line termination an I/O thing keeping HT/VT/CR/LF/FF as literally print related codes.
I did a project to translate data framed in the ASCII field/record separator characters and it was gloriously easy. All the ugly escaping considerations with comma-delimited data went away and it became much easier.
What happens when the data contains the record or field separator characters?
I suppose you could document that it's unsupported, and just drop or reject such values, but then the system couldn't be used to handle test data for such systems, for example.
In the case of this system (a quasi-EDI interface used to move records from a fleet fueling point-of-sale system to the ERP software) those characters were forbidden by the source application. My code would have exploded in a fireball if they had been present, but the specification said they couldn't be.
Otherwise you need to have some sort of escape mechanism, exactly like quoting strings in CSV. In fact, there's an ASCII code "ESC" for entirely that purpose. :)
The problem is that those characters are non-printable, which means if you're just dumping the file out somewhere, you can't see them.
UTF-8 on stdin/stdout works perfectly fine (unless you are on Windows of course, which is stuck in in the early 90s when it comes to international text encoding).
> Using LF or CR or CRLF as line terminators
This is also an operating system convention, and it would be better if programming languages wouldn't try to "guess" the correct line endings, since this causes more problems than it solves - but again, this is mostly a Windows specific problem, and it's Microsoft's job to finally bring Windows into the current century.
Unix followed Multics. Multics chose right. ASCII/EMCA-6/ISO646 drafts discussed this at least as early as 1963¹: “For equipment which uses a single combination (called New Line) [...] NL will be coded at FE₂ [Field Effector 2 = 0x0A].”
For an OS that was being created specifically to process text, having the equivalent of CR being separate to LF to allow for overprinting would/should have been a requirement.
I'd say Multics/Unix was technically correct, except this was still the wrong decision for I/O ever since.
The Record Separator is the logical character code to use to indicate the end of a line of text and print position characters, assuming that a line of text is a "record".
Apple hasn't been using CR since the release of OSX (26 years ago). Microsoft could have made the switch at any time too (just as they could have switched to UTF-8 as universal text encoding on Windows), they just choose not to.
In the end it's not the job of programming languages to clean up Microsoft's mess ;)
> In the end it's not the job of programming languages to clean up Microsoft's mess ;)
Why is it Microsoft's fault? They just stayed on their legacy implementation, Linux and Apple chose to move from the legacy implementation to another legacy implementation. That seems dumb.
Both Linux and MacOS followed the Unix implementation, both of them are derivatives of Unix, so why would that change? Unix derived from Multics which chose LF.
The issue is that none of the print carriage movement ASCII characters should be used internally to indicate "end of line", because each of the chosen possibilities are used separately to indicate different carriage movements.
The logical decision would have been to choose one of the "separator" characters to indicate "separation of one line from another" and then allow the I/O drivers to decide what to send/receive to/from a particular device.
Apparently it's from 1901 (Murray code) or 1932 (ITA2).
The fact that both Apple's and CP/M codes came out roughly at the same time, both on microcomputers, shows that it was probably just a design decision.
rswail said ASCII, which definitely pre-dated Unix, not the other way around. And there was some to and fro about the equivalence of LineFeed and NewLine in the 1960s.
Ok, technically not the programming languages, but their stdlibs. On MSVC at least, opening a file in text mode via fopen will translate CRLF into LF on read, and LF into CRLF on write, which has been a neverending source of confusion since at least the 1990s.
Line feed resetting position really makes no sense.
It should just continue text from where the cursor was but on next line. Like staircase. You need CR to go back to start.
It makes perfect sense when you consider text files. When line ends, next line obviously starts from column zero.
CR is the only wrong choice. There's never a reason to go to start of line without erasing the line or moving to next line in a file. And even user interfaces will have smarter ways to do that. It's a completely useless concept outside of typewriters.
Well, CRLF (or worse, LFCR) is also obviously a wrong choice because it's pointless to demand two characters and create problems when one of them is missing when one totally unambiguous character will do.
Modern computer text output devices don’t have a “carriage” or a “feed” mechanism. I’d argue both CR and LF are legacy, anachronistic characters whose purpose was too device specific to make sense as a text encoding.
* NUL terminated strings (and now, non UTF-8 encoded strings on input/output)
* Using LF or CR or CRLF as line terminators, and pipe/comma-delimited fields when there were other unambiguous ASCII characters that could have been used (eg, GS, FS, RS) that would have made the encoding/decoding of line termination an I/O thing keeping HT/VT/CR/LF/FF as literally print related codes.