29

There are two main approaches to line terminators today:

  • CR+LF: Windows, also the Internet standard. Windows got it from DOS, which got it from CP/M, which got it from DEC operating systems. It goes back to how teletypes required both characters to advance to the next line.
  • bare LF: popularised by Unix, but Unix got it from Multics, where it appears to have originated as a simplification of CR+LF. Multics continued to send CR+LF to terminals, but LFCR+LF translation was performed in the terminal driver, an approach continued by Unix systems today.

However, historically, there has been a third convention, once widespread, but now rare: bare CR. It was very common on 8-bit computer systems, including Commodore 64, Acorn BBC, Apple IIs, TRS-80 and ZX Spectrum. It was also the standard convention on classic Mac OS, which inherited it from Apple IIs. And it also saw use by various other systems, including Oberon and MIT Lisp Machines.

There are also various other conventions which saw some use other than these major three – e.g. EBCDIC NEL character (also present in ISO 8859, ISO 2022, and Unicode as a C1 control), LF+CR (spooled text on Acorn BBC and RISC OS), RS (ASCII record separator, early versions of QNX), not using line terminators at all (e.g. fixed length records, or length-prefixed variable length records—common on mainframe and minicomputer platforms, including IBM mainframes, AS/400, RMS under OpenVMS and before that RSX-11).

But I want to focus this question on the bare CR convention in particular: where did it originate? We know the bare LF convention started on Multics and spread from there; but where did the bare CR convention come from? Does anyone know the first system to have used it? Why did people pick bare CR instead of bare LF?

15
  • 5
    For 8 bit systems it was not really about copying a first but practical application - and part of the common theme of reinventing the wheel. Unix and others moved from physical control (CR+LF) to logical (LF) by employing device drivers to handle any mapping. Micros (re)started development without device drivers, without a driver translating a CR send by ENTER but giving it right to application. Terminals (and printers) could be configured to treat CR (or LF) as CR+LF, making use of CR the most simple way in and out. Once early micros had established this, the rest was copying/following.
    – Raffzahn
    Commented Jul 28 at 0:33
  • 4
    The Multics line terminator was called 'newline' and was represented by 012. It specifically moved the print position to the first column of the next line. On devices that did not have a 'newline' it could be sent as carriage return, line feed. But internally it was a 'newline' character. The point may be obscure if you have only used systems where the internal code and all device codes are identical, but this has not always been true. Newline is a natural choice if you have newline-capable devices; it occurred organically on more than one system.
    – dave
    Commented Jul 28 at 2:04
  • 2
    @hippietrail If EBCDIC is meant to mean/360ish mainframes, line length in next to all handling was done by length termination, either fixed (think 80 char punch cards or tape blocks),or variable with a preceding length (usually halfwords). the only somewhat common use case for a line terminator was teletypes and non formatted terminal output. For such it was neither CR (x'0D') not LF (x'25') but 'logical new line' NL (x'15').
    – Raffzahn
    Commented Jul 28 at 10:34
  • 6
    Acknowledge that it goes all the way back to the typewriter (Manual). Carriage Return and Line Feed were both accomplished by the handle. First the CR and the LF. The LF when the carriage hit the end.
    – DogBoy37
    Commented Jul 28 at 14:22
  • 3
    My overall point is, you are trying to establish "the first" to store just CR, as if there's a line of succession, for what I see as a local choice, organically made. Even if there is a first, chronologically speaking, it does not follow that others "copied" the convention, whatever the convention is (CR, NL, CR-LF, count).
    – dave
    Commented Jul 28 at 15:16

3 Answers 3

19

CR-Only is an Equivalent But Independent Solution

It's easy to assume everything has a lineage of being directly related/developed in knowledge/copied, but real-world progress includes independent rediscovery/reinvention, like Columbus' re-discovery of America half a millennium after the Vikings, or Gerald Rosenberger's 1957 patent for the 'first' usable carry-look-ahead circuit a good 20 years after Zuse had already built a working mechanical computer using one. None of these are lesser discoveries because they have not been the absolute first.

In engineering (CS) it's often about different groups, often at different times (*1), having to find a solution to the same, usually well known (*2) problem. within their own/new environment. Here it's the discrepancy between wanted logical line/record handling and needed physical device handling, or the lack thereof if one had absolute control over (hardware) environment involved. In either situation, the designer may arrive at the same solution as previous systems without being influenced at all.

Gen 0: Unit Record Equipment

Data processing begins without any line terminator. Lines were cards and cards were lines. If more lines were to be printed, cards would be inserted or special conditions were wired for direct control of line and formfeed.

Gen 1: Mainframes

Mainframes stayed line-orientated, but for the (rather rare) case of in-band line handling (*3) it was done by introducing some dedicated logical line terminator, independent of physical control characters. Nicely compiled with the new, all-encompassing 8-bit EBCDIC character set. It featured the physical

  • CR (at x'0D') and
  • LF (at x'25') plus a
  • logical new line, NL, at x'15'.

Software with a need to handle multiple lines in a single block (*4) and outside of raw device handling would use NL to separate those lines. Still, the most common use case was line-length blocks with a format specifier at position 1.

Gen 2: The Minis

Upcoming mini computer system started from scratch. Like the very first computers their purpose was at first to provide some processing at all. Except where mainframes inherited the record-based handling as primary I/O, they restarted at character-based. As close to hardware as possible, but without the luxury of tailoring devices connected to their need, as IBM could do. They had to fit with the lowest common denominator. For I/O this meant CR/LF for TTY and TTY-derived printers. With that it was just natural to also use CR/LF.

Gen 2.5: Multics and Unix

The *ixes developed from there with a clear intention to make things better. Except, they didn't have the luxury IBM had in inventing a complete new 8-bit charset but (had to) stay within the 7 bits ASCII provided. Using any of the weakly defined ones (*5) would have prohibited certain assumed applications(*6). So either CR or LF was it and LF won.

Using LF as logical line separator makes a lot of sense. A driver could deliver (almost) the same versatility as direct output:

  • Logical New Line: LF will be translated to CR/LF
  • 'physical' CR/LF: Turned into CR/LF/CR, virtually identical to CR/LF
  • 'trickster' CR: Is passed through to allow double printing, underlining, strike-through, etc.

Minimal impact while still switching from physical to logical line control. By also adding input translation of CR to LF (and suppression of single LF), one gets 'cooked' input using just logical line markers. Beautiful new world.

Gen 3: Early Micros

Early micros restarted from scratch. While lessons learned with 2.5 were available, they started out with the very same issue as Gen 2 minis: limited resources and glad to work at all. So naturally the same solutions applied here - even more as the engineers creating those first micros and their operating systems were already using (DEC-like) mini computers before or during design.

CP/M, DOS and Windows followed that for upward compatibility ... and ultimately the Web.

Gen 3.5: Home Computer

Home computers were in a position much like the *nixes as the technology was established, but they had to make their own thing. Partly due to limited resources, but more so because they again had a close control over hardware, much more related to the situation IBM had then DEC or *nix. Their developers did not have to bother how terminals worked as they built them themselves. It's a, if not the main feature about home computers that keyboard input and video (display) output is integrated.

They did not have need to think much about third party peripherals. Quite the other way, as those companies were keen on selling everything on their own, using lock-in as an advantage, as if an IBM sales manager had written the requirements (*7).

Example: the Apple II and its Monitor

The Apple II makes a prime example for that situation and solution chosen. Not just because it's an early home computer and was developed in-house without any external goals/restrictions (*8), but also due to being mostly developed by a single engineer.

With built-in display hardware there is no need to differentiate CR/LF at all. In fact, while the Monitor ROM's (*9) screen handling (*10) includes two entry points for CR (returning to column 0) and LF (advancing one line), CR ($FC62) always overflows into LF ($FC66), so CR alone wasn't ever possible and LF never needed. In fact, CR/LF would have resulted in advancing for two lines. CR (and LF) was directly called by COUT1 when a CR was detected. This nicely mirrors the input situation, where any line input using GETLN ($FD6A) was terminated by a single CR (not included in input length).

Either of those worked via default entry points COUT/KEYIN used by most applications including BASIC. Either used a vector which would be rerouted if other devices (printer, serial, etc.) are to be used for I/O including DOS (*11).

As a result Apple II programs would only use a CR for line, never CR/LF, and see only a CR if read on a single char basis. Since DOS hooked those output vectors, any line termination (from BASIC or otherwise) was straightforwardly stored as CR (*12) to record separator. Likewise reading from disk returned the record without trailing CR. As a result the Apple II provided the same comfort of a logical line end as *nixes did, except using CR instead of LF.

For other home computers, the reasoning (single line terminator) and constrictions (screen doesn't need two chars and keyboard delivers CR by default) can be assumed to be similar, leading to the same result.

Oh, and yes, the Mac inherited CR from the Apple II. It wasn't until OSX transplanted it onto a *nix base that LF became the default ... and many files still containing CR terminated lines :))

Conclusion

History doesn't repeat, but similar stages do require similar solutions which may end up different, in good part due the control creators had over their environment.

All strived for single character logical line termination, but

  • only IBM controlled peripheral design and code set,
  • most others controlled neither and had to go without
  • home computer in turn did not control charset (*13) but peripherals (*14)

As result

  • LF was a conscious decision to use a single char with the least impact on existing hardware, while
  • CR did the same yielding the least implementation effort while all-new hardware being developed anyway.

*1 - In some way also a bit like every generation thinks they are the first to invent something different that will forever be the most radical version, no matter whether art, literature or music ... anyone remember feeling shocked how rad Mozart is? :))

*2 - Already Babbage knew that improved carry handling would be of great benefit, he just couldn't come up with a working solution. The issue was widely discussed and tinkered at in the heydays of mechanical calculators (1910s to 1940s) but without much practical result.

*3 - Well, that is after those became sufficient to handle abstraction in software and the need did arise due to devices like screen based terminals.

*4 - Mainframes and their software inherited their line orientation from Unit Record Machinery. They handle a line at a time. The vast majority of I/O data was block orientated, either fixed length (punch card, fixed length file) or variable length, where each line/block was prefixed by a (usually) 16-bit length. Handling was usually single line/block.

If a device allowed line control, it was done by special fields (aka the first character of a line to be printed). This includes terminal output.

The only exception were certain non (or simple) format output modes sending multiple lines in one operation. Only here NL was used for both directions and inserted/replaced by whatever the device used/delivered.

*5 - Like the Device Control or Separator characters.

*6 - As communication and maybe more important data exchange with mainframes using them. Not to mention that the DCs were already used by some hardware, like XON/XOFF being defined by TTYs.

*7 - To be fair, they also had a situation similar to IBM, as there wasn't much third party equipment available to buy at the time they introduced their new systems - at least not much in a price range the intended customer would be able to afford ... and custom interfaces were helping to keep it that way.

*8 - Except for ASCII keyboard and NTSC output

*9 - Kind of Apple II's BIOS, a least for all built-in components.

*10 - A lovely piece of code, even more on the Autostart. Nice and tidy. Though, might need some time to read through :))

*11 - DOS is a more complex issue, as it also used those to hook itself to work at all, but for the issue of CR those quirks don't matter.

*12 - Well, it was $8D as all characters output had the high bit set, but that's also a different issue, not changing the principle of operation.

*13 - They did make up their own 8-bit extensions, but stayed with basic 7-bit ASCII for line control.

*14 - Later, when standard printers emerged during he 1980s, they featured ways to be configured to fit various machines definitions - usually including at least a basic CR->CRLF handling.

19
  • "the Monitor ROM's (*9) screen handling (*10) includes two entry points for CR (returning to column 0) and LF (advancing one line), CR ($FC62) always overflows into LF ($FC66), so CR alone wasn't possible and LF never needed" => this reminds me of the (rather similar) explanation of why Acorn outputs LF+CR instead of the more usual CR+LF – retrocomputing.stackexchange.com/a/29939/17803 – interpretations of control characters being influenced by whatever makes the ROM IO code the smallest Commented Jul 28 at 23:25
  • 1
    @SimonKissane Oh, yes. That's another great point supporting the "related but independent" issue. Thanks. Then again, I wouldn't want to state in any way that Woz was less keen on saving space.
    – Raffzahn
    Commented Jul 29 at 13:38
  • Early glass TTY designs (including the Apple I) kept track of cursor position using a shift register that held one bit per character position saying, essentially, "is the cursor here", and thus had no means of resetting the cursor to the start of a line. Having glass teletypes treat CR as newline and ignore LF was easier than any other approach, and given the limited height of glass TTYs, treating CR+LF+LF as a single newline was in many cases more useful than having it advance twice.
    – supercat
    Commented Jul 29 at 15:11
  • I suspect strongly that the Apple II's use of a bare CR as its line separator was motivated by the fact that the Apple I hardware had been designed that way.
    – supercat
    Commented Jul 29 at 18:48
  • Using a bare CR as a line terminator is not equivalent but deficient because it does not allow to indicate overprinting for bolding/underlining in files destined to be printed, nor to draw progress indicators like -<cr>\<cr>|<cr>/<cr>-<cr>.... when outputting to a terminal. The same spilling from one character code to another could have been done from LF to CR.
    – Leo B.
    Commented Jul 29 at 19:18
14

Albeit not mentioned in Wikipedia, among the systems employing bare CR as the line terminator, there was Xerox Alto (as evidenced by observing the raw format of any of the files on the Alto tapes, for example, a directory, which displays in Unix as

[Indigo]<AltoTape>DDTape-Rev-A.dm!1 18 Dec 80 14:49:04 PST  T10029P T10029B^M[Indigo]<AltoTape>DDTape-Rev-A....

(note the ^M denoting the CR character)

Both Niklaus Wirth, the author of the Oberon system, known to employ CR, and Steve Jobs were familiar with Xerox Alto.

9
  • 1
    @SimonKissane You're right. The Wikipedia table has an omission. Please see the updated answer.
    – Leo B.
    Commented Jul 28 at 5:25
  • 1
    Except that Oberon was developed way later than the common use of CR started, Apple 1 & II already used CR before Jobs visited PARC not to mention that Jobs was no engineer involved in any low level development.
    – Raffzahn
    Commented Jul 28 at 10:28
  • 1
    I suspect, but cannot prove, that the early Apple machines were trying to save space, so used a single character, and used CR as simply what came from the ENTER key. Commented Jul 28 at 12:51
  • 4
    Having written code on systems that stored two characters, I say one character is a superior choice, since it saves nit-picking programmers (guilty as charged) from angst about the semantics of seeing just one of the pair!
    – dave
    Commented Jul 28 at 15:20
  • 1
    @DavidTonhofer Source? en.wikipedia.org/wiki/Newline#Representation mentions Oberon among the CR camp.
    – Leo B.
    Commented Jul 29 at 15:48
-2

Originally, you entered CR on a teletype, and the carriage could take slightly more than one character time to go home from column 80. So the next command sent was a non printing character the Line Feed to move the paper up. So an early system would respond to the user hitting CR by echoing it and then sending a LF.

Otherwise the result could be the first character of the next line smeared across the paper somewhere to the right of column 0.

My first printer was a broken Teletype ASR33 bought for £0.50. And on the way to perfect functioning, it did precisely this-there was a dashpot with a variable damping flap to get the carriage return to smartly go home without bouncing or lagging. It also somewhat stopped the table rocking sideways as the massive carriage hit home...

1
  • 2
    As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.
    – Community Bot
    Commented Jul 29 at 15:33

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .